diff --git a/assets/DetectUI.html b/assets/DetectUI.html new file mode 100644 index 0000000..5150b19 --- /dev/null +++ b/assets/DetectUI.html @@ -0,0 +1,231 @@ + + + + + + Title + + + + + + +
+
+
+ + +
+ + + + 2019-03-28 +
+
第一个测试发送消息的内容
+ +
  • +
    + + + + +
    +
    + + + + 2019-03-28 +
    +
    第一个测试发送消息的内容
    +
  • +
  • +
    + + + + +
    +
    + + + + 2019-03-28 +
    +
    第三个测试发送消息的内容,大声说出你们的爱
    +
  • + +
    + +
    + +
    +
    +
    +
    + + + + \ No newline at end of file diff --git a/assets/GuideUI.html b/assets/GuideUI.html new file mode 100644 index 0000000..bab7a5d --- /dev/null +++ b/assets/GuideUI.html @@ -0,0 +1,132 @@ + +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + + + +

    welcome

    + + + \ No newline at end of file diff --git a/assets/LoginUI.html b/assets/LoginUI.html new file mode 100644 index 0000000..0a95023 --- /dev/null +++ b/assets/LoginUI.html @@ -0,0 +1,154 @@ + + + + +LoginUI + + + + +
    +
    +
    + +
    +
    + 1 + 2 +
    +
    + + + + \ No newline at end of file diff --git a/assets/MainPageUI.html b/assets/MainPageUI.html new file mode 100644 index 0000000..a574603 --- /dev/null +++ b/assets/MainPageUI.html @@ -0,0 +1,192 @@ + + + + + + + + + + + + + 首页 + + + + + + + + + + +
    + +

    + +

    + +
    + +
    + +
    +
    +
    + + + + + +
    + +
    +

    版本更新情况

    + + +
    + +
    +

    服务器列表

    +

    北京 ip:192.168.20.2

    +

    广州 ip:192.168.21.4

    +

    长沙 ip:192.168.23.4

    +
    + +
    +

    最近操作

    +

    开启主备切换服务

    +

    开启Nginx服务

    + + +
    +
    + +
    +

    当前可用服务

    +
    +
    +
    +
    查看主动探测
    +
    +
    +
    +
    查看流量控制
    +
    +
    +
    +
    启用主备切换
    +
    +
    +
    +
    查看Nginx日志
    +
    +
    +
    + + + + + + + \ No newline at end of file diff --git a/assets/RegisterUI.html b/assets/RegisterUI.html new file mode 100644 index 0000000..16902a5 --- /dev/null +++ b/assets/RegisterUI.html @@ -0,0 +1,147 @@ + + + + + 注册页面 + + + + + +
    +
    +

    新用户注册

    +

    USER REGISTER

    +
    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    +
    +

    返回登录界面

    +
    +
    + + diff --git a/assets/assets/css/style.css b/assets/assets/css/style.css new file mode 100644 index 0000000..6f672bf --- /dev/null +++ b/assets/assets/css/style.css @@ -0,0 +1,288 @@ +/*-----------------------------------*\ + #style.css +\*-----------------------------------*/ + +/** + * copyright 2022 codewithsadee + */ + + + + + +/*-----------------------------------*\ + #CUSTOM PROPERTY +\*-----------------------------------*/ + +:root { + + /** + * colors + */ + + --medium-slate-blue: hsl(240, 73%, 65%); + --space-cadet_10: hsl(226, 54%, 26%, 0.1); + --space-cadet: hsl(226, 54%, 26%); + --ghost-white: hsl(227, 69%, 97%); + --cool-gray: hsl(226, 19%, 63%); + --cultured: hsl(0, 0%, 95%); + --white: hsl(0, 0%, 100%); + + /** + * typography + */ + + --ff-dm-sans: 'Roboto', sans-serif; + --ff-helvetica: 'Helvetica', sans-serif; + + --fs-1: 3rem; + --fs-2: 2.4rem; + --fs-3: 1.5rem; + --fs-4: 1.2rem; + + --fw-500: 500; + --fw-600: 600; + --fw-700: 700; + + /** + * shadow + */ + + --shadow: 1px 1px 3px hsla(0, 0%, 0%, 0.15); + + /** + * radius + */ + + --radius-5: 5px; + --radius-15: 15px; + + /** + * transition + */ + + --transition-1: 0.25s ease; + --transition-2: 1s ease; + +} + + + + + +/*-----------------------------------*\ + #RESET +\*-----------------------------------*/ + +*, +*::before, +*::after { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +span, +data { display: block; } + +img { height: auto; } + +table, +tbody, +tr, +th, +td { + all: unset; +} + +html { + font-family: var(--ff-dm-sans); + font-size: 10px; +} + +body { + background-color: var(--ghost-white); + color: var(--cool-gray); + font-size: 1.6rem; + padding-inline: 15px; + min-height: 100vh; +} + + + + + +/*-----------------------------------*\ + #REUSED STYLE +\*-----------------------------------*/ + +.flex-center { + display: flex; + justify-content: center; + align-items: center; +} + +.balance-card, +.chart-card { + width: 300px; + height: 150px; + position: relative; + padding: 5px; + border-radius: var(--radius-10); +} + +.text { font-size: var(--fs-3); } + +.h2 { font-size: var(--fs-2); } + + + + + +/*-----------------------------------*\ + #BALANCE CARD +\*-----------------------------------*/ + +.chart-container { + width: 100%; + max-width: 540px; + margin-inline: 100px; + left: 50px; +} + +.balance-card { + background-color: var(--medium-slate-blue); + color: var(--white); + justify-content: space-between; + margin-block-end: 15px; +} + +.balance-card .text { + font-weight: unset; + margin-block-end: 5px; +} + +.balance-card .h2 { font-weight: var(--fw-700); } + +.balance-card .logo { width: 60px; } + + + + + +/*-----------------------------------*\ + #CHART CARD +\*-----------------------------------*/ + +.chart-card { + position: relative; + margin-right: 30px; + background-color: var(--white); +} + +.chart-card .h2 { + color: var(--space-cadet); + font-weight: var(--fw-500); + margin-block-end: 50px; +} + +.chart-card .card-table { + display: block; + padding-block-end: 24px; + border-block-end: 1px solid var(--space-cadet_10); + margin-block-end: 24px; +} + +.chart-card .table-body { + justify-content: space-evenly; + align-items: stretch; + gap: 12px; +} + +.chart-card .table-row { + flex-direction: column-reverse; + justify-content: flex-start; + gap: 10px; + min-height: calc(150px + 31px); +} + +.chart-card .table-heading { + color: var(--space-cadet); + font-family: var(--ff-helvetica); + font-size: var(--fs-4); +} + +.chart-card .table-data { + min-width: 20px; + height: 100%; + background-color: var(--cultured); + cursor: pointer; +} + +.chart-card .chart-bar { + background-color: var(--medium-slate-blue); + height: 100%; + transform-origin: bottom; + transition: transform var(--transition-2); +} + +.chart-card .chart-bar:hover { opacity: 0.75; } + +.tooltip { + position: fixed; + top: 0; + left: 50%; + transform: translateX(-50%); + background-color: var(--white); + color: var(--space-cadet); + font-family: var(--ff-helvetica); + font-weight: var(--fw-600); + padding: 8px; + border: 1px solid var(--cultured); + border-radius: var(--radius-5); + box-shadow: var(--shadow); + pointer-events: none; + opacity: 0; + transition: var(--transition-1); +} + +.tooltip.active { opacity: 1; } + +.chart-card .wrapper { + justify-content: space-between; + align-items: flex-start; +} + +.chart-card .meta-value { + color: var(--space-cadet); + font-weight: var(--fw-500); + margin-block-start: 5px; +} + +.chart-card .meta-value:not(.small) { font-size: var(--fs-1); } + +.chart-card .card-meta:last-child { + align-self: flex-end; + text-align: right; +} + +.piechart{ + margin-top: -180px; + left: 600px; + width: 150px; + height: 150px; + position: fixed; + padding: 5px; + border-radius: var(--radius-10); +} + + + +/*-----------------------------------*\ + #MEDIA QUERIES +\*-----------------------------------*/ + +/** + * responsive for large than 768px screen + */ + diff --git a/assets/assets/images/Nginx.jpg b/assets/assets/images/Nginx.jpg new file mode 100644 index 0000000..bf3095e Binary files /dev/null and b/assets/assets/images/Nginx.jpg differ diff --git a/assets/assets/images/R-C blue.png b/assets/assets/images/R-C blue.png new file mode 100644 index 0000000..2cb2e95 Binary files /dev/null and b/assets/assets/images/R-C blue.png differ diff --git a/assets/assets/images/R-C green.png b/assets/assets/images/R-C green.png new file mode 100644 index 0000000..c81abe0 Binary files /dev/null and b/assets/assets/images/R-C green.png differ diff --git a/assets/assets/images/R-C pink.png b/assets/assets/images/R-C pink.png new file mode 100644 index 0000000..4724b68 Binary files /dev/null and b/assets/assets/images/R-C pink.png differ diff --git a/assets/assets/images/R-C red.png b/assets/assets/images/R-C red.png new file mode 100644 index 0000000..1464f34 Binary files /dev/null and b/assets/assets/images/R-C red.png differ diff --git a/assets/assets/images/R-C.jpg b/assets/assets/images/R-C.jpg new file mode 100644 index 0000000..41c03fa Binary files /dev/null and b/assets/assets/images/R-C.jpg differ diff --git a/assets/assets/images/R-C.png b/assets/assets/images/R-C.png new file mode 100644 index 0000000..02f0b7d Binary files /dev/null and b/assets/assets/images/R-C.png differ diff --git a/assets/assets/images/bg.png b/assets/assets/images/bg.png new file mode 100644 index 0000000..01feb57 Binary files /dev/null and b/assets/assets/images/bg.png differ diff --git a/assets/assets/images/button.jpg b/assets/assets/images/button.jpg new file mode 100644 index 0000000..74e5f06 Binary files /dev/null and b/assets/assets/images/button.jpg differ diff --git a/assets/assets/images/cg.jpg b/assets/assets/images/cg.jpg new file mode 100644 index 0000000..de0d210 Binary files /dev/null and b/assets/assets/images/cg.jpg differ diff --git a/assets/assets/images/delete.png b/assets/assets/images/delete.png new file mode 100644 index 0000000..5a6f11a Binary files /dev/null and b/assets/assets/images/delete.png differ diff --git a/assets/assets/images/dove.png b/assets/assets/images/dove.png new file mode 100644 index 0000000..6af46ef Binary files /dev/null and b/assets/assets/images/dove.png differ diff --git a/assets/assets/images/logo.svg b/assets/assets/images/logo.svg new file mode 100644 index 0000000..ade3219 --- /dev/null +++ b/assets/assets/images/logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/assets/images/nginx.gif b/assets/assets/images/nginx.gif new file mode 100644 index 0000000..bc78bb8 Binary files /dev/null and b/assets/assets/images/nginx.gif differ diff --git a/assets/assets/js/data.json b/assets/assets/js/data.json new file mode 100644 index 0000000..ffd0733 --- /dev/null +++ b/assets/assets/js/data.json @@ -0,0 +1,20 @@ +[ + { + "server": "shanghai", + "stat": "busy", + "amount": 70, + "recentTime":70 + }, + { + "server": "changsha", + "stat": "busy", + "amount": 50, + "recentTime": 1300 + }, + { + "server": "beijing", + "stat": "busy", + "amount": 56, + "recentTime": 70 + } +] \ No newline at end of file diff --git a/assets/assets/js/jquery.js b/assets/assets/js/jquery.js new file mode 100644 index 0000000..200b54e --- /dev/null +++ b/assets/assets/js/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 select all DOM elements + */ + +const tooltip = document.querySelector("[data-tooltip]"); +const chartBars = document.querySelectorAll("[data-chart-bar]"); + + + +/** + * add event on element + */ + +const addEventOnElem = function (elem, type, callback) { + if (elem.length > 1) { + for (let i = 0; i < elem.length; i++) { + elem[i].addEventListener(type, callback); + } + } else { + elem.addEventListener(type, callback); + } +} + + + +/** + * -> get the max day amount from data + */ + +let maxDayAmount = 0; + +for (let i = 0; i < data.length; i++) { + if (data[i].amount > maxDayAmount) { + maxDayAmount = data[i].amount; + } +} + + + +/** + * -> get chart bars height as array + * -> set the height of all bars in chart + */ + +const setChartBarsHeight = function (height) { + for (let i = 0; i < height.length; i++) { + chartBars[i].style.transform = `scaleY(${height[i] / 100})`; + } +} + + + +/** + * -> get the day amount from data + * -> find the percentage of every number + * -> push all number in chartBarsHeight + */ + +const charBarsHeight = []; + +for (let i = 0; i < data.length; i++) { + const dayAmount = data[i].amount; + const percentOfNum = dayAmount / maxDayAmount * 100; + charBarsHeight.push(percentOfNum); +} + +setChartBarsHeight(charBarsHeight); + + + +/** + * -> get top, left, and chart bar width + * -> get tooltip height + * -> set the gap between chart bar and tooltip + * -> set the tooltip position + */ + +const setTooltipPos = function (top, left, chartBarWidth) { + const tooltipHeight = tooltip.offsetHeight; + const gap = 8; + + tooltip.style.top = `${top - tooltipHeight - gap}px`; + tooltip.style.left = `${left + chartBarWidth / 2}px`; +} + + + +/** + * when chart bar is hover + * -> add active class in tooltip + * -> get chart bar top position from window + * -> get chart bar left position from window + * -> get chart bar width + * -> call setTooltipPos and pass the chart bar top, + * left position and width + */ + +const chartBarOnHover = function () { + tooltip.classList.add("active"); + + const barTopPos = this.getBoundingClientRect().top; + const barLeftPos = this.getBoundingClientRect().left; + const barWidth = this.offsetWidth; + + setTooltipPos(barTopPos, barLeftPos, barWidth); +} + +addEventOnElem(chartBars, "mouseover", chartBarOnHover); + + + +/** + * -> hide tooltip when leave cursor from chart bar + */ + +const hideTooltip = function () { + tooltip.classList.remove("active"); +} + +addEventOnElem(chartBars, "mouseleave", hideTooltip); + + + +/** + * -> add tooltip value when hover on any bar chart + */ + +const addTooltipValue = function () { + for (let i = 0; i < data.length; i++) { + if (data[i].server === this.dataset.chartBar) { + tooltip.innerHTML = data[i].amount.toString(); + break; + } + } +} + +addEventOnElem(chartBars, "mouseover", addTooltipValue); \ No newline at end of file diff --git a/assets/css/index.css b/assets/css/index.css new file mode 100644 index 0000000..9e447fb --- /dev/null +++ b/assets/css/index.css @@ -0,0 +1,235 @@ +@charset "utf-8"; + +/* 统一板块宽度和左右居中 */ + +.banner_con, +.news_con, +.case_con, +.links_con, +.footer_con { + width: 1002px; + margin: 0 auto; +} + +#banner { + height: 465px; + background: gray url("../images/banner1_02_02.jpg") no-repeat center; +} + +#banner .banner_con { + height: 465px; + /* background: pink; */ + margin: 0 auto; +} + +.news_con { + height: 243px; + background: white; +} + +.news_title { + /* background: cadetblue; */ + font-size: 18px; + color: #3f434f; + line-height: 18px; + padding-top: 36px; +} + +.news_list { + /* background: cornflowerblue; */ + margin-top: 23px; +} + +.news_list li { + width: 437px; + height: 25px; + background: url("../images/ico_05.jpg") no-repeat left; + padding-left: 14px; + /* margin-top: 23px;不能给li加哦 要给他爹,不然每个儿子顶部都会空出来*/ +} + +.news_list li a { + float: left; + font-size: 12px; + color: #565656; + line-height: 25px; +} + +.news_list li span { + float: right; + color: #9a9a9a; + font-size: 12px; +} + +.news_l { + width: 480px; + height: 243px; + /* background: rebeccapurple; */ + float: left; + padding-left: 21px; +} + +.news_c { + width: 194px; + height: 243px; + background: #f1f1f1; + float: left; + padding: 0 27px 0 20px; +} + +.news_c .txt1 { + font-size: 12px; + color: #555555; + line-height: 25px; + margin-top: 34px; + /* 行高自己去量哦 */ +} + +.news_c .txt2 { + font-size: 12px; + color: #979797; + line-height: 25px; + margin-top: 15 px; + /* 行高自己去量哦 */ +} + +.news_r { + width: 180px; + height: 243px; + background: #fbfbfb url("../images/ma_05.jpg") no-repeat right bottom; + float: left; + padding: 0 38px 0 24px; +} + +.news_r .txt3 { + font-size: 12px; + color: #585858; + line-height: 24px; + margin: 21px 0 22px 0; +} + +.case_con { + height: 304px; + /* background: goldenrod; */ +} + +.case_con h3 { + font-size: 18px; + color: #3f434f; + /* background: pink; */ + padding: 28px 0 18px 22px; +} + +.case_con .case_box { + height: 240px; + /* background: orange; */ +} + +.case_box dl { + width: 210px; + /* 这是由图片尺寸为210得出的,这样文本就会屈居于一处 */ + /* background: burlywood; */ + float: left; + margin: 0 20px; +} + + +/* 这里很重要!一定要设置宽高,也就是图片尺寸得出,这样以后图片更换,结构就不会乱! */ + +.case_box dl dt { + width: 190px; + height: 190px; +} + +.case_box dl dd { + font-size: 24px; + color: #4f4f4f; + line-height: 24px; + margin-top: 13px; + float: center; + left: 10px; +} + + +/* 上面给dt这个容器指定了宽高,现在让img跟随这个容器的宽高!! */ + +.case_box dl dt img { + width: 100%; + height: 100%; +} + +#links { + background: #e5e5e5; +} + +.links_con { + height: 250px; + /* */ +} + +.links_con .links_title { + color: #5d5d5d; + line-height: 16px; + border-bottom: 1px solid #c1c1c1; + padding: 31px 0 11px 13px; +} + +.links_con .links_l { + width: 452px; + height: 250px; + background: #e5e5e5; + float: left; + margin-left: 20px; +} + +.links_con .links_list { + /* background: cornsilk; */ + height: 170px; + padding-left: 5px; + padding-top: 15px; +} + +.links_con .links_list li { + width: 136px; + height: 24px; + background: url("../images/btn_img_13.jpg") no-repeat left center; + font-size: 12px; + line-height: 24px; + padding-left: 13px; + float: left; +} + +.links_con .links_list li a { + color: #5f5f5f; + white-space:nowrap; +} + +.links_con .links_c { + width: 153px; + height: 250px; + background: #e5e5e5; + float: left; + margin: 0 50px; +} +.links_con .links_a { + width: 265px; + height: 24px; + font-size: 14px; + color: #8f8585; +} + +.links_con .links_c .links_list li { + width: 130px; +} + +.links_con .links_r { + width: 256px; + height: 250px; + background: #e5e5e5; + float: left; +} + +.links_con .links_r .map { + text-align: center; + padding-top: 11px; +} \ No newline at end of file diff --git a/assets/css/msgList.css b/assets/css/msgList.css new file mode 100644 index 0000000..e69de29 diff --git a/assets/css/public.css b/assets/css/public.css new file mode 100644 index 0000000..2a97d43 --- /dev/null +++ b/assets/css/public.css @@ -0,0 +1,138 @@ +@charset "utf-8"; + +/* 公共区域版心宽度一样,左右居中 */ + + +/* .header-wrap { + width: 1100px; + height: 62px; + margin: 0 auto; +} */ + +.header_con { + width: 1002px; + height: 100px; + /* background: pink; */ + /* 左右居中 */ + margin: 0 auto; +} + +.header_con h1 { + width: 604px; + height: 66px; + /* background: orange; */ + float: left; + padding: 34px 0 0 20px; +} + +.header_con form { + width: 227px; + height: 61px; + /* background: orangered; */ + float: left; + padding-top: 39px; + padding-right: 21px; +} + +.header_con .search { + width: 195px; + height: 26px; + background: #f1f1f1; + border: 1px solid #e5e5e5; + /* 清除右侧边框 */ + border-right: none; + float: left; + color: #888888; +} + +.header_con .btn { + width: 30px; + height: 26px; + border: none; + background: #f1f1f1 url("../images/search_03.jpg") no-repeat center; +} + +.header_con form div { + width: 30px; + height: 26px; + border: 1px solid #e5e5e5; + border-left: none; + float: left; + /* 给btn套盒子的时候也要加浮动 */ +} + +#nav { + height: 58px; + background: black; +} + +#nav .nav_con { + width: 1002px; + height: 58px; + background: black; + margin: 0 auto; +} + + +/* 导航横向排列 */ + +#nav .nav_con li { + width: 498px; + height: 58px; + float: left; + background: black; + /* 左右居中 */ + text-align: center; + /* 上下居中 */ + line-height: 58px; + border-left: 1px solid #4a4a4a; + font-size: 12px; +} + +.nav_con li a { + color: white; +} + +.margin-left { + margin-left: 25px; + border-left: none!important; +} + + +/* 公共样式的footer */ + +.footer_con { + height: 82px; + /* background: #cccccc; */ +} + +.footer_con .footer_l { + height: 58px; + float: left; + /* background: red; */ + padding-top: 24px; +} + +.footer_con .footer_l a { + font-size: 12px; + float: left; + color: #868686; + border-right: 1px solid #868686; + /* padding:字体和边框的距离哈 */ + padding: 0 7px; + padding-left: 15px; +} + +.footer_con .footer_l .footer-right { + border-right: none!important; +} + +.footer_con .footer_r { + height: 57px; + color: #8a8a8a; + font-size: 12px; + padding-top: 25px; + /* background: pink; */ + padding-right: 21px; + float: right; +} \ No newline at end of file diff --git a/assets/css/rainbow.css b/assets/css/rainbow.css new file mode 100644 index 0000000..cba9f83 --- /dev/null +++ b/assets/css/rainbow.css @@ -0,0 +1,93 @@ +.loader { + background: #000; + background: radial-gradient(#222, #000); + bottom: 0; + left: 0; + overflow: hidden; + position: fixed; + right: 0; + top: 0; + z-index: 99999; +} + +.loader-inner { + bottom: 0; + height: 60px; + left: 0; + margin: auto; + position: absolute; + right: 0; + top: 0; + width: 100px; +} + +.loader-line-wrap { + animation: + spin 2000ms cubic-bezier(.175, .885, .32, 1.275) infinite +; + box-sizing: border-box; + height: 50px; + left: 0; + overflow: hidden; + position: absolute; + top: 0; + transform-origin: 50% 100%; + width: 100px; +} +.loader-line { + border: 4px solid transparent; + border-radius: 100%; + box-sizing: border-box; + height: 100px; + left: 0; + margin: 0 auto; + position: absolute; + right: 0; + top: 0; + width: 100px; +} +.loader-line-wrap:nth-child(1) { animation-delay: -50ms; } +.loader-line-wrap:nth-child(2) { animation-delay: -100ms; } +.loader-line-wrap:nth-child(3) { animation-delay: -150ms; } +.loader-line-wrap:nth-child(4) { animation-delay: -200ms; } +.loader-line-wrap:nth-child(5) { animation-delay: -250ms; } + +.loader-line-wrap:nth-child(1) .loader-line { + border-color: hsl(0, 80%, 60%); + height: 90px; + width: 90px; + top: 7px; +} +.loader-line-wrap:nth-child(2) .loader-line { + border-color: hsl(60, 80%, 60%); + height: 76px; + width: 76px; + top: 14px; +} +.loader-line-wrap:nth-child(3) .loader-line { + border-color: hsl(120, 80%, 60%); + height: 62px; + width: 62px; + top: 21px; +} +.loader-line-wrap:nth-child(4) .loader-line { + border-color: hsl(180, 80%, 60%); + height: 48px; + width: 48px; + top: 28px; +} +.loader-line-wrap:nth-child(5) .loader-line { + border-color: hsl(240, 80%, 60%); + height: 34px; + width: 34px; + top: 35px; +} + +@keyframes spin { + 0%, 15% { + transform: rotate(0); +} +100% { + transform: rotate(360deg); +} +} \ No newline at end of file diff --git a/assets/css/reset.css b/assets/css/reset.css new file mode 100644 index 0000000..37f2257 --- /dev/null +++ b/assets/css/reset.css @@ -0,0 +1,76 @@ +@charset "utf-8"; + +/* 重置样式表 */ + +* { + margin: 0; + padding: 0; +} + + +/* 统一页面文本 */ + +body { + font-size: 16px; + font-family: "微软雅黑"; +} + + +/* 清除列表符号 */ + +ul, +ol, +li { + list-style: none; +} + + +/* 清除下划线 */ + +u, +a { + text-decoration: none; +} + + +/* 清除倾斜 */ + +i, +em { + font-style: normal; +} + + +/* 清除加粗 */ + +b, +strong { + font-weight: normal; +} + + +/* 清除文本默认大小和加粗 */ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: 16px; + font-weight: normal; +} + + +/* 边框清零 */ + +img { + border: none; +} + + +/* 清除聚焦时候的边框 */ + +input { + outline: none; +} \ No newline at end of file diff --git a/assets/echarts.js b/assets/echarts.js new file mode 100644 index 0000000..f3d8bbf --- /dev/null +++ b/assets/echarts.js @@ -0,0 +1,85683 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.echarts = {})); +}(this, (function (exports) { 'use strict'; + + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + + function __extends(d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + } + + var Browser = (function () { + function Browser() { + this.firefox = false; + this.ie = false; + this.edge = false; + this.newEdge = false; + this.weChat = false; + } + return Browser; + }()); + var Env = (function () { + function Env() { + this.browser = new Browser(); + this.node = false; + this.wxa = false; + this.worker = false; + this.svgSupported = false; + this.touchEventsSupported = false; + this.pointerEventsSupported = false; + this.domSupported = false; + this.transformSupported = false; + this.transform3dSupported = false; + this.hasGlobalWindow = typeof window !== 'undefined'; + } + return Env; + }()); + var env = new Env(); + if (typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function') { + env.wxa = true; + env.touchEventsSupported = true; + } + else if (typeof document === 'undefined' && typeof self !== 'undefined') { + env.worker = true; + } + else if (typeof navigator === 'undefined' + || navigator.userAgent.indexOf('Node.js') === 0) { + env.node = true; + env.svgSupported = true; + } + else { + detect(navigator.userAgent, env); + } + function detect(ua, env) { + var browser = env.browser; + var firefox = ua.match(/Firefox\/([\d.]+)/); + var ie = ua.match(/MSIE\s([\d.]+)/) + || ua.match(/Trident\/.+?rv:(([\d.]+))/); + var edge = ua.match(/Edge?\/([\d.]+)/); + var weChat = (/micromessenger/i).test(ua); + if (firefox) { + browser.firefox = true; + browser.version = firefox[1]; + } + if (ie) { + browser.ie = true; + browser.version = ie[1]; + } + if (edge) { + browser.edge = true; + browser.version = edge[1]; + browser.newEdge = +edge[1].split('.')[0] > 18; + } + if (weChat) { + browser.weChat = true; + } + env.svgSupported = typeof SVGRect !== 'undefined'; + env.touchEventsSupported = 'ontouchstart' in window && !browser.ie && !browser.edge; + env.pointerEventsSupported = 'onpointerdown' in window + && (browser.edge || (browser.ie && +browser.version >= 11)); + env.domSupported = typeof document !== 'undefined'; + var style = document.documentElement.style; + env.transform3dSupported = ((browser.ie && 'transition' in style) + || browser.edge + || (('WebKitCSSMatrix' in window) && ('m11' in new WebKitCSSMatrix())) + || 'MozPerspective' in style) + && !('OTransition' in style); + env.transformSupported = env.transform3dSupported + || (browser.ie && +browser.version >= 9); + } + + var DEFAULT_FONT_SIZE = 12; + var DEFAULT_FONT_FAMILY = 'sans-serif'; + var DEFAULT_FONT = DEFAULT_FONT_SIZE + "px " + DEFAULT_FONT_FAMILY; + var OFFSET = 20; + var SCALE = 100; + var defaultWidthMapStr = "007LLmW'55;N0500LLLLLLLLLL00NNNLzWW\\\\WQb\\0FWLg\\bWb\\WQ\\WrWWQ000CL5LLFLL0LL**F*gLLLL5F0LF\\FFF5.5N"; + function getTextWidthMap(mapStr) { + var map = {}; + if (typeof JSON === 'undefined') { + return map; + } + for (var i = 0; i < mapStr.length; i++) { + var char = String.fromCharCode(i + 32); + var size = (mapStr.charCodeAt(i) - OFFSET) / SCALE; + map[char] = size; + } + return map; + } + var DEFAULT_TEXT_WIDTH_MAP = getTextWidthMap(defaultWidthMapStr); + var platformApi = { + createCanvas: function () { + return typeof document !== 'undefined' + && document.createElement('canvas'); + }, + measureText: (function () { + var _ctx; + var _cachedFont; + return function (text, font) { + if (!_ctx) { + var canvas = platformApi.createCanvas(); + _ctx = canvas && canvas.getContext('2d'); + } + if (_ctx) { + if (_cachedFont !== font) { + _cachedFont = _ctx.font = font || DEFAULT_FONT; + } + return _ctx.measureText(text); + } + else { + text = text || ''; + font = font || DEFAULT_FONT; + var res = /(\d+)px/.exec(font); + var fontSize = res && +res[1] || DEFAULT_FONT_SIZE; + var width = 0; + if (font.indexOf('mono') >= 0) { + width = fontSize * text.length; + } + else { + for (var i = 0; i < text.length; i++) { + var preCalcWidth = DEFAULT_TEXT_WIDTH_MAP[text[i]]; + width += preCalcWidth == null ? fontSize : (preCalcWidth * fontSize); + } + } + return { width: width }; + } + }; + })(), + loadImage: function (src, onload, onerror) { + var image = new Image(); + image.onload = onload; + image.onerror = onerror; + image.src = src; + return image; + } + }; + function setPlatformAPI(newPlatformApis) { + for (var key in platformApi) { + if (newPlatformApis[key]) { + platformApi[key] = newPlatformApis[key]; + } + } + } + + var BUILTIN_OBJECT = reduce([ + 'Function', + 'RegExp', + 'Date', + 'Error', + 'CanvasGradient', + 'CanvasPattern', + 'Image', + 'Canvas' + ], function (obj, val) { + obj['[object ' + val + ']'] = true; + return obj; + }, {}); + var TYPED_ARRAY = reduce([ + 'Int8', + 'Uint8', + 'Uint8Clamped', + 'Int16', + 'Uint16', + 'Int32', + 'Uint32', + 'Float32', + 'Float64' + ], function (obj, val) { + obj['[object ' + val + 'Array]'] = true; + return obj; + }, {}); + var objToString = Object.prototype.toString; + var arrayProto = Array.prototype; + var nativeForEach = arrayProto.forEach; + var nativeFilter = arrayProto.filter; + var nativeSlice = arrayProto.slice; + var nativeMap = arrayProto.map; + var ctorFunction = function () { }.constructor; + var protoFunction = ctorFunction ? ctorFunction.prototype : null; + var protoKey = '__proto__'; + var idStart = 0x0907; + function guid() { + return idStart++; + } + function logError() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (typeof console !== 'undefined') { + console.error.apply(console, args); + } + } + function clone(source) { + if (source == null || typeof source !== 'object') { + return source; + } + var result = source; + var typeStr = objToString.call(source); + if (typeStr === '[object Array]') { + if (!isPrimitive(source)) { + result = []; + for (var i = 0, len = source.length; i < len; i++) { + result[i] = clone(source[i]); + } + } + } + else if (TYPED_ARRAY[typeStr]) { + if (!isPrimitive(source)) { + var Ctor = source.constructor; + if (Ctor.from) { + result = Ctor.from(source); + } + else { + result = new Ctor(source.length); + for (var i = 0, len = source.length; i < len; i++) { + result[i] = source[i]; + } + } + } + } + else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) { + result = {}; + for (var key in source) { + if (source.hasOwnProperty(key) && key !== protoKey) { + result[key] = clone(source[key]); + } + } + } + return result; + } + function merge(target, source, overwrite) { + if (!isObject(source) || !isObject(target)) { + return overwrite ? clone(source) : target; + } + for (var key in source) { + if (source.hasOwnProperty(key) && key !== protoKey) { + var targetProp = target[key]; + var sourceProp = source[key]; + if (isObject(sourceProp) + && isObject(targetProp) + && !isArray(sourceProp) + && !isArray(targetProp) + && !isDom(sourceProp) + && !isDom(targetProp) + && !isBuiltInObject(sourceProp) + && !isBuiltInObject(targetProp) + && !isPrimitive(sourceProp) + && !isPrimitive(targetProp)) { + merge(targetProp, sourceProp, overwrite); + } + else if (overwrite || !(key in target)) { + target[key] = clone(source[key]); + } + } + } + return target; + } + function mergeAll(targetAndSources, overwrite) { + var result = targetAndSources[0]; + for (var i = 1, len = targetAndSources.length; i < len; i++) { + result = merge(result, targetAndSources[i], overwrite); + } + return result; + } + function extend(target, source) { + if (Object.assign) { + Object.assign(target, source); + } + else { + for (var key in source) { + if (source.hasOwnProperty(key) && key !== protoKey) { + target[key] = source[key]; + } + } + } + return target; + } + function defaults(target, source, overlay) { + var keysArr = keys(source); + for (var i = 0; i < keysArr.length; i++) { + var key = keysArr[i]; + if ((overlay ? source[key] != null : target[key] == null)) { + target[key] = source[key]; + } + } + return target; + } + var createCanvas = platformApi.createCanvas; + function indexOf(array, value) { + if (array) { + if (array.indexOf) { + return array.indexOf(value); + } + for (var i = 0, len = array.length; i < len; i++) { + if (array[i] === value) { + return i; + } + } + } + return -1; + } + function inherits(clazz, baseClazz) { + var clazzPrototype = clazz.prototype; + function F() { } + F.prototype = baseClazz.prototype; + clazz.prototype = new F(); + for (var prop in clazzPrototype) { + if (clazzPrototype.hasOwnProperty(prop)) { + clazz.prototype[prop] = clazzPrototype[prop]; + } + } + clazz.prototype.constructor = clazz; + clazz.superClass = baseClazz; + } + function mixin(target, source, override) { + target = 'prototype' in target ? target.prototype : target; + source = 'prototype' in source ? source.prototype : source; + if (Object.getOwnPropertyNames) { + var keyList = Object.getOwnPropertyNames(source); + for (var i = 0; i < keyList.length; i++) { + var key = keyList[i]; + if (key !== 'constructor') { + if ((override ? source[key] != null : target[key] == null)) { + target[key] = source[key]; + } + } + } + } + else { + defaults(target, source, override); + } + } + function isArrayLike(data) { + if (!data) { + return false; + } + if (typeof data === 'string') { + return false; + } + return typeof data.length === 'number'; + } + function each(arr, cb, context) { + if (!(arr && cb)) { + return; + } + if (arr.forEach && arr.forEach === nativeForEach) { + arr.forEach(cb, context); + } + else if (arr.length === +arr.length) { + for (var i = 0, len = arr.length; i < len; i++) { + cb.call(context, arr[i], i, arr); + } + } + else { + for (var key in arr) { + if (arr.hasOwnProperty(key)) { + cb.call(context, arr[key], key, arr); + } + } + } + } + function map(arr, cb, context) { + if (!arr) { + return []; + } + if (!cb) { + return slice(arr); + } + if (arr.map && arr.map === nativeMap) { + return arr.map(cb, context); + } + else { + var result = []; + for (var i = 0, len = arr.length; i < len; i++) { + result.push(cb.call(context, arr[i], i, arr)); + } + return result; + } + } + function reduce(arr, cb, memo, context) { + if (!(arr && cb)) { + return; + } + for (var i = 0, len = arr.length; i < len; i++) { + memo = cb.call(context, memo, arr[i], i, arr); + } + return memo; + } + function filter(arr, cb, context) { + if (!arr) { + return []; + } + if (!cb) { + return slice(arr); + } + if (arr.filter && arr.filter === nativeFilter) { + return arr.filter(cb, context); + } + else { + var result = []; + for (var i = 0, len = arr.length; i < len; i++) { + if (cb.call(context, arr[i], i, arr)) { + result.push(arr[i]); + } + } + return result; + } + } + function find(arr, cb, context) { + if (!(arr && cb)) { + return; + } + for (var i = 0, len = arr.length; i < len; i++) { + if (cb.call(context, arr[i], i, arr)) { + return arr[i]; + } + } + } + function keys(obj) { + if (!obj) { + return []; + } + if (Object.keys) { + return Object.keys(obj); + } + var keyList = []; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + keyList.push(key); + } + } + return keyList; + } + function bindPolyfill(func, context) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + return function () { + return func.apply(context, args.concat(nativeSlice.call(arguments))); + }; + } + var bind = (protoFunction && isFunction(protoFunction.bind)) + ? protoFunction.call.bind(protoFunction.bind) + : bindPolyfill; + function curry(func) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + return function () { + return func.apply(this, args.concat(nativeSlice.call(arguments))); + }; + } + function isArray(value) { + if (Array.isArray) { + return Array.isArray(value); + } + return objToString.call(value) === '[object Array]'; + } + function isFunction(value) { + return typeof value === 'function'; + } + function isString(value) { + return typeof value === 'string'; + } + function isStringSafe(value) { + return objToString.call(value) === '[object String]'; + } + function isNumber(value) { + return typeof value === 'number'; + } + function isObject(value) { + var type = typeof value; + return type === 'function' || (!!value && type === 'object'); + } + function isBuiltInObject(value) { + return !!BUILTIN_OBJECT[objToString.call(value)]; + } + function isTypedArray(value) { + return !!TYPED_ARRAY[objToString.call(value)]; + } + function isDom(value) { + return typeof value === 'object' + && typeof value.nodeType === 'number' + && typeof value.ownerDocument === 'object'; + } + function isGradientObject(value) { + return value.colorStops != null; + } + function isImagePatternObject(value) { + return value.image != null; + } + function isRegExp(value) { + return objToString.call(value) === '[object RegExp]'; + } + function eqNaN(value) { + return value !== value; + } + function retrieve() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + for (var i = 0, len = args.length; i < len; i++) { + if (args[i] != null) { + return args[i]; + } + } + } + function retrieve2(value0, value1) { + return value0 != null + ? value0 + : value1; + } + function retrieve3(value0, value1, value2) { + return value0 != null + ? value0 + : value1 != null + ? value1 + : value2; + } + function slice(arr) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + return nativeSlice.apply(arr, args); + } + function normalizeCssArray(val) { + if (typeof (val) === 'number') { + return [val, val, val, val]; + } + var len = val.length; + if (len === 2) { + return [val[0], val[1], val[0], val[1]]; + } + else if (len === 3) { + return [val[0], val[1], val[2], val[1]]; + } + return val; + } + function assert(condition, message) { + if (!condition) { + throw new Error(message); + } + } + function trim(str) { + if (str == null) { + return null; + } + else if (typeof str.trim === 'function') { + return str.trim(); + } + else { + return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); + } + } + var primitiveKey = '__ec_primitive__'; + function setAsPrimitive(obj) { + obj[primitiveKey] = true; + } + function isPrimitive(obj) { + return obj[primitiveKey]; + } + var MapPolyfill = (function () { + function MapPolyfill() { + this.data = {}; + } + MapPolyfill.prototype["delete"] = function (key) { + var existed = this.has(key); + if (existed) { + delete this.data[key]; + } + return existed; + }; + MapPolyfill.prototype.has = function (key) { + return this.data.hasOwnProperty(key); + }; + MapPolyfill.prototype.get = function (key) { + return this.data[key]; + }; + MapPolyfill.prototype.set = function (key, value) { + this.data[key] = value; + return this; + }; + MapPolyfill.prototype.keys = function () { + return keys(this.data); + }; + MapPolyfill.prototype.forEach = function (callback) { + var data = this.data; + for (var key in data) { + if (data.hasOwnProperty(key)) { + callback(data[key], key); + } + } + }; + return MapPolyfill; + }()); + var isNativeMapSupported = typeof Map === 'function'; + function maybeNativeMap() { + return (isNativeMapSupported ? new Map() : new MapPolyfill()); + } + var HashMap = (function () { + function HashMap(obj) { + var isArr = isArray(obj); + this.data = maybeNativeMap(); + var thisMap = this; + (obj instanceof HashMap) + ? obj.each(visit) + : (obj && each(obj, visit)); + function visit(value, key) { + isArr ? thisMap.set(value, key) : thisMap.set(key, value); + } + } + HashMap.prototype.hasKey = function (key) { + return this.data.has(key); + }; + HashMap.prototype.get = function (key) { + return this.data.get(key); + }; + HashMap.prototype.set = function (key, value) { + this.data.set(key, value); + return value; + }; + HashMap.prototype.each = function (cb, context) { + this.data.forEach(function (value, key) { + cb.call(context, value, key); + }); + }; + HashMap.prototype.keys = function () { + var keys = this.data.keys(); + return isNativeMapSupported + ? Array.from(keys) + : keys; + }; + HashMap.prototype.removeKey = function (key) { + this.data["delete"](key); + }; + return HashMap; + }()); + function createHashMap(obj) { + return new HashMap(obj); + } + function concatArray(a, b) { + var newArray = new a.constructor(a.length + b.length); + for (var i = 0; i < a.length; i++) { + newArray[i] = a[i]; + } + var offset = a.length; + for (var i = 0; i < b.length; i++) { + newArray[i + offset] = b[i]; + } + return newArray; + } + function createObject(proto, properties) { + var obj; + if (Object.create) { + obj = Object.create(proto); + } + else { + var StyleCtor = function () { }; + StyleCtor.prototype = proto; + obj = new StyleCtor(); + } + if (properties) { + extend(obj, properties); + } + return obj; + } + function disableUserSelect(dom) { + var domStyle = dom.style; + domStyle.webkitUserSelect = 'none'; + domStyle.userSelect = 'none'; + domStyle.webkitTapHighlightColor = 'rgba(0,0,0,0)'; + domStyle['-webkit-touch-callout'] = 'none'; + } + function hasOwn(own, prop) { + return own.hasOwnProperty(prop); + } + function noop() { } + var RADIAN_TO_DEGREE = 180 / Math.PI; + + var util = /*#__PURE__*/Object.freeze({ + __proto__: null, + guid: guid, + logError: logError, + clone: clone, + merge: merge, + mergeAll: mergeAll, + extend: extend, + defaults: defaults, + createCanvas: createCanvas, + indexOf: indexOf, + inherits: inherits, + mixin: mixin, + isArrayLike: isArrayLike, + each: each, + map: map, + reduce: reduce, + filter: filter, + find: find, + keys: keys, + bind: bind, + curry: curry, + isArray: isArray, + isFunction: isFunction, + isString: isString, + isStringSafe: isStringSafe, + isNumber: isNumber, + isObject: isObject, + isBuiltInObject: isBuiltInObject, + isTypedArray: isTypedArray, + isDom: isDom, + isGradientObject: isGradientObject, + isImagePatternObject: isImagePatternObject, + isRegExp: isRegExp, + eqNaN: eqNaN, + retrieve: retrieve, + retrieve2: retrieve2, + retrieve3: retrieve3, + slice: slice, + normalizeCssArray: normalizeCssArray, + assert: assert, + trim: trim, + setAsPrimitive: setAsPrimitive, + isPrimitive: isPrimitive, + HashMap: HashMap, + createHashMap: createHashMap, + concatArray: concatArray, + createObject: createObject, + disableUserSelect: disableUserSelect, + hasOwn: hasOwn, + noop: noop, + RADIAN_TO_DEGREE: RADIAN_TO_DEGREE + }); + + function create(x, y) { + if (x == null) { + x = 0; + } + if (y == null) { + y = 0; + } + return [x, y]; + } + function copy(out, v) { + out[0] = v[0]; + out[1] = v[1]; + return out; + } + function clone$1(v) { + return [v[0], v[1]]; + } + function set(out, a, b) { + out[0] = a; + out[1] = b; + return out; + } + function add(out, v1, v2) { + out[0] = v1[0] + v2[0]; + out[1] = v1[1] + v2[1]; + return out; + } + function scaleAndAdd(out, v1, v2, a) { + out[0] = v1[0] + v2[0] * a; + out[1] = v1[1] + v2[1] * a; + return out; + } + function sub(out, v1, v2) { + out[0] = v1[0] - v2[0]; + out[1] = v1[1] - v2[1]; + return out; + } + function len(v) { + return Math.sqrt(lenSquare(v)); + } + var length = len; + function lenSquare(v) { + return v[0] * v[0] + v[1] * v[1]; + } + var lengthSquare = lenSquare; + function mul(out, v1, v2) { + out[0] = v1[0] * v2[0]; + out[1] = v1[1] * v2[1]; + return out; + } + function div(out, v1, v2) { + out[0] = v1[0] / v2[0]; + out[1] = v1[1] / v2[1]; + return out; + } + function dot(v1, v2) { + return v1[0] * v2[0] + v1[1] * v2[1]; + } + function scale(out, v, s) { + out[0] = v[0] * s; + out[1] = v[1] * s; + return out; + } + function normalize(out, v) { + var d = len(v); + if (d === 0) { + out[0] = 0; + out[1] = 0; + } + else { + out[0] = v[0] / d; + out[1] = v[1] / d; + } + return out; + } + function distance(v1, v2) { + return Math.sqrt((v1[0] - v2[0]) * (v1[0] - v2[0]) + + (v1[1] - v2[1]) * (v1[1] - v2[1])); + } + var dist = distance; + function distanceSquare(v1, v2) { + return (v1[0] - v2[0]) * (v1[0] - v2[0]) + + (v1[1] - v2[1]) * (v1[1] - v2[1]); + } + var distSquare = distanceSquare; + function negate(out, v) { + out[0] = -v[0]; + out[1] = -v[1]; + return out; + } + function lerp(out, v1, v2, t) { + out[0] = v1[0] + t * (v2[0] - v1[0]); + out[1] = v1[1] + t * (v2[1] - v1[1]); + return out; + } + function applyTransform(out, v, m) { + var x = v[0]; + var y = v[1]; + out[0] = m[0] * x + m[2] * y + m[4]; + out[1] = m[1] * x + m[3] * y + m[5]; + return out; + } + function min(out, v1, v2) { + out[0] = Math.min(v1[0], v2[0]); + out[1] = Math.min(v1[1], v2[1]); + return out; + } + function max(out, v1, v2) { + out[0] = Math.max(v1[0], v2[0]); + out[1] = Math.max(v1[1], v2[1]); + return out; + } + + var vector = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create, + copy: copy, + clone: clone$1, + set: set, + add: add, + scaleAndAdd: scaleAndAdd, + sub: sub, + len: len, + length: length, + lenSquare: lenSquare, + lengthSquare: lengthSquare, + mul: mul, + div: div, + dot: dot, + scale: scale, + normalize: normalize, + distance: distance, + dist: dist, + distanceSquare: distanceSquare, + distSquare: distSquare, + negate: negate, + lerp: lerp, + applyTransform: applyTransform, + min: min, + max: max + }); + + var Param = (function () { + function Param(target, e) { + this.target = target; + this.topTarget = e && e.topTarget; + } + return Param; + }()); + var Draggable = (function () { + function Draggable(handler) { + this.handler = handler; + handler.on('mousedown', this._dragStart, this); + handler.on('mousemove', this._drag, this); + handler.on('mouseup', this._dragEnd, this); + } + Draggable.prototype._dragStart = function (e) { + var draggingTarget = e.target; + while (draggingTarget && !draggingTarget.draggable) { + draggingTarget = draggingTarget.parent || draggingTarget.__hostTarget; + } + if (draggingTarget) { + this._draggingTarget = draggingTarget; + draggingTarget.dragging = true; + this._x = e.offsetX; + this._y = e.offsetY; + this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragstart', e.event); + } + }; + Draggable.prototype._drag = function (e) { + var draggingTarget = this._draggingTarget; + if (draggingTarget) { + var x = e.offsetX; + var y = e.offsetY; + var dx = x - this._x; + var dy = y - this._y; + this._x = x; + this._y = y; + draggingTarget.drift(dx, dy, e); + this.handler.dispatchToElement(new Param(draggingTarget, e), 'drag', e.event); + var dropTarget = this.handler.findHover(x, y, draggingTarget).target; + var lastDropTarget = this._dropTarget; + this._dropTarget = dropTarget; + if (draggingTarget !== dropTarget) { + if (lastDropTarget && dropTarget !== lastDropTarget) { + this.handler.dispatchToElement(new Param(lastDropTarget, e), 'dragleave', e.event); + } + if (dropTarget && dropTarget !== lastDropTarget) { + this.handler.dispatchToElement(new Param(dropTarget, e), 'dragenter', e.event); + } + } + } + }; + Draggable.prototype._dragEnd = function (e) { + var draggingTarget = this._draggingTarget; + if (draggingTarget) { + draggingTarget.dragging = false; + } + this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragend', e.event); + if (this._dropTarget) { + this.handler.dispatchToElement(new Param(this._dropTarget, e), 'drop', e.event); + } + this._draggingTarget = null; + this._dropTarget = null; + }; + return Draggable; + }()); + + var Eventful = (function () { + function Eventful(eventProcessors) { + if (eventProcessors) { + this._$eventProcessor = eventProcessors; + } + } + Eventful.prototype.on = function (event, query, handler, context) { + if (!this._$handlers) { + this._$handlers = {}; + } + var _h = this._$handlers; + if (typeof query === 'function') { + context = handler; + handler = query; + query = null; + } + if (!handler || !event) { + return this; + } + var eventProcessor = this._$eventProcessor; + if (query != null && eventProcessor && eventProcessor.normalizeQuery) { + query = eventProcessor.normalizeQuery(query); + } + if (!_h[event]) { + _h[event] = []; + } + for (var i = 0; i < _h[event].length; i++) { + if (_h[event][i].h === handler) { + return this; + } + } + var wrap = { + h: handler, + query: query, + ctx: (context || this), + callAtLast: handler.zrEventfulCallAtLast + }; + var lastIndex = _h[event].length - 1; + var lastWrap = _h[event][lastIndex]; + (lastWrap && lastWrap.callAtLast) + ? _h[event].splice(lastIndex, 0, wrap) + : _h[event].push(wrap); + return this; + }; + Eventful.prototype.isSilent = function (eventName) { + var _h = this._$handlers; + return !_h || !_h[eventName] || !_h[eventName].length; + }; + Eventful.prototype.off = function (eventType, handler) { + var _h = this._$handlers; + if (!_h) { + return this; + } + if (!eventType) { + this._$handlers = {}; + return this; + } + if (handler) { + if (_h[eventType]) { + var newList = []; + for (var i = 0, l = _h[eventType].length; i < l; i++) { + if (_h[eventType][i].h !== handler) { + newList.push(_h[eventType][i]); + } + } + _h[eventType] = newList; + } + if (_h[eventType] && _h[eventType].length === 0) { + delete _h[eventType]; + } + } + else { + delete _h[eventType]; + } + return this; + }; + Eventful.prototype.trigger = function (eventType) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + if (!this._$handlers) { + return this; + } + var _h = this._$handlers[eventType]; + var eventProcessor = this._$eventProcessor; + if (_h) { + var argLen = args.length; + var len = _h.length; + for (var i = 0; i < len; i++) { + var hItem = _h[i]; + if (eventProcessor + && eventProcessor.filter + && hItem.query != null + && !eventProcessor.filter(eventType, hItem.query)) { + continue; + } + switch (argLen) { + case 0: + hItem.h.call(hItem.ctx); + break; + case 1: + hItem.h.call(hItem.ctx, args[0]); + break; + case 2: + hItem.h.call(hItem.ctx, args[0], args[1]); + break; + default: + hItem.h.apply(hItem.ctx, args); + break; + } + } + } + eventProcessor && eventProcessor.afterTrigger + && eventProcessor.afterTrigger(eventType); + return this; + }; + Eventful.prototype.triggerWithContext = function (type) { + var args = []; + for (var _i = 1; _i < arguments.length; _i++) { + args[_i - 1] = arguments[_i]; + } + if (!this._$handlers) { + return this; + } + var _h = this._$handlers[type]; + var eventProcessor = this._$eventProcessor; + if (_h) { + var argLen = args.length; + var ctx = args[argLen - 1]; + var len = _h.length; + for (var i = 0; i < len; i++) { + var hItem = _h[i]; + if (eventProcessor + && eventProcessor.filter + && hItem.query != null + && !eventProcessor.filter(type, hItem.query)) { + continue; + } + switch (argLen) { + case 0: + hItem.h.call(ctx); + break; + case 1: + hItem.h.call(ctx, args[0]); + break; + case 2: + hItem.h.call(ctx, args[0], args[1]); + break; + default: + hItem.h.apply(ctx, args.slice(1, argLen - 1)); + break; + } + } + } + eventProcessor && eventProcessor.afterTrigger + && eventProcessor.afterTrigger(type); + return this; + }; + return Eventful; + }()); + + var LN2 = Math.log(2); + function determinant(rows, rank, rowStart, rowMask, colMask, detCache) { + var cacheKey = rowMask + '-' + colMask; + var fullRank = rows.length; + if (detCache.hasOwnProperty(cacheKey)) { + return detCache[cacheKey]; + } + if (rank === 1) { + var colStart = Math.round(Math.log(((1 << fullRank) - 1) & ~colMask) / LN2); + return rows[rowStart][colStart]; + } + var subRowMask = rowMask | (1 << rowStart); + var subRowStart = rowStart + 1; + while (rowMask & (1 << subRowStart)) { + subRowStart++; + } + var sum = 0; + for (var j = 0, colLocalIdx = 0; j < fullRank; j++) { + var colTag = 1 << j; + if (!(colTag & colMask)) { + sum += (colLocalIdx % 2 ? -1 : 1) * rows[rowStart][j] + * determinant(rows, rank - 1, subRowStart, subRowMask, colMask | colTag, detCache); + colLocalIdx++; + } + } + detCache[cacheKey] = sum; + return sum; + } + function buildTransformer(src, dest) { + var mA = [ + [src[0], src[1], 1, 0, 0, 0, -dest[0] * src[0], -dest[0] * src[1]], + [0, 0, 0, src[0], src[1], 1, -dest[1] * src[0], -dest[1] * src[1]], + [src[2], src[3], 1, 0, 0, 0, -dest[2] * src[2], -dest[2] * src[3]], + [0, 0, 0, src[2], src[3], 1, -dest[3] * src[2], -dest[3] * src[3]], + [src[4], src[5], 1, 0, 0, 0, -dest[4] * src[4], -dest[4] * src[5]], + [0, 0, 0, src[4], src[5], 1, -dest[5] * src[4], -dest[5] * src[5]], + [src[6], src[7], 1, 0, 0, 0, -dest[6] * src[6], -dest[6] * src[7]], + [0, 0, 0, src[6], src[7], 1, -dest[7] * src[6], -dest[7] * src[7]] + ]; + var detCache = {}; + var det = determinant(mA, 8, 0, 0, 0, detCache); + if (det === 0) { + return; + } + var vh = []; + for (var i = 0; i < 8; i++) { + for (var j = 0; j < 8; j++) { + vh[j] == null && (vh[j] = 0); + vh[j] += ((i + j) % 2 ? -1 : 1) + * determinant(mA, 7, i === 0 ? 1 : 0, 1 << i, 1 << j, detCache) + / det * dest[i]; + } + } + return function (out, srcPointX, srcPointY) { + var pk = srcPointX * vh[6] + srcPointY * vh[7] + 1; + out[0] = (srcPointX * vh[0] + srcPointY * vh[1] + vh[2]) / pk; + out[1] = (srcPointX * vh[3] + srcPointY * vh[4] + vh[5]) / pk; + }; + } + + var EVENT_SAVED_PROP = '___zrEVENTSAVED'; + var _calcOut = []; + function transformLocalCoord(out, elFrom, elTarget, inX, inY) { + return transformCoordWithViewport(_calcOut, elFrom, inX, inY, true) + && transformCoordWithViewport(out, elTarget, _calcOut[0], _calcOut[1]); + } + function transformCoordWithViewport(out, el, inX, inY, inverse) { + if (el.getBoundingClientRect && env.domSupported && !isCanvasEl(el)) { + var saved = el[EVENT_SAVED_PROP] || (el[EVENT_SAVED_PROP] = {}); + var markers = prepareCoordMarkers(el, saved); + var transformer = preparePointerTransformer(markers, saved, inverse); + if (transformer) { + transformer(out, inX, inY); + return true; + } + } + return false; + } + function prepareCoordMarkers(el, saved) { + var markers = saved.markers; + if (markers) { + return markers; + } + markers = saved.markers = []; + var propLR = ['left', 'right']; + var propTB = ['top', 'bottom']; + for (var i = 0; i < 4; i++) { + var marker = document.createElement('div'); + var stl = marker.style; + var idxLR = i % 2; + var idxTB = (i >> 1) % 2; + stl.cssText = [ + 'position: absolute', + 'visibility: hidden', + 'padding: 0', + 'margin: 0', + 'border-width: 0', + 'user-select: none', + 'width:0', + 'height:0', + propLR[idxLR] + ':0', + propTB[idxTB] + ':0', + propLR[1 - idxLR] + ':auto', + propTB[1 - idxTB] + ':auto', + '' + ].join('!important;'); + el.appendChild(marker); + markers.push(marker); + } + return markers; + } + function preparePointerTransformer(markers, saved, inverse) { + var transformerName = inverse ? 'invTrans' : 'trans'; + var transformer = saved[transformerName]; + var oldSrcCoords = saved.srcCoords; + var srcCoords = []; + var destCoords = []; + var oldCoordTheSame = true; + for (var i = 0; i < 4; i++) { + var rect = markers[i].getBoundingClientRect(); + var ii = 2 * i; + var x = rect.left; + var y = rect.top; + srcCoords.push(x, y); + oldCoordTheSame = oldCoordTheSame && oldSrcCoords && x === oldSrcCoords[ii] && y === oldSrcCoords[ii + 1]; + destCoords.push(markers[i].offsetLeft, markers[i].offsetTop); + } + return (oldCoordTheSame && transformer) + ? transformer + : (saved.srcCoords = srcCoords, + saved[transformerName] = inverse + ? buildTransformer(destCoords, srcCoords) + : buildTransformer(srcCoords, destCoords)); + } + function isCanvasEl(el) { + return el.nodeName.toUpperCase() === 'CANVAS'; + } + var replaceReg = /([&<>"'])/g; + var replaceMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''' + }; + function encodeHTML(source) { + return source == null + ? '' + : (source + '').replace(replaceReg, function (str, c) { + return replaceMap[c]; + }); + } + + var MOUSE_EVENT_REG = /^(?:mouse|pointer|contextmenu|drag|drop)|click/; + var _calcOut$1 = []; + var firefoxNotSupportOffsetXY = env.browser.firefox + && +env.browser.version.split('.')[0] < 39; + function clientToLocal(el, e, out, calculate) { + out = out || {}; + if (calculate) { + calculateZrXY(el, e, out); + } + else if (firefoxNotSupportOffsetXY + && e.layerX != null + && e.layerX !== e.offsetX) { + out.zrX = e.layerX; + out.zrY = e.layerY; + } + else if (e.offsetX != null) { + out.zrX = e.offsetX; + out.zrY = e.offsetY; + } + else { + calculateZrXY(el, e, out); + } + return out; + } + function calculateZrXY(el, e, out) { + if (env.domSupported && el.getBoundingClientRect) { + var ex = e.clientX; + var ey = e.clientY; + if (isCanvasEl(el)) { + var box = el.getBoundingClientRect(); + out.zrX = ex - box.left; + out.zrY = ey - box.top; + return; + } + else { + if (transformCoordWithViewport(_calcOut$1, el, ex, ey)) { + out.zrX = _calcOut$1[0]; + out.zrY = _calcOut$1[1]; + return; + } + } + } + out.zrX = out.zrY = 0; + } + function getNativeEvent(e) { + return e + || window.event; + } + function normalizeEvent(el, e, calculate) { + e = getNativeEvent(e); + if (e.zrX != null) { + return e; + } + var eventType = e.type; + var isTouch = eventType && eventType.indexOf('touch') >= 0; + if (!isTouch) { + clientToLocal(el, e, e, calculate); + var wheelDelta = getWheelDeltaMayPolyfill(e); + e.zrDelta = wheelDelta ? wheelDelta / 120 : -(e.detail || 0) / 3; + } + else { + var touch = eventType !== 'touchend' + ? e.targetTouches[0] + : e.changedTouches[0]; + touch && clientToLocal(el, touch, e, calculate); + } + var button = e.button; + if (e.which == null && button !== undefined && MOUSE_EVENT_REG.test(e.type)) { + e.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0))); + } + return e; + } + function getWheelDeltaMayPolyfill(e) { + var rawWheelDelta = e.wheelDelta; + if (rawWheelDelta) { + return rawWheelDelta; + } + var deltaX = e.deltaX; + var deltaY = e.deltaY; + if (deltaX == null || deltaY == null) { + return rawWheelDelta; + } + var delta = deltaY !== 0 ? Math.abs(deltaY) : Math.abs(deltaX); + var sign = deltaY > 0 ? -1 + : deltaY < 0 ? 1 + : deltaX > 0 ? -1 + : 1; + return 3 * delta * sign; + } + function addEventListener(el, name, handler, opt) { + el.addEventListener(name, handler, opt); + } + function removeEventListener(el, name, handler, opt) { + el.removeEventListener(name, handler, opt); + } + var stop = function (e) { + e.preventDefault(); + e.stopPropagation(); + e.cancelBubble = true; + }; + function isMiddleOrRightButtonOnMouseUpDown(e) { + return e.which === 2 || e.which === 3; + } + + var GestureMgr = (function () { + function GestureMgr() { + this._track = []; + } + GestureMgr.prototype.recognize = function (event, target, root) { + this._doTrack(event, target, root); + return this._recognize(event); + }; + GestureMgr.prototype.clear = function () { + this._track.length = 0; + return this; + }; + GestureMgr.prototype._doTrack = function (event, target, root) { + var touches = event.touches; + if (!touches) { + return; + } + var trackItem = { + points: [], + touches: [], + target: target, + event: event + }; + for (var i = 0, len = touches.length; i < len; i++) { + var touch = touches[i]; + var pos = clientToLocal(root, touch, {}); + trackItem.points.push([pos.zrX, pos.zrY]); + trackItem.touches.push(touch); + } + this._track.push(trackItem); + }; + GestureMgr.prototype._recognize = function (event) { + for (var eventName in recognizers) { + if (recognizers.hasOwnProperty(eventName)) { + var gestureInfo = recognizers[eventName](this._track, event); + if (gestureInfo) { + return gestureInfo; + } + } + } + }; + return GestureMgr; + }()); + function dist$1(pointPair) { + var dx = pointPair[1][0] - pointPair[0][0]; + var dy = pointPair[1][1] - pointPair[0][1]; + return Math.sqrt(dx * dx + dy * dy); + } + function center(pointPair) { + return [ + (pointPair[0][0] + pointPair[1][0]) / 2, + (pointPair[0][1] + pointPair[1][1]) / 2 + ]; + } + var recognizers = { + pinch: function (tracks, event) { + var trackLen = tracks.length; + if (!trackLen) { + return; + } + var pinchEnd = (tracks[trackLen - 1] || {}).points; + var pinchPre = (tracks[trackLen - 2] || {}).points || pinchEnd; + if (pinchPre + && pinchPre.length > 1 + && pinchEnd + && pinchEnd.length > 1) { + var pinchScale = dist$1(pinchEnd) / dist$1(pinchPre); + !isFinite(pinchScale) && (pinchScale = 1); + event.pinchScale = pinchScale; + var pinchCenter = center(pinchEnd); + event.pinchX = pinchCenter[0]; + event.pinchY = pinchCenter[1]; + return { + type: 'pinch', + target: tracks[0].target, + event: event + }; + } + } + }; + + function create$1() { + return [1, 0, 0, 1, 0, 0]; + } + function identity(out) { + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 1; + out[4] = 0; + out[5] = 0; + return out; + } + function copy$1(out, m) { + out[0] = m[0]; + out[1] = m[1]; + out[2] = m[2]; + out[3] = m[3]; + out[4] = m[4]; + out[5] = m[5]; + return out; + } + function mul$1(out, m1, m2) { + var out0 = m1[0] * m2[0] + m1[2] * m2[1]; + var out1 = m1[1] * m2[0] + m1[3] * m2[1]; + var out2 = m1[0] * m2[2] + m1[2] * m2[3]; + var out3 = m1[1] * m2[2] + m1[3] * m2[3]; + var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4]; + var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5]; + out[0] = out0; + out[1] = out1; + out[2] = out2; + out[3] = out3; + out[4] = out4; + out[5] = out5; + return out; + } + function translate(out, a, v) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + out[4] = a[4] + v[0]; + out[5] = a[5] + v[1]; + return out; + } + function rotate(out, a, rad, pivot) { + if (pivot === void 0) { pivot = [0, 0]; } + var aa = a[0]; + var ac = a[2]; + var atx = a[4]; + var ab = a[1]; + var ad = a[3]; + var aty = a[5]; + var st = Math.sin(rad); + var ct = Math.cos(rad); + out[0] = aa * ct + ab * st; + out[1] = -aa * st + ab * ct; + out[2] = ac * ct + ad * st; + out[3] = -ac * st + ct * ad; + out[4] = ct * (atx - pivot[0]) + st * (aty - pivot[1]) + pivot[0]; + out[5] = ct * (aty - pivot[1]) - st * (atx - pivot[0]) + pivot[1]; + return out; + } + function scale$1(out, a, v) { + var vx = v[0]; + var vy = v[1]; + out[0] = a[0] * vx; + out[1] = a[1] * vy; + out[2] = a[2] * vx; + out[3] = a[3] * vy; + out[4] = a[4] * vx; + out[5] = a[5] * vy; + return out; + } + function invert(out, a) { + var aa = a[0]; + var ac = a[2]; + var atx = a[4]; + var ab = a[1]; + var ad = a[3]; + var aty = a[5]; + var det = aa * ad - ab * ac; + if (!det) { + return null; + } + det = 1.0 / det; + out[0] = ad * det; + out[1] = -ab * det; + out[2] = -ac * det; + out[3] = aa * det; + out[4] = (ac * aty - ad * atx) * det; + out[5] = (ab * atx - aa * aty) * det; + return out; + } + function clone$2(a) { + var b = create$1(); + copy$1(b, a); + return b; + } + + var matrix = /*#__PURE__*/Object.freeze({ + __proto__: null, + create: create$1, + identity: identity, + copy: copy$1, + mul: mul$1, + translate: translate, + rotate: rotate, + scale: scale$1, + invert: invert, + clone: clone$2 + }); + + var Point = (function () { + function Point(x, y) { + this.x = x || 0; + this.y = y || 0; + } + Point.prototype.copy = function (other) { + this.x = other.x; + this.y = other.y; + return this; + }; + Point.prototype.clone = function () { + return new Point(this.x, this.y); + }; + Point.prototype.set = function (x, y) { + this.x = x; + this.y = y; + return this; + }; + Point.prototype.equal = function (other) { + return other.x === this.x && other.y === this.y; + }; + Point.prototype.add = function (other) { + this.x += other.x; + this.y += other.y; + return this; + }; + Point.prototype.scale = function (scalar) { + this.x *= scalar; + this.y *= scalar; + }; + Point.prototype.scaleAndAdd = function (other, scalar) { + this.x += other.x * scalar; + this.y += other.y * scalar; + }; + Point.prototype.sub = function (other) { + this.x -= other.x; + this.y -= other.y; + return this; + }; + Point.prototype.dot = function (other) { + return this.x * other.x + this.y * other.y; + }; + Point.prototype.len = function () { + return Math.sqrt(this.x * this.x + this.y * this.y); + }; + Point.prototype.lenSquare = function () { + return this.x * this.x + this.y * this.y; + }; + Point.prototype.normalize = function () { + var len = this.len(); + this.x /= len; + this.y /= len; + return this; + }; + Point.prototype.distance = function (other) { + var dx = this.x - other.x; + var dy = this.y - other.y; + return Math.sqrt(dx * dx + dy * dy); + }; + Point.prototype.distanceSquare = function (other) { + var dx = this.x - other.x; + var dy = this.y - other.y; + return dx * dx + dy * dy; + }; + Point.prototype.negate = function () { + this.x = -this.x; + this.y = -this.y; + return this; + }; + Point.prototype.transform = function (m) { + if (!m) { + return; + } + var x = this.x; + var y = this.y; + this.x = m[0] * x + m[2] * y + m[4]; + this.y = m[1] * x + m[3] * y + m[5]; + return this; + }; + Point.prototype.toArray = function (out) { + out[0] = this.x; + out[1] = this.y; + return out; + }; + Point.prototype.fromArray = function (input) { + this.x = input[0]; + this.y = input[1]; + }; + Point.set = function (p, x, y) { + p.x = x; + p.y = y; + }; + Point.copy = function (p, p2) { + p.x = p2.x; + p.y = p2.y; + }; + Point.len = function (p) { + return Math.sqrt(p.x * p.x + p.y * p.y); + }; + Point.lenSquare = function (p) { + return p.x * p.x + p.y * p.y; + }; + Point.dot = function (p0, p1) { + return p0.x * p1.x + p0.y * p1.y; + }; + Point.add = function (out, p0, p1) { + out.x = p0.x + p1.x; + out.y = p0.y + p1.y; + }; + Point.sub = function (out, p0, p1) { + out.x = p0.x - p1.x; + out.y = p0.y - p1.y; + }; + Point.scale = function (out, p0, scalar) { + out.x = p0.x * scalar; + out.y = p0.y * scalar; + }; + Point.scaleAndAdd = function (out, p0, p1, scalar) { + out.x = p0.x + p1.x * scalar; + out.y = p0.y + p1.y * scalar; + }; + Point.lerp = function (out, p0, p1, t) { + var onet = 1 - t; + out.x = onet * p0.x + t * p1.x; + out.y = onet * p0.y + t * p1.y; + }; + return Point; + }()); + + var mathMin = Math.min; + var mathMax = Math.max; + var lt = new Point(); + var rb = new Point(); + var lb = new Point(); + var rt = new Point(); + var minTv = new Point(); + var maxTv = new Point(); + var BoundingRect = (function () { + function BoundingRect(x, y, width, height) { + if (width < 0) { + x = x + width; + width = -width; + } + if (height < 0) { + y = y + height; + height = -height; + } + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + BoundingRect.prototype.union = function (other) { + var x = mathMin(other.x, this.x); + var y = mathMin(other.y, this.y); + if (isFinite(this.x) && isFinite(this.width)) { + this.width = mathMax(other.x + other.width, this.x + this.width) - x; + } + else { + this.width = other.width; + } + if (isFinite(this.y) && isFinite(this.height)) { + this.height = mathMax(other.y + other.height, this.y + this.height) - y; + } + else { + this.height = other.height; + } + this.x = x; + this.y = y; + }; + BoundingRect.prototype.applyTransform = function (m) { + BoundingRect.applyTransform(this, this, m); + }; + BoundingRect.prototype.calculateTransform = function (b) { + var a = this; + var sx = b.width / a.width; + var sy = b.height / a.height; + var m = create$1(); + translate(m, m, [-a.x, -a.y]); + scale$1(m, m, [sx, sy]); + translate(m, m, [b.x, b.y]); + return m; + }; + BoundingRect.prototype.intersect = function (b, mtv) { + if (!b) { + return false; + } + if (!(b instanceof BoundingRect)) { + b = BoundingRect.create(b); + } + var a = this; + var ax0 = a.x; + var ax1 = a.x + a.width; + var ay0 = a.y; + var ay1 = a.y + a.height; + var bx0 = b.x; + var bx1 = b.x + b.width; + var by0 = b.y; + var by1 = b.y + b.height; + var overlap = !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0); + if (mtv) { + var dMin = Infinity; + var dMax = 0; + var d0 = Math.abs(ax1 - bx0); + var d1 = Math.abs(bx1 - ax0); + var d2 = Math.abs(ay1 - by0); + var d3 = Math.abs(by1 - ay0); + var dx = Math.min(d0, d1); + var dy = Math.min(d2, d3); + if (ax1 < bx0 || bx1 < ax0) { + if (dx > dMax) { + dMax = dx; + if (d0 < d1) { + Point.set(maxTv, -d0, 0); + } + else { + Point.set(maxTv, d1, 0); + } + } + } + else { + if (dx < dMin) { + dMin = dx; + if (d0 < d1) { + Point.set(minTv, d0, 0); + } + else { + Point.set(minTv, -d1, 0); + } + } + } + if (ay1 < by0 || by1 < ay0) { + if (dy > dMax) { + dMax = dy; + if (d2 < d3) { + Point.set(maxTv, 0, -d2); + } + else { + Point.set(maxTv, 0, d3); + } + } + } + else { + if (dx < dMin) { + dMin = dx; + if (d2 < d3) { + Point.set(minTv, 0, d2); + } + else { + Point.set(minTv, 0, -d3); + } + } + } + } + if (mtv) { + Point.copy(mtv, overlap ? minTv : maxTv); + } + return overlap; + }; + BoundingRect.prototype.contain = function (x, y) { + var rect = this; + return x >= rect.x + && x <= (rect.x + rect.width) + && y >= rect.y + && y <= (rect.y + rect.height); + }; + BoundingRect.prototype.clone = function () { + return new BoundingRect(this.x, this.y, this.width, this.height); + }; + BoundingRect.prototype.copy = function (other) { + BoundingRect.copy(this, other); + }; + BoundingRect.prototype.plain = function () { + return { + x: this.x, + y: this.y, + width: this.width, + height: this.height + }; + }; + BoundingRect.prototype.isFinite = function () { + return isFinite(this.x) + && isFinite(this.y) + && isFinite(this.width) + && isFinite(this.height); + }; + BoundingRect.prototype.isZero = function () { + return this.width === 0 || this.height === 0; + }; + BoundingRect.create = function (rect) { + return new BoundingRect(rect.x, rect.y, rect.width, rect.height); + }; + BoundingRect.copy = function (target, source) { + target.x = source.x; + target.y = source.y; + target.width = source.width; + target.height = source.height; + }; + BoundingRect.applyTransform = function (target, source, m) { + if (!m) { + if (target !== source) { + BoundingRect.copy(target, source); + } + return; + } + if (m[1] < 1e-5 && m[1] > -1e-5 && m[2] < 1e-5 && m[2] > -1e-5) { + var sx = m[0]; + var sy = m[3]; + var tx = m[4]; + var ty = m[5]; + target.x = source.x * sx + tx; + target.y = source.y * sy + ty; + target.width = source.width * sx; + target.height = source.height * sy; + if (target.width < 0) { + target.x += target.width; + target.width = -target.width; + } + if (target.height < 0) { + target.y += target.height; + target.height = -target.height; + } + return; + } + lt.x = lb.x = source.x; + lt.y = rt.y = source.y; + rb.x = rt.x = source.x + source.width; + rb.y = lb.y = source.y + source.height; + lt.transform(m); + rt.transform(m); + rb.transform(m); + lb.transform(m); + target.x = mathMin(lt.x, rb.x, lb.x, rt.x); + target.y = mathMin(lt.y, rb.y, lb.y, rt.y); + var maxX = mathMax(lt.x, rb.x, lb.x, rt.x); + var maxY = mathMax(lt.y, rb.y, lb.y, rt.y); + target.width = maxX - target.x; + target.height = maxY - target.y; + }; + return BoundingRect; + }()); + + var SILENT = 'silent'; + function makeEventPacket(eveType, targetInfo, event) { + return { + type: eveType, + event: event, + target: targetInfo.target, + topTarget: targetInfo.topTarget, + cancelBubble: false, + offsetX: event.zrX, + offsetY: event.zrY, + gestureEvent: event.gestureEvent, + pinchX: event.pinchX, + pinchY: event.pinchY, + pinchScale: event.pinchScale, + wheelDelta: event.zrDelta, + zrByTouch: event.zrByTouch, + which: event.which, + stop: stopEvent + }; + } + function stopEvent() { + stop(this.event); + } + var EmptyProxy = (function (_super) { + __extends(EmptyProxy, _super); + function EmptyProxy() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.handler = null; + return _this; + } + EmptyProxy.prototype.dispose = function () { }; + EmptyProxy.prototype.setCursor = function () { }; + return EmptyProxy; + }(Eventful)); + var HoveredResult = (function () { + function HoveredResult(x, y) { + this.x = x; + this.y = y; + } + return HoveredResult; + }()); + var handlerNames = [ + 'click', 'dblclick', 'mousewheel', 'mouseout', + 'mouseup', 'mousedown', 'mousemove', 'contextmenu' + ]; + var tmpRect = new BoundingRect(0, 0, 0, 0); + var Handler = (function (_super) { + __extends(Handler, _super); + function Handler(storage, painter, proxy, painterRoot, pointerSize) { + var _this = _super.call(this) || this; + _this._hovered = new HoveredResult(0, 0); + _this.storage = storage; + _this.painter = painter; + _this.painterRoot = painterRoot; + _this._pointerSize = pointerSize; + proxy = proxy || new EmptyProxy(); + _this.proxy = null; + _this.setHandlerProxy(proxy); + _this._draggingMgr = new Draggable(_this); + return _this; + } + Handler.prototype.setHandlerProxy = function (proxy) { + if (this.proxy) { + this.proxy.dispose(); + } + if (proxy) { + each(handlerNames, function (name) { + proxy.on && proxy.on(name, this[name], this); + }, this); + proxy.handler = this; + } + this.proxy = proxy; + }; + Handler.prototype.mousemove = function (event) { + var x = event.zrX; + var y = event.zrY; + var isOutside = isOutsideBoundary(this, x, y); + var lastHovered = this._hovered; + var lastHoveredTarget = lastHovered.target; + if (lastHoveredTarget && !lastHoveredTarget.__zr) { + lastHovered = this.findHover(lastHovered.x, lastHovered.y); + lastHoveredTarget = lastHovered.target; + } + var hovered = this._hovered = isOutside ? new HoveredResult(x, y) : this.findHover(x, y); + var hoveredTarget = hovered.target; + var proxy = this.proxy; + proxy.setCursor && proxy.setCursor(hoveredTarget ? hoveredTarget.cursor : 'default'); + if (lastHoveredTarget && hoveredTarget !== lastHoveredTarget) { + this.dispatchToElement(lastHovered, 'mouseout', event); + } + this.dispatchToElement(hovered, 'mousemove', event); + if (hoveredTarget && hoveredTarget !== lastHoveredTarget) { + this.dispatchToElement(hovered, 'mouseover', event); + } + }; + Handler.prototype.mouseout = function (event) { + var eventControl = event.zrEventControl; + if (eventControl !== 'only_globalout') { + this.dispatchToElement(this._hovered, 'mouseout', event); + } + if (eventControl !== 'no_globalout') { + this.trigger('globalout', { type: 'globalout', event: event }); + } + }; + Handler.prototype.resize = function () { + this._hovered = new HoveredResult(0, 0); + }; + Handler.prototype.dispatch = function (eventName, eventArgs) { + var handler = this[eventName]; + handler && handler.call(this, eventArgs); + }; + Handler.prototype.dispose = function () { + this.proxy.dispose(); + this.storage = null; + this.proxy = null; + this.painter = null; + }; + Handler.prototype.setCursorStyle = function (cursorStyle) { + var proxy = this.proxy; + proxy.setCursor && proxy.setCursor(cursorStyle); + }; + Handler.prototype.dispatchToElement = function (targetInfo, eventName, event) { + targetInfo = targetInfo || {}; + var el = targetInfo.target; + if (el && el.silent) { + return; + } + var eventKey = ('on' + eventName); + var eventPacket = makeEventPacket(eventName, targetInfo, event); + while (el) { + el[eventKey] + && (eventPacket.cancelBubble = !!el[eventKey].call(el, eventPacket)); + el.trigger(eventName, eventPacket); + el = el.__hostTarget ? el.__hostTarget : el.parent; + if (eventPacket.cancelBubble) { + break; + } + } + if (!eventPacket.cancelBubble) { + this.trigger(eventName, eventPacket); + if (this.painter && this.painter.eachOtherLayer) { + this.painter.eachOtherLayer(function (layer) { + if (typeof (layer[eventKey]) === 'function') { + layer[eventKey].call(layer, eventPacket); + } + if (layer.trigger) { + layer.trigger(eventName, eventPacket); + } + }); + } + } + }; + Handler.prototype.findHover = function (x, y, exclude) { + var list = this.storage.getDisplayList(); + var out = new HoveredResult(x, y); + setHoverTarget(list, out, x, y, exclude); + if (this._pointerSize && !out.target) { + var candidates = []; + var pointerSize = this._pointerSize; + var targetSizeHalf = pointerSize / 2; + var pointerRect = new BoundingRect(x - targetSizeHalf, y - targetSizeHalf, pointerSize, pointerSize); + for (var i = list.length - 1; i >= 0; i--) { + var el = list[i]; + if (el !== exclude + && !el.ignore + && !el.ignoreCoarsePointer + && (!el.parent || !el.parent.ignoreCoarsePointer)) { + tmpRect.copy(el.getBoundingRect()); + if (el.transform) { + tmpRect.applyTransform(el.transform); + } + if (tmpRect.intersect(pointerRect)) { + candidates.push(el); + } + } + } + if (candidates.length) { + var rStep = 4; + var thetaStep = Math.PI / 12; + var PI2 = Math.PI * 2; + for (var r = 0; r < targetSizeHalf; r += rStep) { + for (var theta = 0; theta < PI2; theta += thetaStep) { + var x1 = x + r * Math.cos(theta); + var y1 = y + r * Math.sin(theta); + setHoverTarget(candidates, out, x1, y1, exclude); + if (out.target) { + return out; + } + } + } + } + } + return out; + }; + Handler.prototype.processGesture = function (event, stage) { + if (!this._gestureMgr) { + this._gestureMgr = new GestureMgr(); + } + var gestureMgr = this._gestureMgr; + stage === 'start' && gestureMgr.clear(); + var gestureInfo = gestureMgr.recognize(event, this.findHover(event.zrX, event.zrY, null).target, this.proxy.dom); + stage === 'end' && gestureMgr.clear(); + if (gestureInfo) { + var type = gestureInfo.type; + event.gestureEvent = type; + var res = new HoveredResult(); + res.target = gestureInfo.target; + this.dispatchToElement(res, type, gestureInfo.event); + } + }; + return Handler; + }(Eventful)); + each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) { + Handler.prototype[name] = function (event) { + var x = event.zrX; + var y = event.zrY; + var isOutside = isOutsideBoundary(this, x, y); + var hovered; + var hoveredTarget; + if (name !== 'mouseup' || !isOutside) { + hovered = this.findHover(x, y); + hoveredTarget = hovered.target; + } + if (name === 'mousedown') { + this._downEl = hoveredTarget; + this._downPoint = [event.zrX, event.zrY]; + this._upEl = hoveredTarget; + } + else if (name === 'mouseup') { + this._upEl = hoveredTarget; + } + else if (name === 'click') { + if (this._downEl !== this._upEl + || !this._downPoint + || dist(this._downPoint, [event.zrX, event.zrY]) > 4) { + return; + } + this._downPoint = null; + } + this.dispatchToElement(hovered, name, event); + }; + }); + function isHover(displayable, x, y) { + if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) { + var el = displayable; + var isSilent = void 0; + var ignoreClip = false; + while (el) { + if (el.ignoreClip) { + ignoreClip = true; + } + if (!ignoreClip) { + var clipPath = el.getClipPath(); + if (clipPath && !clipPath.contain(x, y)) { + return false; + } + } + if (el.silent) { + isSilent = true; + } + var hostEl = el.__hostTarget; + el = hostEl ? hostEl : el.parent; + } + return isSilent ? SILENT : true; + } + return false; + } + function setHoverTarget(list, out, x, y, exclude) { + for (var i = list.length - 1; i >= 0; i--) { + var el = list[i]; + var hoverCheckResult = void 0; + if (el !== exclude + && !el.ignore + && (hoverCheckResult = isHover(el, x, y))) { + !out.topTarget && (out.topTarget = el); + if (hoverCheckResult !== SILENT) { + out.target = el; + break; + } + } + } + } + function isOutsideBoundary(handlerInstance, x, y) { + var painter = handlerInstance.painter; + return x < 0 || x > painter.getWidth() || y < 0 || y > painter.getHeight(); + } + + var DEFAULT_MIN_MERGE = 32; + var DEFAULT_MIN_GALLOPING = 7; + function minRunLength(n) { + var r = 0; + while (n >= DEFAULT_MIN_MERGE) { + r |= n & 1; + n >>= 1; + } + return n + r; + } + function makeAscendingRun(array, lo, hi, compare) { + var runHi = lo + 1; + if (runHi === hi) { + return 1; + } + if (compare(array[runHi++], array[lo]) < 0) { + while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) { + runHi++; + } + reverseRun(array, lo, runHi); + } + else { + while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) { + runHi++; + } + } + return runHi - lo; + } + function reverseRun(array, lo, hi) { + hi--; + while (lo < hi) { + var t = array[lo]; + array[lo++] = array[hi]; + array[hi--] = t; + } + } + function binaryInsertionSort(array, lo, hi, start, compare) { + if (start === lo) { + start++; + } + for (; start < hi; start++) { + var pivot = array[start]; + var left = lo; + var right = start; + var mid; + while (left < right) { + mid = left + right >>> 1; + if (compare(pivot, array[mid]) < 0) { + right = mid; + } + else { + left = mid + 1; + } + } + var n = start - left; + switch (n) { + case 3: + array[left + 3] = array[left + 2]; + case 2: + array[left + 2] = array[left + 1]; + case 1: + array[left + 1] = array[left]; + break; + default: + while (n > 0) { + array[left + n] = array[left + n - 1]; + n--; + } + } + array[left] = pivot; + } + } + function gallopLeft(value, array, start, length, hint, compare) { + var lastOffset = 0; + var maxOffset = 0; + var offset = 1; + if (compare(value, array[start + hint]) > 0) { + maxOffset = length - hint; + while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) { + lastOffset = offset; + offset = (offset << 1) + 1; + if (offset <= 0) { + offset = maxOffset; + } + } + if (offset > maxOffset) { + offset = maxOffset; + } + lastOffset += hint; + offset += hint; + } + else { + maxOffset = hint + 1; + while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) { + lastOffset = offset; + offset = (offset << 1) + 1; + if (offset <= 0) { + offset = maxOffset; + } + } + if (offset > maxOffset) { + offset = maxOffset; + } + var tmp = lastOffset; + lastOffset = hint - offset; + offset = hint - tmp; + } + lastOffset++; + while (lastOffset < offset) { + var m = lastOffset + (offset - lastOffset >>> 1); + if (compare(value, array[start + m]) > 0) { + lastOffset = m + 1; + } + else { + offset = m; + } + } + return offset; + } + function gallopRight(value, array, start, length, hint, compare) { + var lastOffset = 0; + var maxOffset = 0; + var offset = 1; + if (compare(value, array[start + hint]) < 0) { + maxOffset = hint + 1; + while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) { + lastOffset = offset; + offset = (offset << 1) + 1; + if (offset <= 0) { + offset = maxOffset; + } + } + if (offset > maxOffset) { + offset = maxOffset; + } + var tmp = lastOffset; + lastOffset = hint - offset; + offset = hint - tmp; + } + else { + maxOffset = length - hint; + while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) { + lastOffset = offset; + offset = (offset << 1) + 1; + if (offset <= 0) { + offset = maxOffset; + } + } + if (offset > maxOffset) { + offset = maxOffset; + } + lastOffset += hint; + offset += hint; + } + lastOffset++; + while (lastOffset < offset) { + var m = lastOffset + (offset - lastOffset >>> 1); + if (compare(value, array[start + m]) < 0) { + offset = m; + } + else { + lastOffset = m + 1; + } + } + return offset; + } + function TimSort(array, compare) { + var minGallop = DEFAULT_MIN_GALLOPING; + var runStart; + var runLength; + var stackSize = 0; + var tmp = []; + runStart = []; + runLength = []; + function pushRun(_runStart, _runLength) { + runStart[stackSize] = _runStart; + runLength[stackSize] = _runLength; + stackSize += 1; + } + function mergeRuns() { + while (stackSize > 1) { + var n = stackSize - 2; + if ((n >= 1 && runLength[n - 1] <= runLength[n] + runLength[n + 1]) + || (n >= 2 && runLength[n - 2] <= runLength[n] + runLength[n - 1])) { + if (runLength[n - 1] < runLength[n + 1]) { + n--; + } + } + else if (runLength[n] > runLength[n + 1]) { + break; + } + mergeAt(n); + } + } + function forceMergeRuns() { + while (stackSize > 1) { + var n = stackSize - 2; + if (n > 0 && runLength[n - 1] < runLength[n + 1]) { + n--; + } + mergeAt(n); + } + } + function mergeAt(i) { + var start1 = runStart[i]; + var length1 = runLength[i]; + var start2 = runStart[i + 1]; + var length2 = runLength[i + 1]; + runLength[i] = length1 + length2; + if (i === stackSize - 3) { + runStart[i + 1] = runStart[i + 2]; + runLength[i + 1] = runLength[i + 2]; + } + stackSize--; + var k = gallopRight(array[start2], array, start1, length1, 0, compare); + start1 += k; + length1 -= k; + if (length1 === 0) { + return; + } + length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare); + if (length2 === 0) { + return; + } + if (length1 <= length2) { + mergeLow(start1, length1, start2, length2); + } + else { + mergeHigh(start1, length1, start2, length2); + } + } + function mergeLow(start1, length1, start2, length2) { + var i = 0; + for (i = 0; i < length1; i++) { + tmp[i] = array[start1 + i]; + } + var cursor1 = 0; + var cursor2 = start2; + var dest = start1; + array[dest++] = array[cursor2++]; + if (--length2 === 0) { + for (i = 0; i < length1; i++) { + array[dest + i] = tmp[cursor1 + i]; + } + return; + } + if (length1 === 1) { + for (i = 0; i < length2; i++) { + array[dest + i] = array[cursor2 + i]; + } + array[dest + length2] = tmp[cursor1]; + return; + } + var _minGallop = minGallop; + var count1; + var count2; + var exit; + while (1) { + count1 = 0; + count2 = 0; + exit = false; + do { + if (compare(array[cursor2], tmp[cursor1]) < 0) { + array[dest++] = array[cursor2++]; + count2++; + count1 = 0; + if (--length2 === 0) { + exit = true; + break; + } + } + else { + array[dest++] = tmp[cursor1++]; + count1++; + count2 = 0; + if (--length1 === 1) { + exit = true; + break; + } + } + } while ((count1 | count2) < _minGallop); + if (exit) { + break; + } + do { + count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare); + if (count1 !== 0) { + for (i = 0; i < count1; i++) { + array[dest + i] = tmp[cursor1 + i]; + } + dest += count1; + cursor1 += count1; + length1 -= count1; + if (length1 <= 1) { + exit = true; + break; + } + } + array[dest++] = array[cursor2++]; + if (--length2 === 0) { + exit = true; + break; + } + count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare); + if (count2 !== 0) { + for (i = 0; i < count2; i++) { + array[dest + i] = array[cursor2 + i]; + } + dest += count2; + cursor2 += count2; + length2 -= count2; + if (length2 === 0) { + exit = true; + break; + } + } + array[dest++] = tmp[cursor1++]; + if (--length1 === 1) { + exit = true; + break; + } + _minGallop--; + } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING); + if (exit) { + break; + } + if (_minGallop < 0) { + _minGallop = 0; + } + _minGallop += 2; + } + minGallop = _minGallop; + minGallop < 1 && (minGallop = 1); + if (length1 === 1) { + for (i = 0; i < length2; i++) { + array[dest + i] = array[cursor2 + i]; + } + array[dest + length2] = tmp[cursor1]; + } + else if (length1 === 0) { + throw new Error(); + } + else { + for (i = 0; i < length1; i++) { + array[dest + i] = tmp[cursor1 + i]; + } + } + } + function mergeHigh(start1, length1, start2, length2) { + var i = 0; + for (i = 0; i < length2; i++) { + tmp[i] = array[start2 + i]; + } + var cursor1 = start1 + length1 - 1; + var cursor2 = length2 - 1; + var dest = start2 + length2 - 1; + var customCursor = 0; + var customDest = 0; + array[dest--] = array[cursor1--]; + if (--length1 === 0) { + customCursor = dest - (length2 - 1); + for (i = 0; i < length2; i++) { + array[customCursor + i] = tmp[i]; + } + return; + } + if (length2 === 1) { + dest -= length1; + cursor1 -= length1; + customDest = dest + 1; + customCursor = cursor1 + 1; + for (i = length1 - 1; i >= 0; i--) { + array[customDest + i] = array[customCursor + i]; + } + array[dest] = tmp[cursor2]; + return; + } + var _minGallop = minGallop; + while (true) { + var count1 = 0; + var count2 = 0; + var exit = false; + do { + if (compare(tmp[cursor2], array[cursor1]) < 0) { + array[dest--] = array[cursor1--]; + count1++; + count2 = 0; + if (--length1 === 0) { + exit = true; + break; + } + } + else { + array[dest--] = tmp[cursor2--]; + count2++; + count1 = 0; + if (--length2 === 1) { + exit = true; + break; + } + } + } while ((count1 | count2) < _minGallop); + if (exit) { + break; + } + do { + count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare); + if (count1 !== 0) { + dest -= count1; + cursor1 -= count1; + length1 -= count1; + customDest = dest + 1; + customCursor = cursor1 + 1; + for (i = count1 - 1; i >= 0; i--) { + array[customDest + i] = array[customCursor + i]; + } + if (length1 === 0) { + exit = true; + break; + } + } + array[dest--] = tmp[cursor2--]; + if (--length2 === 1) { + exit = true; + break; + } + count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare); + if (count2 !== 0) { + dest -= count2; + cursor2 -= count2; + length2 -= count2; + customDest = dest + 1; + customCursor = cursor2 + 1; + for (i = 0; i < count2; i++) { + array[customDest + i] = tmp[customCursor + i]; + } + if (length2 <= 1) { + exit = true; + break; + } + } + array[dest--] = array[cursor1--]; + if (--length1 === 0) { + exit = true; + break; + } + _minGallop--; + } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING); + if (exit) { + break; + } + if (_minGallop < 0) { + _minGallop = 0; + } + _minGallop += 2; + } + minGallop = _minGallop; + if (minGallop < 1) { + minGallop = 1; + } + if (length2 === 1) { + dest -= length1; + cursor1 -= length1; + customDest = dest + 1; + customCursor = cursor1 + 1; + for (i = length1 - 1; i >= 0; i--) { + array[customDest + i] = array[customCursor + i]; + } + array[dest] = tmp[cursor2]; + } + else if (length2 === 0) { + throw new Error(); + } + else { + customCursor = dest - (length2 - 1); + for (i = 0; i < length2; i++) { + array[customCursor + i] = tmp[i]; + } + } + } + return { + mergeRuns: mergeRuns, + forceMergeRuns: forceMergeRuns, + pushRun: pushRun + }; + } + function sort(array, compare, lo, hi) { + if (!lo) { + lo = 0; + } + if (!hi) { + hi = array.length; + } + var remaining = hi - lo; + if (remaining < 2) { + return; + } + var runLength = 0; + if (remaining < DEFAULT_MIN_MERGE) { + runLength = makeAscendingRun(array, lo, hi, compare); + binaryInsertionSort(array, lo, hi, lo + runLength, compare); + return; + } + var ts = TimSort(array, compare); + var minRun = minRunLength(remaining); + do { + runLength = makeAscendingRun(array, lo, hi, compare); + if (runLength < minRun) { + var force = remaining; + if (force > minRun) { + force = minRun; + } + binaryInsertionSort(array, lo, lo + force, lo + runLength, compare); + runLength = force; + } + ts.pushRun(lo, runLength); + ts.mergeRuns(); + remaining -= runLength; + lo += runLength; + } while (remaining !== 0); + ts.forceMergeRuns(); + } + + var REDRAW_BIT = 1; + var STYLE_CHANGED_BIT = 2; + var SHAPE_CHANGED_BIT = 4; + + var invalidZErrorLogged = false; + function logInvalidZError() { + if (invalidZErrorLogged) { + return; + } + invalidZErrorLogged = true; + console.warn('z / z2 / zlevel of displayable is invalid, which may cause unexpected errors'); + } + function shapeCompareFunc(a, b) { + if (a.zlevel === b.zlevel) { + if (a.z === b.z) { + return a.z2 - b.z2; + } + return a.z - b.z; + } + return a.zlevel - b.zlevel; + } + var Storage = (function () { + function Storage() { + this._roots = []; + this._displayList = []; + this._displayListLen = 0; + this.displayableSortFunc = shapeCompareFunc; + } + Storage.prototype.traverse = function (cb, context) { + for (var i = 0; i < this._roots.length; i++) { + this._roots[i].traverse(cb, context); + } + }; + Storage.prototype.getDisplayList = function (update, includeIgnore) { + includeIgnore = includeIgnore || false; + var displayList = this._displayList; + if (update || !displayList.length) { + this.updateDisplayList(includeIgnore); + } + return displayList; + }; + Storage.prototype.updateDisplayList = function (includeIgnore) { + this._displayListLen = 0; + var roots = this._roots; + var displayList = this._displayList; + for (var i = 0, len = roots.length; i < len; i++) { + this._updateAndAddDisplayable(roots[i], null, includeIgnore); + } + displayList.length = this._displayListLen; + sort(displayList, shapeCompareFunc); + }; + Storage.prototype._updateAndAddDisplayable = function (el, clipPaths, includeIgnore) { + if (el.ignore && !includeIgnore) { + return; + } + el.beforeUpdate(); + el.update(); + el.afterUpdate(); + var userSetClipPath = el.getClipPath(); + if (el.ignoreClip) { + clipPaths = null; + } + else if (userSetClipPath) { + if (clipPaths) { + clipPaths = clipPaths.slice(); + } + else { + clipPaths = []; + } + var currentClipPath = userSetClipPath; + var parentClipPath = el; + while (currentClipPath) { + currentClipPath.parent = parentClipPath; + currentClipPath.updateTransform(); + clipPaths.push(currentClipPath); + parentClipPath = currentClipPath; + currentClipPath = currentClipPath.getClipPath(); + } + } + if (el.childrenRef) { + var children = el.childrenRef(); + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (el.__dirty) { + child.__dirty |= REDRAW_BIT; + } + this._updateAndAddDisplayable(child, clipPaths, includeIgnore); + } + el.__dirty = 0; + } + else { + var disp = el; + if (clipPaths && clipPaths.length) { + disp.__clipPaths = clipPaths; + } + else if (disp.__clipPaths && disp.__clipPaths.length > 0) { + disp.__clipPaths = []; + } + if (isNaN(disp.z)) { + logInvalidZError(); + disp.z = 0; + } + if (isNaN(disp.z2)) { + logInvalidZError(); + disp.z2 = 0; + } + if (isNaN(disp.zlevel)) { + logInvalidZError(); + disp.zlevel = 0; + } + this._displayList[this._displayListLen++] = disp; + } + var decalEl = el.getDecalElement && el.getDecalElement(); + if (decalEl) { + this._updateAndAddDisplayable(decalEl, clipPaths, includeIgnore); + } + var textGuide = el.getTextGuideLine(); + if (textGuide) { + this._updateAndAddDisplayable(textGuide, clipPaths, includeIgnore); + } + var textEl = el.getTextContent(); + if (textEl) { + this._updateAndAddDisplayable(textEl, clipPaths, includeIgnore); + } + }; + Storage.prototype.addRoot = function (el) { + if (el.__zr && el.__zr.storage === this) { + return; + } + this._roots.push(el); + }; + Storage.prototype.delRoot = function (el) { + if (el instanceof Array) { + for (var i = 0, l = el.length; i < l; i++) { + this.delRoot(el[i]); + } + return; + } + var idx = indexOf(this._roots, el); + if (idx >= 0) { + this._roots.splice(idx, 1); + } + }; + Storage.prototype.delAllRoots = function () { + this._roots = []; + this._displayList = []; + this._displayListLen = 0; + return; + }; + Storage.prototype.getRoots = function () { + return this._roots; + }; + Storage.prototype.dispose = function () { + this._displayList = null; + this._roots = null; + }; + return Storage; + }()); + + var requestAnimationFrame; + requestAnimationFrame = (env.hasGlobalWindow + && ((window.requestAnimationFrame && window.requestAnimationFrame.bind(window)) + || (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window)) + || window.mozRequestAnimationFrame + || window.webkitRequestAnimationFrame)) || function (func) { + return setTimeout(func, 16); + }; + var requestAnimationFrame$1 = requestAnimationFrame; + + var easingFuncs = { + linear: function (k) { + return k; + }, + quadraticIn: function (k) { + return k * k; + }, + quadraticOut: function (k) { + return k * (2 - k); + }, + quadraticInOut: function (k) { + if ((k *= 2) < 1) { + return 0.5 * k * k; + } + return -0.5 * (--k * (k - 2) - 1); + }, + cubicIn: function (k) { + return k * k * k; + }, + cubicOut: function (k) { + return --k * k * k + 1; + }, + cubicInOut: function (k) { + if ((k *= 2) < 1) { + return 0.5 * k * k * k; + } + return 0.5 * ((k -= 2) * k * k + 2); + }, + quarticIn: function (k) { + return k * k * k * k; + }, + quarticOut: function (k) { + return 1 - (--k * k * k * k); + }, + quarticInOut: function (k) { + if ((k *= 2) < 1) { + return 0.5 * k * k * k * k; + } + return -0.5 * ((k -= 2) * k * k * k - 2); + }, + quinticIn: function (k) { + return k * k * k * k * k; + }, + quinticOut: function (k) { + return --k * k * k * k * k + 1; + }, + quinticInOut: function (k) { + if ((k *= 2) < 1) { + return 0.5 * k * k * k * k * k; + } + return 0.5 * ((k -= 2) * k * k * k * k + 2); + }, + sinusoidalIn: function (k) { + return 1 - Math.cos(k * Math.PI / 2); + }, + sinusoidalOut: function (k) { + return Math.sin(k * Math.PI / 2); + }, + sinusoidalInOut: function (k) { + return 0.5 * (1 - Math.cos(Math.PI * k)); + }, + exponentialIn: function (k) { + return k === 0 ? 0 : Math.pow(1024, k - 1); + }, + exponentialOut: function (k) { + return k === 1 ? 1 : 1 - Math.pow(2, -10 * k); + }, + exponentialInOut: function (k) { + if (k === 0) { + return 0; + } + if (k === 1) { + return 1; + } + if ((k *= 2) < 1) { + return 0.5 * Math.pow(1024, k - 1); + } + return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2); + }, + circularIn: function (k) { + return 1 - Math.sqrt(1 - k * k); + }, + circularOut: function (k) { + return Math.sqrt(1 - (--k * k)); + }, + circularInOut: function (k) { + if ((k *= 2) < 1) { + return -0.5 * (Math.sqrt(1 - k * k) - 1); + } + return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); + }, + elasticIn: function (k) { + var s; + var a = 0.1; + var p = 0.4; + if (k === 0) { + return 0; + } + if (k === 1) { + return 1; + } + if (!a || a < 1) { + a = 1; + s = p / 4; + } + else { + s = p * Math.asin(1 / a) / (2 * Math.PI); + } + return -(a * Math.pow(2, 10 * (k -= 1)) + * Math.sin((k - s) * (2 * Math.PI) / p)); + }, + elasticOut: function (k) { + var s; + var a = 0.1; + var p = 0.4; + if (k === 0) { + return 0; + } + if (k === 1) { + return 1; + } + if (!a || a < 1) { + a = 1; + s = p / 4; + } + else { + s = p * Math.asin(1 / a) / (2 * Math.PI); + } + return (a * Math.pow(2, -10 * k) + * Math.sin((k - s) * (2 * Math.PI) / p) + 1); + }, + elasticInOut: function (k) { + var s; + var a = 0.1; + var p = 0.4; + if (k === 0) { + return 0; + } + if (k === 1) { + return 1; + } + if (!a || a < 1) { + a = 1; + s = p / 4; + } + else { + s = p * Math.asin(1 / a) / (2 * Math.PI); + } + if ((k *= 2) < 1) { + return -0.5 * (a * Math.pow(2, 10 * (k -= 1)) + * Math.sin((k - s) * (2 * Math.PI) / p)); + } + return a * Math.pow(2, -10 * (k -= 1)) + * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1; + }, + backIn: function (k) { + var s = 1.70158; + return k * k * ((s + 1) * k - s); + }, + backOut: function (k) { + var s = 1.70158; + return --k * k * ((s + 1) * k + s) + 1; + }, + backInOut: function (k) { + var s = 1.70158 * 1.525; + if ((k *= 2) < 1) { + return 0.5 * (k * k * ((s + 1) * k - s)); + } + return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2); + }, + bounceIn: function (k) { + return 1 - easingFuncs.bounceOut(1 - k); + }, + bounceOut: function (k) { + if (k < (1 / 2.75)) { + return 7.5625 * k * k; + } + else if (k < (2 / 2.75)) { + return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75; + } + else if (k < (2.5 / 2.75)) { + return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375; + } + else { + return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375; + } + }, + bounceInOut: function (k) { + if (k < 0.5) { + return easingFuncs.bounceIn(k * 2) * 0.5; + } + return easingFuncs.bounceOut(k * 2 - 1) * 0.5 + 0.5; + } + }; + + var mathPow = Math.pow; + var mathSqrt = Math.sqrt; + var EPSILON = 1e-8; + var EPSILON_NUMERIC = 1e-4; + var THREE_SQRT = mathSqrt(3); + var ONE_THIRD = 1 / 3; + var _v0 = create(); + var _v1 = create(); + var _v2 = create(); + function isAroundZero(val) { + return val > -EPSILON && val < EPSILON; + } + function isNotAroundZero(val) { + return val > EPSILON || val < -EPSILON; + } + function cubicAt(p0, p1, p2, p3, t) { + var onet = 1 - t; + return onet * onet * (onet * p0 + 3 * t * p1) + + t * t * (t * p3 + 3 * onet * p2); + } + function cubicDerivativeAt(p0, p1, p2, p3, t) { + var onet = 1 - t; + return 3 * (((p1 - p0) * onet + 2 * (p2 - p1) * t) * onet + + (p3 - p2) * t * t); + } + function cubicRootAt(p0, p1, p2, p3, val, roots) { + var a = p3 + 3 * (p1 - p2) - p0; + var b = 3 * (p2 - p1 * 2 + p0); + var c = 3 * (p1 - p0); + var d = p0 - val; + var A = b * b - 3 * a * c; + var B = b * c - 9 * a * d; + var C = c * c - 3 * b * d; + var n = 0; + if (isAroundZero(A) && isAroundZero(B)) { + if (isAroundZero(b)) { + roots[0] = 0; + } + else { + var t1 = -c / b; + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + } + } + else { + var disc = B * B - 4 * A * C; + if (isAroundZero(disc)) { + var K = B / A; + var t1 = -b / a + K; + var t2 = -K / 2; + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + if (t2 >= 0 && t2 <= 1) { + roots[n++] = t2; + } + } + else if (disc > 0) { + var discSqrt = mathSqrt(disc); + var Y1 = A * b + 1.5 * a * (-B + discSqrt); + var Y2 = A * b + 1.5 * a * (-B - discSqrt); + if (Y1 < 0) { + Y1 = -mathPow(-Y1, ONE_THIRD); + } + else { + Y1 = mathPow(Y1, ONE_THIRD); + } + if (Y2 < 0) { + Y2 = -mathPow(-Y2, ONE_THIRD); + } + else { + Y2 = mathPow(Y2, ONE_THIRD); + } + var t1 = (-b - (Y1 + Y2)) / (3 * a); + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + } + else { + var T = (2 * A * b - 3 * a * B) / (2 * mathSqrt(A * A * A)); + var theta = Math.acos(T) / 3; + var ASqrt = mathSqrt(A); + var tmp = Math.cos(theta); + var t1 = (-b - 2 * ASqrt * tmp) / (3 * a); + var t2 = (-b + ASqrt * (tmp + THREE_SQRT * Math.sin(theta))) / (3 * a); + var t3 = (-b + ASqrt * (tmp - THREE_SQRT * Math.sin(theta))) / (3 * a); + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + if (t2 >= 0 && t2 <= 1) { + roots[n++] = t2; + } + if (t3 >= 0 && t3 <= 1) { + roots[n++] = t3; + } + } + } + return n; + } + function cubicExtrema(p0, p1, p2, p3, extrema) { + var b = 6 * p2 - 12 * p1 + 6 * p0; + var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2; + var c = 3 * p1 - 3 * p0; + var n = 0; + if (isAroundZero(a)) { + if (isNotAroundZero(b)) { + var t1 = -c / b; + if (t1 >= 0 && t1 <= 1) { + extrema[n++] = t1; + } + } + } + else { + var disc = b * b - 4 * a * c; + if (isAroundZero(disc)) { + extrema[0] = -b / (2 * a); + } + else if (disc > 0) { + var discSqrt = mathSqrt(disc); + var t1 = (-b + discSqrt) / (2 * a); + var t2 = (-b - discSqrt) / (2 * a); + if (t1 >= 0 && t1 <= 1) { + extrema[n++] = t1; + } + if (t2 >= 0 && t2 <= 1) { + extrema[n++] = t2; + } + } + } + return n; + } + function cubicSubdivide(p0, p1, p2, p3, t, out) { + var p01 = (p1 - p0) * t + p0; + var p12 = (p2 - p1) * t + p1; + var p23 = (p3 - p2) * t + p2; + var p012 = (p12 - p01) * t + p01; + var p123 = (p23 - p12) * t + p12; + var p0123 = (p123 - p012) * t + p012; + out[0] = p0; + out[1] = p01; + out[2] = p012; + out[3] = p0123; + out[4] = p0123; + out[5] = p123; + out[6] = p23; + out[7] = p3; + } + function cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, out) { + var t; + var interval = 0.005; + var d = Infinity; + var prev; + var next; + var d1; + var d2; + _v0[0] = x; + _v0[1] = y; + for (var _t = 0; _t < 1; _t += 0.05) { + _v1[0] = cubicAt(x0, x1, x2, x3, _t); + _v1[1] = cubicAt(y0, y1, y2, y3, _t); + d1 = distSquare(_v0, _v1); + if (d1 < d) { + t = _t; + d = d1; + } + } + d = Infinity; + for (var i = 0; i < 32; i++) { + if (interval < EPSILON_NUMERIC) { + break; + } + prev = t - interval; + next = t + interval; + _v1[0] = cubicAt(x0, x1, x2, x3, prev); + _v1[1] = cubicAt(y0, y1, y2, y3, prev); + d1 = distSquare(_v1, _v0); + if (prev >= 0 && d1 < d) { + t = prev; + d = d1; + } + else { + _v2[0] = cubicAt(x0, x1, x2, x3, next); + _v2[1] = cubicAt(y0, y1, y2, y3, next); + d2 = distSquare(_v2, _v0); + if (next <= 1 && d2 < d) { + t = next; + d = d2; + } + else { + interval *= 0.5; + } + } + } + if (out) { + out[0] = cubicAt(x0, x1, x2, x3, t); + out[1] = cubicAt(y0, y1, y2, y3, t); + } + return mathSqrt(d); + } + function cubicLength(x0, y0, x1, y1, x2, y2, x3, y3, iteration) { + var px = x0; + var py = y0; + var d = 0; + var step = 1 / iteration; + for (var i = 1; i <= iteration; i++) { + var t = i * step; + var x = cubicAt(x0, x1, x2, x3, t); + var y = cubicAt(y0, y1, y2, y3, t); + var dx = x - px; + var dy = y - py; + d += Math.sqrt(dx * dx + dy * dy); + px = x; + py = y; + } + return d; + } + function quadraticAt(p0, p1, p2, t) { + var onet = 1 - t; + return onet * (onet * p0 + 2 * t * p1) + t * t * p2; + } + function quadraticDerivativeAt(p0, p1, p2, t) { + return 2 * ((1 - t) * (p1 - p0) + t * (p2 - p1)); + } + function quadraticRootAt(p0, p1, p2, val, roots) { + var a = p0 - 2 * p1 + p2; + var b = 2 * (p1 - p0); + var c = p0 - val; + var n = 0; + if (isAroundZero(a)) { + if (isNotAroundZero(b)) { + var t1 = -c / b; + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + } + } + else { + var disc = b * b - 4 * a * c; + if (isAroundZero(disc)) { + var t1 = -b / (2 * a); + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + } + else if (disc > 0) { + var discSqrt = mathSqrt(disc); + var t1 = (-b + discSqrt) / (2 * a); + var t2 = (-b - discSqrt) / (2 * a); + if (t1 >= 0 && t1 <= 1) { + roots[n++] = t1; + } + if (t2 >= 0 && t2 <= 1) { + roots[n++] = t2; + } + } + } + return n; + } + function quadraticExtremum(p0, p1, p2) { + var divider = p0 + p2 - 2 * p1; + if (divider === 0) { + return 0.5; + } + else { + return (p0 - p1) / divider; + } + } + function quadraticSubdivide(p0, p1, p2, t, out) { + var p01 = (p1 - p0) * t + p0; + var p12 = (p2 - p1) * t + p1; + var p012 = (p12 - p01) * t + p01; + out[0] = p0; + out[1] = p01; + out[2] = p012; + out[3] = p012; + out[4] = p12; + out[5] = p2; + } + function quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, out) { + var t; + var interval = 0.005; + var d = Infinity; + _v0[0] = x; + _v0[1] = y; + for (var _t = 0; _t < 1; _t += 0.05) { + _v1[0] = quadraticAt(x0, x1, x2, _t); + _v1[1] = quadraticAt(y0, y1, y2, _t); + var d1 = distSquare(_v0, _v1); + if (d1 < d) { + t = _t; + d = d1; + } + } + d = Infinity; + for (var i = 0; i < 32; i++) { + if (interval < EPSILON_NUMERIC) { + break; + } + var prev = t - interval; + var next = t + interval; + _v1[0] = quadraticAt(x0, x1, x2, prev); + _v1[1] = quadraticAt(y0, y1, y2, prev); + var d1 = distSquare(_v1, _v0); + if (prev >= 0 && d1 < d) { + t = prev; + d = d1; + } + else { + _v2[0] = quadraticAt(x0, x1, x2, next); + _v2[1] = quadraticAt(y0, y1, y2, next); + var d2 = distSquare(_v2, _v0); + if (next <= 1 && d2 < d) { + t = next; + d = d2; + } + else { + interval *= 0.5; + } + } + } + if (out) { + out[0] = quadraticAt(x0, x1, x2, t); + out[1] = quadraticAt(y0, y1, y2, t); + } + return mathSqrt(d); + } + function quadraticLength(x0, y0, x1, y1, x2, y2, iteration) { + var px = x0; + var py = y0; + var d = 0; + var step = 1 / iteration; + for (var i = 1; i <= iteration; i++) { + var t = i * step; + var x = quadraticAt(x0, x1, x2, t); + var y = quadraticAt(y0, y1, y2, t); + var dx = x - px; + var dy = y - py; + d += Math.sqrt(dx * dx + dy * dy); + px = x; + py = y; + } + return d; + } + + var regexp = /cubic-bezier\(([0-9,\.e ]+)\)/; + function createCubicEasingFunc(cubicEasingStr) { + var cubic = cubicEasingStr && regexp.exec(cubicEasingStr); + if (cubic) { + var points = cubic[1].split(','); + var a_1 = +trim(points[0]); + var b_1 = +trim(points[1]); + var c_1 = +trim(points[2]); + var d_1 = +trim(points[3]); + if (isNaN(a_1 + b_1 + c_1 + d_1)) { + return; + } + var roots_1 = []; + return function (p) { + return p <= 0 + ? 0 : p >= 1 + ? 1 + : cubicRootAt(0, a_1, c_1, 1, p, roots_1) && cubicAt(0, b_1, d_1, 1, roots_1[0]); + }; + } + } + + var Clip = (function () { + function Clip(opts) { + this._inited = false; + this._startTime = 0; + this._pausedTime = 0; + this._paused = false; + this._life = opts.life || 1000; + this._delay = opts.delay || 0; + this.loop = opts.loop || false; + this.onframe = opts.onframe || noop; + this.ondestroy = opts.ondestroy || noop; + this.onrestart = opts.onrestart || noop; + opts.easing && this.setEasing(opts.easing); + } + Clip.prototype.step = function (globalTime, deltaTime) { + if (!this._inited) { + this._startTime = globalTime + this._delay; + this._inited = true; + } + if (this._paused) { + this._pausedTime += deltaTime; + return; + } + var life = this._life; + var elapsedTime = globalTime - this._startTime - this._pausedTime; + var percent = elapsedTime / life; + if (percent < 0) { + percent = 0; + } + percent = Math.min(percent, 1); + var easingFunc = this.easingFunc; + var schedule = easingFunc ? easingFunc(percent) : percent; + this.onframe(schedule); + if (percent === 1) { + if (this.loop) { + var remainder = elapsedTime % life; + this._startTime = globalTime - remainder; + this._pausedTime = 0; + this.onrestart(); + } + else { + return true; + } + } + return false; + }; + Clip.prototype.pause = function () { + this._paused = true; + }; + Clip.prototype.resume = function () { + this._paused = false; + }; + Clip.prototype.setEasing = function (easing) { + this.easing = easing; + this.easingFunc = isFunction(easing) + ? easing + : easingFuncs[easing] || createCubicEasingFunc(easing); + }; + return Clip; + }()); + + var Entry = (function () { + function Entry(val) { + this.value = val; + } + return Entry; + }()); + var LinkedList = (function () { + function LinkedList() { + this._len = 0; + } + LinkedList.prototype.insert = function (val) { + var entry = new Entry(val); + this.insertEntry(entry); + return entry; + }; + LinkedList.prototype.insertEntry = function (entry) { + if (!this.head) { + this.head = this.tail = entry; + } + else { + this.tail.next = entry; + entry.prev = this.tail; + entry.next = null; + this.tail = entry; + } + this._len++; + }; + LinkedList.prototype.remove = function (entry) { + var prev = entry.prev; + var next = entry.next; + if (prev) { + prev.next = next; + } + else { + this.head = next; + } + if (next) { + next.prev = prev; + } + else { + this.tail = prev; + } + entry.next = entry.prev = null; + this._len--; + }; + LinkedList.prototype.len = function () { + return this._len; + }; + LinkedList.prototype.clear = function () { + this.head = this.tail = null; + this._len = 0; + }; + return LinkedList; + }()); + var LRU = (function () { + function LRU(maxSize) { + this._list = new LinkedList(); + this._maxSize = 10; + this._map = {}; + this._maxSize = maxSize; + } + LRU.prototype.put = function (key, value) { + var list = this._list; + var map = this._map; + var removed = null; + if (map[key] == null) { + var len = list.len(); + var entry = this._lastRemovedEntry; + if (len >= this._maxSize && len > 0) { + var leastUsedEntry = list.head; + list.remove(leastUsedEntry); + delete map[leastUsedEntry.key]; + removed = leastUsedEntry.value; + this._lastRemovedEntry = leastUsedEntry; + } + if (entry) { + entry.value = value; + } + else { + entry = new Entry(value); + } + entry.key = key; + list.insertEntry(entry); + map[key] = entry; + } + return removed; + }; + LRU.prototype.get = function (key) { + var entry = this._map[key]; + var list = this._list; + if (entry != null) { + if (entry !== list.tail) { + list.remove(entry); + list.insertEntry(entry); + } + return entry.value; + } + }; + LRU.prototype.clear = function () { + this._list.clear(); + this._map = {}; + }; + LRU.prototype.len = function () { + return this._list.len(); + }; + return LRU; + }()); + + var kCSSColorTable = { + 'transparent': [0, 0, 0, 0], 'aliceblue': [240, 248, 255, 1], + 'antiquewhite': [250, 235, 215, 1], 'aqua': [0, 255, 255, 1], + 'aquamarine': [127, 255, 212, 1], 'azure': [240, 255, 255, 1], + 'beige': [245, 245, 220, 1], 'bisque': [255, 228, 196, 1], + 'black': [0, 0, 0, 1], 'blanchedalmond': [255, 235, 205, 1], + 'blue': [0, 0, 255, 1], 'blueviolet': [138, 43, 226, 1], + 'brown': [165, 42, 42, 1], 'burlywood': [222, 184, 135, 1], + 'cadetblue': [95, 158, 160, 1], 'chartreuse': [127, 255, 0, 1], + 'chocolate': [210, 105, 30, 1], 'coral': [255, 127, 80, 1], + 'cornflowerblue': [100, 149, 237, 1], 'cornsilk': [255, 248, 220, 1], + 'crimson': [220, 20, 60, 1], 'cyan': [0, 255, 255, 1], + 'darkblue': [0, 0, 139, 1], 'darkcyan': [0, 139, 139, 1], + 'darkgoldenrod': [184, 134, 11, 1], 'darkgray': [169, 169, 169, 1], + 'darkgreen': [0, 100, 0, 1], 'darkgrey': [169, 169, 169, 1], + 'darkkhaki': [189, 183, 107, 1], 'darkmagenta': [139, 0, 139, 1], + 'darkolivegreen': [85, 107, 47, 1], 'darkorange': [255, 140, 0, 1], + 'darkorchid': [153, 50, 204, 1], 'darkred': [139, 0, 0, 1], + 'darksalmon': [233, 150, 122, 1], 'darkseagreen': [143, 188, 143, 1], + 'darkslateblue': [72, 61, 139, 1], 'darkslategray': [47, 79, 79, 1], + 'darkslategrey': [47, 79, 79, 1], 'darkturquoise': [0, 206, 209, 1], + 'darkviolet': [148, 0, 211, 1], 'deeppink': [255, 20, 147, 1], + 'deepskyblue': [0, 191, 255, 1], 'dimgray': [105, 105, 105, 1], + 'dimgrey': [105, 105, 105, 1], 'dodgerblue': [30, 144, 255, 1], + 'firebrick': [178, 34, 34, 1], 'floralwhite': [255, 250, 240, 1], + 'forestgreen': [34, 139, 34, 1], 'fuchsia': [255, 0, 255, 1], + 'gainsboro': [220, 220, 220, 1], 'ghostwhite': [248, 248, 255, 1], + 'gold': [255, 215, 0, 1], 'goldenrod': [218, 165, 32, 1], + 'gray': [128, 128, 128, 1], 'green': [0, 128, 0, 1], + 'greenyellow': [173, 255, 47, 1], 'grey': [128, 128, 128, 1], + 'honeydew': [240, 255, 240, 1], 'hotpink': [255, 105, 180, 1], + 'indianred': [205, 92, 92, 1], 'indigo': [75, 0, 130, 1], + 'ivory': [255, 255, 240, 1], 'khaki': [240, 230, 140, 1], + 'lavender': [230, 230, 250, 1], 'lavenderblush': [255, 240, 245, 1], + 'lawngreen': [124, 252, 0, 1], 'lemonchiffon': [255, 250, 205, 1], + 'lightblue': [173, 216, 230, 1], 'lightcoral': [240, 128, 128, 1], + 'lightcyan': [224, 255, 255, 1], 'lightgoldenrodyellow': [250, 250, 210, 1], + 'lightgray': [211, 211, 211, 1], 'lightgreen': [144, 238, 144, 1], + 'lightgrey': [211, 211, 211, 1], 'lightpink': [255, 182, 193, 1], + 'lightsalmon': [255, 160, 122, 1], 'lightseagreen': [32, 178, 170, 1], + 'lightskyblue': [135, 206, 250, 1], 'lightslategray': [119, 136, 153, 1], + 'lightslategrey': [119, 136, 153, 1], 'lightsteelblue': [176, 196, 222, 1], + 'lightyellow': [255, 255, 224, 1], 'lime': [0, 255, 0, 1], + 'limegreen': [50, 205, 50, 1], 'linen': [250, 240, 230, 1], + 'magenta': [255, 0, 255, 1], 'maroon': [128, 0, 0, 1], + 'mediumaquamarine': [102, 205, 170, 1], 'mediumblue': [0, 0, 205, 1], + 'mediumorchid': [186, 85, 211, 1], 'mediumpurple': [147, 112, 219, 1], + 'mediumseagreen': [60, 179, 113, 1], 'mediumslateblue': [123, 104, 238, 1], + 'mediumspringgreen': [0, 250, 154, 1], 'mediumturquoise': [72, 209, 204, 1], + 'mediumvioletred': [199, 21, 133, 1], 'midnightblue': [25, 25, 112, 1], + 'mintcream': [245, 255, 250, 1], 'mistyrose': [255, 228, 225, 1], + 'moccasin': [255, 228, 181, 1], 'navajowhite': [255, 222, 173, 1], + 'navy': [0, 0, 128, 1], 'oldlace': [253, 245, 230, 1], + 'olive': [128, 128, 0, 1], 'olivedrab': [107, 142, 35, 1], + 'orange': [255, 165, 0, 1], 'orangered': [255, 69, 0, 1], + 'orchid': [218, 112, 214, 1], 'palegoldenrod': [238, 232, 170, 1], + 'palegreen': [152, 251, 152, 1], 'paleturquoise': [175, 238, 238, 1], + 'palevioletred': [219, 112, 147, 1], 'papayawhip': [255, 239, 213, 1], + 'peachpuff': [255, 218, 185, 1], 'peru': [205, 133, 63, 1], + 'pink': [255, 192, 203, 1], 'plum': [221, 160, 221, 1], + 'powderblue': [176, 224, 230, 1], 'purple': [128, 0, 128, 1], + 'red': [255, 0, 0, 1], 'rosybrown': [188, 143, 143, 1], + 'royalblue': [65, 105, 225, 1], 'saddlebrown': [139, 69, 19, 1], + 'salmon': [250, 128, 114, 1], 'sandybrown': [244, 164, 96, 1], + 'seagreen': [46, 139, 87, 1], 'seashell': [255, 245, 238, 1], + 'sienna': [160, 82, 45, 1], 'silver': [192, 192, 192, 1], + 'skyblue': [135, 206, 235, 1], 'slateblue': [106, 90, 205, 1], + 'slategray': [112, 128, 144, 1], 'slategrey': [112, 128, 144, 1], + 'snow': [255, 250, 250, 1], 'springgreen': [0, 255, 127, 1], + 'steelblue': [70, 130, 180, 1], 'tan': [210, 180, 140, 1], + 'teal': [0, 128, 128, 1], 'thistle': [216, 191, 216, 1], + 'tomato': [255, 99, 71, 1], 'turquoise': [64, 224, 208, 1], + 'violet': [238, 130, 238, 1], 'wheat': [245, 222, 179, 1], + 'white': [255, 255, 255, 1], 'whitesmoke': [245, 245, 245, 1], + 'yellow': [255, 255, 0, 1], 'yellowgreen': [154, 205, 50, 1] + }; + function clampCssByte(i) { + i = Math.round(i); + return i < 0 ? 0 : i > 255 ? 255 : i; + } + function clampCssAngle(i) { + i = Math.round(i); + return i < 0 ? 0 : i > 360 ? 360 : i; + } + function clampCssFloat(f) { + return f < 0 ? 0 : f > 1 ? 1 : f; + } + function parseCssInt(val) { + var str = val; + if (str.length && str.charAt(str.length - 1) === '%') { + return clampCssByte(parseFloat(str) / 100 * 255); + } + return clampCssByte(parseInt(str, 10)); + } + function parseCssFloat(val) { + var str = val; + if (str.length && str.charAt(str.length - 1) === '%') { + return clampCssFloat(parseFloat(str) / 100); + } + return clampCssFloat(parseFloat(str)); + } + function cssHueToRgb(m1, m2, h) { + if (h < 0) { + h += 1; + } + else if (h > 1) { + h -= 1; + } + if (h * 6 < 1) { + return m1 + (m2 - m1) * h * 6; + } + if (h * 2 < 1) { + return m2; + } + if (h * 3 < 2) { + return m1 + (m2 - m1) * (2 / 3 - h) * 6; + } + return m1; + } + function lerpNumber(a, b, p) { + return a + (b - a) * p; + } + function setRgba(out, r, g, b, a) { + out[0] = r; + out[1] = g; + out[2] = b; + out[3] = a; + return out; + } + function copyRgba(out, a) { + out[0] = a[0]; + out[1] = a[1]; + out[2] = a[2]; + out[3] = a[3]; + return out; + } + var colorCache = new LRU(20); + var lastRemovedArr = null; + function putToCache(colorStr, rgbaArr) { + if (lastRemovedArr) { + copyRgba(lastRemovedArr, rgbaArr); + } + lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice())); + } + function parse(colorStr, rgbaArr) { + if (!colorStr) { + return; + } + rgbaArr = rgbaArr || []; + var cached = colorCache.get(colorStr); + if (cached) { + return copyRgba(rgbaArr, cached); + } + colorStr = colorStr + ''; + var str = colorStr.replace(/ /g, '').toLowerCase(); + if (str in kCSSColorTable) { + copyRgba(rgbaArr, kCSSColorTable[str]); + putToCache(colorStr, rgbaArr); + return rgbaArr; + } + var strLen = str.length; + if (str.charAt(0) === '#') { + if (strLen === 4 || strLen === 5) { + var iv = parseInt(str.slice(1, 4), 16); + if (!(iv >= 0 && iv <= 0xfff)) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + setRgba(rgbaArr, ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), (iv & 0xf0) | ((iv & 0xf0) >> 4), (iv & 0xf) | ((iv & 0xf) << 4), strLen === 5 ? parseInt(str.slice(4), 16) / 0xf : 1); + putToCache(colorStr, rgbaArr); + return rgbaArr; + } + else if (strLen === 7 || strLen === 9) { + var iv = parseInt(str.slice(1, 7), 16); + if (!(iv >= 0 && iv <= 0xffffff)) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, strLen === 9 ? parseInt(str.slice(7), 16) / 0xff : 1); + putToCache(colorStr, rgbaArr); + return rgbaArr; + } + return; + } + var op = str.indexOf('('); + var ep = str.indexOf(')'); + if (op !== -1 && ep + 1 === strLen) { + var fname = str.substr(0, op); + var params = str.substr(op + 1, ep - (op + 1)).split(','); + var alpha = 1; + switch (fname) { + case 'rgba': + if (params.length !== 4) { + return params.length === 3 + ? setRgba(rgbaArr, +params[0], +params[1], +params[2], 1) + : setRgba(rgbaArr, 0, 0, 0, 1); + } + alpha = parseCssFloat(params.pop()); + case 'rgb': + if (params.length >= 3) { + setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), params.length === 3 ? alpha : parseCssFloat(params[3])); + putToCache(colorStr, rgbaArr); + return rgbaArr; + } + else { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + case 'hsla': + if (params.length !== 4) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + params[3] = parseCssFloat(params[3]); + hsla2rgba(params, rgbaArr); + putToCache(colorStr, rgbaArr); + return rgbaArr; + case 'hsl': + if (params.length !== 3) { + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + hsla2rgba(params, rgbaArr); + putToCache(colorStr, rgbaArr); + return rgbaArr; + default: + return; + } + } + setRgba(rgbaArr, 0, 0, 0, 1); + return; + } + function hsla2rgba(hsla, rgba) { + var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360; + var s = parseCssFloat(hsla[1]); + var l = parseCssFloat(hsla[2]); + var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; + var m1 = l * 2 - m2; + rgba = rgba || []; + setRgba(rgba, clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255), clampCssByte(cssHueToRgb(m1, m2, h) * 255), clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255), 1); + if (hsla.length === 4) { + rgba[3] = hsla[3]; + } + return rgba; + } + function rgba2hsla(rgba) { + if (!rgba) { + return; + } + var R = rgba[0] / 255; + var G = rgba[1] / 255; + var B = rgba[2] / 255; + var vMin = Math.min(R, G, B); + var vMax = Math.max(R, G, B); + var delta = vMax - vMin; + var L = (vMax + vMin) / 2; + var H; + var S; + if (delta === 0) { + H = 0; + S = 0; + } + else { + if (L < 0.5) { + S = delta / (vMax + vMin); + } + else { + S = delta / (2 - vMax - vMin); + } + var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta; + var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta; + var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta; + if (R === vMax) { + H = deltaB - deltaG; + } + else if (G === vMax) { + H = (1 / 3) + deltaR - deltaB; + } + else if (B === vMax) { + H = (2 / 3) + deltaG - deltaR; + } + if (H < 0) { + H += 1; + } + if (H > 1) { + H -= 1; + } + } + var hsla = [H * 360, S, L]; + if (rgba[3] != null) { + hsla.push(rgba[3]); + } + return hsla; + } + function lift(color, level) { + var colorArr = parse(color); + if (colorArr) { + for (var i = 0; i < 3; i++) { + if (level < 0) { + colorArr[i] = colorArr[i] * (1 - level) | 0; + } + else { + colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0; + } + if (colorArr[i] > 255) { + colorArr[i] = 255; + } + else if (colorArr[i] < 0) { + colorArr[i] = 0; + } + } + return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb'); + } + } + function toHex(color) { + var colorArr = parse(color); + if (colorArr) { + return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1); + } + } + function fastLerp(normalizedValue, colors, out) { + if (!(colors && colors.length) + || !(normalizedValue >= 0 && normalizedValue <= 1)) { + return; + } + out = out || []; + var value = normalizedValue * (colors.length - 1); + var leftIndex = Math.floor(value); + var rightIndex = Math.ceil(value); + var leftColor = colors[leftIndex]; + var rightColor = colors[rightIndex]; + var dv = value - leftIndex; + out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)); + out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)); + out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)); + out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv)); + return out; + } + var fastMapToColor = fastLerp; + function lerp$1(normalizedValue, colors, fullOutput) { + if (!(colors && colors.length) + || !(normalizedValue >= 0 && normalizedValue <= 1)) { + return; + } + var value = normalizedValue * (colors.length - 1); + var leftIndex = Math.floor(value); + var rightIndex = Math.ceil(value); + var leftColor = parse(colors[leftIndex]); + var rightColor = parse(colors[rightIndex]); + var dv = value - leftIndex; + var color = stringify([ + clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)), + clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)), + clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)), + clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv)) + ], 'rgba'); + return fullOutput + ? { + color: color, + leftIndex: leftIndex, + rightIndex: rightIndex, + value: value + } + : color; + } + var mapToColor = lerp$1; + function modifyHSL(color, h, s, l) { + var colorArr = parse(color); + if (color) { + colorArr = rgba2hsla(colorArr); + h != null && (colorArr[0] = clampCssAngle(h)); + s != null && (colorArr[1] = parseCssFloat(s)); + l != null && (colorArr[2] = parseCssFloat(l)); + return stringify(hsla2rgba(colorArr), 'rgba'); + } + } + function modifyAlpha(color, alpha) { + var colorArr = parse(color); + if (colorArr && alpha != null) { + colorArr[3] = clampCssFloat(alpha); + return stringify(colorArr, 'rgba'); + } + } + function stringify(arrColor, type) { + if (!arrColor || !arrColor.length) { + return; + } + var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2]; + if (type === 'rgba' || type === 'hsva' || type === 'hsla') { + colorStr += ',' + arrColor[3]; + } + return type + '(' + colorStr + ')'; + } + function lum(color, backgroundLum) { + var arr = parse(color); + return arr + ? (0.299 * arr[0] + 0.587 * arr[1] + 0.114 * arr[2]) * arr[3] / 255 + + (1 - arr[3]) * backgroundLum + : 0; + } + function random() { + return stringify([ + Math.round(Math.random() * 255), + Math.round(Math.random() * 255), + Math.round(Math.random() * 255) + ], 'rgb'); + } + var liftedColorCache = new LRU(100); + function liftColor(color) { + if (isString(color)) { + var liftedColor = liftedColorCache.get(color); + if (!liftedColor) { + liftedColor = lift(color, -0.1); + liftedColorCache.put(color, liftedColor); + } + return liftedColor; + } + else if (isGradientObject(color)) { + var ret = extend({}, color); + ret.colorStops = map(color.colorStops, function (stop) { return ({ + offset: stop.offset, + color: lift(stop.color, -0.1) + }); }); + return ret; + } + return color; + } + + var color = /*#__PURE__*/Object.freeze({ + __proto__: null, + parse: parse, + lift: lift, + toHex: toHex, + fastLerp: fastLerp, + fastMapToColor: fastMapToColor, + lerp: lerp$1, + mapToColor: mapToColor, + modifyHSL: modifyHSL, + modifyAlpha: modifyAlpha, + stringify: stringify, + lum: lum, + random: random, + liftColor: liftColor + }); + + var mathRound = Math.round; + function normalizeColor(color) { + var opacity; + if (!color || color === 'transparent') { + color = 'none'; + } + else if (typeof color === 'string' && color.indexOf('rgba') > -1) { + var arr = parse(color); + if (arr) { + color = 'rgb(' + arr[0] + ',' + arr[1] + ',' + arr[2] + ')'; + opacity = arr[3]; + } + } + return { + color: color, + opacity: opacity == null ? 1 : opacity + }; + } + var EPSILON$1 = 1e-4; + function isAroundZero$1(transform) { + return transform < EPSILON$1 && transform > -EPSILON$1; + } + function round3(transform) { + return mathRound(transform * 1e3) / 1e3; + } + function round4(transform) { + return mathRound(transform * 1e4) / 1e4; + } + function getMatrixStr(m) { + return 'matrix(' + + round3(m[0]) + ',' + + round3(m[1]) + ',' + + round3(m[2]) + ',' + + round3(m[3]) + ',' + + round4(m[4]) + ',' + + round4(m[5]) + + ')'; + } + var TEXT_ALIGN_TO_ANCHOR = { + left: 'start', + right: 'end', + center: 'middle', + middle: 'middle' + }; + function adjustTextY(y, lineHeight, textBaseline) { + if (textBaseline === 'top') { + y += lineHeight / 2; + } + else if (textBaseline === 'bottom') { + y -= lineHeight / 2; + } + return y; + } + function hasShadow(style) { + return style + && (style.shadowBlur || style.shadowOffsetX || style.shadowOffsetY); + } + function getShadowKey(displayable) { + var style = displayable.style; + var globalScale = displayable.getGlobalScale(); + return [ + style.shadowColor, + (style.shadowBlur || 0).toFixed(2), + (style.shadowOffsetX || 0).toFixed(2), + (style.shadowOffsetY || 0).toFixed(2), + globalScale[0], + globalScale[1] + ].join(','); + } + function isImagePattern(val) { + return val && (!!val.image); + } + function isSVGPattern(val) { + return val && (!!val.svgElement); + } + function isPattern(val) { + return isImagePattern(val) || isSVGPattern(val); + } + function isLinearGradient(val) { + return val.type === 'linear'; + } + function isRadialGradient(val) { + return val.type === 'radial'; + } + function isGradient(val) { + return val && (val.type === 'linear' + || val.type === 'radial'); + } + function getIdURL(id) { + return "url(#" + id + ")"; + } + function getPathPrecision(el) { + var scale = el.getGlobalScale(); + var size = Math.max(scale[0], scale[1]); + return Math.max(Math.ceil(Math.log(size) / Math.log(10)), 1); + } + function getSRTTransformString(transform) { + var x = transform.x || 0; + var y = transform.y || 0; + var rotation = (transform.rotation || 0) * RADIAN_TO_DEGREE; + var scaleX = retrieve2(transform.scaleX, 1); + var scaleY = retrieve2(transform.scaleY, 1); + var skewX = transform.skewX || 0; + var skewY = transform.skewY || 0; + var res = []; + if (x || y) { + res.push("translate(" + x + "px," + y + "px)"); + } + if (rotation) { + res.push("rotate(" + rotation + ")"); + } + if (scaleX !== 1 || scaleY !== 1) { + res.push("scale(" + scaleX + "," + scaleY + ")"); + } + if (skewX || skewY) { + res.push("skew(" + mathRound(skewX * RADIAN_TO_DEGREE) + "deg, " + mathRound(skewY * RADIAN_TO_DEGREE) + "deg)"); + } + return res.join(' '); + } + var encodeBase64 = (function () { + if (env.hasGlobalWindow && isFunction(window.btoa)) { + return function (str) { + return window.btoa(unescape(encodeURIComponent(str))); + }; + } + if (typeof Buffer !== 'undefined') { + return function (str) { + return Buffer.from(str).toString('base64'); + }; + } + return function (str) { + if ("development" !== 'production') { + logError('Base64 isn\'t natively supported in the current environment.'); + } + return null; + }; + })(); + + var arraySlice = Array.prototype.slice; + function interpolateNumber(p0, p1, percent) { + return (p1 - p0) * percent + p0; + } + function interpolate1DArray(out, p0, p1, percent) { + var len = p0.length; + for (var i = 0; i < len; i++) { + out[i] = interpolateNumber(p0[i], p1[i], percent); + } + return out; + } + function interpolate2DArray(out, p0, p1, percent) { + var len = p0.length; + var len2 = len && p0[0].length; + for (var i = 0; i < len; i++) { + if (!out[i]) { + out[i] = []; + } + for (var j = 0; j < len2; j++) { + out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent); + } + } + return out; + } + function add1DArray(out, p0, p1, sign) { + var len = p0.length; + for (var i = 0; i < len; i++) { + out[i] = p0[i] + p1[i] * sign; + } + return out; + } + function add2DArray(out, p0, p1, sign) { + var len = p0.length; + var len2 = len && p0[0].length; + for (var i = 0; i < len; i++) { + if (!out[i]) { + out[i] = []; + } + for (var j = 0; j < len2; j++) { + out[i][j] = p0[i][j] + p1[i][j] * sign; + } + } + return out; + } + function fillColorStops(val0, val1) { + var len0 = val0.length; + var len1 = val1.length; + var shorterArr = len0 > len1 ? val1 : val0; + var shorterLen = Math.min(len0, len1); + var last = shorterArr[shorterLen - 1] || { color: [0, 0, 0, 0], offset: 0 }; + for (var i = shorterLen; i < Math.max(len0, len1); i++) { + shorterArr.push({ + offset: last.offset, + color: last.color.slice() + }); + } + } + function fillArray(val0, val1, arrDim) { + var arr0 = val0; + var arr1 = val1; + if (!arr0.push || !arr1.push) { + return; + } + var arr0Len = arr0.length; + var arr1Len = arr1.length; + if (arr0Len !== arr1Len) { + var isPreviousLarger = arr0Len > arr1Len; + if (isPreviousLarger) { + arr0.length = arr1Len; + } + else { + for (var i = arr0Len; i < arr1Len; i++) { + arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i])); + } + } + } + var len2 = arr0[0] && arr0[0].length; + for (var i = 0; i < arr0.length; i++) { + if (arrDim === 1) { + if (isNaN(arr0[i])) { + arr0[i] = arr1[i]; + } + } + else { + for (var j = 0; j < len2; j++) { + if (isNaN(arr0[i][j])) { + arr0[i][j] = arr1[i][j]; + } + } + } + } + } + function cloneValue(value) { + if (isArrayLike(value)) { + var len = value.length; + if (isArrayLike(value[0])) { + var ret = []; + for (var i = 0; i < len; i++) { + ret.push(arraySlice.call(value[i])); + } + return ret; + } + return arraySlice.call(value); + } + return value; + } + function rgba2String(rgba) { + rgba[0] = Math.floor(rgba[0]) || 0; + rgba[1] = Math.floor(rgba[1]) || 0; + rgba[2] = Math.floor(rgba[2]) || 0; + rgba[3] = rgba[3] == null ? 1 : rgba[3]; + return 'rgba(' + rgba.join(',') + ')'; + } + function guessArrayDim(value) { + return isArrayLike(value && value[0]) ? 2 : 1; + } + var VALUE_TYPE_NUMBER = 0; + var VALUE_TYPE_1D_ARRAY = 1; + var VALUE_TYPE_2D_ARRAY = 2; + var VALUE_TYPE_COLOR = 3; + var VALUE_TYPE_LINEAR_GRADIENT = 4; + var VALUE_TYPE_RADIAL_GRADIENT = 5; + var VALUE_TYPE_UNKOWN = 6; + function isGradientValueType(valType) { + return valType === VALUE_TYPE_LINEAR_GRADIENT || valType === VALUE_TYPE_RADIAL_GRADIENT; + } + function isArrayValueType(valType) { + return valType === VALUE_TYPE_1D_ARRAY || valType === VALUE_TYPE_2D_ARRAY; + } + var tmpRgba = [0, 0, 0, 0]; + var Track = (function () { + function Track(propName) { + this.keyframes = []; + this.discrete = false; + this._invalid = false; + this._needsSort = false; + this._lastFr = 0; + this._lastFrP = 0; + this.propName = propName; + } + Track.prototype.isFinished = function () { + return this._finished; + }; + Track.prototype.setFinished = function () { + this._finished = true; + if (this._additiveTrack) { + this._additiveTrack.setFinished(); + } + }; + Track.prototype.needsAnimate = function () { + return this.keyframes.length >= 1; + }; + Track.prototype.getAdditiveTrack = function () { + return this._additiveTrack; + }; + Track.prototype.addKeyframe = function (time, rawValue, easing) { + this._needsSort = true; + var keyframes = this.keyframes; + var len = keyframes.length; + var discrete = false; + var valType = VALUE_TYPE_UNKOWN; + var value = rawValue; + if (isArrayLike(rawValue)) { + var arrayDim = guessArrayDim(rawValue); + valType = arrayDim; + if (arrayDim === 1 && !isNumber(rawValue[0]) + || arrayDim === 2 && !isNumber(rawValue[0][0])) { + discrete = true; + } + } + else { + if (isNumber(rawValue) && !eqNaN(rawValue)) { + valType = VALUE_TYPE_NUMBER; + } + else if (isString(rawValue)) { + if (!isNaN(+rawValue)) { + valType = VALUE_TYPE_NUMBER; + } + else { + var colorArray = parse(rawValue); + if (colorArray) { + value = colorArray; + valType = VALUE_TYPE_COLOR; + } + } + } + else if (isGradientObject(rawValue)) { + var parsedGradient = extend({}, value); + parsedGradient.colorStops = map(rawValue.colorStops, function (colorStop) { return ({ + offset: colorStop.offset, + color: parse(colorStop.color) + }); }); + if (isLinearGradient(rawValue)) { + valType = VALUE_TYPE_LINEAR_GRADIENT; + } + else if (isRadialGradient(rawValue)) { + valType = VALUE_TYPE_RADIAL_GRADIENT; + } + value = parsedGradient; + } + } + if (len === 0) { + this.valType = valType; + } + else if (valType !== this.valType || valType === VALUE_TYPE_UNKOWN) { + discrete = true; + } + this.discrete = this.discrete || discrete; + var kf = { + time: time, + value: value, + rawValue: rawValue, + percent: 0 + }; + if (easing) { + kf.easing = easing; + kf.easingFunc = isFunction(easing) + ? easing + : easingFuncs[easing] || createCubicEasingFunc(easing); + } + keyframes.push(kf); + return kf; + }; + Track.prototype.prepare = function (maxTime, additiveTrack) { + var kfs = this.keyframes; + if (this._needsSort) { + kfs.sort(function (a, b) { + return a.time - b.time; + }); + } + var valType = this.valType; + var kfsLen = kfs.length; + var lastKf = kfs[kfsLen - 1]; + var isDiscrete = this.discrete; + var isArr = isArrayValueType(valType); + var isGradient = isGradientValueType(valType); + for (var i = 0; i < kfsLen; i++) { + var kf = kfs[i]; + var value = kf.value; + var lastValue = lastKf.value; + kf.percent = kf.time / maxTime; + if (!isDiscrete) { + if (isArr && i !== kfsLen - 1) { + fillArray(value, lastValue, valType); + } + else if (isGradient) { + fillColorStops(value.colorStops, lastValue.colorStops); + } + } + } + if (!isDiscrete + && valType !== VALUE_TYPE_RADIAL_GRADIENT + && additiveTrack + && this.needsAnimate() + && additiveTrack.needsAnimate() + && valType === additiveTrack.valType + && !additiveTrack._finished) { + this._additiveTrack = additiveTrack; + var startValue = kfs[0].value; + for (var i = 0; i < kfsLen; i++) { + if (valType === VALUE_TYPE_NUMBER) { + kfs[i].additiveValue = kfs[i].value - startValue; + } + else if (valType === VALUE_TYPE_COLOR) { + kfs[i].additiveValue = + add1DArray([], kfs[i].value, startValue, -1); + } + else if (isArrayValueType(valType)) { + kfs[i].additiveValue = valType === VALUE_TYPE_1D_ARRAY + ? add1DArray([], kfs[i].value, startValue, -1) + : add2DArray([], kfs[i].value, startValue, -1); + } + } + } + }; + Track.prototype.step = function (target, percent) { + if (this._finished) { + return; + } + if (this._additiveTrack && this._additiveTrack._finished) { + this._additiveTrack = null; + } + var isAdditive = this._additiveTrack != null; + var valueKey = isAdditive ? 'additiveValue' : 'value'; + var valType = this.valType; + var keyframes = this.keyframes; + var kfsNum = keyframes.length; + var propName = this.propName; + var isValueColor = valType === VALUE_TYPE_COLOR; + var frameIdx; + var lastFrame = this._lastFr; + var mathMin = Math.min; + var frame; + var nextFrame; + if (kfsNum === 1) { + frame = nextFrame = keyframes[0]; + } + else { + if (percent < 0) { + frameIdx = 0; + } + else if (percent < this._lastFrP) { + var start = mathMin(lastFrame + 1, kfsNum - 1); + for (frameIdx = start; frameIdx >= 0; frameIdx--) { + if (keyframes[frameIdx].percent <= percent) { + break; + } + } + frameIdx = mathMin(frameIdx, kfsNum - 2); + } + else { + for (frameIdx = lastFrame; frameIdx < kfsNum; frameIdx++) { + if (keyframes[frameIdx].percent > percent) { + break; + } + } + frameIdx = mathMin(frameIdx - 1, kfsNum - 2); + } + nextFrame = keyframes[frameIdx + 1]; + frame = keyframes[frameIdx]; + } + if (!(frame && nextFrame)) { + return; + } + this._lastFr = frameIdx; + this._lastFrP = percent; + var interval = (nextFrame.percent - frame.percent); + var w = interval === 0 ? 1 : mathMin((percent - frame.percent) / interval, 1); + if (nextFrame.easingFunc) { + w = nextFrame.easingFunc(w); + } + var targetArr = isAdditive ? this._additiveValue + : (isValueColor ? tmpRgba : target[propName]); + if ((isArrayValueType(valType) || isValueColor) && !targetArr) { + targetArr = this._additiveValue = []; + } + if (this.discrete) { + target[propName] = w < 1 ? frame.rawValue : nextFrame.rawValue; + } + else if (isArrayValueType(valType)) { + valType === VALUE_TYPE_1D_ARRAY + ? interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w) + : interpolate2DArray(targetArr, frame[valueKey], nextFrame[valueKey], w); + } + else if (isGradientValueType(valType)) { + var val = frame[valueKey]; + var nextVal_1 = nextFrame[valueKey]; + var isLinearGradient_1 = valType === VALUE_TYPE_LINEAR_GRADIENT; + target[propName] = { + type: isLinearGradient_1 ? 'linear' : 'radial', + x: interpolateNumber(val.x, nextVal_1.x, w), + y: interpolateNumber(val.y, nextVal_1.y, w), + colorStops: map(val.colorStops, function (colorStop, idx) { + var nextColorStop = nextVal_1.colorStops[idx]; + return { + offset: interpolateNumber(colorStop.offset, nextColorStop.offset, w), + color: rgba2String(interpolate1DArray([], colorStop.color, nextColorStop.color, w)) + }; + }), + global: nextVal_1.global + }; + if (isLinearGradient_1) { + target[propName].x2 = interpolateNumber(val.x2, nextVal_1.x2, w); + target[propName].y2 = interpolateNumber(val.y2, nextVal_1.y2, w); + } + else { + target[propName].r = interpolateNumber(val.r, nextVal_1.r, w); + } + } + else if (isValueColor) { + interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w); + if (!isAdditive) { + target[propName] = rgba2String(targetArr); + } + } + else { + var value = interpolateNumber(frame[valueKey], nextFrame[valueKey], w); + if (isAdditive) { + this._additiveValue = value; + } + else { + target[propName] = value; + } + } + if (isAdditive) { + this._addToTarget(target); + } + }; + Track.prototype._addToTarget = function (target) { + var valType = this.valType; + var propName = this.propName; + var additiveValue = this._additiveValue; + if (valType === VALUE_TYPE_NUMBER) { + target[propName] = target[propName] + additiveValue; + } + else if (valType === VALUE_TYPE_COLOR) { + parse(target[propName], tmpRgba); + add1DArray(tmpRgba, tmpRgba, additiveValue, 1); + target[propName] = rgba2String(tmpRgba); + } + else if (valType === VALUE_TYPE_1D_ARRAY) { + add1DArray(target[propName], target[propName], additiveValue, 1); + } + else if (valType === VALUE_TYPE_2D_ARRAY) { + add2DArray(target[propName], target[propName], additiveValue, 1); + } + }; + return Track; + }()); + var Animator = (function () { + function Animator(target, loop, allowDiscreteAnimation, additiveTo) { + this._tracks = {}; + this._trackKeys = []; + this._maxTime = 0; + this._started = 0; + this._clip = null; + this._target = target; + this._loop = loop; + if (loop && additiveTo) { + logError('Can\' use additive animation on looped animation.'); + return; + } + this._additiveAnimators = additiveTo; + this._allowDiscrete = allowDiscreteAnimation; + } + Animator.prototype.getMaxTime = function () { + return this._maxTime; + }; + Animator.prototype.getDelay = function () { + return this._delay; + }; + Animator.prototype.getLoop = function () { + return this._loop; + }; + Animator.prototype.getTarget = function () { + return this._target; + }; + Animator.prototype.changeTarget = function (target) { + this._target = target; + }; + Animator.prototype.when = function (time, props, easing) { + return this.whenWithKeys(time, props, keys(props), easing); + }; + Animator.prototype.whenWithKeys = function (time, props, propNames, easing) { + var tracks = this._tracks; + for (var i = 0; i < propNames.length; i++) { + var propName = propNames[i]; + var track = tracks[propName]; + if (!track) { + track = tracks[propName] = new Track(propName); + var initialValue = void 0; + var additiveTrack = this._getAdditiveTrack(propName); + if (additiveTrack) { + var addtiveTrackKfs = additiveTrack.keyframes; + var lastFinalKf = addtiveTrackKfs[addtiveTrackKfs.length - 1]; + initialValue = lastFinalKf && lastFinalKf.value; + if (additiveTrack.valType === VALUE_TYPE_COLOR && initialValue) { + initialValue = rgba2String(initialValue); + } + } + else { + initialValue = this._target[propName]; + } + if (initialValue == null) { + continue; + } + if (time > 0) { + track.addKeyframe(0, cloneValue(initialValue), easing); + } + this._trackKeys.push(propName); + } + track.addKeyframe(time, cloneValue(props[propName]), easing); + } + this._maxTime = Math.max(this._maxTime, time); + return this; + }; + Animator.prototype.pause = function () { + this._clip.pause(); + this._paused = true; + }; + Animator.prototype.resume = function () { + this._clip.resume(); + this._paused = false; + }; + Animator.prototype.isPaused = function () { + return !!this._paused; + }; + Animator.prototype.duration = function (duration) { + this._maxTime = duration; + this._force = true; + return this; + }; + Animator.prototype._doneCallback = function () { + this._setTracksFinished(); + this._clip = null; + var doneList = this._doneCbs; + if (doneList) { + var len = doneList.length; + for (var i = 0; i < len; i++) { + doneList[i].call(this); + } + } + }; + Animator.prototype._abortedCallback = function () { + this._setTracksFinished(); + var animation = this.animation; + var abortedList = this._abortedCbs; + if (animation) { + animation.removeClip(this._clip); + } + this._clip = null; + if (abortedList) { + for (var i = 0; i < abortedList.length; i++) { + abortedList[i].call(this); + } + } + }; + Animator.prototype._setTracksFinished = function () { + var tracks = this._tracks; + var tracksKeys = this._trackKeys; + for (var i = 0; i < tracksKeys.length; i++) { + tracks[tracksKeys[i]].setFinished(); + } + }; + Animator.prototype._getAdditiveTrack = function (trackName) { + var additiveTrack; + var additiveAnimators = this._additiveAnimators; + if (additiveAnimators) { + for (var i = 0; i < additiveAnimators.length; i++) { + var track = additiveAnimators[i].getTrack(trackName); + if (track) { + additiveTrack = track; + } + } + } + return additiveTrack; + }; + Animator.prototype.start = function (easing) { + if (this._started > 0) { + return; + } + this._started = 1; + var self = this; + var tracks = []; + var maxTime = this._maxTime || 0; + for (var i = 0; i < this._trackKeys.length; i++) { + var propName = this._trackKeys[i]; + var track = this._tracks[propName]; + var additiveTrack = this._getAdditiveTrack(propName); + var kfs = track.keyframes; + var kfsNum = kfs.length; + track.prepare(maxTime, additiveTrack); + if (track.needsAnimate()) { + if (!this._allowDiscrete && track.discrete) { + var lastKf = kfs[kfsNum - 1]; + if (lastKf) { + self._target[track.propName] = lastKf.rawValue; + } + track.setFinished(); + } + else { + tracks.push(track); + } + } + } + if (tracks.length || this._force) { + var clip = new Clip({ + life: maxTime, + loop: this._loop, + delay: this._delay || 0, + onframe: function (percent) { + self._started = 2; + var additiveAnimators = self._additiveAnimators; + if (additiveAnimators) { + var stillHasAdditiveAnimator = false; + for (var i = 0; i < additiveAnimators.length; i++) { + if (additiveAnimators[i]._clip) { + stillHasAdditiveAnimator = true; + break; + } + } + if (!stillHasAdditiveAnimator) { + self._additiveAnimators = null; + } + } + for (var i = 0; i < tracks.length; i++) { + tracks[i].step(self._target, percent); + } + var onframeList = self._onframeCbs; + if (onframeList) { + for (var i = 0; i < onframeList.length; i++) { + onframeList[i](self._target, percent); + } + } + }, + ondestroy: function () { + self._doneCallback(); + } + }); + this._clip = clip; + if (this.animation) { + this.animation.addClip(clip); + } + if (easing) { + clip.setEasing(easing); + } + } + else { + this._doneCallback(); + } + return this; + }; + Animator.prototype.stop = function (forwardToLast) { + if (!this._clip) { + return; + } + var clip = this._clip; + if (forwardToLast) { + clip.onframe(1); + } + this._abortedCallback(); + }; + Animator.prototype.delay = function (time) { + this._delay = time; + return this; + }; + Animator.prototype.during = function (cb) { + if (cb) { + if (!this._onframeCbs) { + this._onframeCbs = []; + } + this._onframeCbs.push(cb); + } + return this; + }; + Animator.prototype.done = function (cb) { + if (cb) { + if (!this._doneCbs) { + this._doneCbs = []; + } + this._doneCbs.push(cb); + } + return this; + }; + Animator.prototype.aborted = function (cb) { + if (cb) { + if (!this._abortedCbs) { + this._abortedCbs = []; + } + this._abortedCbs.push(cb); + } + return this; + }; + Animator.prototype.getClip = function () { + return this._clip; + }; + Animator.prototype.getTrack = function (propName) { + return this._tracks[propName]; + }; + Animator.prototype.getTracks = function () { + var _this = this; + return map(this._trackKeys, function (key) { return _this._tracks[key]; }); + }; + Animator.prototype.stopTracks = function (propNames, forwardToLast) { + if (!propNames.length || !this._clip) { + return true; + } + var tracks = this._tracks; + var tracksKeys = this._trackKeys; + for (var i = 0; i < propNames.length; i++) { + var track = tracks[propNames[i]]; + if (track && !track.isFinished()) { + if (forwardToLast) { + track.step(this._target, 1); + } + else if (this._started === 1) { + track.step(this._target, 0); + } + track.setFinished(); + } + } + var allAborted = true; + for (var i = 0; i < tracksKeys.length; i++) { + if (!tracks[tracksKeys[i]].isFinished()) { + allAborted = false; + break; + } + } + if (allAborted) { + this._abortedCallback(); + } + return allAborted; + }; + Animator.prototype.saveTo = function (target, trackKeys, firstOrLast) { + if (!target) { + return; + } + trackKeys = trackKeys || this._trackKeys; + for (var i = 0; i < trackKeys.length; i++) { + var propName = trackKeys[i]; + var track = this._tracks[propName]; + if (!track || track.isFinished()) { + continue; + } + var kfs = track.keyframes; + var kf = kfs[firstOrLast ? 0 : kfs.length - 1]; + if (kf) { + target[propName] = cloneValue(kf.rawValue); + } + } + }; + Animator.prototype.__changeFinalValue = function (finalProps, trackKeys) { + trackKeys = trackKeys || keys(finalProps); + for (var i = 0; i < trackKeys.length; i++) { + var propName = trackKeys[i]; + var track = this._tracks[propName]; + if (!track) { + continue; + } + var kfs = track.keyframes; + if (kfs.length > 1) { + var lastKf = kfs.pop(); + track.addKeyframe(lastKf.time, finalProps[propName]); + track.prepare(this._maxTime, track.getAdditiveTrack()); + } + } + }; + return Animator; + }()); + + function getTime() { + return new Date().getTime(); + } + var Animation = (function (_super) { + __extends(Animation, _super); + function Animation(opts) { + var _this = _super.call(this) || this; + _this._running = false; + _this._time = 0; + _this._pausedTime = 0; + _this._pauseStart = 0; + _this._paused = false; + opts = opts || {}; + _this.stage = opts.stage || {}; + return _this; + } + Animation.prototype.addClip = function (clip) { + if (clip.animation) { + this.removeClip(clip); + } + if (!this._head) { + this._head = this._tail = clip; + } + else { + this._tail.next = clip; + clip.prev = this._tail; + clip.next = null; + this._tail = clip; + } + clip.animation = this; + }; + Animation.prototype.addAnimator = function (animator) { + animator.animation = this; + var clip = animator.getClip(); + if (clip) { + this.addClip(clip); + } + }; + Animation.prototype.removeClip = function (clip) { + if (!clip.animation) { + return; + } + var prev = clip.prev; + var next = clip.next; + if (prev) { + prev.next = next; + } + else { + this._head = next; + } + if (next) { + next.prev = prev; + } + else { + this._tail = prev; + } + clip.next = clip.prev = clip.animation = null; + }; + Animation.prototype.removeAnimator = function (animator) { + var clip = animator.getClip(); + if (clip) { + this.removeClip(clip); + } + animator.animation = null; + }; + Animation.prototype.update = function (notTriggerFrameAndStageUpdate) { + var time = getTime() - this._pausedTime; + var delta = time - this._time; + var clip = this._head; + while (clip) { + var nextClip = clip.next; + var finished = clip.step(time, delta); + if (finished) { + clip.ondestroy(); + this.removeClip(clip); + clip = nextClip; + } + else { + clip = nextClip; + } + } + this._time = time; + if (!notTriggerFrameAndStageUpdate) { + this.trigger('frame', delta); + this.stage.update && this.stage.update(); + } + }; + Animation.prototype._startLoop = function () { + var self = this; + this._running = true; + function step() { + if (self._running) { + requestAnimationFrame$1(step); + !self._paused && self.update(); + } + } + requestAnimationFrame$1(step); + }; + Animation.prototype.start = function () { + if (this._running) { + return; + } + this._time = getTime(); + this._pausedTime = 0; + this._startLoop(); + }; + Animation.prototype.stop = function () { + this._running = false; + }; + Animation.prototype.pause = function () { + if (!this._paused) { + this._pauseStart = getTime(); + this._paused = true; + } + }; + Animation.prototype.resume = function () { + if (this._paused) { + this._pausedTime += getTime() - this._pauseStart; + this._paused = false; + } + }; + Animation.prototype.clear = function () { + var clip = this._head; + while (clip) { + var nextClip = clip.next; + clip.prev = clip.next = clip.animation = null; + clip = nextClip; + } + this._head = this._tail = null; + }; + Animation.prototype.isFinished = function () { + return this._head == null; + }; + Animation.prototype.animate = function (target, options) { + options = options || {}; + this.start(); + var animator = new Animator(target, options.loop); + this.addAnimator(animator); + return animator; + }; + return Animation; + }(Eventful)); + + var TOUCH_CLICK_DELAY = 300; + var globalEventSupported = env.domSupported; + var localNativeListenerNames = (function () { + var mouseHandlerNames = [ + 'click', 'dblclick', 'mousewheel', 'wheel', 'mouseout', + 'mouseup', 'mousedown', 'mousemove', 'contextmenu' + ]; + var touchHandlerNames = [ + 'touchstart', 'touchend', 'touchmove' + ]; + var pointerEventNameMap = { + pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1 + }; + var pointerHandlerNames = map(mouseHandlerNames, function (name) { + var nm = name.replace('mouse', 'pointer'); + return pointerEventNameMap.hasOwnProperty(nm) ? nm : name; + }); + return { + mouse: mouseHandlerNames, + touch: touchHandlerNames, + pointer: pointerHandlerNames + }; + })(); + var globalNativeListenerNames = { + mouse: ['mousemove', 'mouseup'], + pointer: ['pointermove', 'pointerup'] + }; + var wheelEventSupported = false; + function isPointerFromTouch(event) { + var pointerType = event.pointerType; + return pointerType === 'pen' || pointerType === 'touch'; + } + function setTouchTimer(scope) { + scope.touching = true; + if (scope.touchTimer != null) { + clearTimeout(scope.touchTimer); + scope.touchTimer = null; + } + scope.touchTimer = setTimeout(function () { + scope.touching = false; + scope.touchTimer = null; + }, 700); + } + function markTouch(event) { + event && (event.zrByTouch = true); + } + function normalizeGlobalEvent(instance, event) { + return normalizeEvent(instance.dom, new FakeGlobalEvent(instance, event), true); + } + function isLocalEl(instance, el) { + var elTmp = el; + var isLocal = false; + while (elTmp && elTmp.nodeType !== 9 + && !(isLocal = elTmp.domBelongToZr + || (elTmp !== el && elTmp === instance.painterRoot))) { + elTmp = elTmp.parentNode; + } + return isLocal; + } + var FakeGlobalEvent = (function () { + function FakeGlobalEvent(instance, event) { + this.stopPropagation = noop; + this.stopImmediatePropagation = noop; + this.preventDefault = noop; + this.type = event.type; + this.target = this.currentTarget = instance.dom; + this.pointerType = event.pointerType; + this.clientX = event.clientX; + this.clientY = event.clientY; + } + return FakeGlobalEvent; + }()); + var localDOMHandlers = { + mousedown: function (event) { + event = normalizeEvent(this.dom, event); + this.__mayPointerCapture = [event.zrX, event.zrY]; + this.trigger('mousedown', event); + }, + mousemove: function (event) { + event = normalizeEvent(this.dom, event); + var downPoint = this.__mayPointerCapture; + if (downPoint && (event.zrX !== downPoint[0] || event.zrY !== downPoint[1])) { + this.__togglePointerCapture(true); + } + this.trigger('mousemove', event); + }, + mouseup: function (event) { + event = normalizeEvent(this.dom, event); + this.__togglePointerCapture(false); + this.trigger('mouseup', event); + }, + mouseout: function (event) { + event = normalizeEvent(this.dom, event); + var element = event.toElement || event.relatedTarget; + if (!isLocalEl(this, element)) { + if (this.__pointerCapturing) { + event.zrEventControl = 'no_globalout'; + } + this.trigger('mouseout', event); + } + }, + wheel: function (event) { + wheelEventSupported = true; + event = normalizeEvent(this.dom, event); + this.trigger('mousewheel', event); + }, + mousewheel: function (event) { + if (wheelEventSupported) { + return; + } + event = normalizeEvent(this.dom, event); + this.trigger('mousewheel', event); + }, + touchstart: function (event) { + event = normalizeEvent(this.dom, event); + markTouch(event); + this.__lastTouchMoment = new Date(); + this.handler.processGesture(event, 'start'); + localDOMHandlers.mousemove.call(this, event); + localDOMHandlers.mousedown.call(this, event); + }, + touchmove: function (event) { + event = normalizeEvent(this.dom, event); + markTouch(event); + this.handler.processGesture(event, 'change'); + localDOMHandlers.mousemove.call(this, event); + }, + touchend: function (event) { + event = normalizeEvent(this.dom, event); + markTouch(event); + this.handler.processGesture(event, 'end'); + localDOMHandlers.mouseup.call(this, event); + if (+new Date() - (+this.__lastTouchMoment) < TOUCH_CLICK_DELAY) { + localDOMHandlers.click.call(this, event); + } + }, + pointerdown: function (event) { + localDOMHandlers.mousedown.call(this, event); + }, + pointermove: function (event) { + if (!isPointerFromTouch(event)) { + localDOMHandlers.mousemove.call(this, event); + } + }, + pointerup: function (event) { + localDOMHandlers.mouseup.call(this, event); + }, + pointerout: function (event) { + if (!isPointerFromTouch(event)) { + localDOMHandlers.mouseout.call(this, event); + } + } + }; + each(['click', 'dblclick', 'contextmenu'], function (name) { + localDOMHandlers[name] = function (event) { + event = normalizeEvent(this.dom, event); + this.trigger(name, event); + }; + }); + var globalDOMHandlers = { + pointermove: function (event) { + if (!isPointerFromTouch(event)) { + globalDOMHandlers.mousemove.call(this, event); + } + }, + pointerup: function (event) { + globalDOMHandlers.mouseup.call(this, event); + }, + mousemove: function (event) { + this.trigger('mousemove', event); + }, + mouseup: function (event) { + var pointerCaptureReleasing = this.__pointerCapturing; + this.__togglePointerCapture(false); + this.trigger('mouseup', event); + if (pointerCaptureReleasing) { + event.zrEventControl = 'only_globalout'; + this.trigger('mouseout', event); + } + } + }; + function mountLocalDOMEventListeners(instance, scope) { + var domHandlers = scope.domHandlers; + if (env.pointerEventsSupported) { + each(localNativeListenerNames.pointer, function (nativeEventName) { + mountSingleDOMEventListener(scope, nativeEventName, function (event) { + domHandlers[nativeEventName].call(instance, event); + }); + }); + } + else { + if (env.touchEventsSupported) { + each(localNativeListenerNames.touch, function (nativeEventName) { + mountSingleDOMEventListener(scope, nativeEventName, function (event) { + domHandlers[nativeEventName].call(instance, event); + setTouchTimer(scope); + }); + }); + } + each(localNativeListenerNames.mouse, function (nativeEventName) { + mountSingleDOMEventListener(scope, nativeEventName, function (event) { + event = getNativeEvent(event); + if (!scope.touching) { + domHandlers[nativeEventName].call(instance, event); + } + }); + }); + } + } + function mountGlobalDOMEventListeners(instance, scope) { + if (env.pointerEventsSupported) { + each(globalNativeListenerNames.pointer, mount); + } + else if (!env.touchEventsSupported) { + each(globalNativeListenerNames.mouse, mount); + } + function mount(nativeEventName) { + function nativeEventListener(event) { + event = getNativeEvent(event); + if (!isLocalEl(instance, event.target)) { + event = normalizeGlobalEvent(instance, event); + scope.domHandlers[nativeEventName].call(instance, event); + } + } + mountSingleDOMEventListener(scope, nativeEventName, nativeEventListener, { capture: true }); + } + } + function mountSingleDOMEventListener(scope, nativeEventName, listener, opt) { + scope.mounted[nativeEventName] = listener; + scope.listenerOpts[nativeEventName] = opt; + addEventListener(scope.domTarget, nativeEventName, listener, opt); + } + function unmountDOMEventListeners(scope) { + var mounted = scope.mounted; + for (var nativeEventName in mounted) { + if (mounted.hasOwnProperty(nativeEventName)) { + removeEventListener(scope.domTarget, nativeEventName, mounted[nativeEventName], scope.listenerOpts[nativeEventName]); + } + } + scope.mounted = {}; + } + var DOMHandlerScope = (function () { + function DOMHandlerScope(domTarget, domHandlers) { + this.mounted = {}; + this.listenerOpts = {}; + this.touching = false; + this.domTarget = domTarget; + this.domHandlers = domHandlers; + } + return DOMHandlerScope; + }()); + var HandlerDomProxy = (function (_super) { + __extends(HandlerDomProxy, _super); + function HandlerDomProxy(dom, painterRoot) { + var _this = _super.call(this) || this; + _this.__pointerCapturing = false; + _this.dom = dom; + _this.painterRoot = painterRoot; + _this._localHandlerScope = new DOMHandlerScope(dom, localDOMHandlers); + if (globalEventSupported) { + _this._globalHandlerScope = new DOMHandlerScope(document, globalDOMHandlers); + } + mountLocalDOMEventListeners(_this, _this._localHandlerScope); + return _this; + } + HandlerDomProxy.prototype.dispose = function () { + unmountDOMEventListeners(this._localHandlerScope); + if (globalEventSupported) { + unmountDOMEventListeners(this._globalHandlerScope); + } + }; + HandlerDomProxy.prototype.setCursor = function (cursorStyle) { + this.dom.style && (this.dom.style.cursor = cursorStyle || 'default'); + }; + HandlerDomProxy.prototype.__togglePointerCapture = function (isPointerCapturing) { + this.__mayPointerCapture = null; + if (globalEventSupported + && ((+this.__pointerCapturing) ^ (+isPointerCapturing))) { + this.__pointerCapturing = isPointerCapturing; + var globalHandlerScope = this._globalHandlerScope; + isPointerCapturing + ? mountGlobalDOMEventListeners(this, globalHandlerScope) + : unmountDOMEventListeners(globalHandlerScope); + } + }; + return HandlerDomProxy; + }(Eventful)); + + var dpr = 1; + if (env.hasGlobalWindow) { + dpr = Math.max(window.devicePixelRatio + || (window.screen && window.screen.deviceXDPI / window.screen.logicalXDPI) + || 1, 1); + } + var devicePixelRatio = dpr; + var DARK_MODE_THRESHOLD = 0.4; + var DARK_LABEL_COLOR = '#333'; + var LIGHT_LABEL_COLOR = '#ccc'; + var LIGHTER_LABEL_COLOR = '#eee'; + + var mIdentity = identity; + var EPSILON$2 = 5e-5; + function isNotAroundZero$1(val) { + return val > EPSILON$2 || val < -EPSILON$2; + } + var scaleTmp = []; + var tmpTransform = []; + var originTransform = create$1(); + var abs = Math.abs; + var Transformable = (function () { + function Transformable() { + } + Transformable.prototype.getLocalTransform = function (m) { + return Transformable.getLocalTransform(this, m); + }; + Transformable.prototype.setPosition = function (arr) { + this.x = arr[0]; + this.y = arr[1]; + }; + Transformable.prototype.setScale = function (arr) { + this.scaleX = arr[0]; + this.scaleY = arr[1]; + }; + Transformable.prototype.setSkew = function (arr) { + this.skewX = arr[0]; + this.skewY = arr[1]; + }; + Transformable.prototype.setOrigin = function (arr) { + this.originX = arr[0]; + this.originY = arr[1]; + }; + Transformable.prototype.needLocalTransform = function () { + return isNotAroundZero$1(this.rotation) + || isNotAroundZero$1(this.x) + || isNotAroundZero$1(this.y) + || isNotAroundZero$1(this.scaleX - 1) + || isNotAroundZero$1(this.scaleY - 1) + || isNotAroundZero$1(this.skewX) + || isNotAroundZero$1(this.skewY); + }; + Transformable.prototype.updateTransform = function () { + var parentTransform = this.parent && this.parent.transform; + var needLocalTransform = this.needLocalTransform(); + var m = this.transform; + if (!(needLocalTransform || parentTransform)) { + if (m) { + mIdentity(m); + this.invTransform = null; + } + return; + } + m = m || create$1(); + if (needLocalTransform) { + this.getLocalTransform(m); + } + else { + mIdentity(m); + } + if (parentTransform) { + if (needLocalTransform) { + mul$1(m, parentTransform, m); + } + else { + copy$1(m, parentTransform); + } + } + this.transform = m; + this._resolveGlobalScaleRatio(m); + }; + Transformable.prototype._resolveGlobalScaleRatio = function (m) { + var globalScaleRatio = this.globalScaleRatio; + if (globalScaleRatio != null && globalScaleRatio !== 1) { + this.getGlobalScale(scaleTmp); + var relX = scaleTmp[0] < 0 ? -1 : 1; + var relY = scaleTmp[1] < 0 ? -1 : 1; + var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0; + var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0; + m[0] *= sx; + m[1] *= sx; + m[2] *= sy; + m[3] *= sy; + } + this.invTransform = this.invTransform || create$1(); + invert(this.invTransform, m); + }; + Transformable.prototype.getComputedTransform = function () { + var transformNode = this; + var ancestors = []; + while (transformNode) { + ancestors.push(transformNode); + transformNode = transformNode.parent; + } + while (transformNode = ancestors.pop()) { + transformNode.updateTransform(); + } + return this.transform; + }; + Transformable.prototype.setLocalTransform = function (m) { + if (!m) { + return; + } + var sx = m[0] * m[0] + m[1] * m[1]; + var sy = m[2] * m[2] + m[3] * m[3]; + var rotation = Math.atan2(m[1], m[0]); + var shearX = Math.PI / 2 + rotation - Math.atan2(m[3], m[2]); + sy = Math.sqrt(sy) * Math.cos(shearX); + sx = Math.sqrt(sx); + this.skewX = shearX; + this.skewY = 0; + this.rotation = -rotation; + this.x = +m[4]; + this.y = +m[5]; + this.scaleX = sx; + this.scaleY = sy; + this.originX = 0; + this.originY = 0; + }; + Transformable.prototype.decomposeTransform = function () { + if (!this.transform) { + return; + } + var parent = this.parent; + var m = this.transform; + if (parent && parent.transform) { + parent.invTransform = parent.invTransform || create$1(); + mul$1(tmpTransform, parent.invTransform, m); + m = tmpTransform; + } + var ox = this.originX; + var oy = this.originY; + if (ox || oy) { + originTransform[4] = ox; + originTransform[5] = oy; + mul$1(tmpTransform, m, originTransform); + tmpTransform[4] -= ox; + tmpTransform[5] -= oy; + m = tmpTransform; + } + this.setLocalTransform(m); + }; + Transformable.prototype.getGlobalScale = function (out) { + var m = this.transform; + out = out || []; + if (!m) { + out[0] = 1; + out[1] = 1; + return out; + } + out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]); + out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]); + if (m[0] < 0) { + out[0] = -out[0]; + } + if (m[3] < 0) { + out[1] = -out[1]; + } + return out; + }; + Transformable.prototype.transformCoordToLocal = function (x, y) { + var v2 = [x, y]; + var invTransform = this.invTransform; + if (invTransform) { + applyTransform(v2, v2, invTransform); + } + return v2; + }; + Transformable.prototype.transformCoordToGlobal = function (x, y) { + var v2 = [x, y]; + var transform = this.transform; + if (transform) { + applyTransform(v2, v2, transform); + } + return v2; + }; + Transformable.prototype.getLineScale = function () { + var m = this.transform; + return m && abs(m[0] - 1) > 1e-10 && abs(m[3] - 1) > 1e-10 + ? Math.sqrt(abs(m[0] * m[3] - m[2] * m[1])) + : 1; + }; + Transformable.prototype.copyTransform = function (source) { + copyTransform(this, source); + }; + Transformable.getLocalTransform = function (target, m) { + m = m || []; + var ox = target.originX || 0; + var oy = target.originY || 0; + var sx = target.scaleX; + var sy = target.scaleY; + var ax = target.anchorX; + var ay = target.anchorY; + var rotation = target.rotation || 0; + var x = target.x; + var y = target.y; + var skewX = target.skewX ? Math.tan(target.skewX) : 0; + var skewY = target.skewY ? Math.tan(-target.skewY) : 0; + if (ox || oy || ax || ay) { + var dx = ox + ax; + var dy = oy + ay; + m[4] = -dx * sx - skewX * dy * sy; + m[5] = -dy * sy - skewY * dx * sx; + } + else { + m[4] = m[5] = 0; + } + m[0] = sx; + m[3] = sy; + m[1] = skewY * sx; + m[2] = skewX * sy; + rotation && rotate(m, m, rotation); + m[4] += ox + x; + m[5] += oy + y; + return m; + }; + Transformable.initDefaultProps = (function () { + var proto = Transformable.prototype; + proto.scaleX = + proto.scaleY = + proto.globalScaleRatio = 1; + proto.x = + proto.y = + proto.originX = + proto.originY = + proto.skewX = + proto.skewY = + proto.rotation = + proto.anchorX = + proto.anchorY = 0; + })(); + return Transformable; + }()); + var TRANSFORMABLE_PROPS = [ + 'x', 'y', 'originX', 'originY', 'anchorX', 'anchorY', 'rotation', 'scaleX', 'scaleY', 'skewX', 'skewY' + ]; + function copyTransform(target, source) { + for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) { + var propName = TRANSFORMABLE_PROPS[i]; + target[propName] = source[propName]; + } + } + + var textWidthCache = {}; + function getWidth(text, font) { + font = font || DEFAULT_FONT; + var cacheOfFont = textWidthCache[font]; + if (!cacheOfFont) { + cacheOfFont = textWidthCache[font] = new LRU(500); + } + var width = cacheOfFont.get(text); + if (width == null) { + width = platformApi.measureText(text, font).width; + cacheOfFont.put(text, width); + } + return width; + } + function innerGetBoundingRect(text, font, textAlign, textBaseline) { + var width = getWidth(text, font); + var height = getLineHeight(font); + var x = adjustTextX(0, width, textAlign); + var y = adjustTextY$1(0, height, textBaseline); + var rect = new BoundingRect(x, y, width, height); + return rect; + } + function getBoundingRect(text, font, textAlign, textBaseline) { + var textLines = ((text || '') + '').split('\n'); + var len = textLines.length; + if (len === 1) { + return innerGetBoundingRect(textLines[0], font, textAlign, textBaseline); + } + else { + var uniondRect = new BoundingRect(0, 0, 0, 0); + for (var i = 0; i < textLines.length; i++) { + var rect = innerGetBoundingRect(textLines[i], font, textAlign, textBaseline); + i === 0 ? uniondRect.copy(rect) : uniondRect.union(rect); + } + return uniondRect; + } + } + function adjustTextX(x, width, textAlign) { + if (textAlign === 'right') { + x -= width; + } + else if (textAlign === 'center') { + x -= width / 2; + } + return x; + } + function adjustTextY$1(y, height, verticalAlign) { + if (verticalAlign === 'middle') { + y -= height / 2; + } + else if (verticalAlign === 'bottom') { + y -= height; + } + return y; + } + function getLineHeight(font) { + return getWidth('国', font); + } + function parsePercent(value, maxValue) { + if (typeof value === 'string') { + if (value.lastIndexOf('%') >= 0) { + return parseFloat(value) / 100 * maxValue; + } + return parseFloat(value); + } + return value; + } + function calculateTextPosition(out, opts, rect) { + var textPosition = opts.position || 'inside'; + var distance = opts.distance != null ? opts.distance : 5; + var height = rect.height; + var width = rect.width; + var halfHeight = height / 2; + var x = rect.x; + var y = rect.y; + var textAlign = 'left'; + var textVerticalAlign = 'top'; + if (textPosition instanceof Array) { + x += parsePercent(textPosition[0], rect.width); + y += parsePercent(textPosition[1], rect.height); + textAlign = null; + textVerticalAlign = null; + } + else { + switch (textPosition) { + case 'left': + x -= distance; + y += halfHeight; + textAlign = 'right'; + textVerticalAlign = 'middle'; + break; + case 'right': + x += distance + width; + y += halfHeight; + textVerticalAlign = 'middle'; + break; + case 'top': + x += width / 2; + y -= distance; + textAlign = 'center'; + textVerticalAlign = 'bottom'; + break; + case 'bottom': + x += width / 2; + y += height + distance; + textAlign = 'center'; + break; + case 'inside': + x += width / 2; + y += halfHeight; + textAlign = 'center'; + textVerticalAlign = 'middle'; + break; + case 'insideLeft': + x += distance; + y += halfHeight; + textVerticalAlign = 'middle'; + break; + case 'insideRight': + x += width - distance; + y += halfHeight; + textAlign = 'right'; + textVerticalAlign = 'middle'; + break; + case 'insideTop': + x += width / 2; + y += distance; + textAlign = 'center'; + break; + case 'insideBottom': + x += width / 2; + y += height - distance; + textAlign = 'center'; + textVerticalAlign = 'bottom'; + break; + case 'insideTopLeft': + x += distance; + y += distance; + break; + case 'insideTopRight': + x += width - distance; + y += distance; + textAlign = 'right'; + break; + case 'insideBottomLeft': + x += distance; + y += height - distance; + textVerticalAlign = 'bottom'; + break; + case 'insideBottomRight': + x += width - distance; + y += height - distance; + textAlign = 'right'; + textVerticalAlign = 'bottom'; + break; + } + } + out = out || {}; + out.x = x; + out.y = y; + out.align = textAlign; + out.verticalAlign = textVerticalAlign; + return out; + } + + var PRESERVED_NORMAL_STATE = '__zr_normal__'; + var PRIMARY_STATES_KEYS = TRANSFORMABLE_PROPS.concat(['ignore']); + var DEFAULT_ANIMATABLE_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) { + obj[key] = true; + return obj; + }, { ignore: false }); + var tmpTextPosCalcRes = {}; + var tmpBoundingRect = new BoundingRect(0, 0, 0, 0); + var Element = (function () { + function Element(props) { + this.id = guid(); + this.animators = []; + this.currentStates = []; + this.states = {}; + this._init(props); + } + Element.prototype._init = function (props) { + this.attr(props); + }; + Element.prototype.drift = function (dx, dy, e) { + switch (this.draggable) { + case 'horizontal': + dy = 0; + break; + case 'vertical': + dx = 0; + break; + } + var m = this.transform; + if (!m) { + m = this.transform = [1, 0, 0, 1, 0, 0]; + } + m[4] += dx; + m[5] += dy; + this.decomposeTransform(); + this.markRedraw(); + }; + Element.prototype.beforeUpdate = function () { }; + Element.prototype.afterUpdate = function () { }; + Element.prototype.update = function () { + this.updateTransform(); + if (this.__dirty) { + this.updateInnerText(); + } + }; + Element.prototype.updateInnerText = function (forceUpdate) { + var textEl = this._textContent; + if (textEl && (!textEl.ignore || forceUpdate)) { + if (!this.textConfig) { + this.textConfig = {}; + } + var textConfig = this.textConfig; + var isLocal = textConfig.local; + var innerTransformable = textEl.innerTransformable; + var textAlign = void 0; + var textVerticalAlign = void 0; + var textStyleChanged = false; + innerTransformable.parent = isLocal ? this : null; + var innerOrigin = false; + innerTransformable.copyTransform(textEl); + if (textConfig.position != null) { + var layoutRect = tmpBoundingRect; + if (textConfig.layoutRect) { + layoutRect.copy(textConfig.layoutRect); + } + else { + layoutRect.copy(this.getBoundingRect()); + } + if (!isLocal) { + layoutRect.applyTransform(this.transform); + } + if (this.calculateTextPosition) { + this.calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect); + } + else { + calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect); + } + innerTransformable.x = tmpTextPosCalcRes.x; + innerTransformable.y = tmpTextPosCalcRes.y; + textAlign = tmpTextPosCalcRes.align; + textVerticalAlign = tmpTextPosCalcRes.verticalAlign; + var textOrigin = textConfig.origin; + if (textOrigin && textConfig.rotation != null) { + var relOriginX = void 0; + var relOriginY = void 0; + if (textOrigin === 'center') { + relOriginX = layoutRect.width * 0.5; + relOriginY = layoutRect.height * 0.5; + } + else { + relOriginX = parsePercent(textOrigin[0], layoutRect.width); + relOriginY = parsePercent(textOrigin[1], layoutRect.height); + } + innerOrigin = true; + innerTransformable.originX = -innerTransformable.x + relOriginX + (isLocal ? 0 : layoutRect.x); + innerTransformable.originY = -innerTransformable.y + relOriginY + (isLocal ? 0 : layoutRect.y); + } + } + if (textConfig.rotation != null) { + innerTransformable.rotation = textConfig.rotation; + } + var textOffset = textConfig.offset; + if (textOffset) { + innerTransformable.x += textOffset[0]; + innerTransformable.y += textOffset[1]; + if (!innerOrigin) { + innerTransformable.originX = -textOffset[0]; + innerTransformable.originY = -textOffset[1]; + } + } + var isInside = textConfig.inside == null + ? (typeof textConfig.position === 'string' && textConfig.position.indexOf('inside') >= 0) + : textConfig.inside; + var innerTextDefaultStyle = this._innerTextDefaultStyle || (this._innerTextDefaultStyle = {}); + var textFill = void 0; + var textStroke = void 0; + var autoStroke = void 0; + if (isInside && this.canBeInsideText()) { + textFill = textConfig.insideFill; + textStroke = textConfig.insideStroke; + if (textFill == null || textFill === 'auto') { + textFill = this.getInsideTextFill(); + } + if (textStroke == null || textStroke === 'auto') { + textStroke = this.getInsideTextStroke(textFill); + autoStroke = true; + } + } + else { + textFill = textConfig.outsideFill; + textStroke = textConfig.outsideStroke; + if (textFill == null || textFill === 'auto') { + textFill = this.getOutsideFill(); + } + if (textStroke == null || textStroke === 'auto') { + textStroke = this.getOutsideStroke(textFill); + autoStroke = true; + } + } + textFill = textFill || '#000'; + if (textFill !== innerTextDefaultStyle.fill + || textStroke !== innerTextDefaultStyle.stroke + || autoStroke !== innerTextDefaultStyle.autoStroke + || textAlign !== innerTextDefaultStyle.align + || textVerticalAlign !== innerTextDefaultStyle.verticalAlign) { + textStyleChanged = true; + innerTextDefaultStyle.fill = textFill; + innerTextDefaultStyle.stroke = textStroke; + innerTextDefaultStyle.autoStroke = autoStroke; + innerTextDefaultStyle.align = textAlign; + innerTextDefaultStyle.verticalAlign = textVerticalAlign; + textEl.setDefaultTextStyle(innerTextDefaultStyle); + } + textEl.__dirty |= REDRAW_BIT; + if (textStyleChanged) { + textEl.dirtyStyle(true); + } + } + }; + Element.prototype.canBeInsideText = function () { + return true; + }; + Element.prototype.getInsideTextFill = function () { + return '#fff'; + }; + Element.prototype.getInsideTextStroke = function (textFill) { + return '#000'; + }; + Element.prototype.getOutsideFill = function () { + return this.__zr && this.__zr.isDarkMode() ? LIGHT_LABEL_COLOR : DARK_LABEL_COLOR; + }; + Element.prototype.getOutsideStroke = function (textFill) { + var backgroundColor = this.__zr && this.__zr.getBackgroundColor(); + var colorArr = typeof backgroundColor === 'string' && parse(backgroundColor); + if (!colorArr) { + colorArr = [255, 255, 255, 1]; + } + var alpha = colorArr[3]; + var isDark = this.__zr.isDarkMode(); + for (var i = 0; i < 3; i++) { + colorArr[i] = colorArr[i] * alpha + (isDark ? 0 : 255) * (1 - alpha); + } + colorArr[3] = 1; + return stringify(colorArr, 'rgba'); + }; + Element.prototype.traverse = function (cb, context) { }; + Element.prototype.attrKV = function (key, value) { + if (key === 'textConfig') { + this.setTextConfig(value); + } + else if (key === 'textContent') { + this.setTextContent(value); + } + else if (key === 'clipPath') { + this.setClipPath(value); + } + else if (key === 'extra') { + this.extra = this.extra || {}; + extend(this.extra, value); + } + else { + this[key] = value; + } + }; + Element.prototype.hide = function () { + this.ignore = true; + this.markRedraw(); + }; + Element.prototype.show = function () { + this.ignore = false; + this.markRedraw(); + }; + Element.prototype.attr = function (keyOrObj, value) { + if (typeof keyOrObj === 'string') { + this.attrKV(keyOrObj, value); + } + else if (isObject(keyOrObj)) { + var obj = keyOrObj; + var keysArr = keys(obj); + for (var i = 0; i < keysArr.length; i++) { + var key = keysArr[i]; + this.attrKV(key, keyOrObj[key]); + } + } + this.markRedraw(); + return this; + }; + Element.prototype.saveCurrentToNormalState = function (toState) { + this._innerSaveToNormal(toState); + var normalState = this._normalState; + for (var i = 0; i < this.animators.length; i++) { + var animator = this.animators[i]; + var fromStateTransition = animator.__fromStateTransition; + if (animator.getLoop() || fromStateTransition && fromStateTransition !== PRESERVED_NORMAL_STATE) { + continue; + } + var targetName = animator.targetName; + var target = targetName + ? normalState[targetName] : normalState; + animator.saveTo(target); + } + }; + Element.prototype._innerSaveToNormal = function (toState) { + var normalState = this._normalState; + if (!normalState) { + normalState = this._normalState = {}; + } + if (toState.textConfig && !normalState.textConfig) { + normalState.textConfig = this.textConfig; + } + this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS); + }; + Element.prototype._savePrimaryToNormal = function (toState, normalState, primaryKeys) { + for (var i = 0; i < primaryKeys.length; i++) { + var key = primaryKeys[i]; + if (toState[key] != null && !(key in normalState)) { + normalState[key] = this[key]; + } + } + }; + Element.prototype.hasState = function () { + return this.currentStates.length > 0; + }; + Element.prototype.getState = function (name) { + return this.states[name]; + }; + Element.prototype.ensureState = function (name) { + var states = this.states; + if (!states[name]) { + states[name] = {}; + } + return states[name]; + }; + Element.prototype.clearStates = function (noAnimation) { + this.useState(PRESERVED_NORMAL_STATE, false, noAnimation); + }; + Element.prototype.useState = function (stateName, keepCurrentStates, noAnimation, forceUseHoverLayer) { + var toNormalState = stateName === PRESERVED_NORMAL_STATE; + var hasStates = this.hasState(); + if (!hasStates && toNormalState) { + return; + } + var currentStates = this.currentStates; + var animationCfg = this.stateTransition; + if (indexOf(currentStates, stateName) >= 0 && (keepCurrentStates || currentStates.length === 1)) { + return; + } + var state; + if (this.stateProxy && !toNormalState) { + state = this.stateProxy(stateName); + } + if (!state) { + state = (this.states && this.states[stateName]); + } + if (!state && !toNormalState) { + logError("State " + stateName + " not exists."); + return; + } + if (!toNormalState) { + this.saveCurrentToNormalState(state); + } + var useHoverLayer = !!((state && state.hoverLayer) || forceUseHoverLayer); + if (useHoverLayer) { + this._toggleHoverLayerFlag(true); + } + this._applyStateObj(stateName, state, this._normalState, keepCurrentStates, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg); + var textContent = this._textContent; + var textGuide = this._textGuide; + if (textContent) { + textContent.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer); + } + if (textGuide) { + textGuide.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer); + } + if (toNormalState) { + this.currentStates = []; + this._normalState = {}; + } + else { + if (!keepCurrentStates) { + this.currentStates = [stateName]; + } + else { + this.currentStates.push(stateName); + } + } + this._updateAnimationTargets(); + this.markRedraw(); + if (!useHoverLayer && this.__inHover) { + this._toggleHoverLayerFlag(false); + this.__dirty &= ~REDRAW_BIT; + } + return state; + }; + Element.prototype.useStates = function (states, noAnimation, forceUseHoverLayer) { + if (!states.length) { + this.clearStates(); + } + else { + var stateObjects = []; + var currentStates = this.currentStates; + var len = states.length; + var notChange = len === currentStates.length; + if (notChange) { + for (var i = 0; i < len; i++) { + if (states[i] !== currentStates[i]) { + notChange = false; + break; + } + } + } + if (notChange) { + return; + } + for (var i = 0; i < len; i++) { + var stateName = states[i]; + var stateObj = void 0; + if (this.stateProxy) { + stateObj = this.stateProxy(stateName, states); + } + if (!stateObj) { + stateObj = this.states[stateName]; + } + if (stateObj) { + stateObjects.push(stateObj); + } + } + var lastStateObj = stateObjects[len - 1]; + var useHoverLayer = !!((lastStateObj && lastStateObj.hoverLayer) || forceUseHoverLayer); + if (useHoverLayer) { + this._toggleHoverLayerFlag(true); + } + var mergedState = this._mergeStates(stateObjects); + var animationCfg = this.stateTransition; + this.saveCurrentToNormalState(mergedState); + this._applyStateObj(states.join(','), mergedState, this._normalState, false, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg); + var textContent = this._textContent; + var textGuide = this._textGuide; + if (textContent) { + textContent.useStates(states, noAnimation, useHoverLayer); + } + if (textGuide) { + textGuide.useStates(states, noAnimation, useHoverLayer); + } + this._updateAnimationTargets(); + this.currentStates = states.slice(); + this.markRedraw(); + if (!useHoverLayer && this.__inHover) { + this._toggleHoverLayerFlag(false); + this.__dirty &= ~REDRAW_BIT; + } + } + }; + Element.prototype.isSilent = function () { + var isSilent = this.silent; + var ancestor = this.parent; + while (!isSilent && ancestor) { + if (ancestor.silent) { + isSilent = true; + break; + } + ancestor = ancestor.parent; + } + return isSilent; + }; + Element.prototype._updateAnimationTargets = function () { + for (var i = 0; i < this.animators.length; i++) { + var animator = this.animators[i]; + if (animator.targetName) { + animator.changeTarget(this[animator.targetName]); + } + } + }; + Element.prototype.removeState = function (state) { + var idx = indexOf(this.currentStates, state); + if (idx >= 0) { + var currentStates = this.currentStates.slice(); + currentStates.splice(idx, 1); + this.useStates(currentStates); + } + }; + Element.prototype.replaceState = function (oldState, newState, forceAdd) { + var currentStates = this.currentStates.slice(); + var idx = indexOf(currentStates, oldState); + var newStateExists = indexOf(currentStates, newState) >= 0; + if (idx >= 0) { + if (!newStateExists) { + currentStates[idx] = newState; + } + else { + currentStates.splice(idx, 1); + } + } + else if (forceAdd && !newStateExists) { + currentStates.push(newState); + } + this.useStates(currentStates); + }; + Element.prototype.toggleState = function (state, enable) { + if (enable) { + this.useState(state, true); + } + else { + this.removeState(state); + } + }; + Element.prototype._mergeStates = function (states) { + var mergedState = {}; + var mergedTextConfig; + for (var i = 0; i < states.length; i++) { + var state = states[i]; + extend(mergedState, state); + if (state.textConfig) { + mergedTextConfig = mergedTextConfig || {}; + extend(mergedTextConfig, state.textConfig); + } + } + if (mergedTextConfig) { + mergedState.textConfig = mergedTextConfig; + } + return mergedState; + }; + Element.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) { + var needsRestoreToNormal = !(state && keepCurrentStates); + if (state && state.textConfig) { + this.textConfig = extend({}, keepCurrentStates ? this.textConfig : normalState.textConfig); + extend(this.textConfig, state.textConfig); + } + else if (needsRestoreToNormal) { + if (normalState.textConfig) { + this.textConfig = normalState.textConfig; + } + } + var transitionTarget = {}; + var hasTransition = false; + for (var i = 0; i < PRIMARY_STATES_KEYS.length; i++) { + var key = PRIMARY_STATES_KEYS[i]; + var propNeedsTransition = transition && DEFAULT_ANIMATABLE_MAP[key]; + if (state && state[key] != null) { + if (propNeedsTransition) { + hasTransition = true; + transitionTarget[key] = state[key]; + } + else { + this[key] = state[key]; + } + } + else if (needsRestoreToNormal) { + if (normalState[key] != null) { + if (propNeedsTransition) { + hasTransition = true; + transitionTarget[key] = normalState[key]; + } + else { + this[key] = normalState[key]; + } + } + } + } + if (!transition) { + for (var i = 0; i < this.animators.length; i++) { + var animator = this.animators[i]; + var targetName = animator.targetName; + if (!animator.getLoop()) { + animator.__changeFinalValue(targetName + ? (state || normalState)[targetName] + : (state || normalState)); + } + } + } + if (hasTransition) { + this._transitionState(stateName, transitionTarget, animationCfg); + } + }; + Element.prototype._attachComponent = function (componentEl) { + if (componentEl.__zr && !componentEl.__hostTarget) { + if ("development" !== 'production') { + throw new Error('Text element has been added to zrender.'); + } + return; + } + if (componentEl === this) { + if ("development" !== 'production') { + throw new Error('Recursive component attachment.'); + } + return; + } + var zr = this.__zr; + if (zr) { + componentEl.addSelfToZr(zr); + } + componentEl.__zr = zr; + componentEl.__hostTarget = this; + }; + Element.prototype._detachComponent = function (componentEl) { + if (componentEl.__zr) { + componentEl.removeSelfFromZr(componentEl.__zr); + } + componentEl.__zr = null; + componentEl.__hostTarget = null; + }; + Element.prototype.getClipPath = function () { + return this._clipPath; + }; + Element.prototype.setClipPath = function (clipPath) { + if (this._clipPath && this._clipPath !== clipPath) { + this.removeClipPath(); + } + this._attachComponent(clipPath); + this._clipPath = clipPath; + this.markRedraw(); + }; + Element.prototype.removeClipPath = function () { + var clipPath = this._clipPath; + if (clipPath) { + this._detachComponent(clipPath); + this._clipPath = null; + this.markRedraw(); + } + }; + Element.prototype.getTextContent = function () { + return this._textContent; + }; + Element.prototype.setTextContent = function (textEl) { + var previousTextContent = this._textContent; + if (previousTextContent === textEl) { + return; + } + if (previousTextContent && previousTextContent !== textEl) { + this.removeTextContent(); + } + if ("development" !== 'production') { + if (textEl.__zr && !textEl.__hostTarget) { + throw new Error('Text element has been added to zrender.'); + } + } + textEl.innerTransformable = new Transformable(); + this._attachComponent(textEl); + this._textContent = textEl; + this.markRedraw(); + }; + Element.prototype.setTextConfig = function (cfg) { + if (!this.textConfig) { + this.textConfig = {}; + } + extend(this.textConfig, cfg); + this.markRedraw(); + }; + Element.prototype.removeTextConfig = function () { + this.textConfig = null; + this.markRedraw(); + }; + Element.prototype.removeTextContent = function () { + var textEl = this._textContent; + if (textEl) { + textEl.innerTransformable = null; + this._detachComponent(textEl); + this._textContent = null; + this._innerTextDefaultStyle = null; + this.markRedraw(); + } + }; + Element.prototype.getTextGuideLine = function () { + return this._textGuide; + }; + Element.prototype.setTextGuideLine = function (guideLine) { + if (this._textGuide && this._textGuide !== guideLine) { + this.removeTextGuideLine(); + } + this._attachComponent(guideLine); + this._textGuide = guideLine; + this.markRedraw(); + }; + Element.prototype.removeTextGuideLine = function () { + var textGuide = this._textGuide; + if (textGuide) { + this._detachComponent(textGuide); + this._textGuide = null; + this.markRedraw(); + } + }; + Element.prototype.markRedraw = function () { + this.__dirty |= REDRAW_BIT; + var zr = this.__zr; + if (zr) { + if (this.__inHover) { + zr.refreshHover(); + } + else { + zr.refresh(); + } + } + if (this.__hostTarget) { + this.__hostTarget.markRedraw(); + } + }; + Element.prototype.dirty = function () { + this.markRedraw(); + }; + Element.prototype._toggleHoverLayerFlag = function (inHover) { + this.__inHover = inHover; + var textContent = this._textContent; + var textGuide = this._textGuide; + if (textContent) { + textContent.__inHover = inHover; + } + if (textGuide) { + textGuide.__inHover = inHover; + } + }; + Element.prototype.addSelfToZr = function (zr) { + if (this.__zr === zr) { + return; + } + this.__zr = zr; + var animators = this.animators; + if (animators) { + for (var i = 0; i < animators.length; i++) { + zr.animation.addAnimator(animators[i]); + } + } + if (this._clipPath) { + this._clipPath.addSelfToZr(zr); + } + if (this._textContent) { + this._textContent.addSelfToZr(zr); + } + if (this._textGuide) { + this._textGuide.addSelfToZr(zr); + } + }; + Element.prototype.removeSelfFromZr = function (zr) { + if (!this.__zr) { + return; + } + this.__zr = null; + var animators = this.animators; + if (animators) { + for (var i = 0; i < animators.length; i++) { + zr.animation.removeAnimator(animators[i]); + } + } + if (this._clipPath) { + this._clipPath.removeSelfFromZr(zr); + } + if (this._textContent) { + this._textContent.removeSelfFromZr(zr); + } + if (this._textGuide) { + this._textGuide.removeSelfFromZr(zr); + } + }; + Element.prototype.animate = function (key, loop, allowDiscreteAnimation) { + var target = key ? this[key] : this; + if ("development" !== 'production') { + if (!target) { + logError('Property "' + + key + + '" is not existed in element ' + + this.id); + return; + } + } + var animator = new Animator(target, loop, allowDiscreteAnimation); + key && (animator.targetName = key); + this.addAnimator(animator, key); + return animator; + }; + Element.prototype.addAnimator = function (animator, key) { + var zr = this.__zr; + var el = this; + animator.during(function () { + el.updateDuringAnimation(key); + }).done(function () { + var animators = el.animators; + var idx = indexOf(animators, animator); + if (idx >= 0) { + animators.splice(idx, 1); + } + }); + this.animators.push(animator); + if (zr) { + zr.animation.addAnimator(animator); + } + zr && zr.wakeUp(); + }; + Element.prototype.updateDuringAnimation = function (key) { + this.markRedraw(); + }; + Element.prototype.stopAnimation = function (scope, forwardToLast) { + var animators = this.animators; + var len = animators.length; + var leftAnimators = []; + for (var i = 0; i < len; i++) { + var animator = animators[i]; + if (!scope || scope === animator.scope) { + animator.stop(forwardToLast); + } + else { + leftAnimators.push(animator); + } + } + this.animators = leftAnimators; + return this; + }; + Element.prototype.animateTo = function (target, cfg, animationProps) { + animateTo(this, target, cfg, animationProps); + }; + Element.prototype.animateFrom = function (target, cfg, animationProps) { + animateTo(this, target, cfg, animationProps, true); + }; + Element.prototype._transitionState = function (stateName, target, cfg, animationProps) { + var animators = animateTo(this, target, cfg, animationProps); + for (var i = 0; i < animators.length; i++) { + animators[i].__fromStateTransition = stateName; + } + }; + Element.prototype.getBoundingRect = function () { + return null; + }; + Element.prototype.getPaintRect = function () { + return null; + }; + Element.initDefaultProps = (function () { + var elProto = Element.prototype; + elProto.type = 'element'; + elProto.name = ''; + elProto.ignore = + elProto.silent = + elProto.isGroup = + elProto.draggable = + elProto.dragging = + elProto.ignoreClip = + elProto.__inHover = false; + elProto.__dirty = REDRAW_BIT; + var logs = {}; + function logDeprecatedError(key, xKey, yKey) { + if (!logs[key + xKey + yKey]) { + console.warn("DEPRECATED: '" + key + "' has been deprecated. use '" + xKey + "', '" + yKey + "' instead"); + logs[key + xKey + yKey] = true; + } + } + function createLegacyProperty(key, privateKey, xKey, yKey) { + Object.defineProperty(elProto, key, { + get: function () { + if ("development" !== 'production') { + logDeprecatedError(key, xKey, yKey); + } + if (!this[privateKey]) { + var pos = this[privateKey] = []; + enhanceArray(this, pos); + } + return this[privateKey]; + }, + set: function (pos) { + if ("development" !== 'production') { + logDeprecatedError(key, xKey, yKey); + } + this[xKey] = pos[0]; + this[yKey] = pos[1]; + this[privateKey] = pos; + enhanceArray(this, pos); + } + }); + function enhanceArray(self, pos) { + Object.defineProperty(pos, 0, { + get: function () { + return self[xKey]; + }, + set: function (val) { + self[xKey] = val; + } + }); + Object.defineProperty(pos, 1, { + get: function () { + return self[yKey]; + }, + set: function (val) { + self[yKey] = val; + } + }); + } + } + if (Object.defineProperty) { + createLegacyProperty('position', '_legacyPos', 'x', 'y'); + createLegacyProperty('scale', '_legacyScale', 'scaleX', 'scaleY'); + createLegacyProperty('origin', '_legacyOrigin', 'originX', 'originY'); + } + })(); + return Element; + }()); + mixin(Element, Eventful); + mixin(Element, Transformable); + function animateTo(animatable, target, cfg, animationProps, reverse) { + cfg = cfg || {}; + var animators = []; + animateToShallow(animatable, '', animatable, target, cfg, animationProps, animators, reverse); + var finishCount = animators.length; + var doneHappened = false; + var cfgDone = cfg.done; + var cfgAborted = cfg.aborted; + var doneCb = function () { + doneHappened = true; + finishCount--; + if (finishCount <= 0) { + doneHappened + ? (cfgDone && cfgDone()) + : (cfgAborted && cfgAborted()); + } + }; + var abortedCb = function () { + finishCount--; + if (finishCount <= 0) { + doneHappened + ? (cfgDone && cfgDone()) + : (cfgAborted && cfgAborted()); + } + }; + if (!finishCount) { + cfgDone && cfgDone(); + } + if (animators.length > 0 && cfg.during) { + animators[0].during(function (target, percent) { + cfg.during(percent); + }); + } + for (var i = 0; i < animators.length; i++) { + var animator = animators[i]; + if (doneCb) { + animator.done(doneCb); + } + if (abortedCb) { + animator.aborted(abortedCb); + } + if (cfg.force) { + animator.duration(cfg.duration); + } + animator.start(cfg.easing); + } + return animators; + } + function copyArrShallow(source, target, len) { + for (var i = 0; i < len; i++) { + source[i] = target[i]; + } + } + function is2DArray(value) { + return isArrayLike(value[0]); + } + function copyValue(target, source, key) { + if (isArrayLike(source[key])) { + if (!isArrayLike(target[key])) { + target[key] = []; + } + if (isTypedArray(source[key])) { + var len = source[key].length; + if (target[key].length !== len) { + target[key] = new (source[key].constructor)(len); + copyArrShallow(target[key], source[key], len); + } + } + else { + var sourceArr = source[key]; + var targetArr = target[key]; + var len0 = sourceArr.length; + if (is2DArray(sourceArr)) { + var len1 = sourceArr[0].length; + for (var i = 0; i < len0; i++) { + if (!targetArr[i]) { + targetArr[i] = Array.prototype.slice.call(sourceArr[i]); + } + else { + copyArrShallow(targetArr[i], sourceArr[i], len1); + } + } + } + else { + copyArrShallow(targetArr, sourceArr, len0); + } + targetArr.length = sourceArr.length; + } + } + else { + target[key] = source[key]; + } + } + function isValueSame(val1, val2) { + return val1 === val2 + || isArrayLike(val1) && isArrayLike(val2) && is1DArraySame(val1, val2); + } + function is1DArraySame(arr0, arr1) { + var len = arr0.length; + if (len !== arr1.length) { + return false; + } + for (var i = 0; i < len; i++) { + if (arr0[i] !== arr1[i]) { + return false; + } + } + return true; + } + function animateToShallow(animatable, topKey, animateObj, target, cfg, animationProps, animators, reverse) { + var targetKeys = keys(target); + var duration = cfg.duration; + var delay = cfg.delay; + var additive = cfg.additive; + var setToFinal = cfg.setToFinal; + var animateAll = !isObject(animationProps); + var existsAnimators = animatable.animators; + var animationKeys = []; + for (var k = 0; k < targetKeys.length; k++) { + var innerKey = targetKeys[k]; + var targetVal = target[innerKey]; + if (targetVal != null && animateObj[innerKey] != null + && (animateAll || animationProps[innerKey])) { + if (isObject(targetVal) + && !isArrayLike(targetVal) + && !isGradientObject(targetVal)) { + if (topKey) { + if (!reverse) { + animateObj[innerKey] = targetVal; + animatable.updateDuringAnimation(topKey); + } + continue; + } + animateToShallow(animatable, innerKey, animateObj[innerKey], targetVal, cfg, animationProps && animationProps[innerKey], animators, reverse); + } + else { + animationKeys.push(innerKey); + } + } + else if (!reverse) { + animateObj[innerKey] = targetVal; + animatable.updateDuringAnimation(topKey); + animationKeys.push(innerKey); + } + } + var keyLen = animationKeys.length; + if (!additive && keyLen) { + for (var i = 0; i < existsAnimators.length; i++) { + var animator = existsAnimators[i]; + if (animator.targetName === topKey) { + var allAborted = animator.stopTracks(animationKeys); + if (allAborted) { + var idx = indexOf(existsAnimators, animator); + existsAnimators.splice(idx, 1); + } + } + } + } + if (!cfg.force) { + animationKeys = filter(animationKeys, function (key) { return !isValueSame(target[key], animateObj[key]); }); + keyLen = animationKeys.length; + } + if (keyLen > 0 + || (cfg.force && !animators.length)) { + var revertedSource = void 0; + var reversedTarget = void 0; + var sourceClone = void 0; + if (reverse) { + reversedTarget = {}; + if (setToFinal) { + revertedSource = {}; + } + for (var i = 0; i < keyLen; i++) { + var innerKey = animationKeys[i]; + reversedTarget[innerKey] = animateObj[innerKey]; + if (setToFinal) { + revertedSource[innerKey] = target[innerKey]; + } + else { + animateObj[innerKey] = target[innerKey]; + } + } + } + else if (setToFinal) { + sourceClone = {}; + for (var i = 0; i < keyLen; i++) { + var innerKey = animationKeys[i]; + sourceClone[innerKey] = cloneValue(animateObj[innerKey]); + copyValue(animateObj, target, innerKey); + } + } + var animator = new Animator(animateObj, false, false, additive ? filter(existsAnimators, function (animator) { return animator.targetName === topKey; }) : null); + animator.targetName = topKey; + if (cfg.scope) { + animator.scope = cfg.scope; + } + if (setToFinal && revertedSource) { + animator.whenWithKeys(0, revertedSource, animationKeys); + } + if (sourceClone) { + animator.whenWithKeys(0, sourceClone, animationKeys); + } + animator.whenWithKeys(duration == null ? 500 : duration, reverse ? reversedTarget : target, animationKeys).delay(delay || 0); + animatable.addAnimator(animator, topKey); + animators.push(animator); + } + } + + var Group = (function (_super) { + __extends(Group, _super); + function Group(opts) { + var _this = _super.call(this) || this; + _this.isGroup = true; + _this._children = []; + _this.attr(opts); + return _this; + } + Group.prototype.childrenRef = function () { + return this._children; + }; + Group.prototype.children = function () { + return this._children.slice(); + }; + Group.prototype.childAt = function (idx) { + return this._children[idx]; + }; + Group.prototype.childOfName = function (name) { + var children = this._children; + for (var i = 0; i < children.length; i++) { + if (children[i].name === name) { + return children[i]; + } + } + }; + Group.prototype.childCount = function () { + return this._children.length; + }; + Group.prototype.add = function (child) { + if (child) { + if (child !== this && child.parent !== this) { + this._children.push(child); + this._doAdd(child); + } + if ("development" !== 'production') { + if (child.__hostTarget) { + throw 'This elemenet has been used as an attachment'; + } + } + } + return this; + }; + Group.prototype.addBefore = function (child, nextSibling) { + if (child && child !== this && child.parent !== this + && nextSibling && nextSibling.parent === this) { + var children = this._children; + var idx = children.indexOf(nextSibling); + if (idx >= 0) { + children.splice(idx, 0, child); + this._doAdd(child); + } + } + return this; + }; + Group.prototype.replace = function (oldChild, newChild) { + var idx = indexOf(this._children, oldChild); + if (idx >= 0) { + this.replaceAt(newChild, idx); + } + return this; + }; + Group.prototype.replaceAt = function (child, index) { + var children = this._children; + var old = children[index]; + if (child && child !== this && child.parent !== this && child !== old) { + children[index] = child; + old.parent = null; + var zr = this.__zr; + if (zr) { + old.removeSelfFromZr(zr); + } + this._doAdd(child); + } + return this; + }; + Group.prototype._doAdd = function (child) { + if (child.parent) { + child.parent.remove(child); + } + child.parent = this; + var zr = this.__zr; + if (zr && zr !== child.__zr) { + child.addSelfToZr(zr); + } + zr && zr.refresh(); + }; + Group.prototype.remove = function (child) { + var zr = this.__zr; + var children = this._children; + var idx = indexOf(children, child); + if (idx < 0) { + return this; + } + children.splice(idx, 1); + child.parent = null; + if (zr) { + child.removeSelfFromZr(zr); + } + zr && zr.refresh(); + return this; + }; + Group.prototype.removeAll = function () { + var children = this._children; + var zr = this.__zr; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (zr) { + child.removeSelfFromZr(zr); + } + child.parent = null; + } + children.length = 0; + return this; + }; + Group.prototype.eachChild = function (cb, context) { + var children = this._children; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + cb.call(context, child, i); + } + return this; + }; + Group.prototype.traverse = function (cb, context) { + for (var i = 0; i < this._children.length; i++) { + var child = this._children[i]; + var stopped = cb.call(context, child); + if (child.isGroup && !stopped) { + child.traverse(cb, context); + } + } + return this; + }; + Group.prototype.addSelfToZr = function (zr) { + _super.prototype.addSelfToZr.call(this, zr); + for (var i = 0; i < this._children.length; i++) { + var child = this._children[i]; + child.addSelfToZr(zr); + } + }; + Group.prototype.removeSelfFromZr = function (zr) { + _super.prototype.removeSelfFromZr.call(this, zr); + for (var i = 0; i < this._children.length; i++) { + var child = this._children[i]; + child.removeSelfFromZr(zr); + } + }; + Group.prototype.getBoundingRect = function (includeChildren) { + var tmpRect = new BoundingRect(0, 0, 0, 0); + var children = includeChildren || this._children; + var tmpMat = []; + var rect = null; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (child.ignore || child.invisible) { + continue; + } + var childRect = child.getBoundingRect(); + var transform = child.getLocalTransform(tmpMat); + if (transform) { + BoundingRect.applyTransform(tmpRect, childRect, transform); + rect = rect || tmpRect.clone(); + rect.union(tmpRect); + } + else { + rect = rect || childRect.clone(); + rect.union(childRect); + } + } + return rect || tmpRect; + }; + return Group; + }(Element)); + Group.prototype.type = 'group'; + + /*! + * ZRender, a high performance 2d drawing library. + * + * Copyright (c) 2013, Baidu Inc. + * All rights reserved. + * + * LICENSE + * https://github.com/ecomfe/zrender/blob/master/LICENSE.txt + */ + var painterCtors = {}; + var instances = {}; + function delInstance(id) { + delete instances[id]; + } + function isDarkMode(backgroundColor) { + if (!backgroundColor) { + return false; + } + if (typeof backgroundColor === 'string') { + return lum(backgroundColor, 1) < DARK_MODE_THRESHOLD; + } + else if (backgroundColor.colorStops) { + var colorStops = backgroundColor.colorStops; + var totalLum = 0; + var len = colorStops.length; + for (var i = 0; i < len; i++) { + totalLum += lum(colorStops[i].color, 1); + } + totalLum /= len; + return totalLum < DARK_MODE_THRESHOLD; + } + return false; + } + var ZRender = (function () { + function ZRender(id, dom, opts) { + var _this = this; + this._sleepAfterStill = 10; + this._stillFrameAccum = 0; + this._needsRefresh = true; + this._needsRefreshHover = true; + this._darkMode = false; + opts = opts || {}; + this.dom = dom; + this.id = id; + var storage = new Storage(); + var rendererType = opts.renderer || 'canvas'; + if (!painterCtors[rendererType]) { + rendererType = keys(painterCtors)[0]; + } + if ("development" !== 'production') { + if (!painterCtors[rendererType]) { + throw new Error("Renderer '" + rendererType + "' is not imported. Please import it first."); + } + } + opts.useDirtyRect = opts.useDirtyRect == null + ? false + : opts.useDirtyRect; + var painter = new painterCtors[rendererType](dom, storage, opts, id); + var ssrMode = opts.ssr || painter.ssrOnly; + this.storage = storage; + this.painter = painter; + var handlerProxy = (!env.node && !env.worker && !ssrMode) + ? new HandlerDomProxy(painter.getViewportRoot(), painter.root) + : null; + var useCoarsePointer = opts.useCoarsePointer; + var usePointerSize = (useCoarsePointer == null || useCoarsePointer === 'auto') + ? env.touchEventsSupported + : !!useCoarsePointer; + var defaultPointerSize = 44; + var pointerSize; + if (usePointerSize) { + pointerSize = retrieve2(opts.pointerSize, defaultPointerSize); + } + this.handler = new Handler(storage, painter, handlerProxy, painter.root, pointerSize); + this.animation = new Animation({ + stage: { + update: ssrMode ? null : function () { return _this._flush(true); } + } + }); + if (!ssrMode) { + this.animation.start(); + } + } + ZRender.prototype.add = function (el) { + if (this._disposed || !el) { + return; + } + this.storage.addRoot(el); + el.addSelfToZr(this); + this.refresh(); + }; + ZRender.prototype.remove = function (el) { + if (this._disposed || !el) { + return; + } + this.storage.delRoot(el); + el.removeSelfFromZr(this); + this.refresh(); + }; + ZRender.prototype.configLayer = function (zLevel, config) { + if (this._disposed) { + return; + } + if (this.painter.configLayer) { + this.painter.configLayer(zLevel, config); + } + this.refresh(); + }; + ZRender.prototype.setBackgroundColor = function (backgroundColor) { + if (this._disposed) { + return; + } + if (this.painter.setBackgroundColor) { + this.painter.setBackgroundColor(backgroundColor); + } + this.refresh(); + this._backgroundColor = backgroundColor; + this._darkMode = isDarkMode(backgroundColor); + }; + ZRender.prototype.getBackgroundColor = function () { + return this._backgroundColor; + }; + ZRender.prototype.setDarkMode = function (darkMode) { + this._darkMode = darkMode; + }; + ZRender.prototype.isDarkMode = function () { + return this._darkMode; + }; + ZRender.prototype.refreshImmediately = function (fromInside) { + if (this._disposed) { + return; + } + if (!fromInside) { + this.animation.update(true); + } + this._needsRefresh = false; + this.painter.refresh(); + this._needsRefresh = false; + }; + ZRender.prototype.refresh = function () { + if (this._disposed) { + return; + } + this._needsRefresh = true; + this.animation.start(); + }; + ZRender.prototype.flush = function () { + if (this._disposed) { + return; + } + this._flush(false); + }; + ZRender.prototype._flush = function (fromInside) { + var triggerRendered; + var start = getTime(); + if (this._needsRefresh) { + triggerRendered = true; + this.refreshImmediately(fromInside); + } + if (this._needsRefreshHover) { + triggerRendered = true; + this.refreshHoverImmediately(); + } + var end = getTime(); + if (triggerRendered) { + this._stillFrameAccum = 0; + this.trigger('rendered', { + elapsedTime: end - start + }); + } + else if (this._sleepAfterStill > 0) { + this._stillFrameAccum++; + if (this._stillFrameAccum > this._sleepAfterStill) { + this.animation.stop(); + } + } + }; + ZRender.prototype.setSleepAfterStill = function (stillFramesCount) { + this._sleepAfterStill = stillFramesCount; + }; + ZRender.prototype.wakeUp = function () { + if (this._disposed) { + return; + } + this.animation.start(); + this._stillFrameAccum = 0; + }; + ZRender.prototype.refreshHover = function () { + this._needsRefreshHover = true; + }; + ZRender.prototype.refreshHoverImmediately = function () { + if (this._disposed) { + return; + } + this._needsRefreshHover = false; + if (this.painter.refreshHover && this.painter.getType() === 'canvas') { + this.painter.refreshHover(); + } + }; + ZRender.prototype.resize = function (opts) { + if (this._disposed) { + return; + } + opts = opts || {}; + this.painter.resize(opts.width, opts.height); + this.handler.resize(); + }; + ZRender.prototype.clearAnimation = function () { + if (this._disposed) { + return; + } + this.animation.clear(); + }; + ZRender.prototype.getWidth = function () { + if (this._disposed) { + return; + } + return this.painter.getWidth(); + }; + ZRender.prototype.getHeight = function () { + if (this._disposed) { + return; + } + return this.painter.getHeight(); + }; + ZRender.prototype.setCursorStyle = function (cursorStyle) { + if (this._disposed) { + return; + } + this.handler.setCursorStyle(cursorStyle); + }; + ZRender.prototype.findHover = function (x, y) { + if (this._disposed) { + return; + } + return this.handler.findHover(x, y); + }; + ZRender.prototype.on = function (eventName, eventHandler, context) { + if (!this._disposed) { + this.handler.on(eventName, eventHandler, context); + } + return this; + }; + ZRender.prototype.off = function (eventName, eventHandler) { + if (this._disposed) { + return; + } + this.handler.off(eventName, eventHandler); + }; + ZRender.prototype.trigger = function (eventName, event) { + if (this._disposed) { + return; + } + this.handler.trigger(eventName, event); + }; + ZRender.prototype.clear = function () { + if (this._disposed) { + return; + } + var roots = this.storage.getRoots(); + for (var i = 0; i < roots.length; i++) { + if (roots[i] instanceof Group) { + roots[i].removeSelfFromZr(this); + } + } + this.storage.delAllRoots(); + this.painter.clear(); + }; + ZRender.prototype.dispose = function () { + if (this._disposed) { + return; + } + this.animation.stop(); + this.clear(); + this.storage.dispose(); + this.painter.dispose(); + this.handler.dispose(); + this.animation = + this.storage = + this.painter = + this.handler = null; + this._disposed = true; + delInstance(this.id); + }; + return ZRender; + }()); + function init(dom, opts) { + var zr = new ZRender(guid(), dom, opts); + instances[zr.id] = zr; + return zr; + } + function dispose(zr) { + zr.dispose(); + } + function disposeAll() { + for (var key in instances) { + if (instances.hasOwnProperty(key)) { + instances[key].dispose(); + } + } + instances = {}; + } + function getInstance(id) { + return instances[id]; + } + function registerPainter(name, Ctor) { + painterCtors[name] = Ctor; + } + var ssrDataGetter; + function getElementSSRData(el) { + if (typeof ssrDataGetter === 'function') { + return ssrDataGetter(el); + } + } + function registerSSRDataGetter(getter) { + ssrDataGetter = getter; + } + var version = '5.5.0'; + + var zrender = /*#__PURE__*/Object.freeze({ + __proto__: null, + init: init, + dispose: dispose, + disposeAll: disposeAll, + getInstance: getInstance, + registerPainter: registerPainter, + getElementSSRData: getElementSSRData, + registerSSRDataGetter: registerSSRDataGetter, + version: version + }); + + var RADIAN_EPSILON = 1e-4; + // Although chrome already enlarge this number to 100 for `toFixed`, but + // we sill follow the spec for compatibility. + var ROUND_SUPPORTED_PRECISION_MAX = 20; + function _trim(str) { + return str.replace(/^\s+|\s+$/g, ''); + } + /** + * Linear mapping a value from domain to range + * @param val + * @param domain Domain extent domain[0] can be bigger than domain[1] + * @param range Range extent range[0] can be bigger than range[1] + * @param clamp Default to be false + */ + function linearMap(val, domain, range, clamp) { + var d0 = domain[0]; + var d1 = domain[1]; + var r0 = range[0]; + var r1 = range[1]; + var subDomain = d1 - d0; + var subRange = r1 - r0; + if (subDomain === 0) { + return subRange === 0 ? r0 : (r0 + r1) / 2; + } + // Avoid accuracy problem in edge, such as + // 146.39 - 62.83 === 83.55999999999999. + // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError + // It is a little verbose for efficiency considering this method + // is a hotspot. + if (clamp) { + if (subDomain > 0) { + if (val <= d0) { + return r0; + } else if (val >= d1) { + return r1; + } + } else { + if (val >= d0) { + return r0; + } else if (val <= d1) { + return r1; + } + } + } else { + if (val === d0) { + return r0; + } + if (val === d1) { + return r1; + } + } + return (val - d0) / subDomain * subRange + r0; + } + /** + * Convert a percent string to absolute number. + * Returns NaN if percent is not a valid string or number + */ + function parsePercent$1(percent, all) { + switch (percent) { + case 'center': + case 'middle': + percent = '50%'; + break; + case 'left': + case 'top': + percent = '0%'; + break; + case 'right': + case 'bottom': + percent = '100%'; + break; + } + if (isString(percent)) { + if (_trim(percent).match(/%$/)) { + return parseFloat(percent) / 100 * all; + } + return parseFloat(percent); + } + return percent == null ? NaN : +percent; + } + function round(x, precision, returnStr) { + if (precision == null) { + precision = 10; + } + // Avoid range error + precision = Math.min(Math.max(0, precision), ROUND_SUPPORTED_PRECISION_MAX); + // PENDING: 1.005.toFixed(2) is '1.00' rather than '1.01' + x = (+x).toFixed(precision); + return returnStr ? x : +x; + } + /** + * Inplacd asc sort arr. + * The input arr will be modified. + */ + function asc(arr) { + arr.sort(function (a, b) { + return a - b; + }); + return arr; + } + /** + * Get precision. + */ + function getPrecision(val) { + val = +val; + if (isNaN(val)) { + return 0; + } + // It is much faster than methods converting number to string as follows + // let tmp = val.toString(); + // return tmp.length - 1 - tmp.indexOf('.'); + // especially when precision is low + // Notice: + // (1) If the loop count is over about 20, it is slower than `getPrecisionSafe`. + // (see https://jsbench.me/2vkpcekkvw/1) + // (2) If the val is less than for example 1e-15, the result may be incorrect. + // (see test/ut/spec/util/number.test.ts `getPrecision_equal_random`) + if (val > 1e-14) { + var e = 1; + for (var i = 0; i < 15; i++, e *= 10) { + if (Math.round(val * e) / e === val) { + return i; + } + } + } + return getPrecisionSafe(val); + } + /** + * Get precision with slow but safe method + */ + function getPrecisionSafe(val) { + // toLowerCase for: '3.4E-12' + var str = val.toString().toLowerCase(); + // Consider scientific notation: '3.4e-12' '3.4e+12' + var eIndex = str.indexOf('e'); + var exp = eIndex > 0 ? +str.slice(eIndex + 1) : 0; + var significandPartLen = eIndex > 0 ? eIndex : str.length; + var dotIndex = str.indexOf('.'); + var decimalPartLen = dotIndex < 0 ? 0 : significandPartLen - 1 - dotIndex; + return Math.max(0, decimalPartLen - exp); + } + /** + * Minimal dicernible data precisioin according to a single pixel. + */ + function getPixelPrecision(dataExtent, pixelExtent) { + var log = Math.log; + var LN10 = Math.LN10; + var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10); + var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10); + // toFixed() digits argument must be between 0 and 20. + var precision = Math.min(Math.max(-dataQuantity + sizeQuantity, 0), 20); + return !isFinite(precision) ? 20 : precision; + } + /** + * Get a data of given precision, assuring the sum of percentages + * in valueList is 1. + * The largest remainder method is used. + * https://en.wikipedia.org/wiki/Largest_remainder_method + * + * @param valueList a list of all data + * @param idx index of the data to be processed in valueList + * @param precision integer number showing digits of precision + * @return percent ranging from 0 to 100 + */ + function getPercentWithPrecision(valueList, idx, precision) { + if (!valueList[idx]) { + return 0; + } + var seats = getPercentSeats(valueList, precision); + return seats[idx] || 0; + } + /** + * Get a data of given precision, assuring the sum of percentages + * in valueList is 1. + * The largest remainder method is used. + * https://en.wikipedia.org/wiki/Largest_remainder_method + * + * @param valueList a list of all data + * @param precision integer number showing digits of precision + * @return {Array} + */ + function getPercentSeats(valueList, precision) { + var sum = reduce(valueList, function (acc, val) { + return acc + (isNaN(val) ? 0 : val); + }, 0); + if (sum === 0) { + return []; + } + var digits = Math.pow(10, precision); + var votesPerQuota = map(valueList, function (val) { + return (isNaN(val) ? 0 : val) / sum * digits * 100; + }); + var targetSeats = digits * 100; + var seats = map(votesPerQuota, function (votes) { + // Assign automatic seats. + return Math.floor(votes); + }); + var currentSum = reduce(seats, function (acc, val) { + return acc + val; + }, 0); + var remainder = map(votesPerQuota, function (votes, idx) { + return votes - seats[idx]; + }); + // Has remainding votes. + while (currentSum < targetSeats) { + // Find next largest remainder. + var max = Number.NEGATIVE_INFINITY; + var maxId = null; + for (var i = 0, len = remainder.length; i < len; ++i) { + if (remainder[i] > max) { + max = remainder[i]; + maxId = i; + } + } + // Add a vote to max remainder. + ++seats[maxId]; + remainder[maxId] = 0; + ++currentSum; + } + return map(seats, function (seat) { + return seat / digits; + }); + } + /** + * Solve the floating point adding problem like 0.1 + 0.2 === 0.30000000000000004 + * See + */ + function addSafe(val0, val1) { + var maxPrecision = Math.max(getPrecision(val0), getPrecision(val1)); + // const multiplier = Math.pow(10, maxPrecision); + // return (Math.round(val0 * multiplier) + Math.round(val1 * multiplier)) / multiplier; + var sum = val0 + val1; + // // PENDING: support more? + return maxPrecision > ROUND_SUPPORTED_PRECISION_MAX ? sum : round(sum, maxPrecision); + } + // Number.MAX_SAFE_INTEGER, ie do not support. + var MAX_SAFE_INTEGER = 9007199254740991; + /** + * To 0 - 2 * PI, considering negative radian. + */ + function remRadian(radian) { + var pi2 = Math.PI * 2; + return (radian % pi2 + pi2) % pi2; + } + /** + * @param {type} radian + * @return {boolean} + */ + function isRadianAroundZero(val) { + return val > -RADIAN_EPSILON && val < RADIAN_EPSILON; + } + // eslint-disable-next-line + var TIME_REG = /^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d{1,2})(?::(\d{1,2})(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/; // jshint ignore:line + /** + * @param value valid type: number | string | Date, otherwise return `new Date(NaN)` + * These values can be accepted: + * + An instance of Date, represent a time in its own time zone. + * + Or string in a subset of ISO 8601, only including: + * + only year, month, date: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06', + * + separated with T or space: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123', + * + time zone: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00', + * all of which will be treated as local time if time zone is not specified + * (see ). + * + Or other string format, including (all of which will be treated as local time): + * '2012', '2012-3-1', '2012/3/1', '2012/03/01', + * '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123' + * + a timestamp, which represent a time in UTC. + * @return date Never be null/undefined. If invalid, return `new Date(NaN)`. + */ + function parseDate(value) { + if (value instanceof Date) { + return value; + } else if (isString(value)) { + // Different browsers parse date in different way, so we parse it manually. + // Some other issues: + // new Date('1970-01-01') is UTC, + // new Date('1970/01/01') and new Date('1970-1-01') is local. + // See issue #3623 + var match = TIME_REG.exec(value); + if (!match) { + // return Invalid Date. + return new Date(NaN); + } + // Use local time when no timezone offset is specified. + if (!match[8]) { + // match[n] can only be string or undefined. + // But take care of '12' + 1 => '121'. + return new Date(+match[1], +(match[2] || 1) - 1, +match[3] || 1, +match[4] || 0, +(match[5] || 0), +match[6] || 0, match[7] ? +match[7].substring(0, 3) : 0); + } + // Timezoneoffset of Javascript Date has considered DST (Daylight Saving Time, + // https://tc39.github.io/ecma262/#sec-daylight-saving-time-adjustment). + // For example, system timezone is set as "Time Zone: America/Toronto", + // then these code will get different result: + // `new Date(1478411999999).getTimezoneOffset(); // get 240` + // `new Date(1478412000000).getTimezoneOffset(); // get 300` + // So we should not use `new Date`, but use `Date.UTC`. + else { + var hour = +match[4] || 0; + if (match[8].toUpperCase() !== 'Z') { + hour -= +match[8].slice(0, 3); + } + return new Date(Date.UTC(+match[1], +(match[2] || 1) - 1, +match[3] || 1, hour, +(match[5] || 0), +match[6] || 0, match[7] ? +match[7].substring(0, 3) : 0)); + } + } else if (value == null) { + return new Date(NaN); + } + return new Date(Math.round(value)); + } + /** + * Quantity of a number. e.g. 0.1, 1, 10, 100 + * + * @param val + * @return + */ + function quantity(val) { + return Math.pow(10, quantityExponent(val)); + } + /** + * Exponent of the quantity of a number + * e.g., 1234 equals to 1.234*10^3, so quantityExponent(1234) is 3 + * + * @param val non-negative value + * @return + */ + function quantityExponent(val) { + if (val === 0) { + return 0; + } + var exp = Math.floor(Math.log(val) / Math.LN10); + /** + * exp is expected to be the rounded-down result of the base-10 log of val. + * But due to the precision loss with Math.log(val), we need to restore it + * using 10^exp to make sure we can get val back from exp. #11249 + */ + if (val / Math.pow(10, exp) >= 10) { + exp++; + } + return exp; + } + /** + * find a “nice” number approximately equal to x. Round the number if round = true, + * take ceiling if round = false. The primary observation is that the “nicest” + * numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers. + * + * See "Nice Numbers for Graph Labels" of Graphic Gems. + * + * @param val Non-negative value. + * @param round + * @return Niced number + */ + function nice(val, round) { + var exponent = quantityExponent(val); + var exp10 = Math.pow(10, exponent); + var f = val / exp10; // 1 <= f < 10 + var nf; + if (round) { + if (f < 1.5) { + nf = 1; + } else if (f < 2.5) { + nf = 2; + } else if (f < 4) { + nf = 3; + } else if (f < 7) { + nf = 5; + } else { + nf = 10; + } + } else { + if (f < 1) { + nf = 1; + } else if (f < 2) { + nf = 2; + } else if (f < 3) { + nf = 3; + } else if (f < 5) { + nf = 5; + } else { + nf = 10; + } + } + val = nf * exp10; + // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754). + // 20 is the uppper bound of toFixed. + return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val; + } + /** + * This code was copied from "d3.js" + * . + * See the license statement at the head of this file. + * @param ascArr + */ + function quantile(ascArr, p) { + var H = (ascArr.length - 1) * p + 1; + var h = Math.floor(H); + var v = +ascArr[h - 1]; + var e = H - h; + return e ? v + e * (ascArr[h] - v) : v; + } + /** + * Order intervals asc, and split them when overlap. + * expect(numberUtil.reformIntervals([ + * {interval: [18, 62], close: [1, 1]}, + * {interval: [-Infinity, -70], close: [0, 0]}, + * {interval: [-70, -26], close: [1, 1]}, + * {interval: [-26, 18], close: [1, 1]}, + * {interval: [62, 150], close: [1, 1]}, + * {interval: [106, 150], close: [1, 1]}, + * {interval: [150, Infinity], close: [0, 0]} + * ])).toEqual([ + * {interval: [-Infinity, -70], close: [0, 0]}, + * {interval: [-70, -26], close: [1, 1]}, + * {interval: [-26, 18], close: [0, 1]}, + * {interval: [18, 62], close: [0, 1]}, + * {interval: [62, 150], close: [0, 1]}, + * {interval: [150, Infinity], close: [0, 0]} + * ]); + * @param list, where `close` mean open or close + * of the interval, and Infinity can be used. + * @return The origin list, which has been reformed. + */ + function reformIntervals(list) { + list.sort(function (a, b) { + return littleThan(a, b, 0) ? -1 : 1; + }); + var curr = -Infinity; + var currClose = 1; + for (var i = 0; i < list.length;) { + var interval = list[i].interval; + var close_1 = list[i].close; + for (var lg = 0; lg < 2; lg++) { + if (interval[lg] <= curr) { + interval[lg] = curr; + close_1[lg] = !lg ? 1 - currClose : 1; + } + curr = interval[lg]; + currClose = close_1[lg]; + } + if (interval[0] === interval[1] && close_1[0] * close_1[1] !== 1) { + list.splice(i, 1); + } else { + i++; + } + } + return list; + function littleThan(a, b, lg) { + return a.interval[lg] < b.interval[lg] || a.interval[lg] === b.interval[lg] && (a.close[lg] - b.close[lg] === (!lg ? 1 : -1) || !lg && littleThan(a, b, 1)); + } + } + /** + * [Numeric is defined as]: + * `parseFloat(val) == val` + * For example: + * numeric: + * typeof number except NaN, '-123', '123', '2e3', '-2e3', '011', 'Infinity', Infinity, + * and they rounded by white-spaces or line-terminal like ' -123 \n ' (see es spec) + * not-numeric: + * null, undefined, [], {}, true, false, 'NaN', NaN, '123ab', + * empty string, string with only white-spaces or line-terminal (see es spec), + * 0x12, '0x12', '-0x12', 012, '012', '-012', + * non-string, ... + * + * @test See full test cases in `test/ut/spec/util/number.js`. + * @return Must be a typeof number. If not numeric, return NaN. + */ + function numericToNumber(val) { + var valFloat = parseFloat(val); + return valFloat == val // eslint-disable-line eqeqeq + && (valFloat !== 0 || !isString(val) || val.indexOf('x') <= 0) // For case ' 0x0 '. + ? valFloat : NaN; + } + /** + * Definition of "numeric": see `numericToNumber`. + */ + function isNumeric(val) { + return !isNaN(numericToNumber(val)); + } + /** + * Use random base to prevent users hard code depending on + * this auto generated marker id. + * @return An positive integer. + */ + function getRandomIdBase() { + return Math.round(Math.random() * 9); + } + /** + * Get the greatest common divisor. + * + * @param {number} a one number + * @param {number} b the other number + */ + function getGreatestCommonDividor(a, b) { + if (b === 0) { + return a; + } + return getGreatestCommonDividor(b, a % b); + } + /** + * Get the least common multiple. + * + * @param {number} a one number + * @param {number} b the other number + */ + function getLeastCommonMultiple(a, b) { + if (a == null) { + return b; + } + if (b == null) { + return a; + } + return a * b / getGreatestCommonDividor(a, b); + } + + var ECHARTS_PREFIX = '[ECharts] '; + var storedLogs = {}; + var hasConsole = typeof console !== 'undefined' + // eslint-disable-next-line + && console.warn && console.log; + function outputLog(type, str, onlyOnce) { + if (hasConsole) { + if (onlyOnce) { + if (storedLogs[str]) { + return; + } + storedLogs[str] = true; + } + // eslint-disable-next-line + console[type](ECHARTS_PREFIX + str); + } + } + function log(str, onlyOnce) { + outputLog('log', str, onlyOnce); + } + function warn(str, onlyOnce) { + outputLog('warn', str, onlyOnce); + } + function error(str, onlyOnce) { + outputLog('error', str, onlyOnce); + } + function deprecateLog(str) { + if ("development" !== 'production') { + // Not display duplicate message. + outputLog('warn', 'DEPRECATED: ' + str, true); + } + } + function deprecateReplaceLog(oldOpt, newOpt, scope) { + if ("development" !== 'production') { + deprecateLog((scope ? "[" + scope + "]" : '') + (oldOpt + " is deprecated, use " + newOpt + " instead.")); + } + } + /** + * If in __DEV__ environment, get console printable message for users hint. + * Parameters are separated by ' '. + * @usage + * makePrintable('This is an error on', someVar, someObj); + * + * @param hintInfo anything about the current execution context to hint users. + * @throws Error + */ + function makePrintable() { + var hintInfo = []; + for (var _i = 0; _i < arguments.length; _i++) { + hintInfo[_i] = arguments[_i]; + } + var msg = ''; + if ("development" !== 'production') { + // Fuzzy stringify for print. + // This code only exist in dev environment. + var makePrintableStringIfPossible_1 = function (val) { + return val === void 0 ? 'undefined' : val === Infinity ? 'Infinity' : val === -Infinity ? '-Infinity' : eqNaN(val) ? 'NaN' : val instanceof Date ? 'Date(' + val.toISOString() + ')' : isFunction(val) ? 'function () { ... }' : isRegExp(val) ? val + '' : null; + }; + msg = map(hintInfo, function (arg) { + if (isString(arg)) { + // Print without quotation mark for some statement. + return arg; + } else { + var printableStr = makePrintableStringIfPossible_1(arg); + if (printableStr != null) { + return printableStr; + } else if (typeof JSON !== 'undefined' && JSON.stringify) { + try { + return JSON.stringify(arg, function (n, val) { + var printableStr = makePrintableStringIfPossible_1(val); + return printableStr == null ? val : printableStr; + }); + // In most cases the info object is small, so do not line break. + } catch (err) { + return '?'; + } + } else { + return '?'; + } + } + }).join(' '); + } + return msg; + } + /** + * @throws Error + */ + function throwError(msg) { + throw new Error(msg); + } + + function interpolateNumber$1(p0, p1, percent) { + return (p1 - p0) * percent + p0; + } + /** + * Make the name displayable. But we should + * make sure it is not duplicated with user + * specified name, so use '\0'; + */ + var DUMMY_COMPONENT_NAME_PREFIX = 'series\0'; + var INTERNAL_COMPONENT_ID_PREFIX = '\0_ec_\0'; + /** + * If value is not array, then translate it to array. + * @param {*} value + * @return {Array} [value] or value + */ + function normalizeToArray(value) { + return value instanceof Array ? value : value == null ? [] : [value]; + } + /** + * Sync default option between normal and emphasis like `position` and `show` + * In case some one will write code like + * label: { + * show: false, + * position: 'outside', + * fontSize: 18 + * }, + * emphasis: { + * label: { show: true } + * } + */ + function defaultEmphasis(opt, key, subOpts) { + // Caution: performance sensitive. + if (opt) { + opt[key] = opt[key] || {}; + opt.emphasis = opt.emphasis || {}; + opt.emphasis[key] = opt.emphasis[key] || {}; + // Default emphasis option from normal + for (var i = 0, len = subOpts.length; i < len; i++) { + var subOptName = subOpts[i]; + if (!opt.emphasis[key].hasOwnProperty(subOptName) && opt[key].hasOwnProperty(subOptName)) { + opt.emphasis[key][subOptName] = opt[key][subOptName]; + } + } + } + } + var TEXT_STYLE_OPTIONS = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'rich', 'tag', 'color', 'textBorderColor', 'textBorderWidth', 'width', 'height', 'lineHeight', 'align', 'verticalAlign', 'baseline', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY', 'backgroundColor', 'borderColor', 'borderWidth', 'borderRadius', 'padding']; + // modelUtil.LABEL_OPTIONS = modelUtil.TEXT_STYLE_OPTIONS.concat([ + // 'position', 'offset', 'rotate', 'origin', 'show', 'distance', 'formatter', + // 'fontStyle', 'fontWeight', 'fontSize', 'fontFamily', + // // FIXME: deprecated, check and remove it. + // 'textStyle' + // ]); + /** + * The method does not ensure performance. + * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}] + * This helper method retrieves value from data. + */ + function getDataItemValue(dataItem) { + return isObject(dataItem) && !isArray(dataItem) && !(dataItem instanceof Date) ? dataItem.value : dataItem; + } + /** + * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}] + * This helper method determine if dataItem has extra option besides value + */ + function isDataItemOption(dataItem) { + return isObject(dataItem) && !(dataItem instanceof Array); + // // markLine data can be array + // && !(dataItem[0] && isObject(dataItem[0]) && !(dataItem[0] instanceof Array)); + } + /** + * Mapping to existings for merge. + * + * Mode "normalMege": + * The mapping result (merge result) will keep the order of the existing + * component, rather than the order of new option. Because we should ensure + * some specified index reference (like xAxisIndex) keep work. + * And in most cases, "merge option" is used to update partial option but not + * be expected to change the order. + * + * Mode "replaceMege": + * (1) Only the id mapped components will be merged. + * (2) Other existing components (except internal components) will be removed. + * (3) Other new options will be used to create new component. + * (4) The index of the existing components will not be modified. + * That means their might be "hole" after the removal. + * The new components are created first at those available index. + * + * Mode "replaceAll": + * This mode try to support that reproduce an echarts instance from another + * echarts instance (via `getOption`) in some simple cases. + * In this scenario, the `result` index are exactly the consistent with the `newCmptOptions`, + * which ensures the component index referring (like `xAxisIndex: ?`) corrent. That is, + * the "hole" in `newCmptOptions` will also be kept. + * On the contrary, other modes try best to eliminate holes. + * PENDING: This is an experimental mode yet. + * + * @return See the comment of . + */ + function mappingToExists(existings, newCmptOptions, mode) { + var isNormalMergeMode = mode === 'normalMerge'; + var isReplaceMergeMode = mode === 'replaceMerge'; + var isReplaceAllMode = mode === 'replaceAll'; + existings = existings || []; + newCmptOptions = (newCmptOptions || []).slice(); + var existingIdIdxMap = createHashMap(); + // Validate id and name on user input option. + each(newCmptOptions, function (cmptOption, index) { + if (!isObject(cmptOption)) { + newCmptOptions[index] = null; + return; + } + if ("development" !== 'production') { + // There is some legacy case that name is set as `false`. + // But should work normally rather than throw error. + if (cmptOption.id != null && !isValidIdOrName(cmptOption.id)) { + warnInvalidateIdOrName(cmptOption.id); + } + if (cmptOption.name != null && !isValidIdOrName(cmptOption.name)) { + warnInvalidateIdOrName(cmptOption.name); + } + } + }); + var result = prepareResult(existings, existingIdIdxMap, mode); + if (isNormalMergeMode || isReplaceMergeMode) { + mappingById(result, existings, existingIdIdxMap, newCmptOptions); + } + if (isNormalMergeMode) { + mappingByName(result, newCmptOptions); + } + if (isNormalMergeMode || isReplaceMergeMode) { + mappingByIndex(result, newCmptOptions, isReplaceMergeMode); + } else if (isReplaceAllMode) { + mappingInReplaceAllMode(result, newCmptOptions); + } + makeIdAndName(result); + // The array `result` MUST NOT contain elided items, otherwise the + // forEach will omit those items and result in incorrect result. + return result; + } + function prepareResult(existings, existingIdIdxMap, mode) { + var result = []; + if (mode === 'replaceAll') { + return result; + } + // Do not use native `map` to in case that the array `existings` + // contains elided items, which will be omitted. + for (var index = 0; index < existings.length; index++) { + var existing = existings[index]; + // Because of replaceMerge, `existing` may be null/undefined. + if (existing && existing.id != null) { + existingIdIdxMap.set(existing.id, index); + } + // For non-internal-componnets: + // Mode "normalMerge": all existings kept. + // Mode "replaceMerge": all existing removed unless mapped by id. + // For internal-components: + // go with "replaceMerge" approach in both mode. + result.push({ + existing: mode === 'replaceMerge' || isComponentIdInternal(existing) ? null : existing, + newOption: null, + keyInfo: null, + brandNew: null + }); + } + return result; + } + function mappingById(result, existings, existingIdIdxMap, newCmptOptions) { + // Mapping by id if specified. + each(newCmptOptions, function (cmptOption, index) { + if (!cmptOption || cmptOption.id == null) { + return; + } + var optionId = makeComparableKey(cmptOption.id); + var existingIdx = existingIdIdxMap.get(optionId); + if (existingIdx != null) { + var resultItem = result[existingIdx]; + assert(!resultItem.newOption, 'Duplicated option on id "' + optionId + '".'); + resultItem.newOption = cmptOption; + // In both mode, if id matched, new option will be merged to + // the existings rather than creating new component model. + resultItem.existing = existings[existingIdx]; + newCmptOptions[index] = null; + } + }); + } + function mappingByName(result, newCmptOptions) { + // Mapping by name if specified. + each(newCmptOptions, function (cmptOption, index) { + if (!cmptOption || cmptOption.name == null) { + return; + } + for (var i = 0; i < result.length; i++) { + var existing = result[i].existing; + if (!result[i].newOption // Consider name: two map to one. + // Can not match when both ids existing but different. + && existing && (existing.id == null || cmptOption.id == null) && !isComponentIdInternal(cmptOption) && !isComponentIdInternal(existing) && keyExistAndEqual('name', existing, cmptOption)) { + result[i].newOption = cmptOption; + newCmptOptions[index] = null; + return; + } + } + }); + } + function mappingByIndex(result, newCmptOptions, brandNew) { + each(newCmptOptions, function (cmptOption) { + if (!cmptOption) { + return; + } + // Find the first place that not mapped by id and not internal component (consider the "hole"). + var resultItem; + var nextIdx = 0; + while ( + // Be `!resultItem` only when `nextIdx >= result.length`. + (resultItem = result[nextIdx] + // (1) Existing models that already have id should be able to mapped to. Because + // after mapping performed, model will always be assigned with an id if user not given. + // After that all models have id. + // (2) If new option has id, it can only set to a hole or append to the last. It should + // not be merged to the existings with different id. Because id should not be overwritten. + // (3) Name can be overwritten, because axis use name as 'show label text'. + ) && (resultItem.newOption || isComponentIdInternal(resultItem.existing) || + // In mode "replaceMerge", here no not-mapped-non-internal-existing. + resultItem.existing && cmptOption.id != null && !keyExistAndEqual('id', cmptOption, resultItem.existing))) { + nextIdx++; + } + if (resultItem) { + resultItem.newOption = cmptOption; + resultItem.brandNew = brandNew; + } else { + result.push({ + newOption: cmptOption, + brandNew: brandNew, + existing: null, + keyInfo: null + }); + } + nextIdx++; + }); + } + function mappingInReplaceAllMode(result, newCmptOptions) { + each(newCmptOptions, function (cmptOption) { + // The feature "reproduce" requires "hole" will also reproduced + // in case that component index referring are broken. + result.push({ + newOption: cmptOption, + brandNew: true, + existing: null, + keyInfo: null + }); + }); + } + /** + * Make id and name for mapping result (result of mappingToExists) + * into `keyInfo` field. + */ + function makeIdAndName(mapResult) { + // We use this id to hash component models and view instances + // in echarts. id can be specified by user, or auto generated. + // The id generation rule ensures new view instance are able + // to mapped to old instance when setOption are called in + // no-merge mode. So we generate model id by name and plus + // type in view id. + // name can be duplicated among components, which is convenient + // to specify multi components (like series) by one name. + // Ensure that each id is distinct. + var idMap = createHashMap(); + each(mapResult, function (item) { + var existing = item.existing; + existing && idMap.set(existing.id, item); + }); + each(mapResult, function (item) { + var opt = item.newOption; + // Force ensure id not duplicated. + assert(!opt || opt.id == null || !idMap.get(opt.id) || idMap.get(opt.id) === item, 'id duplicates: ' + (opt && opt.id)); + opt && opt.id != null && idMap.set(opt.id, item); + !item.keyInfo && (item.keyInfo = {}); + }); + // Make name and id. + each(mapResult, function (item, index) { + var existing = item.existing; + var opt = item.newOption; + var keyInfo = item.keyInfo; + if (!isObject(opt)) { + return; + } + // Name can be overwritten. Consider case: axis.name = '20km'. + // But id generated by name will not be changed, which affect + // only in that case: setOption with 'not merge mode' and view + // instance will be recreated, which can be accepted. + keyInfo.name = opt.name != null ? makeComparableKey(opt.name) : existing ? existing.name + // Avoid that different series has the same name, + // because name may be used like in color pallet. + : DUMMY_COMPONENT_NAME_PREFIX + index; + if (existing) { + keyInfo.id = makeComparableKey(existing.id); + } else if (opt.id != null) { + keyInfo.id = makeComparableKey(opt.id); + } else { + // Consider this situatoin: + // optionA: [{name: 'a'}, {name: 'a'}, {..}] + // optionB [{..}, {name: 'a'}, {name: 'a'}] + // Series with the same name between optionA and optionB + // should be mapped. + var idNum = 0; + do { + keyInfo.id = '\0' + keyInfo.name + '\0' + idNum++; + } while (idMap.get(keyInfo.id)); + } + idMap.set(keyInfo.id, item); + }); + } + function keyExistAndEqual(attr, obj1, obj2) { + var key1 = convertOptionIdName(obj1[attr], null); + var key2 = convertOptionIdName(obj2[attr], null); + // See `MappingExistingItem`. `id` and `name` trade string equals to number. + return key1 != null && key2 != null && key1 === key2; + } + /** + * @return return null if not exist. + */ + function makeComparableKey(val) { + if ("development" !== 'production') { + if (val == null) { + throw new Error(); + } + } + return convertOptionIdName(val, ''); + } + function convertOptionIdName(idOrName, defaultValue) { + if (idOrName == null) { + return defaultValue; + } + return isString(idOrName) ? idOrName : isNumber(idOrName) || isStringSafe(idOrName) ? idOrName + '' : defaultValue; + } + function warnInvalidateIdOrName(idOrName) { + if ("development" !== 'production') { + warn('`' + idOrName + '` is invalid id or name. Must be a string or number.'); + } + } + function isValidIdOrName(idOrName) { + return isStringSafe(idOrName) || isNumeric(idOrName); + } + function isNameSpecified(componentModel) { + var name = componentModel.name; + // Is specified when `indexOf` get -1 or > 0. + return !!(name && name.indexOf(DUMMY_COMPONENT_NAME_PREFIX)); + } + /** + * @public + * @param {Object} cmptOption + * @return {boolean} + */ + function isComponentIdInternal(cmptOption) { + return cmptOption && cmptOption.id != null && makeComparableKey(cmptOption.id).indexOf(INTERNAL_COMPONENT_ID_PREFIX) === 0; + } + function makeInternalComponentId(idSuffix) { + return INTERNAL_COMPONENT_ID_PREFIX + idSuffix; + } + function setComponentTypeToKeyInfo(mappingResult, mainType, componentModelCtor) { + // Set mainType and complete subType. + each(mappingResult, function (item) { + var newOption = item.newOption; + if (isObject(newOption)) { + item.keyInfo.mainType = mainType; + item.keyInfo.subType = determineSubType(mainType, newOption, item.existing, componentModelCtor); + } + }); + } + function determineSubType(mainType, newCmptOption, existComponent, componentModelCtor) { + var subType = newCmptOption.type ? newCmptOption.type : existComponent ? existComponent.subType + // Use determineSubType only when there is no existComponent. + : componentModelCtor.determineSubType(mainType, newCmptOption); + // tooltip, markline, markpoint may always has no subType + return subType; + } + /** + * A helper for removing duplicate items between batchA and batchB, + * and in themselves, and categorize by series. + * + * @param batchA Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...] + * @param batchB Like: [{seriesId: 2, dataIndex: [32, 4, 5]}, ...] + * @return result: [resultBatchA, resultBatchB] + */ + function compressBatches(batchA, batchB) { + var mapA = {}; + var mapB = {}; + makeMap(batchA || [], mapA); + makeMap(batchB || [], mapB, mapA); + return [mapToArray(mapA), mapToArray(mapB)]; + function makeMap(sourceBatch, map, otherMap) { + for (var i = 0, len = sourceBatch.length; i < len; i++) { + var seriesId = convertOptionIdName(sourceBatch[i].seriesId, null); + if (seriesId == null) { + return; + } + var dataIndices = normalizeToArray(sourceBatch[i].dataIndex); + var otherDataIndices = otherMap && otherMap[seriesId]; + for (var j = 0, lenj = dataIndices.length; j < lenj; j++) { + var dataIndex = dataIndices[j]; + if (otherDataIndices && otherDataIndices[dataIndex]) { + otherDataIndices[dataIndex] = null; + } else { + (map[seriesId] || (map[seriesId] = {}))[dataIndex] = 1; + } + } + } + } + function mapToArray(map, isData) { + var result = []; + for (var i in map) { + if (map.hasOwnProperty(i) && map[i] != null) { + if (isData) { + result.push(+i); + } else { + var dataIndices = mapToArray(map[i], true); + dataIndices.length && result.push({ + seriesId: i, + dataIndex: dataIndices + }); + } + } + } + return result; + } + } + /** + * @param payload Contains dataIndex (means rawIndex) / dataIndexInside / name + * each of which can be Array or primary type. + * @return dataIndex If not found, return undefined/null. + */ + function queryDataIndex(data, payload) { + if (payload.dataIndexInside != null) { + return payload.dataIndexInside; + } else if (payload.dataIndex != null) { + return isArray(payload.dataIndex) ? map(payload.dataIndex, function (value) { + return data.indexOfRawIndex(value); + }) : data.indexOfRawIndex(payload.dataIndex); + } else if (payload.name != null) { + return isArray(payload.name) ? map(payload.name, function (value) { + return data.indexOfName(value); + }) : data.indexOfName(payload.name); + } + } + /** + * Enable property storage to any host object. + * Notice: Serialization is not supported. + * + * For example: + * let inner = zrUitl.makeInner(); + * + * function some1(hostObj) { + * inner(hostObj).someProperty = 1212; + * ... + * } + * function some2() { + * let fields = inner(this); + * fields.someProperty1 = 1212; + * fields.someProperty2 = 'xx'; + * ... + * } + * + * @return {Function} + */ + function makeInner() { + var key = '__ec_inner_' + innerUniqueIndex++; + return function (hostObj) { + return hostObj[key] || (hostObj[key] = {}); + }; + } + var innerUniqueIndex = getRandomIdBase(); + /** + * The same behavior as `component.getReferringComponents`. + */ + function parseFinder(ecModel, finderInput, opt) { + var _a = preParseFinder(finderInput, opt), + mainTypeSpecified = _a.mainTypeSpecified, + queryOptionMap = _a.queryOptionMap, + others = _a.others; + var result = others; + var defaultMainType = opt ? opt.defaultMainType : null; + if (!mainTypeSpecified && defaultMainType) { + queryOptionMap.set(defaultMainType, {}); + } + queryOptionMap.each(function (queryOption, mainType) { + var queryResult = queryReferringComponents(ecModel, mainType, queryOption, { + useDefault: defaultMainType === mainType, + enableAll: opt && opt.enableAll != null ? opt.enableAll : true, + enableNone: opt && opt.enableNone != null ? opt.enableNone : true + }); + result[mainType + 'Models'] = queryResult.models; + result[mainType + 'Model'] = queryResult.models[0]; + }); + return result; + } + function preParseFinder(finderInput, opt) { + var finder; + if (isString(finderInput)) { + var obj = {}; + obj[finderInput + 'Index'] = 0; + finder = obj; + } else { + finder = finderInput; + } + var queryOptionMap = createHashMap(); + var others = {}; + var mainTypeSpecified = false; + each(finder, function (value, key) { + // Exclude 'dataIndex' and other illgal keys. + if (key === 'dataIndex' || key === 'dataIndexInside') { + others[key] = value; + return; + } + var parsedKey = key.match(/^(\w+)(Index|Id|Name)$/) || []; + var mainType = parsedKey[1]; + var queryType = (parsedKey[2] || '').toLowerCase(); + if (!mainType || !queryType || opt && opt.includeMainTypes && indexOf(opt.includeMainTypes, mainType) < 0) { + return; + } + mainTypeSpecified = mainTypeSpecified || !!mainType; + var queryOption = queryOptionMap.get(mainType) || queryOptionMap.set(mainType, {}); + queryOption[queryType] = value; + }); + return { + mainTypeSpecified: mainTypeSpecified, + queryOptionMap: queryOptionMap, + others: others + }; + } + var SINGLE_REFERRING = { + useDefault: true, + enableAll: false, + enableNone: false + }; + var MULTIPLE_REFERRING = { + useDefault: false, + enableAll: true, + enableNone: true + }; + function queryReferringComponents(ecModel, mainType, userOption, opt) { + opt = opt || SINGLE_REFERRING; + var indexOption = userOption.index; + var idOption = userOption.id; + var nameOption = userOption.name; + var result = { + models: null, + specified: indexOption != null || idOption != null || nameOption != null + }; + if (!result.specified) { + // Use the first as default if `useDefault`. + var firstCmpt = void 0; + result.models = opt.useDefault && (firstCmpt = ecModel.getComponent(mainType)) ? [firstCmpt] : []; + return result; + } + if (indexOption === 'none' || indexOption === false) { + assert(opt.enableNone, '`"none"` or `false` is not a valid value on index option.'); + result.models = []; + return result; + } + // `queryComponents` will return all components if + // both all of index/id/name are null/undefined. + if (indexOption === 'all') { + assert(opt.enableAll, '`"all"` is not a valid value on index option.'); + indexOption = idOption = nameOption = null; + } + result.models = ecModel.queryComponents({ + mainType: mainType, + index: indexOption, + id: idOption, + name: nameOption + }); + return result; + } + function setAttribute(dom, key, value) { + dom.setAttribute ? dom.setAttribute(key, value) : dom[key] = value; + } + function getAttribute(dom, key) { + return dom.getAttribute ? dom.getAttribute(key) : dom[key]; + } + function getTooltipRenderMode(renderModeOption) { + if (renderModeOption === 'auto') { + // Using html when `document` exists, use richText otherwise + return env.domSupported ? 'html' : 'richText'; + } else { + return renderModeOption || 'html'; + } + } + /** + * Group a list by key. + */ + function groupData(array, getKey // return key + ) { + var buckets = createHashMap(); + var keys = []; + each(array, function (item) { + var key = getKey(item); + (buckets.get(key) || (keys.push(key), buckets.set(key, []))).push(item); + }); + return { + keys: keys, + buckets: buckets + }; + } + /** + * Interpolate raw values of a series with percent + * + * @param data data + * @param labelModel label model of the text element + * @param sourceValue start value. May be null/undefined when init. + * @param targetValue end value + * @param percent 0~1 percentage; 0 uses start value while 1 uses end value + * @return interpolated values + * If `sourceValue` and `targetValue` are `number`, return `number`. + * If `sourceValue` and `targetValue` are `string`, return `string`. + * If `sourceValue` and `targetValue` are `(string | number)[]`, return `(string | number)[]`. + * Other cases do not supported. + */ + function interpolateRawValues(data, precision, sourceValue, targetValue, percent) { + var isAutoPrecision = precision == null || precision === 'auto'; + if (targetValue == null) { + return targetValue; + } + if (isNumber(targetValue)) { + var value = interpolateNumber$1(sourceValue || 0, targetValue, percent); + return round(value, isAutoPrecision ? Math.max(getPrecision(sourceValue || 0), getPrecision(targetValue)) : precision); + } else if (isString(targetValue)) { + return percent < 1 ? sourceValue : targetValue; + } else { + var interpolated = []; + var leftArr = sourceValue; + var rightArr = targetValue; + var length_1 = Math.max(leftArr ? leftArr.length : 0, rightArr.length); + for (var i = 0; i < length_1; ++i) { + var info = data.getDimensionInfo(i); + // Don't interpolate ordinal dims + if (info && info.type === 'ordinal') { + // In init, there is no `sourceValue`, but should better not to get undefined result. + interpolated[i] = (percent < 1 && leftArr ? leftArr : rightArr)[i]; + } else { + var leftVal = leftArr && leftArr[i] ? leftArr[i] : 0; + var rightVal = rightArr[i]; + var value = interpolateNumber$1(leftVal, rightVal, percent); + interpolated[i] = round(value, isAutoPrecision ? Math.max(getPrecision(leftVal), getPrecision(rightVal)) : precision); + } + } + return interpolated; + } + } + + var TYPE_DELIMITER = '.'; + var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___'; + var IS_EXTENDED_CLASS = '___EC__EXTENDED_CLASS___'; + /** + * Notice, parseClassType('') should returns {main: '', sub: ''} + * @public + */ + function parseClassType(componentType) { + var ret = { + main: '', + sub: '' + }; + if (componentType) { + var typeArr = componentType.split(TYPE_DELIMITER); + ret.main = typeArr[0] || ''; + ret.sub = typeArr[1] || ''; + } + return ret; + } + /** + * @public + */ + function checkClassType(componentType) { + assert(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(componentType), 'componentType "' + componentType + '" illegal'); + } + function isExtendedClass(clz) { + return !!(clz && clz[IS_EXTENDED_CLASS]); + } + /** + * Implements `ExtendableConstructor` for `rootClz`. + * + * @usage + * ```ts + * class Xxx {} + * type XxxConstructor = typeof Xxx & ExtendableConstructor + * enableClassExtend(Xxx as XxxConstructor); + * ``` + */ + function enableClassExtend(rootClz, mandatoryMethods) { + rootClz.$constructor = rootClz; // FIXME: not necessary? + rootClz.extend = function (proto) { + if ("development" !== 'production') { + each(mandatoryMethods, function (method) { + if (!proto[method]) { + console.warn('Method `' + method + '` should be implemented' + (proto.type ? ' in ' + proto.type : '') + '.'); + } + }); + } + var superClass = this; + var ExtendedClass; + if (isESClass(superClass)) { + ExtendedClass = /** @class */function (_super) { + __extends(class_1, _super); + function class_1() { + return _super.apply(this, arguments) || this; + } + return class_1; + }(superClass); + } else { + // For backward compat, we both support ts class inheritance and this + // "extend" approach. + // The constructor should keep the same behavior as ts class inheritance: + // If this constructor/$constructor is not declared, auto invoke the super + // constructor. + // If this constructor/$constructor is declared, it is responsible for + // calling the super constructor. + ExtendedClass = function () { + (proto.$constructor || superClass).apply(this, arguments); + }; + inherits(ExtendedClass, this); + } + extend(ExtendedClass.prototype, proto); + ExtendedClass[IS_EXTENDED_CLASS] = true; + ExtendedClass.extend = this.extend; + ExtendedClass.superCall = superCall; + ExtendedClass.superApply = superApply; + ExtendedClass.superClass = superClass; + return ExtendedClass; + }; + } + function isESClass(fn) { + return isFunction(fn) && /^class\s/.test(Function.prototype.toString.call(fn)); + } + /** + * A work around to both support ts extend and this extend mechanism. + * on sub-class. + * @usage + * ```ts + * class Component { ... } + * classUtil.enableClassExtend(Component); + * classUtil.enableClassManagement(Component, {registerWhenExtend: true}); + * + * class Series extends Component { ... } + * // Without calling `markExtend`, `registerWhenExtend` will not work. + * Component.markExtend(Series); + * ``` + */ + function mountExtend(SubClz, SupperClz) { + SubClz.extend = SupperClz.extend; + } + // A random offset. + var classBase = Math.round(Math.random() * 10); + /** + * Implements `CheckableConstructor` for `target`. + * Can not use instanceof, consider different scope by + * cross domain or es module import in ec extensions. + * Mount a method "isInstance()" to Clz. + * + * @usage + * ```ts + * class Xxx {} + * type XxxConstructor = typeof Xxx & CheckableConstructor; + * enableClassCheck(Xxx as XxxConstructor) + * ``` + */ + function enableClassCheck(target) { + var classAttr = ['__\0is_clz', classBase++].join('_'); + target.prototype[classAttr] = true; + if ("development" !== 'production') { + assert(!target.isInstance, 'The method "is" can not be defined.'); + } + target.isInstance = function (obj) { + return !!(obj && obj[classAttr]); + }; + } + // superCall should have class info, which can not be fetched from 'this'. + // Consider this case: + // class A has method f, + // class B inherits class A, overrides method f, f call superApply('f'), + // class C inherits class B, does not override method f, + // then when method of class C is called, dead loop occurred. + function superCall(context, methodName) { + var args = []; + for (var _i = 2; _i < arguments.length; _i++) { + args[_i - 2] = arguments[_i]; + } + return this.superClass.prototype[methodName].apply(context, args); + } + function superApply(context, methodName, args) { + return this.superClass.prototype[methodName].apply(context, args); + } + /** + * Implements `ClassManager` for `target` + * + * @usage + * ```ts + * class Xxx {} + * type XxxConstructor = typeof Xxx & ClassManager + * enableClassManagement(Xxx as XxxConstructor); + * ``` + */ + function enableClassManagement(target) { + /** + * Component model classes + * key: componentType, + * value: + * componentClass, when componentType is 'a' + * or Object., when componentType is 'a.b' + */ + var storage = {}; + target.registerClass = function (clz) { + // `type` should not be a "instance member". + // If using TS class, should better declared as `static type = 'series.pie'`. + // otherwise users have to mount `type` on prototype manually. + // For backward compat and enable instance visit type via `this.type`, + // we still support fetch `type` from prototype. + var componentFullType = clz.type || clz.prototype.type; + if (componentFullType) { + checkClassType(componentFullType); + // If only static type declared, we assign it to prototype mandatorily. + clz.prototype.type = componentFullType; + var componentTypeInfo = parseClassType(componentFullType); + if (!componentTypeInfo.sub) { + if ("development" !== 'production') { + if (storage[componentTypeInfo.main]) { + console.warn(componentTypeInfo.main + ' exists.'); + } + } + storage[componentTypeInfo.main] = clz; + } else if (componentTypeInfo.sub !== IS_CONTAINER) { + var container = makeContainer(componentTypeInfo); + container[componentTypeInfo.sub] = clz; + } + } + return clz; + }; + target.getClass = function (mainType, subType, throwWhenNotFound) { + var clz = storage[mainType]; + if (clz && clz[IS_CONTAINER]) { + clz = subType ? clz[subType] : null; + } + if (throwWhenNotFound && !clz) { + throw new Error(!subType ? mainType + '.' + 'type should be specified.' : 'Component ' + mainType + '.' + (subType || '') + ' is used but not imported.'); + } + return clz; + }; + target.getClassesByMainType = function (componentType) { + var componentTypeInfo = parseClassType(componentType); + var result = []; + var obj = storage[componentTypeInfo.main]; + if (obj && obj[IS_CONTAINER]) { + each(obj, function (o, type) { + type !== IS_CONTAINER && result.push(o); + }); + } else { + result.push(obj); + } + return result; + }; + target.hasClass = function (componentType) { + // Just consider componentType.main. + var componentTypeInfo = parseClassType(componentType); + return !!storage[componentTypeInfo.main]; + }; + /** + * @return Like ['aa', 'bb'], but can not be ['aa.xx'] + */ + target.getAllClassMainTypes = function () { + var types = []; + each(storage, function (obj, type) { + types.push(type); + }); + return types; + }; + /** + * If a main type is container and has sub types + */ + target.hasSubTypes = function (componentType) { + var componentTypeInfo = parseClassType(componentType); + var obj = storage[componentTypeInfo.main]; + return obj && obj[IS_CONTAINER]; + }; + function makeContainer(componentTypeInfo) { + var container = storage[componentTypeInfo.main]; + if (!container || !container[IS_CONTAINER]) { + container = storage[componentTypeInfo.main] = {}; + container[IS_CONTAINER] = true; + } + return container; + } + } + // /** + // * @param {string|Array.} properties + // */ + // export function setReadOnly(obj, properties) { + // FIXME It seems broken in IE8 simulation of IE11 + // if (!zrUtil.isArray(properties)) { + // properties = properties != null ? [properties] : []; + // } + // zrUtil.each(properties, function (prop) { + // let value = obj[prop]; + // Object.defineProperty + // && Object.defineProperty(obj, prop, { + // value: value, writable: false + // }); + // zrUtil.isArray(obj[prop]) + // && Object.freeze + // && Object.freeze(obj[prop]); + // }); + // } + + function makeStyleMapper(properties, ignoreParent) { + // Normalize + for (var i = 0; i < properties.length; i++) { + if (!properties[i][1]) { + properties[i][1] = properties[i][0]; + } + } + ignoreParent = ignoreParent || false; + return function (model, excludes, includes) { + var style = {}; + for (var i = 0; i < properties.length; i++) { + var propName = properties[i][1]; + if (excludes && indexOf(excludes, propName) >= 0 || includes && indexOf(includes, propName) < 0) { + continue; + } + var val = model.getShallow(propName, ignoreParent); + if (val != null) { + style[properties[i][0]] = val; + } + } + // TODO Text or image? + return style; + }; + } + + var AREA_STYLE_KEY_MAP = [['fill', 'color'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['opacity'], ['shadowColor'] + // Option decal is in `DecalObject` but style.decal is in `PatternObject`. + // So do not transfer decal directly. + ]; + + var getAreaStyle = makeStyleMapper(AREA_STYLE_KEY_MAP); + var AreaStyleMixin = /** @class */function () { + function AreaStyleMixin() {} + AreaStyleMixin.prototype.getAreaStyle = function (excludes, includes) { + return getAreaStyle(this, excludes, includes); + }; + return AreaStyleMixin; + }(); + + var globalImageCache = new LRU(50); + function findExistImage(newImageOrSrc) { + if (typeof newImageOrSrc === 'string') { + var cachedImgObj = globalImageCache.get(newImageOrSrc); + return cachedImgObj && cachedImgObj.image; + } + else { + return newImageOrSrc; + } + } + function createOrUpdateImage(newImageOrSrc, image, hostEl, onload, cbPayload) { + if (!newImageOrSrc) { + return image; + } + else if (typeof newImageOrSrc === 'string') { + if ((image && image.__zrImageSrc === newImageOrSrc) || !hostEl) { + return image; + } + var cachedImgObj = globalImageCache.get(newImageOrSrc); + var pendingWrap = { hostEl: hostEl, cb: onload, cbPayload: cbPayload }; + if (cachedImgObj) { + image = cachedImgObj.image; + !isImageReady(image) && cachedImgObj.pending.push(pendingWrap); + } + else { + image = platformApi.loadImage(newImageOrSrc, imageOnLoad, imageOnLoad); + image.__zrImageSrc = newImageOrSrc; + globalImageCache.put(newImageOrSrc, image.__cachedImgObj = { + image: image, + pending: [pendingWrap] + }); + } + return image; + } + else { + return newImageOrSrc; + } + } + function imageOnLoad() { + var cachedImgObj = this.__cachedImgObj; + this.onload = this.onerror = this.__cachedImgObj = null; + for (var i = 0; i < cachedImgObj.pending.length; i++) { + var pendingWrap = cachedImgObj.pending[i]; + var cb = pendingWrap.cb; + cb && cb(this, pendingWrap.cbPayload); + pendingWrap.hostEl.dirty(); + } + cachedImgObj.pending.length = 0; + } + function isImageReady(image) { + return image && image.width && image.height; + } + + var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g; + function truncateText(text, containerWidth, font, ellipsis, options) { + if (!containerWidth) { + return ''; + } + var textLines = (text + '').split('\n'); + options = prepareTruncateOptions(containerWidth, font, ellipsis, options); + for (var i = 0, len = textLines.length; i < len; i++) { + textLines[i] = truncateSingleLine(textLines[i], options); + } + return textLines.join('\n'); + } + function prepareTruncateOptions(containerWidth, font, ellipsis, options) { + options = options || {}; + var preparedOpts = extend({}, options); + preparedOpts.font = font; + ellipsis = retrieve2(ellipsis, '...'); + preparedOpts.maxIterations = retrieve2(options.maxIterations, 2); + var minChar = preparedOpts.minChar = retrieve2(options.minChar, 0); + preparedOpts.cnCharWidth = getWidth('国', font); + var ascCharWidth = preparedOpts.ascCharWidth = getWidth('a', font); + preparedOpts.placeholder = retrieve2(options.placeholder, ''); + var contentWidth = containerWidth = Math.max(0, containerWidth - 1); + for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) { + contentWidth -= ascCharWidth; + } + var ellipsisWidth = getWidth(ellipsis, font); + if (ellipsisWidth > contentWidth) { + ellipsis = ''; + ellipsisWidth = 0; + } + contentWidth = containerWidth - ellipsisWidth; + preparedOpts.ellipsis = ellipsis; + preparedOpts.ellipsisWidth = ellipsisWidth; + preparedOpts.contentWidth = contentWidth; + preparedOpts.containerWidth = containerWidth; + return preparedOpts; + } + function truncateSingleLine(textLine, options) { + var containerWidth = options.containerWidth; + var font = options.font; + var contentWidth = options.contentWidth; + if (!containerWidth) { + return ''; + } + var lineWidth = getWidth(textLine, font); + if (lineWidth <= containerWidth) { + return textLine; + } + for (var j = 0;; j++) { + if (lineWidth <= contentWidth || j >= options.maxIterations) { + textLine += options.ellipsis; + break; + } + var subLength = j === 0 + ? estimateLength(textLine, contentWidth, options.ascCharWidth, options.cnCharWidth) + : lineWidth > 0 + ? Math.floor(textLine.length * contentWidth / lineWidth) + : 0; + textLine = textLine.substr(0, subLength); + lineWidth = getWidth(textLine, font); + } + if (textLine === '') { + textLine = options.placeholder; + } + return textLine; + } + function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) { + var width = 0; + var i = 0; + for (var len = text.length; i < len && width < contentWidth; i++) { + var charCode = text.charCodeAt(i); + width += (0 <= charCode && charCode <= 127) ? ascCharWidth : cnCharWidth; + } + return i; + } + function parsePlainText(text, style) { + text != null && (text += ''); + var overflow = style.overflow; + var padding = style.padding; + var font = style.font; + var truncate = overflow === 'truncate'; + var calculatedLineHeight = getLineHeight(font); + var lineHeight = retrieve2(style.lineHeight, calculatedLineHeight); + var bgColorDrawn = !!(style.backgroundColor); + var truncateLineOverflow = style.lineOverflow === 'truncate'; + var width = style.width; + var lines; + if (width != null && (overflow === 'break' || overflow === 'breakAll')) { + lines = text ? wrapText(text, style.font, width, overflow === 'breakAll', 0).lines : []; + } + else { + lines = text ? text.split('\n') : []; + } + var contentHeight = lines.length * lineHeight; + var height = retrieve2(style.height, contentHeight); + if (contentHeight > height && truncateLineOverflow) { + var lineCount = Math.floor(height / lineHeight); + lines = lines.slice(0, lineCount); + } + if (text && truncate && width != null) { + var options = prepareTruncateOptions(width, font, style.ellipsis, { + minChar: style.truncateMinChar, + placeholder: style.placeholder + }); + for (var i = 0; i < lines.length; i++) { + lines[i] = truncateSingleLine(lines[i], options); + } + } + var outerHeight = height; + var contentWidth = 0; + for (var i = 0; i < lines.length; i++) { + contentWidth = Math.max(getWidth(lines[i], font), contentWidth); + } + if (width == null) { + width = contentWidth; + } + var outerWidth = contentWidth; + if (padding) { + outerHeight += padding[0] + padding[2]; + outerWidth += padding[1] + padding[3]; + width += padding[1] + padding[3]; + } + if (bgColorDrawn) { + outerWidth = width; + } + return { + lines: lines, + height: height, + outerWidth: outerWidth, + outerHeight: outerHeight, + lineHeight: lineHeight, + calculatedLineHeight: calculatedLineHeight, + contentWidth: contentWidth, + contentHeight: contentHeight, + width: width + }; + } + var RichTextToken = (function () { + function RichTextToken() { + } + return RichTextToken; + }()); + var RichTextLine = (function () { + function RichTextLine(tokens) { + this.tokens = []; + if (tokens) { + this.tokens = tokens; + } + } + return RichTextLine; + }()); + var RichTextContentBlock = (function () { + function RichTextContentBlock() { + this.width = 0; + this.height = 0; + this.contentWidth = 0; + this.contentHeight = 0; + this.outerWidth = 0; + this.outerHeight = 0; + this.lines = []; + } + return RichTextContentBlock; + }()); + function parseRichText(text, style) { + var contentBlock = new RichTextContentBlock(); + text != null && (text += ''); + if (!text) { + return contentBlock; + } + var topWidth = style.width; + var topHeight = style.height; + var overflow = style.overflow; + var wrapInfo = (overflow === 'break' || overflow === 'breakAll') && topWidth != null + ? { width: topWidth, accumWidth: 0, breakAll: overflow === 'breakAll' } + : null; + var lastIndex = STYLE_REG.lastIndex = 0; + var result; + while ((result = STYLE_REG.exec(text)) != null) { + var matchedIndex = result.index; + if (matchedIndex > lastIndex) { + pushTokens(contentBlock, text.substring(lastIndex, matchedIndex), style, wrapInfo); + } + pushTokens(contentBlock, result[2], style, wrapInfo, result[1]); + lastIndex = STYLE_REG.lastIndex; + } + if (lastIndex < text.length) { + pushTokens(contentBlock, text.substring(lastIndex, text.length), style, wrapInfo); + } + var pendingList = []; + var calculatedHeight = 0; + var calculatedWidth = 0; + var stlPadding = style.padding; + var truncate = overflow === 'truncate'; + var truncateLine = style.lineOverflow === 'truncate'; + function finishLine(line, lineWidth, lineHeight) { + line.width = lineWidth; + line.lineHeight = lineHeight; + calculatedHeight += lineHeight; + calculatedWidth = Math.max(calculatedWidth, lineWidth); + } + outer: for (var i = 0; i < contentBlock.lines.length; i++) { + var line = contentBlock.lines[i]; + var lineHeight = 0; + var lineWidth = 0; + for (var j = 0; j < line.tokens.length; j++) { + var token = line.tokens[j]; + var tokenStyle = token.styleName && style.rich[token.styleName] || {}; + var textPadding = token.textPadding = tokenStyle.padding; + var paddingH = textPadding ? textPadding[1] + textPadding[3] : 0; + var font = token.font = tokenStyle.font || style.font; + token.contentHeight = getLineHeight(font); + var tokenHeight = retrieve2(tokenStyle.height, token.contentHeight); + token.innerHeight = tokenHeight; + textPadding && (tokenHeight += textPadding[0] + textPadding[2]); + token.height = tokenHeight; + token.lineHeight = retrieve3(tokenStyle.lineHeight, style.lineHeight, tokenHeight); + token.align = tokenStyle && tokenStyle.align || style.align; + token.verticalAlign = tokenStyle && tokenStyle.verticalAlign || 'middle'; + if (truncateLine && topHeight != null && calculatedHeight + token.lineHeight > topHeight) { + if (j > 0) { + line.tokens = line.tokens.slice(0, j); + finishLine(line, lineWidth, lineHeight); + contentBlock.lines = contentBlock.lines.slice(0, i + 1); + } + else { + contentBlock.lines = contentBlock.lines.slice(0, i); + } + break outer; + } + var styleTokenWidth = tokenStyle.width; + var tokenWidthNotSpecified = styleTokenWidth == null || styleTokenWidth === 'auto'; + if (typeof styleTokenWidth === 'string' && styleTokenWidth.charAt(styleTokenWidth.length - 1) === '%') { + token.percentWidth = styleTokenWidth; + pendingList.push(token); + token.contentWidth = getWidth(token.text, font); + } + else { + if (tokenWidthNotSpecified) { + var textBackgroundColor = tokenStyle.backgroundColor; + var bgImg = textBackgroundColor && textBackgroundColor.image; + if (bgImg) { + bgImg = findExistImage(bgImg); + if (isImageReady(bgImg)) { + token.width = Math.max(token.width, bgImg.width * tokenHeight / bgImg.height); + } + } + } + var remainTruncWidth = truncate && topWidth != null + ? topWidth - lineWidth : null; + if (remainTruncWidth != null && remainTruncWidth < token.width) { + if (!tokenWidthNotSpecified || remainTruncWidth < paddingH) { + token.text = ''; + token.width = token.contentWidth = 0; + } + else { + token.text = truncateText(token.text, remainTruncWidth - paddingH, font, style.ellipsis, { minChar: style.truncateMinChar }); + token.width = token.contentWidth = getWidth(token.text, font); + } + } + else { + token.contentWidth = getWidth(token.text, font); + } + } + token.width += paddingH; + lineWidth += token.width; + tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight)); + } + finishLine(line, lineWidth, lineHeight); + } + contentBlock.outerWidth = contentBlock.width = retrieve2(topWidth, calculatedWidth); + contentBlock.outerHeight = contentBlock.height = retrieve2(topHeight, calculatedHeight); + contentBlock.contentHeight = calculatedHeight; + contentBlock.contentWidth = calculatedWidth; + if (stlPadding) { + contentBlock.outerWidth += stlPadding[1] + stlPadding[3]; + contentBlock.outerHeight += stlPadding[0] + stlPadding[2]; + } + for (var i = 0; i < pendingList.length; i++) { + var token = pendingList[i]; + var percentWidth = token.percentWidth; + token.width = parseInt(percentWidth, 10) / 100 * contentBlock.width; + } + return contentBlock; + } + function pushTokens(block, str, style, wrapInfo, styleName) { + var isEmptyStr = str === ''; + var tokenStyle = styleName && style.rich[styleName] || {}; + var lines = block.lines; + var font = tokenStyle.font || style.font; + var newLine = false; + var strLines; + var linesWidths; + if (wrapInfo) { + var tokenPadding = tokenStyle.padding; + var tokenPaddingH = tokenPadding ? tokenPadding[1] + tokenPadding[3] : 0; + if (tokenStyle.width != null && tokenStyle.width !== 'auto') { + var outerWidth_1 = parsePercent(tokenStyle.width, wrapInfo.width) + tokenPaddingH; + if (lines.length > 0) { + if (outerWidth_1 + wrapInfo.accumWidth > wrapInfo.width) { + strLines = str.split('\n'); + newLine = true; + } + } + wrapInfo.accumWidth = outerWidth_1; + } + else { + var res = wrapText(str, font, wrapInfo.width, wrapInfo.breakAll, wrapInfo.accumWidth); + wrapInfo.accumWidth = res.accumWidth + tokenPaddingH; + linesWidths = res.linesWidths; + strLines = res.lines; + } + } + else { + strLines = str.split('\n'); + } + for (var i = 0; i < strLines.length; i++) { + var text = strLines[i]; + var token = new RichTextToken(); + token.styleName = styleName; + token.text = text; + token.isLineHolder = !text && !isEmptyStr; + if (typeof tokenStyle.width === 'number') { + token.width = tokenStyle.width; + } + else { + token.width = linesWidths + ? linesWidths[i] + : getWidth(text, font); + } + if (!i && !newLine) { + var tokens = (lines[lines.length - 1] || (lines[0] = new RichTextLine())).tokens; + var tokensLen = tokens.length; + (tokensLen === 1 && tokens[0].isLineHolder) + ? (tokens[0] = token) + : ((text || !tokensLen || isEmptyStr) && tokens.push(token)); + } + else { + lines.push(new RichTextLine([token])); + } + } + } + function isAlphabeticLetter(ch) { + var code = ch.charCodeAt(0); + return code >= 0x20 && code <= 0x24F + || code >= 0x370 && code <= 0x10FF + || code >= 0x1200 && code <= 0x13FF + || code >= 0x1E00 && code <= 0x206F; + } + var breakCharMap = reduce(',&?/;] '.split(''), function (obj, ch) { + obj[ch] = true; + return obj; + }, {}); + function isWordBreakChar(ch) { + if (isAlphabeticLetter(ch)) { + if (breakCharMap[ch]) { + return true; + } + return false; + } + return true; + } + function wrapText(text, font, lineWidth, isBreakAll, lastAccumWidth) { + var lines = []; + var linesWidths = []; + var line = ''; + var currentWord = ''; + var currentWordWidth = 0; + var accumWidth = 0; + for (var i = 0; i < text.length; i++) { + var ch = text.charAt(i); + if (ch === '\n') { + if (currentWord) { + line += currentWord; + accumWidth += currentWordWidth; + } + lines.push(line); + linesWidths.push(accumWidth); + line = ''; + currentWord = ''; + currentWordWidth = 0; + accumWidth = 0; + continue; + } + var chWidth = getWidth(ch, font); + var inWord = isBreakAll ? false : !isWordBreakChar(ch); + if (!lines.length + ? lastAccumWidth + accumWidth + chWidth > lineWidth + : accumWidth + chWidth > lineWidth) { + if (!accumWidth) { + if (inWord) { + lines.push(currentWord); + linesWidths.push(currentWordWidth); + currentWord = ch; + currentWordWidth = chWidth; + } + else { + lines.push(ch); + linesWidths.push(chWidth); + } + } + else if (line || currentWord) { + if (inWord) { + if (!line) { + line = currentWord; + currentWord = ''; + currentWordWidth = 0; + accumWidth = currentWordWidth; + } + lines.push(line); + linesWidths.push(accumWidth - currentWordWidth); + currentWord += ch; + currentWordWidth += chWidth; + line = ''; + accumWidth = currentWordWidth; + } + else { + if (currentWord) { + line += currentWord; + currentWord = ''; + currentWordWidth = 0; + } + lines.push(line); + linesWidths.push(accumWidth); + line = ch; + accumWidth = chWidth; + } + } + continue; + } + accumWidth += chWidth; + if (inWord) { + currentWord += ch; + currentWordWidth += chWidth; + } + else { + if (currentWord) { + line += currentWord; + currentWord = ''; + currentWordWidth = 0; + } + line += ch; + } + } + if (!lines.length && !line) { + line = text; + currentWord = ''; + currentWordWidth = 0; + } + if (currentWord) { + line += currentWord; + } + if (line) { + lines.push(line); + linesWidths.push(accumWidth); + } + if (lines.length === 1) { + accumWidth += lastAccumWidth; + } + return { + accumWidth: accumWidth, + lines: lines, + linesWidths: linesWidths + }; + } + + var STYLE_MAGIC_KEY = '__zr_style_' + Math.round((Math.random() * 10)); + var DEFAULT_COMMON_STYLE = { + shadowBlur: 0, + shadowOffsetX: 0, + shadowOffsetY: 0, + shadowColor: '#000', + opacity: 1, + blend: 'source-over' + }; + var DEFAULT_COMMON_ANIMATION_PROPS = { + style: { + shadowBlur: true, + shadowOffsetX: true, + shadowOffsetY: true, + shadowColor: true, + opacity: true + } + }; + DEFAULT_COMMON_STYLE[STYLE_MAGIC_KEY] = true; + var PRIMARY_STATES_KEYS$1 = ['z', 'z2', 'invisible']; + var PRIMARY_STATES_KEYS_IN_HOVER_LAYER = ['invisible']; + var Displayable = (function (_super) { + __extends(Displayable, _super); + function Displayable(props) { + return _super.call(this, props) || this; + } + Displayable.prototype._init = function (props) { + var keysArr = keys(props); + for (var i = 0; i < keysArr.length; i++) { + var key = keysArr[i]; + if (key === 'style') { + this.useStyle(props[key]); + } + else { + _super.prototype.attrKV.call(this, key, props[key]); + } + } + if (!this.style) { + this.useStyle({}); + } + }; + Displayable.prototype.beforeBrush = function () { }; + Displayable.prototype.afterBrush = function () { }; + Displayable.prototype.innerBeforeBrush = function () { }; + Displayable.prototype.innerAfterBrush = function () { }; + Displayable.prototype.shouldBePainted = function (viewWidth, viewHeight, considerClipPath, considerAncestors) { + var m = this.transform; + if (this.ignore + || this.invisible + || this.style.opacity === 0 + || (this.culling + && isDisplayableCulled(this, viewWidth, viewHeight)) + || (m && !m[0] && !m[3])) { + return false; + } + if (considerClipPath && this.__clipPaths) { + for (var i = 0; i < this.__clipPaths.length; ++i) { + if (this.__clipPaths[i].isZeroArea()) { + return false; + } + } + } + if (considerAncestors && this.parent) { + var parent_1 = this.parent; + while (parent_1) { + if (parent_1.ignore) { + return false; + } + parent_1 = parent_1.parent; + } + } + return true; + }; + Displayable.prototype.contain = function (x, y) { + return this.rectContain(x, y); + }; + Displayable.prototype.traverse = function (cb, context) { + cb.call(context, this); + }; + Displayable.prototype.rectContain = function (x, y) { + var coord = this.transformCoordToLocal(x, y); + var rect = this.getBoundingRect(); + return rect.contain(coord[0], coord[1]); + }; + Displayable.prototype.getPaintRect = function () { + var rect = this._paintRect; + if (!this._paintRect || this.__dirty) { + var transform = this.transform; + var elRect = this.getBoundingRect(); + var style = this.style; + var shadowSize = style.shadowBlur || 0; + var shadowOffsetX = style.shadowOffsetX || 0; + var shadowOffsetY = style.shadowOffsetY || 0; + rect = this._paintRect || (this._paintRect = new BoundingRect(0, 0, 0, 0)); + if (transform) { + BoundingRect.applyTransform(rect, elRect, transform); + } + else { + rect.copy(elRect); + } + if (shadowSize || shadowOffsetX || shadowOffsetY) { + rect.width += shadowSize * 2 + Math.abs(shadowOffsetX); + rect.height += shadowSize * 2 + Math.abs(shadowOffsetY); + rect.x = Math.min(rect.x, rect.x + shadowOffsetX - shadowSize); + rect.y = Math.min(rect.y, rect.y + shadowOffsetY - shadowSize); + } + var tolerance = this.dirtyRectTolerance; + if (!rect.isZero()) { + rect.x = Math.floor(rect.x - tolerance); + rect.y = Math.floor(rect.y - tolerance); + rect.width = Math.ceil(rect.width + 1 + tolerance * 2); + rect.height = Math.ceil(rect.height + 1 + tolerance * 2); + } + } + return rect; + }; + Displayable.prototype.setPrevPaintRect = function (paintRect) { + if (paintRect) { + this._prevPaintRect = this._prevPaintRect || new BoundingRect(0, 0, 0, 0); + this._prevPaintRect.copy(paintRect); + } + else { + this._prevPaintRect = null; + } + }; + Displayable.prototype.getPrevPaintRect = function () { + return this._prevPaintRect; + }; + Displayable.prototype.animateStyle = function (loop) { + return this.animate('style', loop); + }; + Displayable.prototype.updateDuringAnimation = function (targetKey) { + if (targetKey === 'style') { + this.dirtyStyle(); + } + else { + this.markRedraw(); + } + }; + Displayable.prototype.attrKV = function (key, value) { + if (key !== 'style') { + _super.prototype.attrKV.call(this, key, value); + } + else { + if (!this.style) { + this.useStyle(value); + } + else { + this.setStyle(value); + } + } + }; + Displayable.prototype.setStyle = function (keyOrObj, value) { + if (typeof keyOrObj === 'string') { + this.style[keyOrObj] = value; + } + else { + extend(this.style, keyOrObj); + } + this.dirtyStyle(); + return this; + }; + Displayable.prototype.dirtyStyle = function (notRedraw) { + if (!notRedraw) { + this.markRedraw(); + } + this.__dirty |= STYLE_CHANGED_BIT; + if (this._rect) { + this._rect = null; + } + }; + Displayable.prototype.dirty = function () { + this.dirtyStyle(); + }; + Displayable.prototype.styleChanged = function () { + return !!(this.__dirty & STYLE_CHANGED_BIT); + }; + Displayable.prototype.styleUpdated = function () { + this.__dirty &= ~STYLE_CHANGED_BIT; + }; + Displayable.prototype.createStyle = function (obj) { + return createObject(DEFAULT_COMMON_STYLE, obj); + }; + Displayable.prototype.useStyle = function (obj) { + if (!obj[STYLE_MAGIC_KEY]) { + obj = this.createStyle(obj); + } + if (this.__inHover) { + this.__hoverStyle = obj; + } + else { + this.style = obj; + } + this.dirtyStyle(); + }; + Displayable.prototype.isStyleObject = function (obj) { + return obj[STYLE_MAGIC_KEY]; + }; + Displayable.prototype._innerSaveToNormal = function (toState) { + _super.prototype._innerSaveToNormal.call(this, toState); + var normalState = this._normalState; + if (toState.style && !normalState.style) { + normalState.style = this._mergeStyle(this.createStyle(), this.style); + } + this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS$1); + }; + Displayable.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) { + _super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg); + var needsRestoreToNormal = !(state && keepCurrentStates); + var targetStyle; + if (state && state.style) { + if (transition) { + if (keepCurrentStates) { + targetStyle = state.style; + } + else { + targetStyle = this._mergeStyle(this.createStyle(), normalState.style); + this._mergeStyle(targetStyle, state.style); + } + } + else { + targetStyle = this._mergeStyle(this.createStyle(), keepCurrentStates ? this.style : normalState.style); + this._mergeStyle(targetStyle, state.style); + } + } + else if (needsRestoreToNormal) { + targetStyle = normalState.style; + } + if (targetStyle) { + if (transition) { + var sourceStyle = this.style; + this.style = this.createStyle(needsRestoreToNormal ? {} : sourceStyle); + if (needsRestoreToNormal) { + var changedKeys = keys(sourceStyle); + for (var i = 0; i < changedKeys.length; i++) { + var key = changedKeys[i]; + if (key in targetStyle) { + targetStyle[key] = targetStyle[key]; + this.style[key] = sourceStyle[key]; + } + } + } + var targetKeys = keys(targetStyle); + for (var i = 0; i < targetKeys.length; i++) { + var key = targetKeys[i]; + this.style[key] = this.style[key]; + } + this._transitionState(stateName, { + style: targetStyle + }, animationCfg, this.getAnimationStyleProps()); + } + else { + this.useStyle(targetStyle); + } + } + var statesKeys = this.__inHover ? PRIMARY_STATES_KEYS_IN_HOVER_LAYER : PRIMARY_STATES_KEYS$1; + for (var i = 0; i < statesKeys.length; i++) { + var key = statesKeys[i]; + if (state && state[key] != null) { + this[key] = state[key]; + } + else if (needsRestoreToNormal) { + if (normalState[key] != null) { + this[key] = normalState[key]; + } + } + } + }; + Displayable.prototype._mergeStates = function (states) { + var mergedState = _super.prototype._mergeStates.call(this, states); + var mergedStyle; + for (var i = 0; i < states.length; i++) { + var state = states[i]; + if (state.style) { + mergedStyle = mergedStyle || {}; + this._mergeStyle(mergedStyle, state.style); + } + } + if (mergedStyle) { + mergedState.style = mergedStyle; + } + return mergedState; + }; + Displayable.prototype._mergeStyle = function (targetStyle, sourceStyle) { + extend(targetStyle, sourceStyle); + return targetStyle; + }; + Displayable.prototype.getAnimationStyleProps = function () { + return DEFAULT_COMMON_ANIMATION_PROPS; + }; + Displayable.initDefaultProps = (function () { + var dispProto = Displayable.prototype; + dispProto.type = 'displayable'; + dispProto.invisible = false; + dispProto.z = 0; + dispProto.z2 = 0; + dispProto.zlevel = 0; + dispProto.culling = false; + dispProto.cursor = 'pointer'; + dispProto.rectHover = false; + dispProto.incremental = false; + dispProto._rect = null; + dispProto.dirtyRectTolerance = 0; + dispProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT; + })(); + return Displayable; + }(Element)); + var tmpRect$1 = new BoundingRect(0, 0, 0, 0); + var viewRect = new BoundingRect(0, 0, 0, 0); + function isDisplayableCulled(el, width, height) { + tmpRect$1.copy(el.getBoundingRect()); + if (el.transform) { + tmpRect$1.applyTransform(el.transform); + } + viewRect.width = width; + viewRect.height = height; + return !tmpRect$1.intersect(viewRect); + } + + var mathMin$1 = Math.min; + var mathMax$1 = Math.max; + var mathSin = Math.sin; + var mathCos = Math.cos; + var PI2 = Math.PI * 2; + var start = create(); + var end = create(); + var extremity = create(); + function fromPoints(points, min, max) { + if (points.length === 0) { + return; + } + var p = points[0]; + var left = p[0]; + var right = p[0]; + var top = p[1]; + var bottom = p[1]; + for (var i = 1; i < points.length; i++) { + p = points[i]; + left = mathMin$1(left, p[0]); + right = mathMax$1(right, p[0]); + top = mathMin$1(top, p[1]); + bottom = mathMax$1(bottom, p[1]); + } + min[0] = left; + min[1] = top; + max[0] = right; + max[1] = bottom; + } + function fromLine(x0, y0, x1, y1, min, max) { + min[0] = mathMin$1(x0, x1); + min[1] = mathMin$1(y0, y1); + max[0] = mathMax$1(x0, x1); + max[1] = mathMax$1(y0, y1); + } + var xDim = []; + var yDim = []; + function fromCubic(x0, y0, x1, y1, x2, y2, x3, y3, min, max) { + var cubicExtrema$1 = cubicExtrema; + var cubicAt$1 = cubicAt; + var n = cubicExtrema$1(x0, x1, x2, x3, xDim); + min[0] = Infinity; + min[1] = Infinity; + max[0] = -Infinity; + max[1] = -Infinity; + for (var i = 0; i < n; i++) { + var x = cubicAt$1(x0, x1, x2, x3, xDim[i]); + min[0] = mathMin$1(x, min[0]); + max[0] = mathMax$1(x, max[0]); + } + n = cubicExtrema$1(y0, y1, y2, y3, yDim); + for (var i = 0; i < n; i++) { + var y = cubicAt$1(y0, y1, y2, y3, yDim[i]); + min[1] = mathMin$1(y, min[1]); + max[1] = mathMax$1(y, max[1]); + } + min[0] = mathMin$1(x0, min[0]); + max[0] = mathMax$1(x0, max[0]); + min[0] = mathMin$1(x3, min[0]); + max[0] = mathMax$1(x3, max[0]); + min[1] = mathMin$1(y0, min[1]); + max[1] = mathMax$1(y0, max[1]); + min[1] = mathMin$1(y3, min[1]); + max[1] = mathMax$1(y3, max[1]); + } + function fromQuadratic(x0, y0, x1, y1, x2, y2, min, max) { + var quadraticExtremum$1 = quadraticExtremum; + var quadraticAt$1 = quadraticAt; + var tx = mathMax$1(mathMin$1(quadraticExtremum$1(x0, x1, x2), 1), 0); + var ty = mathMax$1(mathMin$1(quadraticExtremum$1(y0, y1, y2), 1), 0); + var x = quadraticAt$1(x0, x1, x2, tx); + var y = quadraticAt$1(y0, y1, y2, ty); + min[0] = mathMin$1(x0, x2, x); + min[1] = mathMin$1(y0, y2, y); + max[0] = mathMax$1(x0, x2, x); + max[1] = mathMax$1(y0, y2, y); + } + function fromArc(x, y, rx, ry, startAngle, endAngle, anticlockwise, min$1, max$1) { + var vec2Min = min; + var vec2Max = max; + var diff = Math.abs(startAngle - endAngle); + if (diff % PI2 < 1e-4 && diff > 1e-4) { + min$1[0] = x - rx; + min$1[1] = y - ry; + max$1[0] = x + rx; + max$1[1] = y + ry; + return; + } + start[0] = mathCos(startAngle) * rx + x; + start[1] = mathSin(startAngle) * ry + y; + end[0] = mathCos(endAngle) * rx + x; + end[1] = mathSin(endAngle) * ry + y; + vec2Min(min$1, start, end); + vec2Max(max$1, start, end); + startAngle = startAngle % (PI2); + if (startAngle < 0) { + startAngle = startAngle + PI2; + } + endAngle = endAngle % (PI2); + if (endAngle < 0) { + endAngle = endAngle + PI2; + } + if (startAngle > endAngle && !anticlockwise) { + endAngle += PI2; + } + else if (startAngle < endAngle && anticlockwise) { + startAngle += PI2; + } + if (anticlockwise) { + var tmp = endAngle; + endAngle = startAngle; + startAngle = tmp; + } + for (var angle = 0; angle < endAngle; angle += Math.PI / 2) { + if (angle > startAngle) { + extremity[0] = mathCos(angle) * rx + x; + extremity[1] = mathSin(angle) * ry + y; + vec2Min(min$1, extremity, min$1); + vec2Max(max$1, extremity, max$1); + } + } + } + + var CMD = { + M: 1, + L: 2, + C: 3, + Q: 4, + A: 5, + Z: 6, + R: 7 + }; + var tmpOutX = []; + var tmpOutY = []; + var min$1 = []; + var max$1 = []; + var min2 = []; + var max2 = []; + var mathMin$2 = Math.min; + var mathMax$2 = Math.max; + var mathCos$1 = Math.cos; + var mathSin$1 = Math.sin; + var mathAbs = Math.abs; + var PI = Math.PI; + var PI2$1 = PI * 2; + var hasTypedArray = typeof Float32Array !== 'undefined'; + var tmpAngles = []; + function modPI2(radian) { + var n = Math.round(radian / PI * 1e8) / 1e8; + return (n % 2) * PI; + } + function normalizeArcAngles(angles, anticlockwise) { + var newStartAngle = modPI2(angles[0]); + if (newStartAngle < 0) { + newStartAngle += PI2$1; + } + var delta = newStartAngle - angles[0]; + var newEndAngle = angles[1]; + newEndAngle += delta; + if (!anticlockwise && newEndAngle - newStartAngle >= PI2$1) { + newEndAngle = newStartAngle + PI2$1; + } + else if (anticlockwise && newStartAngle - newEndAngle >= PI2$1) { + newEndAngle = newStartAngle - PI2$1; + } + else if (!anticlockwise && newStartAngle > newEndAngle) { + newEndAngle = newStartAngle + (PI2$1 - modPI2(newStartAngle - newEndAngle)); + } + else if (anticlockwise && newStartAngle < newEndAngle) { + newEndAngle = newStartAngle - (PI2$1 - modPI2(newEndAngle - newStartAngle)); + } + angles[0] = newStartAngle; + angles[1] = newEndAngle; + } + var PathProxy = (function () { + function PathProxy(notSaveData) { + this.dpr = 1; + this._xi = 0; + this._yi = 0; + this._x0 = 0; + this._y0 = 0; + this._len = 0; + if (notSaveData) { + this._saveData = false; + } + if (this._saveData) { + this.data = []; + } + } + PathProxy.prototype.increaseVersion = function () { + this._version++; + }; + PathProxy.prototype.getVersion = function () { + return this._version; + }; + PathProxy.prototype.setScale = function (sx, sy, segmentIgnoreThreshold) { + segmentIgnoreThreshold = segmentIgnoreThreshold || 0; + if (segmentIgnoreThreshold > 0) { + this._ux = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sx) || 0; + this._uy = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sy) || 0; + } + }; + PathProxy.prototype.setDPR = function (dpr) { + this.dpr = dpr; + }; + PathProxy.prototype.setContext = function (ctx) { + this._ctx = ctx; + }; + PathProxy.prototype.getContext = function () { + return this._ctx; + }; + PathProxy.prototype.beginPath = function () { + this._ctx && this._ctx.beginPath(); + this.reset(); + return this; + }; + PathProxy.prototype.reset = function () { + if (this._saveData) { + this._len = 0; + } + if (this._pathSegLen) { + this._pathSegLen = null; + this._pathLen = 0; + } + this._version++; + }; + PathProxy.prototype.moveTo = function (x, y) { + this._drawPendingPt(); + this.addData(CMD.M, x, y); + this._ctx && this._ctx.moveTo(x, y); + this._x0 = x; + this._y0 = y; + this._xi = x; + this._yi = y; + return this; + }; + PathProxy.prototype.lineTo = function (x, y) { + var dx = mathAbs(x - this._xi); + var dy = mathAbs(y - this._yi); + var exceedUnit = dx > this._ux || dy > this._uy; + this.addData(CMD.L, x, y); + if (this._ctx && exceedUnit) { + this._ctx.lineTo(x, y); + } + if (exceedUnit) { + this._xi = x; + this._yi = y; + this._pendingPtDist = 0; + } + else { + var d2 = dx * dx + dy * dy; + if (d2 > this._pendingPtDist) { + this._pendingPtX = x; + this._pendingPtY = y; + this._pendingPtDist = d2; + } + } + return this; + }; + PathProxy.prototype.bezierCurveTo = function (x1, y1, x2, y2, x3, y3) { + this._drawPendingPt(); + this.addData(CMD.C, x1, y1, x2, y2, x3, y3); + if (this._ctx) { + this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); + } + this._xi = x3; + this._yi = y3; + return this; + }; + PathProxy.prototype.quadraticCurveTo = function (x1, y1, x2, y2) { + this._drawPendingPt(); + this.addData(CMD.Q, x1, y1, x2, y2); + if (this._ctx) { + this._ctx.quadraticCurveTo(x1, y1, x2, y2); + } + this._xi = x2; + this._yi = y2; + return this; + }; + PathProxy.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) { + this._drawPendingPt(); + tmpAngles[0] = startAngle; + tmpAngles[1] = endAngle; + normalizeArcAngles(tmpAngles, anticlockwise); + startAngle = tmpAngles[0]; + endAngle = tmpAngles[1]; + var delta = endAngle - startAngle; + this.addData(CMD.A, cx, cy, r, r, startAngle, delta, 0, anticlockwise ? 0 : 1); + this._ctx && this._ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise); + this._xi = mathCos$1(endAngle) * r + cx; + this._yi = mathSin$1(endAngle) * r + cy; + return this; + }; + PathProxy.prototype.arcTo = function (x1, y1, x2, y2, radius) { + this._drawPendingPt(); + if (this._ctx) { + this._ctx.arcTo(x1, y1, x2, y2, radius); + } + return this; + }; + PathProxy.prototype.rect = function (x, y, w, h) { + this._drawPendingPt(); + this._ctx && this._ctx.rect(x, y, w, h); + this.addData(CMD.R, x, y, w, h); + return this; + }; + PathProxy.prototype.closePath = function () { + this._drawPendingPt(); + this.addData(CMD.Z); + var ctx = this._ctx; + var x0 = this._x0; + var y0 = this._y0; + if (ctx) { + ctx.closePath(); + } + this._xi = x0; + this._yi = y0; + return this; + }; + PathProxy.prototype.fill = function (ctx) { + ctx && ctx.fill(); + this.toStatic(); + }; + PathProxy.prototype.stroke = function (ctx) { + ctx && ctx.stroke(); + this.toStatic(); + }; + PathProxy.prototype.len = function () { + return this._len; + }; + PathProxy.prototype.setData = function (data) { + var len = data.length; + if (!(this.data && this.data.length === len) && hasTypedArray) { + this.data = new Float32Array(len); + } + for (var i = 0; i < len; i++) { + this.data[i] = data[i]; + } + this._len = len; + }; + PathProxy.prototype.appendPath = function (path) { + if (!(path instanceof Array)) { + path = [path]; + } + var len = path.length; + var appendSize = 0; + var offset = this._len; + for (var i = 0; i < len; i++) { + appendSize += path[i].len(); + } + if (hasTypedArray && (this.data instanceof Float32Array)) { + this.data = new Float32Array(offset + appendSize); + } + for (var i = 0; i < len; i++) { + var appendPathData = path[i].data; + for (var k = 0; k < appendPathData.length; k++) { + this.data[offset++] = appendPathData[k]; + } + } + this._len = offset; + }; + PathProxy.prototype.addData = function (cmd, a, b, c, d, e, f, g, h) { + if (!this._saveData) { + return; + } + var data = this.data; + if (this._len + arguments.length > data.length) { + this._expandData(); + data = this.data; + } + for (var i = 0; i < arguments.length; i++) { + data[this._len++] = arguments[i]; + } + }; + PathProxy.prototype._drawPendingPt = function () { + if (this._pendingPtDist > 0) { + this._ctx && this._ctx.lineTo(this._pendingPtX, this._pendingPtY); + this._pendingPtDist = 0; + } + }; + PathProxy.prototype._expandData = function () { + if (!(this.data instanceof Array)) { + var newData = []; + for (var i = 0; i < this._len; i++) { + newData[i] = this.data[i]; + } + this.data = newData; + } + }; + PathProxy.prototype.toStatic = function () { + if (!this._saveData) { + return; + } + this._drawPendingPt(); + var data = this.data; + if (data instanceof Array) { + data.length = this._len; + if (hasTypedArray && this._len > 11) { + this.data = new Float32Array(data); + } + } + }; + PathProxy.prototype.getBoundingRect = function () { + min$1[0] = min$1[1] = min2[0] = min2[1] = Number.MAX_VALUE; + max$1[0] = max$1[1] = max2[0] = max2[1] = -Number.MAX_VALUE; + var data = this.data; + var xi = 0; + var yi = 0; + var x0 = 0; + var y0 = 0; + var i; + for (i = 0; i < this._len;) { + var cmd = data[i++]; + var isFirst = i === 1; + if (isFirst) { + xi = data[i]; + yi = data[i + 1]; + x0 = xi; + y0 = yi; + } + switch (cmd) { + case CMD.M: + xi = x0 = data[i++]; + yi = y0 = data[i++]; + min2[0] = x0; + min2[1] = y0; + max2[0] = x0; + max2[1] = y0; + break; + case CMD.L: + fromLine(xi, yi, data[i], data[i + 1], min2, max2); + xi = data[i++]; + yi = data[i++]; + break; + case CMD.C: + fromCubic(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], min2, max2); + xi = data[i++]; + yi = data[i++]; + break; + case CMD.Q: + fromQuadratic(xi, yi, data[i++], data[i++], data[i], data[i + 1], min2, max2); + xi = data[i++]; + yi = data[i++]; + break; + case CMD.A: + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var startAngle = data[i++]; + var endAngle = data[i++] + startAngle; + i += 1; + var anticlockwise = !data[i++]; + if (isFirst) { + x0 = mathCos$1(startAngle) * rx + cx; + y0 = mathSin$1(startAngle) * ry + cy; + } + fromArc(cx, cy, rx, ry, startAngle, endAngle, anticlockwise, min2, max2); + xi = mathCos$1(endAngle) * rx + cx; + yi = mathSin$1(endAngle) * ry + cy; + break; + case CMD.R: + x0 = xi = data[i++]; + y0 = yi = data[i++]; + var width = data[i++]; + var height = data[i++]; + fromLine(x0, y0, x0 + width, y0 + height, min2, max2); + break; + case CMD.Z: + xi = x0; + yi = y0; + break; + } + min(min$1, min$1, min2); + max(max$1, max$1, max2); + } + if (i === 0) { + min$1[0] = min$1[1] = max$1[0] = max$1[1] = 0; + } + return new BoundingRect(min$1[0], min$1[1], max$1[0] - min$1[0], max$1[1] - min$1[1]); + }; + PathProxy.prototype._calculateLength = function () { + var data = this.data; + var len = this._len; + var ux = this._ux; + var uy = this._uy; + var xi = 0; + var yi = 0; + var x0 = 0; + var y0 = 0; + if (!this._pathSegLen) { + this._pathSegLen = []; + } + var pathSegLen = this._pathSegLen; + var pathTotalLen = 0; + var segCount = 0; + for (var i = 0; i < len;) { + var cmd = data[i++]; + var isFirst = i === 1; + if (isFirst) { + xi = data[i]; + yi = data[i + 1]; + x0 = xi; + y0 = yi; + } + var l = -1; + switch (cmd) { + case CMD.M: + xi = x0 = data[i++]; + yi = y0 = data[i++]; + break; + case CMD.L: { + var x2 = data[i++]; + var y2 = data[i++]; + var dx = x2 - xi; + var dy = y2 - yi; + if (mathAbs(dx) > ux || mathAbs(dy) > uy || i === len - 1) { + l = Math.sqrt(dx * dx + dy * dy); + xi = x2; + yi = y2; + } + break; + } + case CMD.C: { + var x1 = data[i++]; + var y1 = data[i++]; + var x2 = data[i++]; + var y2 = data[i++]; + var x3 = data[i++]; + var y3 = data[i++]; + l = cubicLength(xi, yi, x1, y1, x2, y2, x3, y3, 10); + xi = x3; + yi = y3; + break; + } + case CMD.Q: { + var x1 = data[i++]; + var y1 = data[i++]; + var x2 = data[i++]; + var y2 = data[i++]; + l = quadraticLength(xi, yi, x1, y1, x2, y2, 10); + xi = x2; + yi = y2; + break; + } + case CMD.A: + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var startAngle = data[i++]; + var delta = data[i++]; + var endAngle = delta + startAngle; + i += 1; + if (isFirst) { + x0 = mathCos$1(startAngle) * rx + cx; + y0 = mathSin$1(startAngle) * ry + cy; + } + l = mathMax$2(rx, ry) * mathMin$2(PI2$1, Math.abs(delta)); + xi = mathCos$1(endAngle) * rx + cx; + yi = mathSin$1(endAngle) * ry + cy; + break; + case CMD.R: { + x0 = xi = data[i++]; + y0 = yi = data[i++]; + var width = data[i++]; + var height = data[i++]; + l = width * 2 + height * 2; + break; + } + case CMD.Z: { + var dx = x0 - xi; + var dy = y0 - yi; + l = Math.sqrt(dx * dx + dy * dy); + xi = x0; + yi = y0; + break; + } + } + if (l >= 0) { + pathSegLen[segCount++] = l; + pathTotalLen += l; + } + } + this._pathLen = pathTotalLen; + return pathTotalLen; + }; + PathProxy.prototype.rebuildPath = function (ctx, percent) { + var d = this.data; + var ux = this._ux; + var uy = this._uy; + var len = this._len; + var x0; + var y0; + var xi; + var yi; + var x; + var y; + var drawPart = percent < 1; + var pathSegLen; + var pathTotalLen; + var accumLength = 0; + var segCount = 0; + var displayedLength; + var pendingPtDist = 0; + var pendingPtX; + var pendingPtY; + if (drawPart) { + if (!this._pathSegLen) { + this._calculateLength(); + } + pathSegLen = this._pathSegLen; + pathTotalLen = this._pathLen; + displayedLength = percent * pathTotalLen; + if (!displayedLength) { + return; + } + } + lo: for (var i = 0; i < len;) { + var cmd = d[i++]; + var isFirst = i === 1; + if (isFirst) { + xi = d[i]; + yi = d[i + 1]; + x0 = xi; + y0 = yi; + } + if (cmd !== CMD.L && pendingPtDist > 0) { + ctx.lineTo(pendingPtX, pendingPtY); + pendingPtDist = 0; + } + switch (cmd) { + case CMD.M: + x0 = xi = d[i++]; + y0 = yi = d[i++]; + ctx.moveTo(xi, yi); + break; + case CMD.L: { + x = d[i++]; + y = d[i++]; + var dx = mathAbs(x - xi); + var dy = mathAbs(y - yi); + if (dx > ux || dy > uy) { + if (drawPart) { + var l = pathSegLen[segCount++]; + if (accumLength + l > displayedLength) { + var t = (displayedLength - accumLength) / l; + ctx.lineTo(xi * (1 - t) + x * t, yi * (1 - t) + y * t); + break lo; + } + accumLength += l; + } + ctx.lineTo(x, y); + xi = x; + yi = y; + pendingPtDist = 0; + } + else { + var d2 = dx * dx + dy * dy; + if (d2 > pendingPtDist) { + pendingPtX = x; + pendingPtY = y; + pendingPtDist = d2; + } + } + break; + } + case CMD.C: { + var x1 = d[i++]; + var y1 = d[i++]; + var x2 = d[i++]; + var y2 = d[i++]; + var x3 = d[i++]; + var y3 = d[i++]; + if (drawPart) { + var l = pathSegLen[segCount++]; + if (accumLength + l > displayedLength) { + var t = (displayedLength - accumLength) / l; + cubicSubdivide(xi, x1, x2, x3, t, tmpOutX); + cubicSubdivide(yi, y1, y2, y3, t, tmpOutY); + ctx.bezierCurveTo(tmpOutX[1], tmpOutY[1], tmpOutX[2], tmpOutY[2], tmpOutX[3], tmpOutY[3]); + break lo; + } + accumLength += l; + } + ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); + xi = x3; + yi = y3; + break; + } + case CMD.Q: { + var x1 = d[i++]; + var y1 = d[i++]; + var x2 = d[i++]; + var y2 = d[i++]; + if (drawPart) { + var l = pathSegLen[segCount++]; + if (accumLength + l > displayedLength) { + var t = (displayedLength - accumLength) / l; + quadraticSubdivide(xi, x1, x2, t, tmpOutX); + quadraticSubdivide(yi, y1, y2, t, tmpOutY); + ctx.quadraticCurveTo(tmpOutX[1], tmpOutY[1], tmpOutX[2], tmpOutY[2]); + break lo; + } + accumLength += l; + } + ctx.quadraticCurveTo(x1, y1, x2, y2); + xi = x2; + yi = y2; + break; + } + case CMD.A: + var cx = d[i++]; + var cy = d[i++]; + var rx = d[i++]; + var ry = d[i++]; + var startAngle = d[i++]; + var delta = d[i++]; + var psi = d[i++]; + var anticlockwise = !d[i++]; + var r = (rx > ry) ? rx : ry; + var isEllipse = mathAbs(rx - ry) > 1e-3; + var endAngle = startAngle + delta; + var breakBuild = false; + if (drawPart) { + var l = pathSegLen[segCount++]; + if (accumLength + l > displayedLength) { + endAngle = startAngle + delta * (displayedLength - accumLength) / l; + breakBuild = true; + } + accumLength += l; + } + if (isEllipse && ctx.ellipse) { + ctx.ellipse(cx, cy, rx, ry, psi, startAngle, endAngle, anticlockwise); + } + else { + ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise); + } + if (breakBuild) { + break lo; + } + if (isFirst) { + x0 = mathCos$1(startAngle) * rx + cx; + y0 = mathSin$1(startAngle) * ry + cy; + } + xi = mathCos$1(endAngle) * rx + cx; + yi = mathSin$1(endAngle) * ry + cy; + break; + case CMD.R: + x0 = xi = d[i]; + y0 = yi = d[i + 1]; + x = d[i++]; + y = d[i++]; + var width = d[i++]; + var height = d[i++]; + if (drawPart) { + var l = pathSegLen[segCount++]; + if (accumLength + l > displayedLength) { + var d_1 = displayedLength - accumLength; + ctx.moveTo(x, y); + ctx.lineTo(x + mathMin$2(d_1, width), y); + d_1 -= width; + if (d_1 > 0) { + ctx.lineTo(x + width, y + mathMin$2(d_1, height)); + } + d_1 -= height; + if (d_1 > 0) { + ctx.lineTo(x + mathMax$2(width - d_1, 0), y + height); + } + d_1 -= width; + if (d_1 > 0) { + ctx.lineTo(x, y + mathMax$2(height - d_1, 0)); + } + break lo; + } + accumLength += l; + } + ctx.rect(x, y, width, height); + break; + case CMD.Z: + if (drawPart) { + var l = pathSegLen[segCount++]; + if (accumLength + l > displayedLength) { + var t = (displayedLength - accumLength) / l; + ctx.lineTo(xi * (1 - t) + x0 * t, yi * (1 - t) + y0 * t); + break lo; + } + accumLength += l; + } + ctx.closePath(); + xi = x0; + yi = y0; + } + } + }; + PathProxy.prototype.clone = function () { + var newProxy = new PathProxy(); + var data = this.data; + newProxy.data = data.slice ? data.slice() + : Array.prototype.slice.call(data); + newProxy._len = this._len; + return newProxy; + }; + PathProxy.CMD = CMD; + PathProxy.initDefaultProps = (function () { + var proto = PathProxy.prototype; + proto._saveData = true; + proto._ux = 0; + proto._uy = 0; + proto._pendingPtDist = 0; + proto._version = 0; + })(); + return PathProxy; + }()); + + function containStroke(x0, y0, x1, y1, lineWidth, x, y) { + if (lineWidth === 0) { + return false; + } + var _l = lineWidth; + var _a = 0; + var _b = x0; + if ((y > y0 + _l && y > y1 + _l) + || (y < y0 - _l && y < y1 - _l) + || (x > x0 + _l && x > x1 + _l) + || (x < x0 - _l && x < x1 - _l)) { + return false; + } + if (x0 !== x1) { + _a = (y0 - y1) / (x0 - x1); + _b = (x0 * y1 - x1 * y0) / (x0 - x1); + } + else { + return Math.abs(x - x0) <= _l / 2; + } + var tmp = _a * x - y + _b; + var _s = tmp * tmp / (_a * _a + 1); + return _s <= _l / 2 * _l / 2; + } + + function containStroke$1(x0, y0, x1, y1, x2, y2, x3, y3, lineWidth, x, y) { + if (lineWidth === 0) { + return false; + } + var _l = lineWidth; + if ((y > y0 + _l && y > y1 + _l && y > y2 + _l && y > y3 + _l) + || (y < y0 - _l && y < y1 - _l && y < y2 - _l && y < y3 - _l) + || (x > x0 + _l && x > x1 + _l && x > x2 + _l && x > x3 + _l) + || (x < x0 - _l && x < x1 - _l && x < x2 - _l && x < x3 - _l)) { + return false; + } + var d = cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, null); + return d <= _l / 2; + } + + function containStroke$2(x0, y0, x1, y1, x2, y2, lineWidth, x, y) { + if (lineWidth === 0) { + return false; + } + var _l = lineWidth; + if ((y > y0 + _l && y > y1 + _l && y > y2 + _l) + || (y < y0 - _l && y < y1 - _l && y < y2 - _l) + || (x > x0 + _l && x > x1 + _l && x > x2 + _l) + || (x < x0 - _l && x < x1 - _l && x < x2 - _l)) { + return false; + } + var d = quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, null); + return d <= _l / 2; + } + + var PI2$2 = Math.PI * 2; + function normalizeRadian(angle) { + angle %= PI2$2; + if (angle < 0) { + angle += PI2$2; + } + return angle; + } + + var PI2$3 = Math.PI * 2; + function containStroke$3(cx, cy, r, startAngle, endAngle, anticlockwise, lineWidth, x, y) { + if (lineWidth === 0) { + return false; + } + var _l = lineWidth; + x -= cx; + y -= cy; + var d = Math.sqrt(x * x + y * y); + if ((d - _l > r) || (d + _l < r)) { + return false; + } + if (Math.abs(startAngle - endAngle) % PI2$3 < 1e-4) { + return true; + } + if (anticlockwise) { + var tmp = startAngle; + startAngle = normalizeRadian(endAngle); + endAngle = normalizeRadian(tmp); + } + else { + startAngle = normalizeRadian(startAngle); + endAngle = normalizeRadian(endAngle); + } + if (startAngle > endAngle) { + endAngle += PI2$3; + } + var angle = Math.atan2(y, x); + if (angle < 0) { + angle += PI2$3; + } + return (angle >= startAngle && angle <= endAngle) + || (angle + PI2$3 >= startAngle && angle + PI2$3 <= endAngle); + } + + function windingLine(x0, y0, x1, y1, x, y) { + if ((y > y0 && y > y1) || (y < y0 && y < y1)) { + return 0; + } + if (y1 === y0) { + return 0; + } + var t = (y - y0) / (y1 - y0); + var dir = y1 < y0 ? 1 : -1; + if (t === 1 || t === 0) { + dir = y1 < y0 ? 0.5 : -0.5; + } + var x_ = t * (x1 - x0) + x0; + return x_ === x ? Infinity : x_ > x ? dir : 0; + } + + var CMD$1 = PathProxy.CMD; + var PI2$4 = Math.PI * 2; + var EPSILON$3 = 1e-4; + function isAroundEqual(a, b) { + return Math.abs(a - b) < EPSILON$3; + } + var roots = [-1, -1, -1]; + var extrema = [-1, -1]; + function swapExtrema() { + var tmp = extrema[0]; + extrema[0] = extrema[1]; + extrema[1] = tmp; + } + function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) { + if ((y > y0 && y > y1 && y > y2 && y > y3) + || (y < y0 && y < y1 && y < y2 && y < y3)) { + return 0; + } + var nRoots = cubicRootAt(y0, y1, y2, y3, y, roots); + if (nRoots === 0) { + return 0; + } + else { + var w = 0; + var nExtrema = -1; + var y0_ = void 0; + var y1_ = void 0; + for (var i = 0; i < nRoots; i++) { + var t = roots[i]; + var unit = (t === 0 || t === 1) ? 0.5 : 1; + var x_ = cubicAt(x0, x1, x2, x3, t); + if (x_ < x) { + continue; + } + if (nExtrema < 0) { + nExtrema = cubicExtrema(y0, y1, y2, y3, extrema); + if (extrema[1] < extrema[0] && nExtrema > 1) { + swapExtrema(); + } + y0_ = cubicAt(y0, y1, y2, y3, extrema[0]); + if (nExtrema > 1) { + y1_ = cubicAt(y0, y1, y2, y3, extrema[1]); + } + } + if (nExtrema === 2) { + if (t < extrema[0]) { + w += y0_ < y0 ? unit : -unit; + } + else if (t < extrema[1]) { + w += y1_ < y0_ ? unit : -unit; + } + else { + w += y3 < y1_ ? unit : -unit; + } + } + else { + if (t < extrema[0]) { + w += y0_ < y0 ? unit : -unit; + } + else { + w += y3 < y0_ ? unit : -unit; + } + } + } + return w; + } + } + function windingQuadratic(x0, y0, x1, y1, x2, y2, x, y) { + if ((y > y0 && y > y1 && y > y2) + || (y < y0 && y < y1 && y < y2)) { + return 0; + } + var nRoots = quadraticRootAt(y0, y1, y2, y, roots); + if (nRoots === 0) { + return 0; + } + else { + var t = quadraticExtremum(y0, y1, y2); + if (t >= 0 && t <= 1) { + var w = 0; + var y_ = quadraticAt(y0, y1, y2, t); + for (var i = 0; i < nRoots; i++) { + var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1; + var x_ = quadraticAt(x0, x1, x2, roots[i]); + if (x_ < x) { + continue; + } + if (roots[i] < t) { + w += y_ < y0 ? unit : -unit; + } + else { + w += y2 < y_ ? unit : -unit; + } + } + return w; + } + else { + var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1; + var x_ = quadraticAt(x0, x1, x2, roots[0]); + if (x_ < x) { + return 0; + } + return y2 < y0 ? unit : -unit; + } + } + } + function windingArc(cx, cy, r, startAngle, endAngle, anticlockwise, x, y) { + y -= cy; + if (y > r || y < -r) { + return 0; + } + var tmp = Math.sqrt(r * r - y * y); + roots[0] = -tmp; + roots[1] = tmp; + var dTheta = Math.abs(startAngle - endAngle); + if (dTheta < 1e-4) { + return 0; + } + if (dTheta >= PI2$4 - 1e-4) { + startAngle = 0; + endAngle = PI2$4; + var dir = anticlockwise ? 1 : -1; + if (x >= roots[0] + cx && x <= roots[1] + cx) { + return dir; + } + else { + return 0; + } + } + if (startAngle > endAngle) { + var tmp_1 = startAngle; + startAngle = endAngle; + endAngle = tmp_1; + } + if (startAngle < 0) { + startAngle += PI2$4; + endAngle += PI2$4; + } + var w = 0; + for (var i = 0; i < 2; i++) { + var x_ = roots[i]; + if (x_ + cx > x) { + var angle = Math.atan2(y, x_); + var dir = anticlockwise ? 1 : -1; + if (angle < 0) { + angle = PI2$4 + angle; + } + if ((angle >= startAngle && angle <= endAngle) + || (angle + PI2$4 >= startAngle && angle + PI2$4 <= endAngle)) { + if (angle > Math.PI / 2 && angle < Math.PI * 1.5) { + dir = -dir; + } + w += dir; + } + } + } + return w; + } + function containPath(path, lineWidth, isStroke, x, y) { + var data = path.data; + var len = path.len(); + var w = 0; + var xi = 0; + var yi = 0; + var x0 = 0; + var y0 = 0; + var x1; + var y1; + for (var i = 0; i < len;) { + var cmd = data[i++]; + var isFirst = i === 1; + if (cmd === CMD$1.M && i > 1) { + if (!isStroke) { + w += windingLine(xi, yi, x0, y0, x, y); + } + } + if (isFirst) { + xi = data[i]; + yi = data[i + 1]; + x0 = xi; + y0 = yi; + } + switch (cmd) { + case CMD$1.M: + x0 = data[i++]; + y0 = data[i++]; + xi = x0; + yi = y0; + break; + case CMD$1.L: + if (isStroke) { + if (containStroke(xi, yi, data[i], data[i + 1], lineWidth, x, y)) { + return true; + } + } + else { + w += windingLine(xi, yi, data[i], data[i + 1], x, y) || 0; + } + xi = data[i++]; + yi = data[i++]; + break; + case CMD$1.C: + if (isStroke) { + if (containStroke$1(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], lineWidth, x, y)) { + return true; + } + } + else { + w += windingCubic(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], x, y) || 0; + } + xi = data[i++]; + yi = data[i++]; + break; + case CMD$1.Q: + if (isStroke) { + if (containStroke$2(xi, yi, data[i++], data[i++], data[i], data[i + 1], lineWidth, x, y)) { + return true; + } + } + else { + w += windingQuadratic(xi, yi, data[i++], data[i++], data[i], data[i + 1], x, y) || 0; + } + xi = data[i++]; + yi = data[i++]; + break; + case CMD$1.A: + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var theta = data[i++]; + var dTheta = data[i++]; + i += 1; + var anticlockwise = !!(1 - data[i++]); + x1 = Math.cos(theta) * rx + cx; + y1 = Math.sin(theta) * ry + cy; + if (!isFirst) { + w += windingLine(xi, yi, x1, y1, x, y); + } + else { + x0 = x1; + y0 = y1; + } + var _x = (x - cx) * ry / rx + cx; + if (isStroke) { + if (containStroke$3(cx, cy, ry, theta, theta + dTheta, anticlockwise, lineWidth, _x, y)) { + return true; + } + } + else { + w += windingArc(cx, cy, ry, theta, theta + dTheta, anticlockwise, _x, y); + } + xi = Math.cos(theta + dTheta) * rx + cx; + yi = Math.sin(theta + dTheta) * ry + cy; + break; + case CMD$1.R: + x0 = xi = data[i++]; + y0 = yi = data[i++]; + var width = data[i++]; + var height = data[i++]; + x1 = x0 + width; + y1 = y0 + height; + if (isStroke) { + if (containStroke(x0, y0, x1, y0, lineWidth, x, y) + || containStroke(x1, y0, x1, y1, lineWidth, x, y) + || containStroke(x1, y1, x0, y1, lineWidth, x, y) + || containStroke(x0, y1, x0, y0, lineWidth, x, y)) { + return true; + } + } + else { + w += windingLine(x1, y0, x1, y1, x, y); + w += windingLine(x0, y1, x0, y0, x, y); + } + break; + case CMD$1.Z: + if (isStroke) { + if (containStroke(xi, yi, x0, y0, lineWidth, x, y)) { + return true; + } + } + else { + w += windingLine(xi, yi, x0, y0, x, y); + } + xi = x0; + yi = y0; + break; + } + } + if (!isStroke && !isAroundEqual(yi, y0)) { + w += windingLine(xi, yi, x0, y0, x, y) || 0; + } + return w !== 0; + } + function contain(pathProxy, x, y) { + return containPath(pathProxy, 0, false, x, y); + } + function containStroke$4(pathProxy, lineWidth, x, y) { + return containPath(pathProxy, lineWidth, true, x, y); + } + + var DEFAULT_PATH_STYLE = defaults({ + fill: '#000', + stroke: null, + strokePercent: 1, + fillOpacity: 1, + strokeOpacity: 1, + lineDashOffset: 0, + lineWidth: 1, + lineCap: 'butt', + miterLimit: 10, + strokeNoScale: false, + strokeFirst: false + }, DEFAULT_COMMON_STYLE); + var DEFAULT_PATH_ANIMATION_PROPS = { + style: defaults({ + fill: true, + stroke: true, + strokePercent: true, + fillOpacity: true, + strokeOpacity: true, + lineDashOffset: true, + lineWidth: true, + miterLimit: true + }, DEFAULT_COMMON_ANIMATION_PROPS.style) + }; + var pathCopyParams = TRANSFORMABLE_PROPS.concat(['invisible', + 'culling', 'z', 'z2', 'zlevel', 'parent' + ]); + var Path = (function (_super) { + __extends(Path, _super); + function Path(opts) { + return _super.call(this, opts) || this; + } + Path.prototype.update = function () { + var _this = this; + _super.prototype.update.call(this); + var style = this.style; + if (style.decal) { + var decalEl = this._decalEl = this._decalEl || new Path(); + if (decalEl.buildPath === Path.prototype.buildPath) { + decalEl.buildPath = function (ctx) { + _this.buildPath(ctx, _this.shape); + }; + } + decalEl.silent = true; + var decalElStyle = decalEl.style; + for (var key in style) { + if (decalElStyle[key] !== style[key]) { + decalElStyle[key] = style[key]; + } + } + decalElStyle.fill = style.fill ? style.decal : null; + decalElStyle.decal = null; + decalElStyle.shadowColor = null; + style.strokeFirst && (decalElStyle.stroke = null); + for (var i = 0; i < pathCopyParams.length; ++i) { + decalEl[pathCopyParams[i]] = this[pathCopyParams[i]]; + } + decalEl.__dirty |= REDRAW_BIT; + } + else if (this._decalEl) { + this._decalEl = null; + } + }; + Path.prototype.getDecalElement = function () { + return this._decalEl; + }; + Path.prototype._init = function (props) { + var keysArr = keys(props); + this.shape = this.getDefaultShape(); + var defaultStyle = this.getDefaultStyle(); + if (defaultStyle) { + this.useStyle(defaultStyle); + } + for (var i = 0; i < keysArr.length; i++) { + var key = keysArr[i]; + var value = props[key]; + if (key === 'style') { + if (!this.style) { + this.useStyle(value); + } + else { + extend(this.style, value); + } + } + else if (key === 'shape') { + extend(this.shape, value); + } + else { + _super.prototype.attrKV.call(this, key, value); + } + } + if (!this.style) { + this.useStyle({}); + } + }; + Path.prototype.getDefaultStyle = function () { + return null; + }; + Path.prototype.getDefaultShape = function () { + return {}; + }; + Path.prototype.canBeInsideText = function () { + return this.hasFill(); + }; + Path.prototype.getInsideTextFill = function () { + var pathFill = this.style.fill; + if (pathFill !== 'none') { + if (isString(pathFill)) { + var fillLum = lum(pathFill, 0); + if (fillLum > 0.5) { + return DARK_LABEL_COLOR; + } + else if (fillLum > 0.2) { + return LIGHTER_LABEL_COLOR; + } + return LIGHT_LABEL_COLOR; + } + else if (pathFill) { + return LIGHT_LABEL_COLOR; + } + } + return DARK_LABEL_COLOR; + }; + Path.prototype.getInsideTextStroke = function (textFill) { + var pathFill = this.style.fill; + if (isString(pathFill)) { + var zr = this.__zr; + var isDarkMode = !!(zr && zr.isDarkMode()); + var isDarkLabel = lum(textFill, 0) < DARK_MODE_THRESHOLD; + if (isDarkMode === isDarkLabel) { + return pathFill; + } + } + }; + Path.prototype.buildPath = function (ctx, shapeCfg, inBatch) { }; + Path.prototype.pathUpdated = function () { + this.__dirty &= ~SHAPE_CHANGED_BIT; + }; + Path.prototype.getUpdatedPathProxy = function (inBatch) { + !this.path && this.createPathProxy(); + this.path.beginPath(); + this.buildPath(this.path, this.shape, inBatch); + return this.path; + }; + Path.prototype.createPathProxy = function () { + this.path = new PathProxy(false); + }; + Path.prototype.hasStroke = function () { + var style = this.style; + var stroke = style.stroke; + return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0)); + }; + Path.prototype.hasFill = function () { + var style = this.style; + var fill = style.fill; + return fill != null && fill !== 'none'; + }; + Path.prototype.getBoundingRect = function () { + var rect = this._rect; + var style = this.style; + var needsUpdateRect = !rect; + if (needsUpdateRect) { + var firstInvoke = false; + if (!this.path) { + firstInvoke = true; + this.createPathProxy(); + } + var path = this.path; + if (firstInvoke || (this.__dirty & SHAPE_CHANGED_BIT)) { + path.beginPath(); + this.buildPath(path, this.shape, false); + this.pathUpdated(); + } + rect = path.getBoundingRect(); + } + this._rect = rect; + if (this.hasStroke() && this.path && this.path.len() > 0) { + var rectStroke = this._rectStroke || (this._rectStroke = rect.clone()); + if (this.__dirty || needsUpdateRect) { + rectStroke.copy(rect); + var lineScale = style.strokeNoScale ? this.getLineScale() : 1; + var w = style.lineWidth; + if (!this.hasFill()) { + var strokeContainThreshold = this.strokeContainThreshold; + w = Math.max(w, strokeContainThreshold == null ? 4 : strokeContainThreshold); + } + if (lineScale > 1e-10) { + rectStroke.width += w / lineScale; + rectStroke.height += w / lineScale; + rectStroke.x -= w / lineScale / 2; + rectStroke.y -= w / lineScale / 2; + } + } + return rectStroke; + } + return rect; + }; + Path.prototype.contain = function (x, y) { + var localPos = this.transformCoordToLocal(x, y); + var rect = this.getBoundingRect(); + var style = this.style; + x = localPos[0]; + y = localPos[1]; + if (rect.contain(x, y)) { + var pathProxy = this.path; + if (this.hasStroke()) { + var lineWidth = style.lineWidth; + var lineScale = style.strokeNoScale ? this.getLineScale() : 1; + if (lineScale > 1e-10) { + if (!this.hasFill()) { + lineWidth = Math.max(lineWidth, this.strokeContainThreshold); + } + if (containStroke$4(pathProxy, lineWidth / lineScale, x, y)) { + return true; + } + } + } + if (this.hasFill()) { + return contain(pathProxy, x, y); + } + } + return false; + }; + Path.prototype.dirtyShape = function () { + this.__dirty |= SHAPE_CHANGED_BIT; + if (this._rect) { + this._rect = null; + } + if (this._decalEl) { + this._decalEl.dirtyShape(); + } + this.markRedraw(); + }; + Path.prototype.dirty = function () { + this.dirtyStyle(); + this.dirtyShape(); + }; + Path.prototype.animateShape = function (loop) { + return this.animate('shape', loop); + }; + Path.prototype.updateDuringAnimation = function (targetKey) { + if (targetKey === 'style') { + this.dirtyStyle(); + } + else if (targetKey === 'shape') { + this.dirtyShape(); + } + else { + this.markRedraw(); + } + }; + Path.prototype.attrKV = function (key, value) { + if (key === 'shape') { + this.setShape(value); + } + else { + _super.prototype.attrKV.call(this, key, value); + } + }; + Path.prototype.setShape = function (keyOrObj, value) { + var shape = this.shape; + if (!shape) { + shape = this.shape = {}; + } + if (typeof keyOrObj === 'string') { + shape[keyOrObj] = value; + } + else { + extend(shape, keyOrObj); + } + this.dirtyShape(); + return this; + }; + Path.prototype.shapeChanged = function () { + return !!(this.__dirty & SHAPE_CHANGED_BIT); + }; + Path.prototype.createStyle = function (obj) { + return createObject(DEFAULT_PATH_STYLE, obj); + }; + Path.prototype._innerSaveToNormal = function (toState) { + _super.prototype._innerSaveToNormal.call(this, toState); + var normalState = this._normalState; + if (toState.shape && !normalState.shape) { + normalState.shape = extend({}, this.shape); + } + }; + Path.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) { + _super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg); + var needsRestoreToNormal = !(state && keepCurrentStates); + var targetShape; + if (state && state.shape) { + if (transition) { + if (keepCurrentStates) { + targetShape = state.shape; + } + else { + targetShape = extend({}, normalState.shape); + extend(targetShape, state.shape); + } + } + else { + targetShape = extend({}, keepCurrentStates ? this.shape : normalState.shape); + extend(targetShape, state.shape); + } + } + else if (needsRestoreToNormal) { + targetShape = normalState.shape; + } + if (targetShape) { + if (transition) { + this.shape = extend({}, this.shape); + var targetShapePrimaryProps = {}; + var shapeKeys = keys(targetShape); + for (var i = 0; i < shapeKeys.length; i++) { + var key = shapeKeys[i]; + if (typeof targetShape[key] === 'object') { + this.shape[key] = targetShape[key]; + } + else { + targetShapePrimaryProps[key] = targetShape[key]; + } + } + this._transitionState(stateName, { + shape: targetShapePrimaryProps + }, animationCfg); + } + else { + this.shape = targetShape; + this.dirtyShape(); + } + } + }; + Path.prototype._mergeStates = function (states) { + var mergedState = _super.prototype._mergeStates.call(this, states); + var mergedShape; + for (var i = 0; i < states.length; i++) { + var state = states[i]; + if (state.shape) { + mergedShape = mergedShape || {}; + this._mergeStyle(mergedShape, state.shape); + } + } + if (mergedShape) { + mergedState.shape = mergedShape; + } + return mergedState; + }; + Path.prototype.getAnimationStyleProps = function () { + return DEFAULT_PATH_ANIMATION_PROPS; + }; + Path.prototype.isZeroArea = function () { + return false; + }; + Path.extend = function (defaultProps) { + var Sub = (function (_super) { + __extends(Sub, _super); + function Sub(opts) { + var _this = _super.call(this, opts) || this; + defaultProps.init && defaultProps.init.call(_this, opts); + return _this; + } + Sub.prototype.getDefaultStyle = function () { + return clone(defaultProps.style); + }; + Sub.prototype.getDefaultShape = function () { + return clone(defaultProps.shape); + }; + return Sub; + }(Path)); + for (var key in defaultProps) { + if (typeof defaultProps[key] === 'function') { + Sub.prototype[key] = defaultProps[key]; + } + } + return Sub; + }; + Path.initDefaultProps = (function () { + var pathProto = Path.prototype; + pathProto.type = 'path'; + pathProto.strokeContainThreshold = 5; + pathProto.segmentIgnoreThreshold = 0; + pathProto.subPixelOptimize = false; + pathProto.autoBatch = false; + pathProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT | SHAPE_CHANGED_BIT; + })(); + return Path; + }(Displayable)); + + var DEFAULT_TSPAN_STYLE = defaults({ + strokeFirst: true, + font: DEFAULT_FONT, + x: 0, + y: 0, + textAlign: 'left', + textBaseline: 'top', + miterLimit: 2 + }, DEFAULT_PATH_STYLE); + var TSpan = (function (_super) { + __extends(TSpan, _super); + function TSpan() { + return _super !== null && _super.apply(this, arguments) || this; + } + TSpan.prototype.hasStroke = function () { + var style = this.style; + var stroke = style.stroke; + return stroke != null && stroke !== 'none' && style.lineWidth > 0; + }; + TSpan.prototype.hasFill = function () { + var style = this.style; + var fill = style.fill; + return fill != null && fill !== 'none'; + }; + TSpan.prototype.createStyle = function (obj) { + return createObject(DEFAULT_TSPAN_STYLE, obj); + }; + TSpan.prototype.setBoundingRect = function (rect) { + this._rect = rect; + }; + TSpan.prototype.getBoundingRect = function () { + var style = this.style; + if (!this._rect) { + var text = style.text; + text != null ? (text += '') : (text = ''); + var rect = getBoundingRect(text, style.font, style.textAlign, style.textBaseline); + rect.x += style.x || 0; + rect.y += style.y || 0; + if (this.hasStroke()) { + var w = style.lineWidth; + rect.x -= w / 2; + rect.y -= w / 2; + rect.width += w; + rect.height += w; + } + this._rect = rect; + } + return this._rect; + }; + TSpan.initDefaultProps = (function () { + var tspanProto = TSpan.prototype; + tspanProto.dirtyRectTolerance = 10; + })(); + return TSpan; + }(Displayable)); + TSpan.prototype.type = 'tspan'; + + var DEFAULT_IMAGE_STYLE = defaults({ + x: 0, + y: 0 + }, DEFAULT_COMMON_STYLE); + var DEFAULT_IMAGE_ANIMATION_PROPS = { + style: defaults({ + x: true, + y: true, + width: true, + height: true, + sx: true, + sy: true, + sWidth: true, + sHeight: true + }, DEFAULT_COMMON_ANIMATION_PROPS.style) + }; + function isImageLike(source) { + return !!(source + && typeof source !== 'string' + && source.width && source.height); + } + var ZRImage = (function (_super) { + __extends(ZRImage, _super); + function ZRImage() { + return _super !== null && _super.apply(this, arguments) || this; + } + ZRImage.prototype.createStyle = function (obj) { + return createObject(DEFAULT_IMAGE_STYLE, obj); + }; + ZRImage.prototype._getSize = function (dim) { + var style = this.style; + var size = style[dim]; + if (size != null) { + return size; + } + var imageSource = isImageLike(style.image) + ? style.image : this.__image; + if (!imageSource) { + return 0; + } + var otherDim = dim === 'width' ? 'height' : 'width'; + var otherDimSize = style[otherDim]; + if (otherDimSize == null) { + return imageSource[dim]; + } + else { + return imageSource[dim] / imageSource[otherDim] * otherDimSize; + } + }; + ZRImage.prototype.getWidth = function () { + return this._getSize('width'); + }; + ZRImage.prototype.getHeight = function () { + return this._getSize('height'); + }; + ZRImage.prototype.getAnimationStyleProps = function () { + return DEFAULT_IMAGE_ANIMATION_PROPS; + }; + ZRImage.prototype.getBoundingRect = function () { + var style = this.style; + if (!this._rect) { + this._rect = new BoundingRect(style.x || 0, style.y || 0, this.getWidth(), this.getHeight()); + } + return this._rect; + }; + return ZRImage; + }(Displayable)); + ZRImage.prototype.type = 'image'; + + function buildPath(ctx, shape) { + var x = shape.x; + var y = shape.y; + var width = shape.width; + var height = shape.height; + var r = shape.r; + var r1; + var r2; + var r3; + var r4; + if (width < 0) { + x = x + width; + width = -width; + } + if (height < 0) { + y = y + height; + height = -height; + } + if (typeof r === 'number') { + r1 = r2 = r3 = r4 = r; + } + else if (r instanceof Array) { + if (r.length === 1) { + r1 = r2 = r3 = r4 = r[0]; + } + else if (r.length === 2) { + r1 = r3 = r[0]; + r2 = r4 = r[1]; + } + else if (r.length === 3) { + r1 = r[0]; + r2 = r4 = r[1]; + r3 = r[2]; + } + else { + r1 = r[0]; + r2 = r[1]; + r3 = r[2]; + r4 = r[3]; + } + } + else { + r1 = r2 = r3 = r4 = 0; + } + var total; + if (r1 + r2 > width) { + total = r1 + r2; + r1 *= width / total; + r2 *= width / total; + } + if (r3 + r4 > width) { + total = r3 + r4; + r3 *= width / total; + r4 *= width / total; + } + if (r2 + r3 > height) { + total = r2 + r3; + r2 *= height / total; + r3 *= height / total; + } + if (r1 + r4 > height) { + total = r1 + r4; + r1 *= height / total; + r4 *= height / total; + } + ctx.moveTo(x + r1, y); + ctx.lineTo(x + width - r2, y); + r2 !== 0 && ctx.arc(x + width - r2, y + r2, r2, -Math.PI / 2, 0); + ctx.lineTo(x + width, y + height - r3); + r3 !== 0 && ctx.arc(x + width - r3, y + height - r3, r3, 0, Math.PI / 2); + ctx.lineTo(x + r4, y + height); + r4 !== 0 && ctx.arc(x + r4, y + height - r4, r4, Math.PI / 2, Math.PI); + ctx.lineTo(x, y + r1); + r1 !== 0 && ctx.arc(x + r1, y + r1, r1, Math.PI, Math.PI * 1.5); + } + + var round$1 = Math.round; + function subPixelOptimizeLine(outputShape, inputShape, style) { + if (!inputShape) { + return; + } + var x1 = inputShape.x1; + var x2 = inputShape.x2; + var y1 = inputShape.y1; + var y2 = inputShape.y2; + outputShape.x1 = x1; + outputShape.x2 = x2; + outputShape.y1 = y1; + outputShape.y2 = y2; + var lineWidth = style && style.lineWidth; + if (!lineWidth) { + return outputShape; + } + if (round$1(x1 * 2) === round$1(x2 * 2)) { + outputShape.x1 = outputShape.x2 = subPixelOptimize(x1, lineWidth, true); + } + if (round$1(y1 * 2) === round$1(y2 * 2)) { + outputShape.y1 = outputShape.y2 = subPixelOptimize(y1, lineWidth, true); + } + return outputShape; + } + function subPixelOptimizeRect(outputShape, inputShape, style) { + if (!inputShape) { + return; + } + var originX = inputShape.x; + var originY = inputShape.y; + var originWidth = inputShape.width; + var originHeight = inputShape.height; + outputShape.x = originX; + outputShape.y = originY; + outputShape.width = originWidth; + outputShape.height = originHeight; + var lineWidth = style && style.lineWidth; + if (!lineWidth) { + return outputShape; + } + outputShape.x = subPixelOptimize(originX, lineWidth, true); + outputShape.y = subPixelOptimize(originY, lineWidth, true); + outputShape.width = Math.max(subPixelOptimize(originX + originWidth, lineWidth, false) - outputShape.x, originWidth === 0 ? 0 : 1); + outputShape.height = Math.max(subPixelOptimize(originY + originHeight, lineWidth, false) - outputShape.y, originHeight === 0 ? 0 : 1); + return outputShape; + } + function subPixelOptimize(position, lineWidth, positiveOrNegative) { + if (!lineWidth) { + return position; + } + var doubledPosition = round$1(position * 2); + return (doubledPosition + round$1(lineWidth)) % 2 === 0 + ? doubledPosition / 2 + : (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2; + } + + var RectShape = (function () { + function RectShape() { + this.x = 0; + this.y = 0; + this.width = 0; + this.height = 0; + } + return RectShape; + }()); + var subPixelOptimizeOutputShape = {}; + var Rect = (function (_super) { + __extends(Rect, _super); + function Rect(opts) { + return _super.call(this, opts) || this; + } + Rect.prototype.getDefaultShape = function () { + return new RectShape(); + }; + Rect.prototype.buildPath = function (ctx, shape) { + var x; + var y; + var width; + var height; + if (this.subPixelOptimize) { + var optimizedShape = subPixelOptimizeRect(subPixelOptimizeOutputShape, shape, this.style); + x = optimizedShape.x; + y = optimizedShape.y; + width = optimizedShape.width; + height = optimizedShape.height; + optimizedShape.r = shape.r; + shape = optimizedShape; + } + else { + x = shape.x; + y = shape.y; + width = shape.width; + height = shape.height; + } + if (!shape.r) { + ctx.rect(x, y, width, height); + } + else { + buildPath(ctx, shape); + } + }; + Rect.prototype.isZeroArea = function () { + return !this.shape.width || !this.shape.height; + }; + return Rect; + }(Path)); + Rect.prototype.type = 'rect'; + + var DEFAULT_RICH_TEXT_COLOR = { + fill: '#000' + }; + var DEFAULT_STROKE_LINE_WIDTH = 2; + var DEFAULT_TEXT_ANIMATION_PROPS = { + style: defaults({ + fill: true, + stroke: true, + fillOpacity: true, + strokeOpacity: true, + lineWidth: true, + fontSize: true, + lineHeight: true, + width: true, + height: true, + textShadowColor: true, + textShadowBlur: true, + textShadowOffsetX: true, + textShadowOffsetY: true, + backgroundColor: true, + padding: true, + borderColor: true, + borderWidth: true, + borderRadius: true + }, DEFAULT_COMMON_ANIMATION_PROPS.style) + }; + var ZRText = (function (_super) { + __extends(ZRText, _super); + function ZRText(opts) { + var _this = _super.call(this) || this; + _this.type = 'text'; + _this._children = []; + _this._defaultStyle = DEFAULT_RICH_TEXT_COLOR; + _this.attr(opts); + return _this; + } + ZRText.prototype.childrenRef = function () { + return this._children; + }; + ZRText.prototype.update = function () { + _super.prototype.update.call(this); + if (this.styleChanged()) { + this._updateSubTexts(); + } + for (var i = 0; i < this._children.length; i++) { + var child = this._children[i]; + child.zlevel = this.zlevel; + child.z = this.z; + child.z2 = this.z2; + child.culling = this.culling; + child.cursor = this.cursor; + child.invisible = this.invisible; + } + }; + ZRText.prototype.updateTransform = function () { + var innerTransformable = this.innerTransformable; + if (innerTransformable) { + innerTransformable.updateTransform(); + if (innerTransformable.transform) { + this.transform = innerTransformable.transform; + } + } + else { + _super.prototype.updateTransform.call(this); + } + }; + ZRText.prototype.getLocalTransform = function (m) { + var innerTransformable = this.innerTransformable; + return innerTransformable + ? innerTransformable.getLocalTransform(m) + : _super.prototype.getLocalTransform.call(this, m); + }; + ZRText.prototype.getComputedTransform = function () { + if (this.__hostTarget) { + this.__hostTarget.getComputedTransform(); + this.__hostTarget.updateInnerText(true); + } + return _super.prototype.getComputedTransform.call(this); + }; + ZRText.prototype._updateSubTexts = function () { + this._childCursor = 0; + normalizeTextStyle(this.style); + this.style.rich + ? this._updateRichTexts() + : this._updatePlainTexts(); + this._children.length = this._childCursor; + this.styleUpdated(); + }; + ZRText.prototype.addSelfToZr = function (zr) { + _super.prototype.addSelfToZr.call(this, zr); + for (var i = 0; i < this._children.length; i++) { + this._children[i].__zr = zr; + } + }; + ZRText.prototype.removeSelfFromZr = function (zr) { + _super.prototype.removeSelfFromZr.call(this, zr); + for (var i = 0; i < this._children.length; i++) { + this._children[i].__zr = null; + } + }; + ZRText.prototype.getBoundingRect = function () { + if (this.styleChanged()) { + this._updateSubTexts(); + } + if (!this._rect) { + var tmpRect = new BoundingRect(0, 0, 0, 0); + var children = this._children; + var tmpMat = []; + var rect = null; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + var childRect = child.getBoundingRect(); + var transform = child.getLocalTransform(tmpMat); + if (transform) { + tmpRect.copy(childRect); + tmpRect.applyTransform(transform); + rect = rect || tmpRect.clone(); + rect.union(tmpRect); + } + else { + rect = rect || childRect.clone(); + rect.union(childRect); + } + } + this._rect = rect || tmpRect; + } + return this._rect; + }; + ZRText.prototype.setDefaultTextStyle = function (defaultTextStyle) { + this._defaultStyle = defaultTextStyle || DEFAULT_RICH_TEXT_COLOR; + }; + ZRText.prototype.setTextContent = function (textContent) { + if ("development" !== 'production') { + throw new Error('Can\'t attach text on another text'); + } + }; + ZRText.prototype._mergeStyle = function (targetStyle, sourceStyle) { + if (!sourceStyle) { + return targetStyle; + } + var sourceRich = sourceStyle.rich; + var targetRich = targetStyle.rich || (sourceRich && {}); + extend(targetStyle, sourceStyle); + if (sourceRich && targetRich) { + this._mergeRich(targetRich, sourceRich); + targetStyle.rich = targetRich; + } + else if (targetRich) { + targetStyle.rich = targetRich; + } + return targetStyle; + }; + ZRText.prototype._mergeRich = function (targetRich, sourceRich) { + var richNames = keys(sourceRich); + for (var i = 0; i < richNames.length; i++) { + var richName = richNames[i]; + targetRich[richName] = targetRich[richName] || {}; + extend(targetRich[richName], sourceRich[richName]); + } + }; + ZRText.prototype.getAnimationStyleProps = function () { + return DEFAULT_TEXT_ANIMATION_PROPS; + }; + ZRText.prototype._getOrCreateChild = function (Ctor) { + var child = this._children[this._childCursor]; + if (!child || !(child instanceof Ctor)) { + child = new Ctor(); + } + this._children[this._childCursor++] = child; + child.__zr = this.__zr; + child.parent = this; + return child; + }; + ZRText.prototype._updatePlainTexts = function () { + var style = this.style; + var textFont = style.font || DEFAULT_FONT; + var textPadding = style.padding; + var text = getStyleText(style); + var contentBlock = parsePlainText(text, style); + var needDrawBg = needDrawBackground(style); + var bgColorDrawn = !!(style.backgroundColor); + var outerHeight = contentBlock.outerHeight; + var outerWidth = contentBlock.outerWidth; + var contentWidth = contentBlock.contentWidth; + var textLines = contentBlock.lines; + var lineHeight = contentBlock.lineHeight; + var defaultStyle = this._defaultStyle; + var baseX = style.x || 0; + var baseY = style.y || 0; + var textAlign = style.align || defaultStyle.align || 'left'; + var verticalAlign = style.verticalAlign || defaultStyle.verticalAlign || 'top'; + var textX = baseX; + var textY = adjustTextY$1(baseY, contentBlock.contentHeight, verticalAlign); + if (needDrawBg || textPadding) { + var boxX = adjustTextX(baseX, outerWidth, textAlign); + var boxY = adjustTextY$1(baseY, outerHeight, verticalAlign); + needDrawBg && this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight); + } + textY += lineHeight / 2; + if (textPadding) { + textX = getTextXForPadding(baseX, textAlign, textPadding); + if (verticalAlign === 'top') { + textY += textPadding[0]; + } + else if (verticalAlign === 'bottom') { + textY -= textPadding[2]; + } + } + var defaultLineWidth = 0; + var useDefaultFill = false; + var textFill = getFill('fill' in style + ? style.fill + : (useDefaultFill = true, defaultStyle.fill)); + var textStroke = getStroke('stroke' in style + ? style.stroke + : (!bgColorDrawn + && (!defaultStyle.autoStroke || useDefaultFill)) + ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke) + : null); + var hasShadow = style.textShadowBlur > 0; + var fixedBoundingRect = style.width != null + && (style.overflow === 'truncate' || style.overflow === 'break' || style.overflow === 'breakAll'); + var calculatedLineHeight = contentBlock.calculatedLineHeight; + for (var i = 0; i < textLines.length; i++) { + var el = this._getOrCreateChild(TSpan); + var subElStyle = el.createStyle(); + el.useStyle(subElStyle); + subElStyle.text = textLines[i]; + subElStyle.x = textX; + subElStyle.y = textY; + if (textAlign) { + subElStyle.textAlign = textAlign; + } + subElStyle.textBaseline = 'middle'; + subElStyle.opacity = style.opacity; + subElStyle.strokeFirst = true; + if (hasShadow) { + subElStyle.shadowBlur = style.textShadowBlur || 0; + subElStyle.shadowColor = style.textShadowColor || 'transparent'; + subElStyle.shadowOffsetX = style.textShadowOffsetX || 0; + subElStyle.shadowOffsetY = style.textShadowOffsetY || 0; + } + subElStyle.stroke = textStroke; + subElStyle.fill = textFill; + if (textStroke) { + subElStyle.lineWidth = style.lineWidth || defaultLineWidth; + subElStyle.lineDash = style.lineDash; + subElStyle.lineDashOffset = style.lineDashOffset || 0; + } + subElStyle.font = textFont; + setSeparateFont(subElStyle, style); + textY += lineHeight; + if (fixedBoundingRect) { + el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, style.width, subElStyle.textAlign), adjustTextY$1(subElStyle.y, calculatedLineHeight, subElStyle.textBaseline), contentWidth, calculatedLineHeight)); + } + } + }; + ZRText.prototype._updateRichTexts = function () { + var style = this.style; + var text = getStyleText(style); + var contentBlock = parseRichText(text, style); + var contentWidth = contentBlock.width; + var outerWidth = contentBlock.outerWidth; + var outerHeight = contentBlock.outerHeight; + var textPadding = style.padding; + var baseX = style.x || 0; + var baseY = style.y || 0; + var defaultStyle = this._defaultStyle; + var textAlign = style.align || defaultStyle.align; + var verticalAlign = style.verticalAlign || defaultStyle.verticalAlign; + var boxX = adjustTextX(baseX, outerWidth, textAlign); + var boxY = adjustTextY$1(baseY, outerHeight, verticalAlign); + var xLeft = boxX; + var lineTop = boxY; + if (textPadding) { + xLeft += textPadding[3]; + lineTop += textPadding[0]; + } + var xRight = xLeft + contentWidth; + if (needDrawBackground(style)) { + this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight); + } + var bgColorDrawn = !!(style.backgroundColor); + for (var i = 0; i < contentBlock.lines.length; i++) { + var line = contentBlock.lines[i]; + var tokens = line.tokens; + var tokenCount = tokens.length; + var lineHeight = line.lineHeight; + var remainedWidth = line.width; + var leftIndex = 0; + var lineXLeft = xLeft; + var lineXRight = xRight; + var rightIndex = tokenCount - 1; + var token = void 0; + while (leftIndex < tokenCount + && (token = tokens[leftIndex], !token.align || token.align === 'left')) { + this._placeToken(token, style, lineHeight, lineTop, lineXLeft, 'left', bgColorDrawn); + remainedWidth -= token.width; + lineXLeft += token.width; + leftIndex++; + } + while (rightIndex >= 0 + && (token = tokens[rightIndex], token.align === 'right')) { + this._placeToken(token, style, lineHeight, lineTop, lineXRight, 'right', bgColorDrawn); + remainedWidth -= token.width; + lineXRight -= token.width; + rightIndex--; + } + lineXLeft += (contentWidth - (lineXLeft - xLeft) - (xRight - lineXRight) - remainedWidth) / 2; + while (leftIndex <= rightIndex) { + token = tokens[leftIndex]; + this._placeToken(token, style, lineHeight, lineTop, lineXLeft + token.width / 2, 'center', bgColorDrawn); + lineXLeft += token.width; + leftIndex++; + } + lineTop += lineHeight; + } + }; + ZRText.prototype._placeToken = function (token, style, lineHeight, lineTop, x, textAlign, parentBgColorDrawn) { + var tokenStyle = style.rich[token.styleName] || {}; + tokenStyle.text = token.text; + var verticalAlign = token.verticalAlign; + var y = lineTop + lineHeight / 2; + if (verticalAlign === 'top') { + y = lineTop + token.height / 2; + } + else if (verticalAlign === 'bottom') { + y = lineTop + lineHeight - token.height / 2; + } + var needDrawBg = !token.isLineHolder && needDrawBackground(tokenStyle); + needDrawBg && this._renderBackground(tokenStyle, style, textAlign === 'right' + ? x - token.width + : textAlign === 'center' + ? x - token.width / 2 + : x, y - token.height / 2, token.width, token.height); + var bgColorDrawn = !!tokenStyle.backgroundColor; + var textPadding = token.textPadding; + if (textPadding) { + x = getTextXForPadding(x, textAlign, textPadding); + y -= token.height / 2 - textPadding[0] - token.innerHeight / 2; + } + var el = this._getOrCreateChild(TSpan); + var subElStyle = el.createStyle(); + el.useStyle(subElStyle); + var defaultStyle = this._defaultStyle; + var useDefaultFill = false; + var defaultLineWidth = 0; + var textFill = getFill('fill' in tokenStyle ? tokenStyle.fill + : 'fill' in style ? style.fill + : (useDefaultFill = true, defaultStyle.fill)); + var textStroke = getStroke('stroke' in tokenStyle ? tokenStyle.stroke + : 'stroke' in style ? style.stroke + : (!bgColorDrawn + && !parentBgColorDrawn + && (!defaultStyle.autoStroke || useDefaultFill)) ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke) + : null); + var hasShadow = tokenStyle.textShadowBlur > 0 + || style.textShadowBlur > 0; + subElStyle.text = token.text; + subElStyle.x = x; + subElStyle.y = y; + if (hasShadow) { + subElStyle.shadowBlur = tokenStyle.textShadowBlur || style.textShadowBlur || 0; + subElStyle.shadowColor = tokenStyle.textShadowColor || style.textShadowColor || 'transparent'; + subElStyle.shadowOffsetX = tokenStyle.textShadowOffsetX || style.textShadowOffsetX || 0; + subElStyle.shadowOffsetY = tokenStyle.textShadowOffsetY || style.textShadowOffsetY || 0; + } + subElStyle.textAlign = textAlign; + subElStyle.textBaseline = 'middle'; + subElStyle.font = token.font || DEFAULT_FONT; + subElStyle.opacity = retrieve3(tokenStyle.opacity, style.opacity, 1); + setSeparateFont(subElStyle, tokenStyle); + if (textStroke) { + subElStyle.lineWidth = retrieve3(tokenStyle.lineWidth, style.lineWidth, defaultLineWidth); + subElStyle.lineDash = retrieve2(tokenStyle.lineDash, style.lineDash); + subElStyle.lineDashOffset = style.lineDashOffset || 0; + subElStyle.stroke = textStroke; + } + if (textFill) { + subElStyle.fill = textFill; + } + var textWidth = token.contentWidth; + var textHeight = token.contentHeight; + el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, textWidth, subElStyle.textAlign), adjustTextY$1(subElStyle.y, textHeight, subElStyle.textBaseline), textWidth, textHeight)); + }; + ZRText.prototype._renderBackground = function (style, topStyle, x, y, width, height) { + var textBackgroundColor = style.backgroundColor; + var textBorderWidth = style.borderWidth; + var textBorderColor = style.borderColor; + var isImageBg = textBackgroundColor && textBackgroundColor.image; + var isPlainOrGradientBg = textBackgroundColor && !isImageBg; + var textBorderRadius = style.borderRadius; + var self = this; + var rectEl; + var imgEl; + if (isPlainOrGradientBg || style.lineHeight || (textBorderWidth && textBorderColor)) { + rectEl = this._getOrCreateChild(Rect); + rectEl.useStyle(rectEl.createStyle()); + rectEl.style.fill = null; + var rectShape = rectEl.shape; + rectShape.x = x; + rectShape.y = y; + rectShape.width = width; + rectShape.height = height; + rectShape.r = textBorderRadius; + rectEl.dirtyShape(); + } + if (isPlainOrGradientBg) { + var rectStyle = rectEl.style; + rectStyle.fill = textBackgroundColor || null; + rectStyle.fillOpacity = retrieve2(style.fillOpacity, 1); + } + else if (isImageBg) { + imgEl = this._getOrCreateChild(ZRImage); + imgEl.onload = function () { + self.dirtyStyle(); + }; + var imgStyle = imgEl.style; + imgStyle.image = textBackgroundColor.image; + imgStyle.x = x; + imgStyle.y = y; + imgStyle.width = width; + imgStyle.height = height; + } + if (textBorderWidth && textBorderColor) { + var rectStyle = rectEl.style; + rectStyle.lineWidth = textBorderWidth; + rectStyle.stroke = textBorderColor; + rectStyle.strokeOpacity = retrieve2(style.strokeOpacity, 1); + rectStyle.lineDash = style.borderDash; + rectStyle.lineDashOffset = style.borderDashOffset || 0; + rectEl.strokeContainThreshold = 0; + if (rectEl.hasFill() && rectEl.hasStroke()) { + rectStyle.strokeFirst = true; + rectStyle.lineWidth *= 2; + } + } + var commonStyle = (rectEl || imgEl).style; + commonStyle.shadowBlur = style.shadowBlur || 0; + commonStyle.shadowColor = style.shadowColor || 'transparent'; + commonStyle.shadowOffsetX = style.shadowOffsetX || 0; + commonStyle.shadowOffsetY = style.shadowOffsetY || 0; + commonStyle.opacity = retrieve3(style.opacity, topStyle.opacity, 1); + }; + ZRText.makeFont = function (style) { + var font = ''; + if (hasSeparateFont(style)) { + font = [ + style.fontStyle, + style.fontWeight, + parseFontSize(style.fontSize), + style.fontFamily || 'sans-serif' + ].join(' '); + } + return font && trim(font) || style.textFont || style.font; + }; + return ZRText; + }(Displayable)); + var VALID_TEXT_ALIGN = { left: true, right: 1, center: 1 }; + var VALID_TEXT_VERTICAL_ALIGN = { top: 1, bottom: 1, middle: 1 }; + var FONT_PARTS = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily']; + function parseFontSize(fontSize) { + if (typeof fontSize === 'string' + && (fontSize.indexOf('px') !== -1 + || fontSize.indexOf('rem') !== -1 + || fontSize.indexOf('em') !== -1)) { + return fontSize; + } + else if (!isNaN(+fontSize)) { + return fontSize + 'px'; + } + else { + return DEFAULT_FONT_SIZE + 'px'; + } + } + function setSeparateFont(targetStyle, sourceStyle) { + for (var i = 0; i < FONT_PARTS.length; i++) { + var fontProp = FONT_PARTS[i]; + var val = sourceStyle[fontProp]; + if (val != null) { + targetStyle[fontProp] = val; + } + } + } + function hasSeparateFont(style) { + return style.fontSize != null || style.fontFamily || style.fontWeight; + } + function normalizeTextStyle(style) { + normalizeStyle(style); + each(style.rich, normalizeStyle); + return style; + } + function normalizeStyle(style) { + if (style) { + style.font = ZRText.makeFont(style); + var textAlign = style.align; + textAlign === 'middle' && (textAlign = 'center'); + style.align = (textAlign == null || VALID_TEXT_ALIGN[textAlign]) ? textAlign : 'left'; + var verticalAlign = style.verticalAlign; + verticalAlign === 'center' && (verticalAlign = 'middle'); + style.verticalAlign = (verticalAlign == null || VALID_TEXT_VERTICAL_ALIGN[verticalAlign]) ? verticalAlign : 'top'; + var textPadding = style.padding; + if (textPadding) { + style.padding = normalizeCssArray(style.padding); + } + } + } + function getStroke(stroke, lineWidth) { + return (stroke == null || lineWidth <= 0 || stroke === 'transparent' || stroke === 'none') + ? null + : (stroke.image || stroke.colorStops) + ? '#000' + : stroke; + } + function getFill(fill) { + return (fill == null || fill === 'none') + ? null + : (fill.image || fill.colorStops) + ? '#000' + : fill; + } + function getTextXForPadding(x, textAlign, textPadding) { + return textAlign === 'right' + ? (x - textPadding[1]) + : textAlign === 'center' + ? (x + textPadding[3] / 2 - textPadding[1] / 2) + : (x + textPadding[3]); + } + function getStyleText(style) { + var text = style.text; + text != null && (text += ''); + return text; + } + function needDrawBackground(style) { + return !!(style.backgroundColor + || style.lineHeight + || (style.borderWidth && style.borderColor)); + } + + var getECData = makeInner(); + var setCommonECData = function (seriesIndex, dataType, dataIdx, el) { + if (el) { + var ecData = getECData(el); + // Add data index and series index for indexing the data by element + // Useful in tooltip + ecData.dataIndex = dataIdx; + ecData.dataType = dataType; + ecData.seriesIndex = seriesIndex; + ecData.ssrType = 'chart'; + // TODO: not store dataIndex on children. + if (el.type === 'group') { + el.traverse(function (child) { + var childECData = getECData(child); + childECData.seriesIndex = seriesIndex; + childECData.dataIndex = dataIdx; + childECData.dataType = dataType; + childECData.ssrType = 'chart'; + }); + } + } + }; + + // Reserve 0 as default. + var _highlightNextDigit = 1; + var _highlightKeyMap = {}; + var getSavedStates = makeInner(); + var getComponentStates = makeInner(); + var HOVER_STATE_NORMAL = 0; + var HOVER_STATE_BLUR = 1; + var HOVER_STATE_EMPHASIS = 2; + var SPECIAL_STATES = ['emphasis', 'blur', 'select']; + var DISPLAY_STATES = ['normal', 'emphasis', 'blur', 'select']; + var Z2_EMPHASIS_LIFT = 10; + var Z2_SELECT_LIFT = 9; + var HIGHLIGHT_ACTION_TYPE = 'highlight'; + var DOWNPLAY_ACTION_TYPE = 'downplay'; + var SELECT_ACTION_TYPE = 'select'; + var UNSELECT_ACTION_TYPE = 'unselect'; + var TOGGLE_SELECT_ACTION_TYPE = 'toggleSelect'; + function hasFillOrStroke(fillOrStroke) { + return fillOrStroke != null && fillOrStroke !== 'none'; + } + function doChangeHoverState(el, stateName, hoverStateEnum) { + if (el.onHoverStateChange && (el.hoverState || 0) !== hoverStateEnum) { + el.onHoverStateChange(stateName); + } + el.hoverState = hoverStateEnum; + } + function singleEnterEmphasis(el) { + // Only mark the flag. + // States will be applied in the echarts.ts in next frame. + doChangeHoverState(el, 'emphasis', HOVER_STATE_EMPHASIS); + } + function singleLeaveEmphasis(el) { + // Only mark the flag. + // States will be applied in the echarts.ts in next frame. + if (el.hoverState === HOVER_STATE_EMPHASIS) { + doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL); + } + } + function singleEnterBlur(el) { + doChangeHoverState(el, 'blur', HOVER_STATE_BLUR); + } + function singleLeaveBlur(el) { + if (el.hoverState === HOVER_STATE_BLUR) { + doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL); + } + } + function singleEnterSelect(el) { + el.selected = true; + } + function singleLeaveSelect(el) { + el.selected = false; + } + function updateElementState(el, updater, commonParam) { + updater(el, commonParam); + } + function traverseUpdateState(el, updater, commonParam) { + updateElementState(el, updater, commonParam); + el.isGroup && el.traverse(function (child) { + updateElementState(child, updater, commonParam); + }); + } + function setStatesFlag(el, stateName) { + switch (stateName) { + case 'emphasis': + el.hoverState = HOVER_STATE_EMPHASIS; + break; + case 'normal': + el.hoverState = HOVER_STATE_NORMAL; + break; + case 'blur': + el.hoverState = HOVER_STATE_BLUR; + break; + case 'select': + el.selected = true; + } + } + function getFromStateStyle(el, props, toStateName, defaultValue) { + var style = el.style; + var fromState = {}; + for (var i = 0; i < props.length; i++) { + var propName = props[i]; + var val = style[propName]; + fromState[propName] = val == null ? defaultValue && defaultValue[propName] : val; + } + for (var i = 0; i < el.animators.length; i++) { + var animator = el.animators[i]; + if (animator.__fromStateTransition + // Don't consider the animation to emphasis state. + && animator.__fromStateTransition.indexOf(toStateName) < 0 && animator.targetName === 'style') { + animator.saveTo(fromState, props); + } + } + return fromState; + } + function createEmphasisDefaultState(el, stateName, targetStates, state) { + var hasSelect = targetStates && indexOf(targetStates, 'select') >= 0; + var cloned = false; + if (el instanceof Path) { + var store = getSavedStates(el); + var fromFill = hasSelect ? store.selectFill || store.normalFill : store.normalFill; + var fromStroke = hasSelect ? store.selectStroke || store.normalStroke : store.normalStroke; + if (hasFillOrStroke(fromFill) || hasFillOrStroke(fromStroke)) { + state = state || {}; + var emphasisStyle = state.style || {}; + // inherit case + if (emphasisStyle.fill === 'inherit') { + cloned = true; + state = extend({}, state); + emphasisStyle = extend({}, emphasisStyle); + emphasisStyle.fill = fromFill; + } + // Apply default color lift + else if (!hasFillOrStroke(emphasisStyle.fill) && hasFillOrStroke(fromFill)) { + cloned = true; + // Not modify the original value. + state = extend({}, state); + emphasisStyle = extend({}, emphasisStyle); + // Already being applied 'emphasis'. DON'T lift color multiple times. + emphasisStyle.fill = liftColor(fromFill); + } + // Not highlight stroke if fill has been highlighted. + else if (!hasFillOrStroke(emphasisStyle.stroke) && hasFillOrStroke(fromStroke)) { + if (!cloned) { + state = extend({}, state); + emphasisStyle = extend({}, emphasisStyle); + } + emphasisStyle.stroke = liftColor(fromStroke); + } + state.style = emphasisStyle; + } + } + if (state) { + // TODO Share with textContent? + if (state.z2 == null) { + if (!cloned) { + state = extend({}, state); + } + var z2EmphasisLift = el.z2EmphasisLift; + state.z2 = el.z2 + (z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT); + } + } + return state; + } + function createSelectDefaultState(el, stateName, state) { + // const hasSelect = indexOf(el.currentStates, stateName) >= 0; + if (state) { + // TODO Share with textContent? + if (state.z2 == null) { + state = extend({}, state); + var z2SelectLift = el.z2SelectLift; + state.z2 = el.z2 + (z2SelectLift != null ? z2SelectLift : Z2_SELECT_LIFT); + } + } + return state; + } + function createBlurDefaultState(el, stateName, state) { + var hasBlur = indexOf(el.currentStates, stateName) >= 0; + var currentOpacity = el.style.opacity; + var fromState = !hasBlur ? getFromStateStyle(el, ['opacity'], stateName, { + opacity: 1 + }) : null; + state = state || {}; + var blurStyle = state.style || {}; + if (blurStyle.opacity == null) { + // clone state + state = extend({}, state); + blurStyle = extend({ + // Already being applied 'emphasis'. DON'T mul opacity multiple times. + opacity: hasBlur ? currentOpacity : fromState.opacity * 0.1 + }, blurStyle); + state.style = blurStyle; + } + return state; + } + function elementStateProxy(stateName, targetStates) { + var state = this.states[stateName]; + if (this.style) { + if (stateName === 'emphasis') { + return createEmphasisDefaultState(this, stateName, targetStates, state); + } else if (stateName === 'blur') { + return createBlurDefaultState(this, stateName, state); + } else if (stateName === 'select') { + return createSelectDefaultState(this, stateName, state); + } + } + return state; + } + /** + * Set hover style (namely "emphasis style") of element. + * @param el Should not be `zrender/graphic/Group`. + * @param focus 'self' | 'selfInSeries' | 'series' + */ + function setDefaultStateProxy(el) { + el.stateProxy = elementStateProxy; + var textContent = el.getTextContent(); + var textGuide = el.getTextGuideLine(); + if (textContent) { + textContent.stateProxy = elementStateProxy; + } + if (textGuide) { + textGuide.stateProxy = elementStateProxy; + } + } + function enterEmphasisWhenMouseOver(el, e) { + !shouldSilent(el, e) + // "emphasis" event highlight has higher priority than mouse highlight. + && !el.__highByOuter && traverseUpdateState(el, singleEnterEmphasis); + } + function leaveEmphasisWhenMouseOut(el, e) { + !shouldSilent(el, e) + // "emphasis" event highlight has higher priority than mouse highlight. + && !el.__highByOuter && traverseUpdateState(el, singleLeaveEmphasis); + } + function enterEmphasis(el, highlightDigit) { + el.__highByOuter |= 1 << (highlightDigit || 0); + traverseUpdateState(el, singleEnterEmphasis); + } + function leaveEmphasis(el, highlightDigit) { + !(el.__highByOuter &= ~(1 << (highlightDigit || 0))) && traverseUpdateState(el, singleLeaveEmphasis); + } + function enterBlur(el) { + traverseUpdateState(el, singleEnterBlur); + } + function leaveBlur(el) { + traverseUpdateState(el, singleLeaveBlur); + } + function enterSelect(el) { + traverseUpdateState(el, singleEnterSelect); + } + function leaveSelect(el) { + traverseUpdateState(el, singleLeaveSelect); + } + function shouldSilent(el, e) { + return el.__highDownSilentOnTouch && e.zrByTouch; + } + function allLeaveBlur(api) { + var model = api.getModel(); + var leaveBlurredSeries = []; + var allComponentViews = []; + model.eachComponent(function (componentType, componentModel) { + var componentStates = getComponentStates(componentModel); + var isSeries = componentType === 'series'; + var view = isSeries ? api.getViewOfSeriesModel(componentModel) : api.getViewOfComponentModel(componentModel); + !isSeries && allComponentViews.push(view); + if (componentStates.isBlured) { + // Leave blur anyway + view.group.traverse(function (child) { + singleLeaveBlur(child); + }); + isSeries && leaveBlurredSeries.push(componentModel); + } + componentStates.isBlured = false; + }); + each(allComponentViews, function (view) { + if (view && view.toggleBlurSeries) { + view.toggleBlurSeries(leaveBlurredSeries, false, model); + } + }); + } + function blurSeries(targetSeriesIndex, focus, blurScope, api) { + var ecModel = api.getModel(); + blurScope = blurScope || 'coordinateSystem'; + function leaveBlurOfIndices(data, dataIndices) { + for (var i = 0; i < dataIndices.length; i++) { + var itemEl = data.getItemGraphicEl(dataIndices[i]); + itemEl && leaveBlur(itemEl); + } + } + if (targetSeriesIndex == null) { + return; + } + if (!focus || focus === 'none') { + return; + } + var targetSeriesModel = ecModel.getSeriesByIndex(targetSeriesIndex); + var targetCoordSys = targetSeriesModel.coordinateSystem; + if (targetCoordSys && targetCoordSys.master) { + targetCoordSys = targetCoordSys.master; + } + var blurredSeries = []; + ecModel.eachSeries(function (seriesModel) { + var sameSeries = targetSeriesModel === seriesModel; + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.master) { + coordSys = coordSys.master; + } + var sameCoordSys = coordSys && targetCoordSys ? coordSys === targetCoordSys : sameSeries; // If there is no coordinate system. use sameSeries instead. + if (!( + // Not blur other series if blurScope series + blurScope === 'series' && !sameSeries + // Not blur other coordinate system if blurScope is coordinateSystem + || blurScope === 'coordinateSystem' && !sameCoordSys + // Not blur self series if focus is series. + || focus === 'series' && sameSeries + // TODO blurScope: coordinate system + )) { + var view = api.getViewOfSeriesModel(seriesModel); + view.group.traverse(function (child) { + // For the elements that have been triggered by other components, + // and are still required to be highlighted, + // because the current is directly forced to blur the element, + // it will cause the focus self to be unable to highlight, so skip the blur of this element. + if (child.__highByOuter && sameSeries && focus === 'self') { + return; + } + singleEnterBlur(child); + }); + if (isArrayLike(focus)) { + leaveBlurOfIndices(seriesModel.getData(), focus); + } else if (isObject(focus)) { + var dataTypes = keys(focus); + for (var d = 0; d < dataTypes.length; d++) { + leaveBlurOfIndices(seriesModel.getData(dataTypes[d]), focus[dataTypes[d]]); + } + } + blurredSeries.push(seriesModel); + getComponentStates(seriesModel).isBlured = true; + } + }); + ecModel.eachComponent(function (componentType, componentModel) { + if (componentType === 'series') { + return; + } + var view = api.getViewOfComponentModel(componentModel); + if (view && view.toggleBlurSeries) { + view.toggleBlurSeries(blurredSeries, true, ecModel); + } + }); + } + function blurComponent(componentMainType, componentIndex, api) { + if (componentMainType == null || componentIndex == null) { + return; + } + var componentModel = api.getModel().getComponent(componentMainType, componentIndex); + if (!componentModel) { + return; + } + getComponentStates(componentModel).isBlured = true; + var view = api.getViewOfComponentModel(componentModel); + if (!view || !view.focusBlurEnabled) { + return; + } + view.group.traverse(function (child) { + singleEnterBlur(child); + }); + } + function blurSeriesFromHighlightPayload(seriesModel, payload, api) { + var seriesIndex = seriesModel.seriesIndex; + var data = seriesModel.getData(payload.dataType); + if (!data) { + if ("development" !== 'production') { + error("Unknown dataType " + payload.dataType); + } + return; + } + var dataIndex = queryDataIndex(data, payload); + // Pick the first one if there is multiple/none exists. + dataIndex = (isArray(dataIndex) ? dataIndex[0] : dataIndex) || 0; + var el = data.getItemGraphicEl(dataIndex); + if (!el) { + var count = data.count(); + var current = 0; + // If data on dataIndex is NaN. + while (!el && current < count) { + el = data.getItemGraphicEl(current++); + } + } + if (el) { + var ecData = getECData(el); + blurSeries(seriesIndex, ecData.focus, ecData.blurScope, api); + } else { + // If there is no element put on the data. Try getting it from raw option + // TODO Should put it on seriesModel? + var focus_1 = seriesModel.get(['emphasis', 'focus']); + var blurScope = seriesModel.get(['emphasis', 'blurScope']); + if (focus_1 != null) { + blurSeries(seriesIndex, focus_1, blurScope, api); + } + } + } + function findComponentHighDownDispatchers(componentMainType, componentIndex, name, api) { + var ret = { + focusSelf: false, + dispatchers: null + }; + if (componentMainType == null || componentMainType === 'series' || componentIndex == null || name == null) { + return ret; + } + var componentModel = api.getModel().getComponent(componentMainType, componentIndex); + if (!componentModel) { + return ret; + } + var view = api.getViewOfComponentModel(componentModel); + if (!view || !view.findHighDownDispatchers) { + return ret; + } + var dispatchers = view.findHighDownDispatchers(name); + // At presnet, the component (like Geo) only blur inside itself. + // So we do not use `blurScope` in component. + var focusSelf; + for (var i = 0; i < dispatchers.length; i++) { + if ("development" !== 'production' && !isHighDownDispatcher(dispatchers[i])) { + error('param should be highDownDispatcher'); + } + if (getECData(dispatchers[i]).focus === 'self') { + focusSelf = true; + break; + } + } + return { + focusSelf: focusSelf, + dispatchers: dispatchers + }; + } + function handleGlobalMouseOverForHighDown(dispatcher, e, api) { + if ("development" !== 'production' && !isHighDownDispatcher(dispatcher)) { + error('param should be highDownDispatcher'); + } + var ecData = getECData(dispatcher); + var _a = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api), + dispatchers = _a.dispatchers, + focusSelf = _a.focusSelf; + // If `findHighDownDispatchers` is supported on the component, + // highlight/downplay elements with the same name. + if (dispatchers) { + if (focusSelf) { + blurComponent(ecData.componentMainType, ecData.componentIndex, api); + } + each(dispatchers, function (dispatcher) { + return enterEmphasisWhenMouseOver(dispatcher, e); + }); + } else { + // Try blur all in the related series. Then emphasis the hoverred. + // TODO. progressive mode. + blurSeries(ecData.seriesIndex, ecData.focus, ecData.blurScope, api); + if (ecData.focus === 'self') { + blurComponent(ecData.componentMainType, ecData.componentIndex, api); + } + // Other than series, component that not support `findHighDownDispatcher` will + // also use it. But in this case, highlight/downplay are only supported in + // mouse hover but not in dispatchAction. + enterEmphasisWhenMouseOver(dispatcher, e); + } + } + function handleGlobalMouseOutForHighDown(dispatcher, e, api) { + if ("development" !== 'production' && !isHighDownDispatcher(dispatcher)) { + error('param should be highDownDispatcher'); + } + allLeaveBlur(api); + var ecData = getECData(dispatcher); + var dispatchers = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api).dispatchers; + if (dispatchers) { + each(dispatchers, function (dispatcher) { + return leaveEmphasisWhenMouseOut(dispatcher, e); + }); + } else { + leaveEmphasisWhenMouseOut(dispatcher, e); + } + } + function toggleSelectionFromPayload(seriesModel, payload, api) { + if (!isSelectChangePayload(payload)) { + return; + } + var dataType = payload.dataType; + var data = seriesModel.getData(dataType); + var dataIndex = queryDataIndex(data, payload); + if (!isArray(dataIndex)) { + dataIndex = [dataIndex]; + } + seriesModel[payload.type === TOGGLE_SELECT_ACTION_TYPE ? 'toggleSelect' : payload.type === SELECT_ACTION_TYPE ? 'select' : 'unselect'](dataIndex, dataType); + } + function updateSeriesElementSelection(seriesModel) { + var allData = seriesModel.getAllData(); + each(allData, function (_a) { + var data = _a.data, + type = _a.type; + data.eachItemGraphicEl(function (el, idx) { + seriesModel.isSelected(idx, type) ? enterSelect(el) : leaveSelect(el); + }); + }); + } + function getAllSelectedIndices(ecModel) { + var ret = []; + ecModel.eachSeries(function (seriesModel) { + var allData = seriesModel.getAllData(); + each(allData, function (_a) { + var data = _a.data, + type = _a.type; + var dataIndices = seriesModel.getSelectedDataIndices(); + if (dataIndices.length > 0) { + var item = { + dataIndex: dataIndices, + seriesIndex: seriesModel.seriesIndex + }; + if (type != null) { + item.dataType = type; + } + ret.push(item); + } + }); + }); + return ret; + } + /** + * Enable the function that mouseover will trigger the emphasis state. + * + * NOTE: + * This function should be used on the element with dataIndex, seriesIndex. + * + */ + function enableHoverEmphasis(el, focus, blurScope) { + setAsHighDownDispatcher(el, true); + traverseUpdateState(el, setDefaultStateProxy); + enableHoverFocus(el, focus, blurScope); + } + function disableHoverEmphasis(el) { + setAsHighDownDispatcher(el, false); + } + function toggleHoverEmphasis(el, focus, blurScope, isDisabled) { + isDisabled ? disableHoverEmphasis(el) : enableHoverEmphasis(el, focus, blurScope); + } + function enableHoverFocus(el, focus, blurScope) { + var ecData = getECData(el); + if (focus != null) { + // TODO dataIndex may be set after this function. This check is not useful. + // if (ecData.dataIndex == null) { + // if (__DEV__) { + // console.warn('focus can only been set on element with dataIndex'); + // } + // } + // else { + ecData.focus = focus; + ecData.blurScope = blurScope; + // } + } else if (ecData.focus) { + ecData.focus = null; + } + } + var OTHER_STATES = ['emphasis', 'blur', 'select']; + var defaultStyleGetterMap = { + itemStyle: 'getItemStyle', + lineStyle: 'getLineStyle', + areaStyle: 'getAreaStyle' + }; + /** + * Set emphasis/blur/selected states of element. + */ + function setStatesStylesFromModel(el, itemModel, styleType, + // default itemStyle + getter) { + styleType = styleType || 'itemStyle'; + for (var i = 0; i < OTHER_STATES.length; i++) { + var stateName = OTHER_STATES[i]; + var model = itemModel.getModel([stateName, styleType]); + var state = el.ensureState(stateName); + // Let it throw error if getterType is not found. + state.style = getter ? getter(model) : model[defaultStyleGetterMap[styleType]](); + } + } + /** + * + * Set element as highlight / downplay dispatcher. + * It will be checked when element received mouseover event or from highlight action. + * It's in change of all highlight/downplay behavior of it's children. + * + * @param el + * @param el.highDownSilentOnTouch + * In touch device, mouseover event will be trigger on touchstart event + * (see module:zrender/dom/HandlerProxy). By this mechanism, we can + * conveniently use hoverStyle when tap on touch screen without additional + * code for compatibility. + * But if the chart/component has select feature, which usually also use + * hoverStyle, there might be conflict between 'select-highlight' and + * 'hover-highlight' especially when roam is enabled (see geo for example). + * In this case, `highDownSilentOnTouch` should be used to disable + * hover-highlight on touch device. + * @param asDispatcher If `false`, do not set as "highDownDispatcher". + */ + function setAsHighDownDispatcher(el, asDispatcher) { + var disable = asDispatcher === false; + var extendedEl = el; + // Make `highDownSilentOnTouch` and `onStateChange` only work after + // `setAsHighDownDispatcher` called. Avoid it is modified by user unexpectedly. + if (el.highDownSilentOnTouch) { + extendedEl.__highDownSilentOnTouch = el.highDownSilentOnTouch; + } + // Simple optimize, since this method might be + // called for each elements of a group in some cases. + if (!disable || extendedEl.__highDownDispatcher) { + // Emphasis, normal can be triggered manually by API or other components like hover link. + // el[method]('emphasis', onElementEmphasisEvent)[method]('normal', onElementNormalEvent); + // Also keep previous record. + extendedEl.__highByOuter = extendedEl.__highByOuter || 0; + extendedEl.__highDownDispatcher = !disable; + } + } + function isHighDownDispatcher(el) { + return !!(el && el.__highDownDispatcher); + } + /** + * Enable component highlight/downplay features: + * + hover link (within the same name) + * + focus blur in component + */ + function enableComponentHighDownFeatures(el, componentModel, componentHighDownName) { + var ecData = getECData(el); + ecData.componentMainType = componentModel.mainType; + ecData.componentIndex = componentModel.componentIndex; + ecData.componentHighDownName = componentHighDownName; + } + /** + * Support highlight/downplay record on each elements. + * For the case: hover highlight/downplay (legend, visualMap, ...) and + * user triggered highlight/downplay should not conflict. + * Only all of the highlightDigit cleared, return to normal. + * @param {string} highlightKey + * @return {number} highlightDigit + */ + function getHighlightDigit(highlightKey) { + var highlightDigit = _highlightKeyMap[highlightKey]; + if (highlightDigit == null && _highlightNextDigit <= 32) { + highlightDigit = _highlightKeyMap[highlightKey] = _highlightNextDigit++; + } + return highlightDigit; + } + function isSelectChangePayload(payload) { + var payloadType = payload.type; + return payloadType === SELECT_ACTION_TYPE || payloadType === UNSELECT_ACTION_TYPE || payloadType === TOGGLE_SELECT_ACTION_TYPE; + } + function isHighDownPayload(payload) { + var payloadType = payload.type; + return payloadType === HIGHLIGHT_ACTION_TYPE || payloadType === DOWNPLAY_ACTION_TYPE; + } + function savePathStates(el) { + var store = getSavedStates(el); + store.normalFill = el.style.fill; + store.normalStroke = el.style.stroke; + var selectState = el.states.select || {}; + store.selectFill = selectState.style && selectState.style.fill || null; + store.selectStroke = selectState.style && selectState.style.stroke || null; + } + + var CMD$2 = PathProxy.CMD; + var points = [[], [], []]; + var mathSqrt$1 = Math.sqrt; + var mathAtan2 = Math.atan2; + function transformPath(path, m) { + if (!m) { + return; + } + var data = path.data; + var len = path.len(); + var cmd; + var nPoint; + var i; + var j; + var k; + var p; + var M = CMD$2.M; + var C = CMD$2.C; + var L = CMD$2.L; + var R = CMD$2.R; + var A = CMD$2.A; + var Q = CMD$2.Q; + for (i = 0, j = 0; i < len;) { + cmd = data[i++]; + j = i; + nPoint = 0; + switch (cmd) { + case M: + nPoint = 1; + break; + case L: + nPoint = 1; + break; + case C: + nPoint = 3; + break; + case Q: + nPoint = 2; + break; + case A: + var x = m[4]; + var y = m[5]; + var sx = mathSqrt$1(m[0] * m[0] + m[1] * m[1]); + var sy = mathSqrt$1(m[2] * m[2] + m[3] * m[3]); + var angle = mathAtan2(-m[1] / sy, m[0] / sx); + data[i] *= sx; + data[i++] += x; + data[i] *= sy; + data[i++] += y; + data[i++] *= sx; + data[i++] *= sy; + data[i++] += angle; + data[i++] += angle; + i += 2; + j = i; + break; + case R: + p[0] = data[i++]; + p[1] = data[i++]; + applyTransform(p, p, m); + data[j++] = p[0]; + data[j++] = p[1]; + p[0] += data[i++]; + p[1] += data[i++]; + applyTransform(p, p, m); + data[j++] = p[0]; + data[j++] = p[1]; + } + for (k = 0; k < nPoint; k++) { + var p_1 = points[k]; + p_1[0] = data[i++]; + p_1[1] = data[i++]; + applyTransform(p_1, p_1, m); + data[j++] = p_1[0]; + data[j++] = p_1[1]; + } + } + path.increaseVersion(); + } + + var mathSqrt$2 = Math.sqrt; + var mathSin$2 = Math.sin; + var mathCos$2 = Math.cos; + var PI$1 = Math.PI; + function vMag(v) { + return Math.sqrt(v[0] * v[0] + v[1] * v[1]); + } + function vRatio(u, v) { + return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v)); + } + function vAngle(u, v) { + return (u[0] * v[1] < u[1] * v[0] ? -1 : 1) + * Math.acos(vRatio(u, v)); + } + function processArc(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg, cmd, path) { + var psi = psiDeg * (PI$1 / 180.0); + var xp = mathCos$2(psi) * (x1 - x2) / 2.0 + + mathSin$2(psi) * (y1 - y2) / 2.0; + var yp = -1 * mathSin$2(psi) * (x1 - x2) / 2.0 + + mathCos$2(psi) * (y1 - y2) / 2.0; + var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry); + if (lambda > 1) { + rx *= mathSqrt$2(lambda); + ry *= mathSqrt$2(lambda); + } + var f = (fa === fs ? -1 : 1) + * mathSqrt$2((((rx * rx) * (ry * ry)) + - ((rx * rx) * (yp * yp)) + - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp) + + (ry * ry) * (xp * xp))) || 0; + var cxp = f * rx * yp / ry; + var cyp = f * -ry * xp / rx; + var cx = (x1 + x2) / 2.0 + + mathCos$2(psi) * cxp + - mathSin$2(psi) * cyp; + var cy = (y1 + y2) / 2.0 + + mathSin$2(psi) * cxp + + mathCos$2(psi) * cyp; + var theta = vAngle([1, 0], [(xp - cxp) / rx, (yp - cyp) / ry]); + var u = [(xp - cxp) / rx, (yp - cyp) / ry]; + var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry]; + var dTheta = vAngle(u, v); + if (vRatio(u, v) <= -1) { + dTheta = PI$1; + } + if (vRatio(u, v) >= 1) { + dTheta = 0; + } + if (dTheta < 0) { + var n = Math.round(dTheta / PI$1 * 1e6) / 1e6; + dTheta = PI$1 * 2 + (n % 2) * PI$1; + } + path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs); + } + var commandReg = /([mlvhzcqtsa])([^mlvhzcqtsa]*)/ig; + var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g; + function createPathProxyFromString(data) { + var path = new PathProxy(); + if (!data) { + return path; + } + var cpx = 0; + var cpy = 0; + var subpathX = cpx; + var subpathY = cpy; + var prevCmd; + var CMD = PathProxy.CMD; + var cmdList = data.match(commandReg); + if (!cmdList) { + return path; + } + for (var l = 0; l < cmdList.length; l++) { + var cmdText = cmdList[l]; + var cmdStr = cmdText.charAt(0); + var cmd = void 0; + var p = cmdText.match(numberReg) || []; + var pLen = p.length; + for (var i = 0; i < pLen; i++) { + p[i] = parseFloat(p[i]); + } + var off = 0; + while (off < pLen) { + var ctlPtx = void 0; + var ctlPty = void 0; + var rx = void 0; + var ry = void 0; + var psi = void 0; + var fa = void 0; + var fs = void 0; + var x1 = cpx; + var y1 = cpy; + var len = void 0; + var pathData = void 0; + switch (cmdStr) { + case 'l': + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'L': + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'm': + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.M; + path.addData(cmd, cpx, cpy); + subpathX = cpx; + subpathY = cpy; + cmdStr = 'l'; + break; + case 'M': + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.M; + path.addData(cmd, cpx, cpy); + subpathX = cpx; + subpathY = cpy; + cmdStr = 'L'; + break; + case 'h': + cpx += p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'H': + cpx = p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'v': + cpy += p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'V': + cpy = p[off++]; + cmd = CMD.L; + path.addData(cmd, cpx, cpy); + break; + case 'C': + cmd = CMD.C; + path.addData(cmd, p[off++], p[off++], p[off++], p[off++], p[off++], p[off++]); + cpx = p[off - 2]; + cpy = p[off - 1]; + break; + case 'c': + cmd = CMD.C; + path.addData(cmd, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy); + cpx += p[off - 2]; + cpy += p[off - 1]; + break; + case 'S': + ctlPtx = cpx; + ctlPty = cpy; + len = path.len(); + pathData = path.data; + if (prevCmd === CMD.C) { + ctlPtx += cpx - pathData[len - 4]; + ctlPty += cpy - pathData[len - 3]; + } + cmd = CMD.C; + x1 = p[off++]; + y1 = p[off++]; + cpx = p[off++]; + cpy = p[off++]; + path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy); + break; + case 's': + ctlPtx = cpx; + ctlPty = cpy; + len = path.len(); + pathData = path.data; + if (prevCmd === CMD.C) { + ctlPtx += cpx - pathData[len - 4]; + ctlPty += cpy - pathData[len - 3]; + } + cmd = CMD.C; + x1 = cpx + p[off++]; + y1 = cpy + p[off++]; + cpx += p[off++]; + cpy += p[off++]; + path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy); + break; + case 'Q': + x1 = p[off++]; + y1 = p[off++]; + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.Q; + path.addData(cmd, x1, y1, cpx, cpy); + break; + case 'q': + x1 = p[off++] + cpx; + y1 = p[off++] + cpy; + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.Q; + path.addData(cmd, x1, y1, cpx, cpy); + break; + case 'T': + ctlPtx = cpx; + ctlPty = cpy; + len = path.len(); + pathData = path.data; + if (prevCmd === CMD.Q) { + ctlPtx += cpx - pathData[len - 4]; + ctlPty += cpy - pathData[len - 3]; + } + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.Q; + path.addData(cmd, ctlPtx, ctlPty, cpx, cpy); + break; + case 't': + ctlPtx = cpx; + ctlPty = cpy; + len = path.len(); + pathData = path.data; + if (prevCmd === CMD.Q) { + ctlPtx += cpx - pathData[len - 4]; + ctlPty += cpy - pathData[len - 3]; + } + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.Q; + path.addData(cmd, ctlPtx, ctlPty, cpx, cpy); + break; + case 'A': + rx = p[off++]; + ry = p[off++]; + psi = p[off++]; + fa = p[off++]; + fs = p[off++]; + x1 = cpx, y1 = cpy; + cpx = p[off++]; + cpy = p[off++]; + cmd = CMD.A; + processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path); + break; + case 'a': + rx = p[off++]; + ry = p[off++]; + psi = p[off++]; + fa = p[off++]; + fs = p[off++]; + x1 = cpx, y1 = cpy; + cpx += p[off++]; + cpy += p[off++]; + cmd = CMD.A; + processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path); + break; + } + } + if (cmdStr === 'z' || cmdStr === 'Z') { + cmd = CMD.Z; + path.addData(cmd); + cpx = subpathX; + cpy = subpathY; + } + prevCmd = cmd; + } + path.toStatic(); + return path; + } + var SVGPath = (function (_super) { + __extends(SVGPath, _super); + function SVGPath() { + return _super !== null && _super.apply(this, arguments) || this; + } + SVGPath.prototype.applyTransform = function (m) { }; + return SVGPath; + }(Path)); + function isPathProxy(path) { + return path.setData != null; + } + function createPathOptions(str, opts) { + var pathProxy = createPathProxyFromString(str); + var innerOpts = extend({}, opts); + innerOpts.buildPath = function (path) { + if (isPathProxy(path)) { + path.setData(pathProxy.data); + var ctx = path.getContext(); + if (ctx) { + path.rebuildPath(ctx, 1); + } + } + else { + var ctx = path; + pathProxy.rebuildPath(ctx, 1); + } + }; + innerOpts.applyTransform = function (m) { + transformPath(pathProxy, m); + this.dirtyShape(); + }; + return innerOpts; + } + function createFromString(str, opts) { + return new SVGPath(createPathOptions(str, opts)); + } + function extendFromString(str, defaultOpts) { + var innerOpts = createPathOptions(str, defaultOpts); + var Sub = (function (_super) { + __extends(Sub, _super); + function Sub(opts) { + var _this = _super.call(this, opts) || this; + _this.applyTransform = innerOpts.applyTransform; + _this.buildPath = innerOpts.buildPath; + return _this; + } + return Sub; + }(SVGPath)); + return Sub; + } + function mergePath(pathEls, opts) { + var pathList = []; + var len = pathEls.length; + for (var i = 0; i < len; i++) { + var pathEl = pathEls[i]; + pathList.push(pathEl.getUpdatedPathProxy(true)); + } + var pathBundle = new Path(opts); + pathBundle.createPathProxy(); + pathBundle.buildPath = function (path) { + if (isPathProxy(path)) { + path.appendPath(pathList); + var ctx = path.getContext(); + if (ctx) { + path.rebuildPath(ctx, 1); + } + } + }; + return pathBundle; + } + function clonePath(sourcePath, opts) { + opts = opts || {}; + var path = new Path(); + if (sourcePath.shape) { + path.setShape(sourcePath.shape); + } + path.setStyle(sourcePath.style); + if (opts.bakeTransform) { + transformPath(path.path, sourcePath.getComputedTransform()); + } + else { + if (opts.toLocal) { + path.setLocalTransform(sourcePath.getComputedTransform()); + } + else { + path.copyTransform(sourcePath); + } + } + path.buildPath = sourcePath.buildPath; + path.applyTransform = path.applyTransform; + path.z = sourcePath.z; + path.z2 = sourcePath.z2; + path.zlevel = sourcePath.zlevel; + return path; + } + + var CircleShape = (function () { + function CircleShape() { + this.cx = 0; + this.cy = 0; + this.r = 0; + } + return CircleShape; + }()); + var Circle = (function (_super) { + __extends(Circle, _super); + function Circle(opts) { + return _super.call(this, opts) || this; + } + Circle.prototype.getDefaultShape = function () { + return new CircleShape(); + }; + Circle.prototype.buildPath = function (ctx, shape) { + ctx.moveTo(shape.cx + shape.r, shape.cy); + ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2); + }; + return Circle; + }(Path)); + Circle.prototype.type = 'circle'; + + var EllipseShape = (function () { + function EllipseShape() { + this.cx = 0; + this.cy = 0; + this.rx = 0; + this.ry = 0; + } + return EllipseShape; + }()); + var Ellipse = (function (_super) { + __extends(Ellipse, _super); + function Ellipse(opts) { + return _super.call(this, opts) || this; + } + Ellipse.prototype.getDefaultShape = function () { + return new EllipseShape(); + }; + Ellipse.prototype.buildPath = function (ctx, shape) { + var k = 0.5522848; + var x = shape.cx; + var y = shape.cy; + var a = shape.rx; + var b = shape.ry; + var ox = a * k; + var oy = b * k; + ctx.moveTo(x - a, y); + ctx.bezierCurveTo(x - a, y - oy, x - ox, y - b, x, y - b); + ctx.bezierCurveTo(x + ox, y - b, x + a, y - oy, x + a, y); + ctx.bezierCurveTo(x + a, y + oy, x + ox, y + b, x, y + b); + ctx.bezierCurveTo(x - ox, y + b, x - a, y + oy, x - a, y); + ctx.closePath(); + }; + return Ellipse; + }(Path)); + Ellipse.prototype.type = 'ellipse'; + + var PI$2 = Math.PI; + var PI2$5 = PI$2 * 2; + var mathSin$3 = Math.sin; + var mathCos$3 = Math.cos; + var mathACos = Math.acos; + var mathATan2 = Math.atan2; + var mathAbs$1 = Math.abs; + var mathSqrt$3 = Math.sqrt; + var mathMax$3 = Math.max; + var mathMin$3 = Math.min; + var e = 1e-4; + function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { + var dx10 = x1 - x0; + var dy10 = y1 - y0; + var dx32 = x3 - x2; + var dy32 = y3 - y2; + var t = dy32 * dx10 - dx32 * dy10; + if (t * t < e) { + return; + } + t = (dx32 * (y0 - y2) - dy32 * (x0 - x2)) / t; + return [x0 + t * dx10, y0 + t * dy10]; + } + function computeCornerTangents(x0, y0, x1, y1, radius, cr, clockwise) { + var x01 = x0 - x1; + var y01 = y0 - y1; + var lo = (clockwise ? cr : -cr) / mathSqrt$3(x01 * x01 + y01 * y01); + var ox = lo * y01; + var oy = -lo * x01; + var x11 = x0 + ox; + var y11 = y0 + oy; + var x10 = x1 + ox; + var y10 = y1 + oy; + var x00 = (x11 + x10) / 2; + var y00 = (y11 + y10) / 2; + var dx = x10 - x11; + var dy = y10 - y11; + var d2 = dx * dx + dy * dy; + var r = radius - cr; + var s = x11 * y10 - x10 * y11; + var d = (dy < 0 ? -1 : 1) * mathSqrt$3(mathMax$3(0, r * r * d2 - s * s)); + var cx0 = (s * dy - dx * d) / d2; + var cy0 = (-s * dx - dy * d) / d2; + var cx1 = (s * dy + dx * d) / d2; + var cy1 = (-s * dx + dy * d) / d2; + var dx0 = cx0 - x00; + var dy0 = cy0 - y00; + var dx1 = cx1 - x00; + var dy1 = cy1 - y00; + if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) { + cx0 = cx1; + cy0 = cy1; + } + return { + cx: cx0, + cy: cy0, + x0: -ox, + y0: -oy, + x1: cx0 * (radius / r - 1), + y1: cy0 * (radius / r - 1) + }; + } + function normalizeCornerRadius(cr) { + var arr; + if (isArray(cr)) { + var len = cr.length; + if (!len) { + return cr; + } + if (len === 1) { + arr = [cr[0], cr[0], 0, 0]; + } + else if (len === 2) { + arr = [cr[0], cr[0], cr[1], cr[1]]; + } + else if (len === 3) { + arr = cr.concat(cr[2]); + } + else { + arr = cr; + } + } + else { + arr = [cr, cr, cr, cr]; + } + return arr; + } + function buildPath$1(ctx, shape) { + var _a; + var radius = mathMax$3(shape.r, 0); + var innerRadius = mathMax$3(shape.r0 || 0, 0); + var hasRadius = radius > 0; + var hasInnerRadius = innerRadius > 0; + if (!hasRadius && !hasInnerRadius) { + return; + } + if (!hasRadius) { + radius = innerRadius; + innerRadius = 0; + } + if (innerRadius > radius) { + var tmp = radius; + radius = innerRadius; + innerRadius = tmp; + } + var startAngle = shape.startAngle, endAngle = shape.endAngle; + if (isNaN(startAngle) || isNaN(endAngle)) { + return; + } + var cx = shape.cx, cy = shape.cy; + var clockwise = !!shape.clockwise; + var arc = mathAbs$1(endAngle - startAngle); + var mod = arc > PI2$5 && arc % PI2$5; + mod > e && (arc = mod); + if (!(radius > e)) { + ctx.moveTo(cx, cy); + } + else if (arc > PI2$5 - e) { + ctx.moveTo(cx + radius * mathCos$3(startAngle), cy + radius * mathSin$3(startAngle)); + ctx.arc(cx, cy, radius, startAngle, endAngle, !clockwise); + if (innerRadius > e) { + ctx.moveTo(cx + innerRadius * mathCos$3(endAngle), cy + innerRadius * mathSin$3(endAngle)); + ctx.arc(cx, cy, innerRadius, endAngle, startAngle, clockwise); + } + } + else { + var icrStart = void 0; + var icrEnd = void 0; + var ocrStart = void 0; + var ocrEnd = void 0; + var ocrs = void 0; + var ocre = void 0; + var icrs = void 0; + var icre = void 0; + var ocrMax = void 0; + var icrMax = void 0; + var limitedOcrMax = void 0; + var limitedIcrMax = void 0; + var xre = void 0; + var yre = void 0; + var xirs = void 0; + var yirs = void 0; + var xrs = radius * mathCos$3(startAngle); + var yrs = radius * mathSin$3(startAngle); + var xire = innerRadius * mathCos$3(endAngle); + var yire = innerRadius * mathSin$3(endAngle); + var hasArc = arc > e; + if (hasArc) { + var cornerRadius = shape.cornerRadius; + if (cornerRadius) { + _a = normalizeCornerRadius(cornerRadius), icrStart = _a[0], icrEnd = _a[1], ocrStart = _a[2], ocrEnd = _a[3]; + } + var halfRd = mathAbs$1(radius - innerRadius) / 2; + ocrs = mathMin$3(halfRd, ocrStart); + ocre = mathMin$3(halfRd, ocrEnd); + icrs = mathMin$3(halfRd, icrStart); + icre = mathMin$3(halfRd, icrEnd); + limitedOcrMax = ocrMax = mathMax$3(ocrs, ocre); + limitedIcrMax = icrMax = mathMax$3(icrs, icre); + if (ocrMax > e || icrMax > e) { + xre = radius * mathCos$3(endAngle); + yre = radius * mathSin$3(endAngle); + xirs = innerRadius * mathCos$3(startAngle); + yirs = innerRadius * mathSin$3(startAngle); + if (arc < PI$2) { + var it_1 = intersect(xrs, yrs, xirs, yirs, xre, yre, xire, yire); + if (it_1) { + var x0 = xrs - it_1[0]; + var y0 = yrs - it_1[1]; + var x1 = xre - it_1[0]; + var y1 = yre - it_1[1]; + var a = 1 / mathSin$3(mathACos((x0 * x1 + y0 * y1) / (mathSqrt$3(x0 * x0 + y0 * y0) * mathSqrt$3(x1 * x1 + y1 * y1))) / 2); + var b = mathSqrt$3(it_1[0] * it_1[0] + it_1[1] * it_1[1]); + limitedOcrMax = mathMin$3(ocrMax, (radius - b) / (a + 1)); + limitedIcrMax = mathMin$3(icrMax, (innerRadius - b) / (a - 1)); + } + } + } + } + if (!hasArc) { + ctx.moveTo(cx + xrs, cy + yrs); + } + else if (limitedOcrMax > e) { + var crStart = mathMin$3(ocrStart, limitedOcrMax); + var crEnd = mathMin$3(ocrEnd, limitedOcrMax); + var ct0 = computeCornerTangents(xirs, yirs, xrs, yrs, radius, crStart, clockwise); + var ct1 = computeCornerTangents(xre, yre, xire, yire, radius, crEnd, clockwise); + ctx.moveTo(cx + ct0.cx + ct0.x0, cy + ct0.cy + ct0.y0); + if (limitedOcrMax < ocrMax && crStart === crEnd) { + ctx.arc(cx + ct0.cx, cy + ct0.cy, limitedOcrMax, mathATan2(ct0.y0, ct0.x0), mathATan2(ct1.y0, ct1.x0), !clockwise); + } + else { + crStart > 0 && ctx.arc(cx + ct0.cx, cy + ct0.cy, crStart, mathATan2(ct0.y0, ct0.x0), mathATan2(ct0.y1, ct0.x1), !clockwise); + ctx.arc(cx, cy, radius, mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1), mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1), !clockwise); + crEnd > 0 && ctx.arc(cx + ct1.cx, cy + ct1.cy, crEnd, mathATan2(ct1.y1, ct1.x1), mathATan2(ct1.y0, ct1.x0), !clockwise); + } + } + else { + ctx.moveTo(cx + xrs, cy + yrs); + ctx.arc(cx, cy, radius, startAngle, endAngle, !clockwise); + } + if (!(innerRadius > e) || !hasArc) { + ctx.lineTo(cx + xire, cy + yire); + } + else if (limitedIcrMax > e) { + var crStart = mathMin$3(icrStart, limitedIcrMax); + var crEnd = mathMin$3(icrEnd, limitedIcrMax); + var ct0 = computeCornerTangents(xire, yire, xre, yre, innerRadius, -crEnd, clockwise); + var ct1 = computeCornerTangents(xrs, yrs, xirs, yirs, innerRadius, -crStart, clockwise); + ctx.lineTo(cx + ct0.cx + ct0.x0, cy + ct0.cy + ct0.y0); + if (limitedIcrMax < icrMax && crStart === crEnd) { + ctx.arc(cx + ct0.cx, cy + ct0.cy, limitedIcrMax, mathATan2(ct0.y0, ct0.x0), mathATan2(ct1.y0, ct1.x0), !clockwise); + } + else { + crEnd > 0 && ctx.arc(cx + ct0.cx, cy + ct0.cy, crEnd, mathATan2(ct0.y0, ct0.x0), mathATan2(ct0.y1, ct0.x1), !clockwise); + ctx.arc(cx, cy, innerRadius, mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1), mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1), clockwise); + crStart > 0 && ctx.arc(cx + ct1.cx, cy + ct1.cy, crStart, mathATan2(ct1.y1, ct1.x1), mathATan2(ct1.y0, ct1.x0), !clockwise); + } + } + else { + ctx.lineTo(cx + xire, cy + yire); + ctx.arc(cx, cy, innerRadius, endAngle, startAngle, clockwise); + } + } + ctx.closePath(); + } + + var SectorShape = (function () { + function SectorShape() { + this.cx = 0; + this.cy = 0; + this.r0 = 0; + this.r = 0; + this.startAngle = 0; + this.endAngle = Math.PI * 2; + this.clockwise = true; + this.cornerRadius = 0; + } + return SectorShape; + }()); + var Sector = (function (_super) { + __extends(Sector, _super); + function Sector(opts) { + return _super.call(this, opts) || this; + } + Sector.prototype.getDefaultShape = function () { + return new SectorShape(); + }; + Sector.prototype.buildPath = function (ctx, shape) { + buildPath$1(ctx, shape); + }; + Sector.prototype.isZeroArea = function () { + return this.shape.startAngle === this.shape.endAngle + || this.shape.r === this.shape.r0; + }; + return Sector; + }(Path)); + Sector.prototype.type = 'sector'; + + var RingShape = (function () { + function RingShape() { + this.cx = 0; + this.cy = 0; + this.r = 0; + this.r0 = 0; + } + return RingShape; + }()); + var Ring = (function (_super) { + __extends(Ring, _super); + function Ring(opts) { + return _super.call(this, opts) || this; + } + Ring.prototype.getDefaultShape = function () { + return new RingShape(); + }; + Ring.prototype.buildPath = function (ctx, shape) { + var x = shape.cx; + var y = shape.cy; + var PI2 = Math.PI * 2; + ctx.moveTo(x + shape.r, y); + ctx.arc(x, y, shape.r, 0, PI2, false); + ctx.moveTo(x + shape.r0, y); + ctx.arc(x, y, shape.r0, 0, PI2, true); + }; + return Ring; + }(Path)); + Ring.prototype.type = 'ring'; + + function smoothBezier(points, smooth, isLoop, constraint) { + var cps = []; + var v = []; + var v1 = []; + var v2 = []; + var prevPoint; + var nextPoint; + var min$1; + var max$1; + if (constraint) { + min$1 = [Infinity, Infinity]; + max$1 = [-Infinity, -Infinity]; + for (var i = 0, len = points.length; i < len; i++) { + min(min$1, min$1, points[i]); + max(max$1, max$1, points[i]); + } + min(min$1, min$1, constraint[0]); + max(max$1, max$1, constraint[1]); + } + for (var i = 0, len = points.length; i < len; i++) { + var point = points[i]; + if (isLoop) { + prevPoint = points[i ? i - 1 : len - 1]; + nextPoint = points[(i + 1) % len]; + } + else { + if (i === 0 || i === len - 1) { + cps.push(clone$1(points[i])); + continue; + } + else { + prevPoint = points[i - 1]; + nextPoint = points[i + 1]; + } + } + sub(v, nextPoint, prevPoint); + scale(v, v, smooth); + var d0 = distance(point, prevPoint); + var d1 = distance(point, nextPoint); + var sum = d0 + d1; + if (sum !== 0) { + d0 /= sum; + d1 /= sum; + } + scale(v1, v, -d0); + scale(v2, v, d1); + var cp0 = add([], point, v1); + var cp1 = add([], point, v2); + if (constraint) { + max(cp0, cp0, min$1); + min(cp0, cp0, max$1); + max(cp1, cp1, min$1); + min(cp1, cp1, max$1); + } + cps.push(cp0); + cps.push(cp1); + } + if (isLoop) { + cps.push(cps.shift()); + } + return cps; + } + + function buildPath$2(ctx, shape, closePath) { + var smooth = shape.smooth; + var points = shape.points; + if (points && points.length >= 2) { + if (smooth) { + var controlPoints = smoothBezier(points, smooth, closePath, shape.smoothConstraint); + ctx.moveTo(points[0][0], points[0][1]); + var len = points.length; + for (var i = 0; i < (closePath ? len : len - 1); i++) { + var cp1 = controlPoints[i * 2]; + var cp2 = controlPoints[i * 2 + 1]; + var p = points[(i + 1) % len]; + ctx.bezierCurveTo(cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]); + } + } + else { + ctx.moveTo(points[0][0], points[0][1]); + for (var i = 1, l = points.length; i < l; i++) { + ctx.lineTo(points[i][0], points[i][1]); + } + } + closePath && ctx.closePath(); + } + } + + var PolygonShape = (function () { + function PolygonShape() { + this.points = null; + this.smooth = 0; + this.smoothConstraint = null; + } + return PolygonShape; + }()); + var Polygon = (function (_super) { + __extends(Polygon, _super); + function Polygon(opts) { + return _super.call(this, opts) || this; + } + Polygon.prototype.getDefaultShape = function () { + return new PolygonShape(); + }; + Polygon.prototype.buildPath = function (ctx, shape) { + buildPath$2(ctx, shape, true); + }; + return Polygon; + }(Path)); + Polygon.prototype.type = 'polygon'; + + var PolylineShape = (function () { + function PolylineShape() { + this.points = null; + this.percent = 1; + this.smooth = 0; + this.smoothConstraint = null; + } + return PolylineShape; + }()); + var Polyline = (function (_super) { + __extends(Polyline, _super); + function Polyline(opts) { + return _super.call(this, opts) || this; + } + Polyline.prototype.getDefaultStyle = function () { + return { + stroke: '#000', + fill: null + }; + }; + Polyline.prototype.getDefaultShape = function () { + return new PolylineShape(); + }; + Polyline.prototype.buildPath = function (ctx, shape) { + buildPath$2(ctx, shape, false); + }; + return Polyline; + }(Path)); + Polyline.prototype.type = 'polyline'; + + var subPixelOptimizeOutputShape$1 = {}; + var LineShape = (function () { + function LineShape() { + this.x1 = 0; + this.y1 = 0; + this.x2 = 0; + this.y2 = 0; + this.percent = 1; + } + return LineShape; + }()); + var Line = (function (_super) { + __extends(Line, _super); + function Line(opts) { + return _super.call(this, opts) || this; + } + Line.prototype.getDefaultStyle = function () { + return { + stroke: '#000', + fill: null + }; + }; + Line.prototype.getDefaultShape = function () { + return new LineShape(); + }; + Line.prototype.buildPath = function (ctx, shape) { + var x1; + var y1; + var x2; + var y2; + if (this.subPixelOptimize) { + var optimizedShape = subPixelOptimizeLine(subPixelOptimizeOutputShape$1, shape, this.style); + x1 = optimizedShape.x1; + y1 = optimizedShape.y1; + x2 = optimizedShape.x2; + y2 = optimizedShape.y2; + } + else { + x1 = shape.x1; + y1 = shape.y1; + x2 = shape.x2; + y2 = shape.y2; + } + var percent = shape.percent; + if (percent === 0) { + return; + } + ctx.moveTo(x1, y1); + if (percent < 1) { + x2 = x1 * (1 - percent) + x2 * percent; + y2 = y1 * (1 - percent) + y2 * percent; + } + ctx.lineTo(x2, y2); + }; + Line.prototype.pointAt = function (p) { + var shape = this.shape; + return [ + shape.x1 * (1 - p) + shape.x2 * p, + shape.y1 * (1 - p) + shape.y2 * p + ]; + }; + return Line; + }(Path)); + Line.prototype.type = 'line'; + + var out = []; + var BezierCurveShape = (function () { + function BezierCurveShape() { + this.x1 = 0; + this.y1 = 0; + this.x2 = 0; + this.y2 = 0; + this.cpx1 = 0; + this.cpy1 = 0; + this.percent = 1; + } + return BezierCurveShape; + }()); + function someVectorAt(shape, t, isTangent) { + var cpx2 = shape.cpx2; + var cpy2 = shape.cpy2; + if (cpx2 != null || cpy2 != null) { + return [ + (isTangent ? cubicDerivativeAt : cubicAt)(shape.x1, shape.cpx1, shape.cpx2, shape.x2, t), + (isTangent ? cubicDerivativeAt : cubicAt)(shape.y1, shape.cpy1, shape.cpy2, shape.y2, t) + ]; + } + else { + return [ + (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t), + (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t) + ]; + } + } + var BezierCurve = (function (_super) { + __extends(BezierCurve, _super); + function BezierCurve(opts) { + return _super.call(this, opts) || this; + } + BezierCurve.prototype.getDefaultStyle = function () { + return { + stroke: '#000', + fill: null + }; + }; + BezierCurve.prototype.getDefaultShape = function () { + return new BezierCurveShape(); + }; + BezierCurve.prototype.buildPath = function (ctx, shape) { + var x1 = shape.x1; + var y1 = shape.y1; + var x2 = shape.x2; + var y2 = shape.y2; + var cpx1 = shape.cpx1; + var cpy1 = shape.cpy1; + var cpx2 = shape.cpx2; + var cpy2 = shape.cpy2; + var percent = shape.percent; + if (percent === 0) { + return; + } + ctx.moveTo(x1, y1); + if (cpx2 == null || cpy2 == null) { + if (percent < 1) { + quadraticSubdivide(x1, cpx1, x2, percent, out); + cpx1 = out[1]; + x2 = out[2]; + quadraticSubdivide(y1, cpy1, y2, percent, out); + cpy1 = out[1]; + y2 = out[2]; + } + ctx.quadraticCurveTo(cpx1, cpy1, x2, y2); + } + else { + if (percent < 1) { + cubicSubdivide(x1, cpx1, cpx2, x2, percent, out); + cpx1 = out[1]; + cpx2 = out[2]; + x2 = out[3]; + cubicSubdivide(y1, cpy1, cpy2, y2, percent, out); + cpy1 = out[1]; + cpy2 = out[2]; + y2 = out[3]; + } + ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x2, y2); + } + }; + BezierCurve.prototype.pointAt = function (t) { + return someVectorAt(this.shape, t, false); + }; + BezierCurve.prototype.tangentAt = function (t) { + var p = someVectorAt(this.shape, t, true); + return normalize(p, p); + }; + return BezierCurve; + }(Path)); + BezierCurve.prototype.type = 'bezier-curve'; + + var ArcShape = (function () { + function ArcShape() { + this.cx = 0; + this.cy = 0; + this.r = 0; + this.startAngle = 0; + this.endAngle = Math.PI * 2; + this.clockwise = true; + } + return ArcShape; + }()); + var Arc = (function (_super) { + __extends(Arc, _super); + function Arc(opts) { + return _super.call(this, opts) || this; + } + Arc.prototype.getDefaultStyle = function () { + return { + stroke: '#000', + fill: null + }; + }; + Arc.prototype.getDefaultShape = function () { + return new ArcShape(); + }; + Arc.prototype.buildPath = function (ctx, shape) { + var x = shape.cx; + var y = shape.cy; + var r = Math.max(shape.r, 0); + var startAngle = shape.startAngle; + var endAngle = shape.endAngle; + var clockwise = shape.clockwise; + var unitX = Math.cos(startAngle); + var unitY = Math.sin(startAngle); + ctx.moveTo(unitX * r + x, unitY * r + y); + ctx.arc(x, y, r, startAngle, endAngle, !clockwise); + }; + return Arc; + }(Path)); + Arc.prototype.type = 'arc'; + + var CompoundPath = (function (_super) { + __extends(CompoundPath, _super); + function CompoundPath() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = 'compound'; + return _this; + } + CompoundPath.prototype._updatePathDirty = function () { + var paths = this.shape.paths; + var dirtyPath = this.shapeChanged(); + for (var i = 0; i < paths.length; i++) { + dirtyPath = dirtyPath || paths[i].shapeChanged(); + } + if (dirtyPath) { + this.dirtyShape(); + } + }; + CompoundPath.prototype.beforeBrush = function () { + this._updatePathDirty(); + var paths = this.shape.paths || []; + var scale = this.getGlobalScale(); + for (var i = 0; i < paths.length; i++) { + if (!paths[i].path) { + paths[i].createPathProxy(); + } + paths[i].path.setScale(scale[0], scale[1], paths[i].segmentIgnoreThreshold); + } + }; + CompoundPath.prototype.buildPath = function (ctx, shape) { + var paths = shape.paths || []; + for (var i = 0; i < paths.length; i++) { + paths[i].buildPath(ctx, paths[i].shape, true); + } + }; + CompoundPath.prototype.afterBrush = function () { + var paths = this.shape.paths || []; + for (var i = 0; i < paths.length; i++) { + paths[i].pathUpdated(); + } + }; + CompoundPath.prototype.getBoundingRect = function () { + this._updatePathDirty.call(this); + return Path.prototype.getBoundingRect.call(this); + }; + return CompoundPath; + }(Path)); + + var Gradient = (function () { + function Gradient(colorStops) { + this.colorStops = colorStops || []; + } + Gradient.prototype.addColorStop = function (offset, color) { + this.colorStops.push({ + offset: offset, + color: color + }); + }; + return Gradient; + }()); + + var LinearGradient = (function (_super) { + __extends(LinearGradient, _super); + function LinearGradient(x, y, x2, y2, colorStops, globalCoord) { + var _this = _super.call(this, colorStops) || this; + _this.x = x == null ? 0 : x; + _this.y = y == null ? 0 : y; + _this.x2 = x2 == null ? 1 : x2; + _this.y2 = y2 == null ? 0 : y2; + _this.type = 'linear'; + _this.global = globalCoord || false; + return _this; + } + return LinearGradient; + }(Gradient)); + + var RadialGradient = (function (_super) { + __extends(RadialGradient, _super); + function RadialGradient(x, y, r, colorStops, globalCoord) { + var _this = _super.call(this, colorStops) || this; + _this.x = x == null ? 0.5 : x; + _this.y = y == null ? 0.5 : y; + _this.r = r == null ? 0.5 : r; + _this.type = 'radial'; + _this.global = globalCoord || false; + return _this; + } + return RadialGradient; + }(Gradient)); + + var extent = [0, 0]; + var extent2 = [0, 0]; + var minTv$1 = new Point(); + var maxTv$1 = new Point(); + var OrientedBoundingRect = (function () { + function OrientedBoundingRect(rect, transform) { + this._corners = []; + this._axes = []; + this._origin = [0, 0]; + for (var i = 0; i < 4; i++) { + this._corners[i] = new Point(); + } + for (var i = 0; i < 2; i++) { + this._axes[i] = new Point(); + } + if (rect) { + this.fromBoundingRect(rect, transform); + } + } + OrientedBoundingRect.prototype.fromBoundingRect = function (rect, transform) { + var corners = this._corners; + var axes = this._axes; + var x = rect.x; + var y = rect.y; + var x2 = x + rect.width; + var y2 = y + rect.height; + corners[0].set(x, y); + corners[1].set(x2, y); + corners[2].set(x2, y2); + corners[3].set(x, y2); + if (transform) { + for (var i = 0; i < 4; i++) { + corners[i].transform(transform); + } + } + Point.sub(axes[0], corners[1], corners[0]); + Point.sub(axes[1], corners[3], corners[0]); + axes[0].normalize(); + axes[1].normalize(); + for (var i = 0; i < 2; i++) { + this._origin[i] = axes[i].dot(corners[0]); + } + }; + OrientedBoundingRect.prototype.intersect = function (other, mtv) { + var overlapped = true; + var noMtv = !mtv; + minTv$1.set(Infinity, Infinity); + maxTv$1.set(0, 0); + if (!this._intersectCheckOneSide(this, other, minTv$1, maxTv$1, noMtv, 1)) { + overlapped = false; + if (noMtv) { + return overlapped; + } + } + if (!this._intersectCheckOneSide(other, this, minTv$1, maxTv$1, noMtv, -1)) { + overlapped = false; + if (noMtv) { + return overlapped; + } + } + if (!noMtv) { + Point.copy(mtv, overlapped ? minTv$1 : maxTv$1); + } + return overlapped; + }; + OrientedBoundingRect.prototype._intersectCheckOneSide = function (self, other, minTv, maxTv, noMtv, inverse) { + var overlapped = true; + for (var i = 0; i < 2; i++) { + var axis = this._axes[i]; + this._getProjMinMaxOnAxis(i, self._corners, extent); + this._getProjMinMaxOnAxis(i, other._corners, extent2); + if (extent[1] < extent2[0] || extent[0] > extent2[1]) { + overlapped = false; + if (noMtv) { + return overlapped; + } + var dist0 = Math.abs(extent2[0] - extent[1]); + var dist1 = Math.abs(extent[0] - extent2[1]); + if (Math.min(dist0, dist1) > maxTv.len()) { + if (dist0 < dist1) { + Point.scale(maxTv, axis, -dist0 * inverse); + } + else { + Point.scale(maxTv, axis, dist1 * inverse); + } + } + } + else if (minTv) { + var dist0 = Math.abs(extent2[0] - extent[1]); + var dist1 = Math.abs(extent[0] - extent2[1]); + if (Math.min(dist0, dist1) < minTv.len()) { + if (dist0 < dist1) { + Point.scale(minTv, axis, dist0 * inverse); + } + else { + Point.scale(minTv, axis, -dist1 * inverse); + } + } + } + } + return overlapped; + }; + OrientedBoundingRect.prototype._getProjMinMaxOnAxis = function (dim, corners, out) { + var axis = this._axes[dim]; + var origin = this._origin; + var proj = corners[0].dot(axis) + origin[dim]; + var min = proj; + var max = proj; + for (var i = 1; i < corners.length; i++) { + var proj_1 = corners[i].dot(axis) + origin[dim]; + min = Math.min(proj_1, min); + max = Math.max(proj_1, max); + } + out[0] = min; + out[1] = max; + }; + return OrientedBoundingRect; + }()); + + var m = []; + var IncrementalDisplayable = (function (_super) { + __extends(IncrementalDisplayable, _super); + function IncrementalDisplayable() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.notClear = true; + _this.incremental = true; + _this._displayables = []; + _this._temporaryDisplayables = []; + _this._cursor = 0; + return _this; + } + IncrementalDisplayable.prototype.traverse = function (cb, context) { + cb.call(context, this); + }; + IncrementalDisplayable.prototype.useStyle = function () { + this.style = {}; + }; + IncrementalDisplayable.prototype.getCursor = function () { + return this._cursor; + }; + IncrementalDisplayable.prototype.innerAfterBrush = function () { + this._cursor = this._displayables.length; + }; + IncrementalDisplayable.prototype.clearDisplaybles = function () { + this._displayables = []; + this._temporaryDisplayables = []; + this._cursor = 0; + this.markRedraw(); + this.notClear = false; + }; + IncrementalDisplayable.prototype.clearTemporalDisplayables = function () { + this._temporaryDisplayables = []; + }; + IncrementalDisplayable.prototype.addDisplayable = function (displayable, notPersistent) { + if (notPersistent) { + this._temporaryDisplayables.push(displayable); + } + else { + this._displayables.push(displayable); + } + this.markRedraw(); + }; + IncrementalDisplayable.prototype.addDisplayables = function (displayables, notPersistent) { + notPersistent = notPersistent || false; + for (var i = 0; i < displayables.length; i++) { + this.addDisplayable(displayables[i], notPersistent); + } + }; + IncrementalDisplayable.prototype.getDisplayables = function () { + return this._displayables; + }; + IncrementalDisplayable.prototype.getTemporalDisplayables = function () { + return this._temporaryDisplayables; + }; + IncrementalDisplayable.prototype.eachPendingDisplayable = function (cb) { + for (var i = this._cursor; i < this._displayables.length; i++) { + cb && cb(this._displayables[i]); + } + for (var i = 0; i < this._temporaryDisplayables.length; i++) { + cb && cb(this._temporaryDisplayables[i]); + } + }; + IncrementalDisplayable.prototype.update = function () { + this.updateTransform(); + for (var i = this._cursor; i < this._displayables.length; i++) { + var displayable = this._displayables[i]; + displayable.parent = this; + displayable.update(); + displayable.parent = null; + } + for (var i = 0; i < this._temporaryDisplayables.length; i++) { + var displayable = this._temporaryDisplayables[i]; + displayable.parent = this; + displayable.update(); + displayable.parent = null; + } + }; + IncrementalDisplayable.prototype.getBoundingRect = function () { + if (!this._rect) { + var rect = new BoundingRect(Infinity, Infinity, -Infinity, -Infinity); + for (var i = 0; i < this._displayables.length; i++) { + var displayable = this._displayables[i]; + var childRect = displayable.getBoundingRect().clone(); + if (displayable.needLocalTransform()) { + childRect.applyTransform(displayable.getLocalTransform(m)); + } + rect.union(childRect); + } + this._rect = rect; + } + return this._rect; + }; + IncrementalDisplayable.prototype.contain = function (x, y) { + var localPos = this.transformCoordToLocal(x, y); + var rect = this.getBoundingRect(); + if (rect.contain(localPos[0], localPos[1])) { + for (var i = 0; i < this._displayables.length; i++) { + var displayable = this._displayables[i]; + if (displayable.contain(x, y)) { + return true; + } + } + } + return false; + }; + return IncrementalDisplayable; + }(Displayable)); + + // Stored properties for further transition. + var transitionStore = makeInner(); + /** + * Return null if animation is disabled. + */ + function getAnimationConfig(animationType, animatableModel, dataIndex, + // Extra opts can override the option in animatable model. + extraOpts, + // TODO It's only for pictorial bar now. + extraDelayParams) { + var animationPayload; + // Check if there is global animation configuration from dataZoom/resize can override the config in option. + // If animation is enabled. Will use this animation config in payload. + // If animation is disabled. Just ignore it. + if (animatableModel && animatableModel.ecModel) { + var updatePayload = animatableModel.ecModel.getUpdatePayload(); + animationPayload = updatePayload && updatePayload.animation; + } + var animationEnabled = animatableModel && animatableModel.isAnimationEnabled(); + var isUpdate = animationType === 'update'; + if (animationEnabled) { + var duration = void 0; + var easing = void 0; + var delay = void 0; + if (extraOpts) { + duration = retrieve2(extraOpts.duration, 200); + easing = retrieve2(extraOpts.easing, 'cubicOut'); + delay = 0; + } else { + duration = animatableModel.getShallow(isUpdate ? 'animationDurationUpdate' : 'animationDuration'); + easing = animatableModel.getShallow(isUpdate ? 'animationEasingUpdate' : 'animationEasing'); + delay = animatableModel.getShallow(isUpdate ? 'animationDelayUpdate' : 'animationDelay'); + } + // animation from payload has highest priority. + if (animationPayload) { + animationPayload.duration != null && (duration = animationPayload.duration); + animationPayload.easing != null && (easing = animationPayload.easing); + animationPayload.delay != null && (delay = animationPayload.delay); + } + if (isFunction(delay)) { + delay = delay(dataIndex, extraDelayParams); + } + if (isFunction(duration)) { + duration = duration(dataIndex); + } + var config = { + duration: duration || 0, + delay: delay, + easing: easing + }; + return config; + } else { + return null; + } + } + function animateOrSetProps(animationType, el, props, animatableModel, dataIndex, cb, during) { + var isFrom = false; + var removeOpt; + if (isFunction(dataIndex)) { + during = cb; + cb = dataIndex; + dataIndex = null; + } else if (isObject(dataIndex)) { + cb = dataIndex.cb; + during = dataIndex.during; + isFrom = dataIndex.isFrom; + removeOpt = dataIndex.removeOpt; + dataIndex = dataIndex.dataIndex; + } + var isRemove = animationType === 'leave'; + if (!isRemove) { + // Must stop the remove animation. + el.stopAnimation('leave'); + } + var animationConfig = getAnimationConfig(animationType, animatableModel, dataIndex, isRemove ? removeOpt || {} : null, animatableModel && animatableModel.getAnimationDelayParams ? animatableModel.getAnimationDelayParams(el, dataIndex) : null); + if (animationConfig && animationConfig.duration > 0) { + var duration = animationConfig.duration; + var animationDelay = animationConfig.delay; + var animationEasing = animationConfig.easing; + var animateConfig = { + duration: duration, + delay: animationDelay || 0, + easing: animationEasing, + done: cb, + force: !!cb || !!during, + // Set to final state in update/init animation. + // So the post processing based on the path shape can be done correctly. + setToFinal: !isRemove, + scope: animationType, + during: during + }; + isFrom ? el.animateFrom(props, animateConfig) : el.animateTo(props, animateConfig); + } else { + el.stopAnimation(); + // If `isFrom`, the props is the "from" props. + !isFrom && el.attr(props); + // Call during at least once. + during && during(1); + cb && cb(); + } + } + /** + * Update graphic element properties with or without animation according to the + * configuration in series. + * + * Caution: this method will stop previous animation. + * So do not use this method to one element twice before + * animation starts, unless you know what you are doing. + * @example + * graphic.updateProps(el, { + * position: [100, 100] + * }, seriesModel, dataIndex, function () { console.log('Animation done!'); }); + * // Or + * graphic.updateProps(el, { + * position: [100, 100] + * }, seriesModel, function () { console.log('Animation done!'); }); + */ + function updateProps(el, props, + // TODO: TYPE AnimatableModel + animatableModel, dataIndex, cb, during) { + animateOrSetProps('update', el, props, animatableModel, dataIndex, cb, during); + } + /** + * Init graphic element properties with or without animation according to the + * configuration in series. + * + * Caution: this method will stop previous animation. + * So do not use this method to one element twice before + * animation starts, unless you know what you are doing. + */ + function initProps(el, props, animatableModel, dataIndex, cb, during) { + animateOrSetProps('enter', el, props, animatableModel, dataIndex, cb, during); + } + /** + * If element is removed. + * It can determine if element is having remove animation. + */ + function isElementRemoved(el) { + if (!el.__zr) { + return true; + } + for (var i = 0; i < el.animators.length; i++) { + var animator = el.animators[i]; + if (animator.scope === 'leave') { + return true; + } + } + return false; + } + /** + * Remove graphic element + */ + function removeElement(el, props, animatableModel, dataIndex, cb, during) { + // Don't do remove animation twice. + if (isElementRemoved(el)) { + return; + } + animateOrSetProps('leave', el, props, animatableModel, dataIndex, cb, during); + } + function fadeOutDisplayable(el, animatableModel, dataIndex, done) { + el.removeTextContent(); + el.removeTextGuideLine(); + removeElement(el, { + style: { + opacity: 0 + } + }, animatableModel, dataIndex, done); + } + function removeElementWithFadeOut(el, animatableModel, dataIndex) { + function doRemove() { + el.parent && el.parent.remove(el); + } + // Hide label and labelLine first + // TODO Also use fade out animation? + if (!el.isGroup) { + fadeOutDisplayable(el, animatableModel, dataIndex, doRemove); + } else { + el.traverse(function (disp) { + if (!disp.isGroup) { + // Can invoke doRemove multiple times. + fadeOutDisplayable(disp, animatableModel, dataIndex, doRemove); + } + }); + } + } + /** + * Save old style for style transition in universalTransition module. + * It's used when element will be reused in each render. + * For chart like map, heatmap, which will always create new element. + * We don't need to save this because universalTransition can get old style from the old element + */ + function saveOldStyle(el) { + transitionStore(el).oldStyle = el.style; + } + function getOldStyle(el) { + return transitionStore(el).oldStyle; + } + + var mathMax$4 = Math.max; + var mathMin$4 = Math.min; + var _customShapeMap = {}; + /** + * Extend shape with parameters + */ + function extendShape(opts) { + return Path.extend(opts); + } + var extendPathFromString = extendFromString; + /** + * Extend path + */ + function extendPath(pathData, opts) { + return extendPathFromString(pathData, opts); + } + /** + * Register a user defined shape. + * The shape class can be fetched by `getShapeClass` + * This method will overwrite the registered shapes, including + * the registered built-in shapes, if using the same `name`. + * The shape can be used in `custom series` and + * `graphic component` by declaring `{type: name}`. + * + * @param name + * @param ShapeClass Can be generated by `extendShape`. + */ + function registerShape(name, ShapeClass) { + _customShapeMap[name] = ShapeClass; + } + /** + * Find shape class registered by `registerShape`. Usually used in + * fetching user defined shape. + * + * [Caution]: + * (1) This method **MUST NOT be used inside echarts !!!**, unless it is prepared + * to use user registered shapes. + * Because the built-in shape (see `getBuiltInShape`) will be registered by + * `registerShape` by default. That enables users to get both built-in + * shapes as well as the shapes belonging to themsleves. But users can overwrite + * the built-in shapes by using names like 'circle', 'rect' via calling + * `registerShape`. So the echarts inner featrues should not fetch shapes from here + * in case that it is overwritten by users, except that some features, like + * `custom series`, `graphic component`, do it deliberately. + * + * (2) In the features like `custom series`, `graphic component`, the user input + * `{tpye: 'xxx'}` does not only specify shapes but also specify other graphic + * elements like `'group'`, `'text'`, `'image'` or event `'path'`. Those names + * are reserved names, that is, if some user registers a shape named `'image'`, + * the shape will not be used. If we intending to add some more reserved names + * in feature, that might bring break changes (disable some existing user shape + * names). But that case probably rarely happens. So we don't make more mechanism + * to resolve this issue here. + * + * @param name + * @return The shape class. If not found, return nothing. + */ + function getShapeClass(name) { + if (_customShapeMap.hasOwnProperty(name)) { + return _customShapeMap[name]; + } + } + /** + * Create a path element from path data string + * @param pathData + * @param opts + * @param rect + * @param layout 'center' or 'cover' default to be cover + */ + function makePath(pathData, opts, rect, layout) { + var path = createFromString(pathData, opts); + if (rect) { + if (layout === 'center') { + rect = centerGraphic(rect, path.getBoundingRect()); + } + resizePath(path, rect); + } + return path; + } + /** + * Create a image element from image url + * @param imageUrl image url + * @param opts options + * @param rect constrain rect + * @param layout 'center' or 'cover'. Default to be 'cover' + */ + function makeImage(imageUrl, rect, layout) { + var zrImg = new ZRImage({ + style: { + image: imageUrl, + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + }, + onload: function (img) { + if (layout === 'center') { + var boundingRect = { + width: img.width, + height: img.height + }; + zrImg.setStyle(centerGraphic(rect, boundingRect)); + } + } + }); + return zrImg; + } + /** + * Get position of centered element in bounding box. + * + * @param rect element local bounding box + * @param boundingRect constraint bounding box + * @return element position containing x, y, width, and height + */ + function centerGraphic(rect, boundingRect) { + // Set rect to center, keep width / height ratio. + var aspect = boundingRect.width / boundingRect.height; + var width = rect.height * aspect; + var height; + if (width <= rect.width) { + height = rect.height; + } else { + width = rect.width; + height = width / aspect; + } + var cx = rect.x + rect.width / 2; + var cy = rect.y + rect.height / 2; + return { + x: cx - width / 2, + y: cy - height / 2, + width: width, + height: height + }; + } + var mergePath$1 = mergePath; + /** + * Resize a path to fit the rect + * @param path + * @param rect + */ + function resizePath(path, rect) { + if (!path.applyTransform) { + return; + } + var pathRect = path.getBoundingRect(); + var m = pathRect.calculateTransform(rect); + path.applyTransform(m); + } + /** + * Sub pixel optimize line for canvas + */ + function subPixelOptimizeLine$1(shape, lineWidth) { + subPixelOptimizeLine(shape, shape, { + lineWidth: lineWidth + }); + return shape; + } + /** + * Sub pixel optimize rect for canvas + */ + function subPixelOptimizeRect$1(param) { + subPixelOptimizeRect(param.shape, param.shape, param.style); + return param; + } + /** + * Sub pixel optimize for canvas + * + * @param position Coordinate, such as x, y + * @param lineWidth Should be nonnegative integer. + * @param positiveOrNegative Default false (negative). + * @return Optimized position. + */ + var subPixelOptimize$1 = subPixelOptimize; + /** + * Get transform matrix of target (param target), + * in coordinate of its ancestor (param ancestor) + * + * @param target + * @param [ancestor] + */ + function getTransform(target, ancestor) { + var mat = identity([]); + while (target && target !== ancestor) { + mul$1(mat, target.getLocalTransform(), mat); + target = target.parent; + } + return mat; + } + /** + * Apply transform to an vertex. + * @param target [x, y] + * @param transform Can be: + * + Transform matrix: like [1, 0, 0, 1, 0, 0] + * + {position, rotation, scale}, the same as `zrender/Transformable`. + * @param invert Whether use invert matrix. + * @return [x, y] + */ + function applyTransform$1(target, transform, invert$1) { + if (transform && !isArrayLike(transform)) { + transform = Transformable.getLocalTransform(transform); + } + if (invert$1) { + transform = invert([], transform); + } + return applyTransform([], target, transform); + } + /** + * @param direction 'left' 'right' 'top' 'bottom' + * @param transform Transform matrix: like [1, 0, 0, 1, 0, 0] + * @param invert Whether use invert matrix. + * @return Transformed direction. 'left' 'right' 'top' 'bottom' + */ + function transformDirection(direction, transform, invert) { + // Pick a base, ensure that transform result will not be (0, 0). + var hBase = transform[4] === 0 || transform[5] === 0 || transform[0] === 0 ? 1 : Math.abs(2 * transform[4] / transform[0]); + var vBase = transform[4] === 0 || transform[5] === 0 || transform[2] === 0 ? 1 : Math.abs(2 * transform[4] / transform[2]); + var vertex = [direction === 'left' ? -hBase : direction === 'right' ? hBase : 0, direction === 'top' ? -vBase : direction === 'bottom' ? vBase : 0]; + vertex = applyTransform$1(vertex, transform, invert); + return Math.abs(vertex[0]) > Math.abs(vertex[1]) ? vertex[0] > 0 ? 'right' : 'left' : vertex[1] > 0 ? 'bottom' : 'top'; + } + function isNotGroup(el) { + return !el.isGroup; + } + function isPath(el) { + return el.shape != null; + } + /** + * Apply group transition animation from g1 to g2. + * If no animatableModel, no animation. + */ + function groupTransition(g1, g2, animatableModel) { + if (!g1 || !g2) { + return; + } + function getElMap(g) { + var elMap = {}; + g.traverse(function (el) { + if (isNotGroup(el) && el.anid) { + elMap[el.anid] = el; + } + }); + return elMap; + } + function getAnimatableProps(el) { + var obj = { + x: el.x, + y: el.y, + rotation: el.rotation + }; + if (isPath(el)) { + obj.shape = extend({}, el.shape); + } + return obj; + } + var elMap1 = getElMap(g1); + g2.traverse(function (el) { + if (isNotGroup(el) && el.anid) { + var oldEl = elMap1[el.anid]; + if (oldEl) { + var newProp = getAnimatableProps(el); + el.attr(getAnimatableProps(oldEl)); + updateProps(el, newProp, animatableModel, getECData(el).dataIndex); + } + } + }); + } + function clipPointsByRect(points, rect) { + // FIXME: This way might be incorrect when graphic clipped by a corner + // and when element has a border. + return map(points, function (point) { + var x = point[0]; + x = mathMax$4(x, rect.x); + x = mathMin$4(x, rect.x + rect.width); + var y = point[1]; + y = mathMax$4(y, rect.y); + y = mathMin$4(y, rect.y + rect.height); + return [x, y]; + }); + } + /** + * Return a new clipped rect. If rect size are negative, return undefined. + */ + function clipRectByRect(targetRect, rect) { + var x = mathMax$4(targetRect.x, rect.x); + var x2 = mathMin$4(targetRect.x + targetRect.width, rect.x + rect.width); + var y = mathMax$4(targetRect.y, rect.y); + var y2 = mathMin$4(targetRect.y + targetRect.height, rect.y + rect.height); + // If the total rect is cliped, nothing, including the border, + // should be painted. So return undefined. + if (x2 >= x && y2 >= y) { + return { + x: x, + y: y, + width: x2 - x, + height: y2 - y + }; + } + } + function createIcon(iconStr, + // Support 'image://' or 'path://' or direct svg path. + opt, rect) { + var innerOpts = extend({ + rectHover: true + }, opt); + var style = innerOpts.style = { + strokeNoScale: true + }; + rect = rect || { + x: -1, + y: -1, + width: 2, + height: 2 + }; + if (iconStr) { + return iconStr.indexOf('image://') === 0 ? (style.image = iconStr.slice(8), defaults(style, rect), new ZRImage(innerOpts)) : makePath(iconStr.replace('path://', ''), innerOpts, rect, 'center'); + } + } + /** + * Return `true` if the given line (line `a`) and the given polygon + * are intersect. + * Note that we do not count colinear as intersect here because no + * requirement for that. We could do that if required in future. + */ + function linePolygonIntersect(a1x, a1y, a2x, a2y, points) { + for (var i = 0, p2 = points[points.length - 1]; i < points.length; i++) { + var p = points[i]; + if (lineLineIntersect(a1x, a1y, a2x, a2y, p[0], p[1], p2[0], p2[1])) { + return true; + } + p2 = p; + } + } + /** + * Return `true` if the given two lines (line `a` and line `b`) + * are intersect. + * Note that we do not count colinear as intersect here because no + * requirement for that. We could do that if required in future. + */ + function lineLineIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) { + // let `vec_m` to be `vec_a2 - vec_a1` and `vec_n` to be `vec_b2 - vec_b1`. + var mx = a2x - a1x; + var my = a2y - a1y; + var nx = b2x - b1x; + var ny = b2y - b1y; + // `vec_m` and `vec_n` are parallel iff + // existing `k` such that `vec_m = k · vec_n`, equivalent to `vec_m X vec_n = 0`. + var nmCrossProduct = crossProduct2d(nx, ny, mx, my); + if (nearZero(nmCrossProduct)) { + return false; + } + // `vec_m` and `vec_n` are intersect iff + // existing `p` and `q` in [0, 1] such that `vec_a1 + p * vec_m = vec_b1 + q * vec_n`, + // such that `q = ((vec_a1 - vec_b1) X vec_m) / (vec_n X vec_m)` + // and `p = ((vec_a1 - vec_b1) X vec_n) / (vec_n X vec_m)`. + var b1a1x = a1x - b1x; + var b1a1y = a1y - b1y; + var q = crossProduct2d(b1a1x, b1a1y, mx, my) / nmCrossProduct; + if (q < 0 || q > 1) { + return false; + } + var p = crossProduct2d(b1a1x, b1a1y, nx, ny) / nmCrossProduct; + if (p < 0 || p > 1) { + return false; + } + return true; + } + /** + * Cross product of 2-dimension vector. + */ + function crossProduct2d(x1, y1, x2, y2) { + return x1 * y2 - x2 * y1; + } + function nearZero(val) { + return val <= 1e-6 && val >= -1e-6; + } + function setTooltipConfig(opt) { + var itemTooltipOption = opt.itemTooltipOption; + var componentModel = opt.componentModel; + var itemName = opt.itemName; + var itemTooltipOptionObj = isString(itemTooltipOption) ? { + formatter: itemTooltipOption + } : itemTooltipOption; + var mainType = componentModel.mainType; + var componentIndex = componentModel.componentIndex; + var formatterParams = { + componentType: mainType, + name: itemName, + $vars: ['name'] + }; + formatterParams[mainType + 'Index'] = componentIndex; + var formatterParamsExtra = opt.formatterParamsExtra; + if (formatterParamsExtra) { + each(keys(formatterParamsExtra), function (key) { + if (!hasOwn(formatterParams, key)) { + formatterParams[key] = formatterParamsExtra[key]; + formatterParams.$vars.push(key); + } + }); + } + var ecData = getECData(opt.el); + ecData.componentMainType = mainType; + ecData.componentIndex = componentIndex; + ecData.tooltipConfig = { + name: itemName, + option: defaults({ + content: itemName, + formatterParams: formatterParams + }, itemTooltipOptionObj) + }; + } + function traverseElement(el, cb) { + var stopped; + // TODO + // Polyfill for fixing zrender group traverse don't visit it's root issue. + if (el.isGroup) { + stopped = cb(el); + } + if (!stopped) { + el.traverse(cb); + } + } + function traverseElements(els, cb) { + if (els) { + if (isArray(els)) { + for (var i = 0; i < els.length; i++) { + traverseElement(els[i], cb); + } + } else { + traverseElement(els, cb); + } + } + } + // Register built-in shapes. These shapes might be overwritten + // by users, although we do not recommend that. + registerShape('circle', Circle); + registerShape('ellipse', Ellipse); + registerShape('sector', Sector); + registerShape('ring', Ring); + registerShape('polygon', Polygon); + registerShape('polyline', Polyline); + registerShape('rect', Rect); + registerShape('line', Line); + registerShape('bezierCurve', BezierCurve); + registerShape('arc', Arc); + + var graphic = /*#__PURE__*/Object.freeze({ + __proto__: null, + updateProps: updateProps, + initProps: initProps, + removeElement: removeElement, + removeElementWithFadeOut: removeElementWithFadeOut, + isElementRemoved: isElementRemoved, + extendShape: extendShape, + extendPath: extendPath, + registerShape: registerShape, + getShapeClass: getShapeClass, + makePath: makePath, + makeImage: makeImage, + mergePath: mergePath$1, + resizePath: resizePath, + subPixelOptimizeLine: subPixelOptimizeLine$1, + subPixelOptimizeRect: subPixelOptimizeRect$1, + subPixelOptimize: subPixelOptimize$1, + getTransform: getTransform, + applyTransform: applyTransform$1, + transformDirection: transformDirection, + groupTransition: groupTransition, + clipPointsByRect: clipPointsByRect, + clipRectByRect: clipRectByRect, + createIcon: createIcon, + linePolygonIntersect: linePolygonIntersect, + lineLineIntersect: lineLineIntersect, + setTooltipConfig: setTooltipConfig, + traverseElements: traverseElements, + Group: Group, + Image: ZRImage, + Text: ZRText, + Circle: Circle, + Ellipse: Ellipse, + Sector: Sector, + Ring: Ring, + Polygon: Polygon, + Polyline: Polyline, + Rect: Rect, + Line: Line, + BezierCurve: BezierCurve, + Arc: Arc, + IncrementalDisplayable: IncrementalDisplayable, + CompoundPath: CompoundPath, + LinearGradient: LinearGradient, + RadialGradient: RadialGradient, + BoundingRect: BoundingRect, + OrientedBoundingRect: OrientedBoundingRect, + Point: Point, + Path: Path + }); + + var EMPTY_OBJ = {}; + function setLabelText(label, labelTexts) { + for (var i = 0; i < SPECIAL_STATES.length; i++) { + var stateName = SPECIAL_STATES[i]; + var text = labelTexts[stateName]; + var state = label.ensureState(stateName); + state.style = state.style || {}; + state.style.text = text; + } + var oldStates = label.currentStates.slice(); + label.clearStates(true); + label.setStyle({ + text: labelTexts.normal + }); + label.useStates(oldStates, true); + } + function getLabelText(opt, stateModels, interpolatedValue) { + var labelFetcher = opt.labelFetcher; + var labelDataIndex = opt.labelDataIndex; + var labelDimIndex = opt.labelDimIndex; + var normalModel = stateModels.normal; + var baseText; + if (labelFetcher) { + baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex, normalModel && normalModel.get('formatter'), interpolatedValue != null ? { + interpolatedValue: interpolatedValue + } : null); + } + if (baseText == null) { + baseText = isFunction(opt.defaultText) ? opt.defaultText(labelDataIndex, opt, interpolatedValue) : opt.defaultText; + } + var statesText = { + normal: baseText + }; + for (var i = 0; i < SPECIAL_STATES.length; i++) { + var stateName = SPECIAL_STATES[i]; + var stateModel = stateModels[stateName]; + statesText[stateName] = retrieve2(labelFetcher ? labelFetcher.getFormattedLabel(labelDataIndex, stateName, null, labelDimIndex, stateModel && stateModel.get('formatter')) : null, baseText); + } + return statesText; + } + function setLabelStyle(targetEl, labelStatesModels, opt, stateSpecified + // TODO specified position? + ) { + opt = opt || EMPTY_OBJ; + var isSetOnText = targetEl instanceof ZRText; + var needsCreateText = false; + for (var i = 0; i < DISPLAY_STATES.length; i++) { + var stateModel = labelStatesModels[DISPLAY_STATES[i]]; + if (stateModel && stateModel.getShallow('show')) { + needsCreateText = true; + break; + } + } + var textContent = isSetOnText ? targetEl : targetEl.getTextContent(); + if (needsCreateText) { + if (!isSetOnText) { + // Reuse the previous + if (!textContent) { + textContent = new ZRText(); + targetEl.setTextContent(textContent); + } + // Use same state proxy + if (targetEl.stateProxy) { + textContent.stateProxy = targetEl.stateProxy; + } + } + var labelStatesTexts = getLabelText(opt, labelStatesModels); + var normalModel = labelStatesModels.normal; + var showNormal = !!normalModel.getShallow('show'); + var normalStyle = createTextStyle(normalModel, stateSpecified && stateSpecified.normal, opt, false, !isSetOnText); + normalStyle.text = labelStatesTexts.normal; + if (!isSetOnText) { + // Always create new + targetEl.setTextConfig(createTextConfig(normalModel, opt, false)); + } + for (var i = 0; i < SPECIAL_STATES.length; i++) { + var stateName = SPECIAL_STATES[i]; + var stateModel = labelStatesModels[stateName]; + if (stateModel) { + var stateObj = textContent.ensureState(stateName); + var stateShow = !!retrieve2(stateModel.getShallow('show'), showNormal); + if (stateShow !== showNormal) { + stateObj.ignore = !stateShow; + } + stateObj.style = createTextStyle(stateModel, stateSpecified && stateSpecified[stateName], opt, true, !isSetOnText); + stateObj.style.text = labelStatesTexts[stateName]; + if (!isSetOnText) { + var targetElEmphasisState = targetEl.ensureState(stateName); + targetElEmphasisState.textConfig = createTextConfig(stateModel, opt, true); + } + } + } + // PENDING: if there is many requirements that emphasis position + // need to be different from normal position, we might consider + // auto silent is those cases. + textContent.silent = !!normalModel.getShallow('silent'); + // Keep x and y + if (textContent.style.x != null) { + normalStyle.x = textContent.style.x; + } + if (textContent.style.y != null) { + normalStyle.y = textContent.style.y; + } + textContent.ignore = !showNormal; + // Always create new style. + textContent.useStyle(normalStyle); + textContent.dirty(); + if (opt.enableTextSetter) { + labelInner(textContent).setLabelText = function (interpolatedValue) { + var labelStatesTexts = getLabelText(opt, labelStatesModels, interpolatedValue); + setLabelText(textContent, labelStatesTexts); + }; + } + } else if (textContent) { + // Not display rich text. + textContent.ignore = true; + } + targetEl.dirty(); + } + function getLabelStatesModels(itemModel, labelName) { + labelName = labelName || 'label'; + var statesModels = { + normal: itemModel.getModel(labelName) + }; + for (var i = 0; i < SPECIAL_STATES.length; i++) { + var stateName = SPECIAL_STATES[i]; + statesModels[stateName] = itemModel.getModel([stateName, labelName]); + } + return statesModels; + } + /** + * Set basic textStyle properties. + */ + function createTextStyle(textStyleModel, specifiedTextStyle, + // Fixed style in the code. Can't be set by model. + opt, isNotNormal, isAttached // If text is attached on an element. If so, auto color will handling in zrender. + ) { + var textStyle = {}; + setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached); + specifiedTextStyle && extend(textStyle, specifiedTextStyle); + // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false); + return textStyle; + } + function createTextConfig(textStyleModel, opt, isNotNormal) { + opt = opt || {}; + var textConfig = {}; + var labelPosition; + var labelRotate = textStyleModel.getShallow('rotate'); + var labelDistance = retrieve2(textStyleModel.getShallow('distance'), isNotNormal ? null : 5); + var labelOffset = textStyleModel.getShallow('offset'); + labelPosition = textStyleModel.getShallow('position') || (isNotNormal ? null : 'inside'); + // 'outside' is not a valid zr textPostion value, but used + // in bar series, and magric type should be considered. + labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top'); + if (labelPosition != null) { + textConfig.position = labelPosition; + } + if (labelOffset != null) { + textConfig.offset = labelOffset; + } + if (labelRotate != null) { + labelRotate *= Math.PI / 180; + textConfig.rotation = labelRotate; + } + if (labelDistance != null) { + textConfig.distance = labelDistance; + } + // fill and auto is determined by the color of path fill if it's not specified by developers. + textConfig.outsideFill = textStyleModel.get('color') === 'inherit' ? opt.inheritColor || null : 'auto'; + return textConfig; + } + /** + * The uniform entry of set text style, that is, retrieve style definitions + * from `model` and set to `textStyle` object. + * + * Never in merge mode, but in overwrite mode, that is, all of the text style + * properties will be set. (Consider the states of normal and emphasis and + * default value can be adopted, merge would make the logic too complicated + * to manage.) + */ + function setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached) { + // Consider there will be abnormal when merge hover style to normal style if given default value. + opt = opt || EMPTY_OBJ; + var ecModel = textStyleModel.ecModel; + var globalTextStyle = ecModel && ecModel.option.textStyle; + // Consider case: + // { + // data: [{ + // value: 12, + // label: { + // rich: { + // // no 'a' here but using parent 'a'. + // } + // } + // }], + // rich: { + // a: { ... } + // } + // } + var richItemNames = getRichItemNames(textStyleModel); + var richResult; + if (richItemNames) { + richResult = {}; + for (var name_1 in richItemNames) { + if (richItemNames.hasOwnProperty(name_1)) { + // Cascade is supported in rich. + var richTextStyle = textStyleModel.getModel(['rich', name_1]); + // In rich, never `disableBox`. + // FIXME: consider `label: {formatter: '{a|xx}', color: 'blue', rich: {a: {}}}`, + // the default color `'blue'` will not be adopted if no color declared in `rich`. + // That might confuses users. So probably we should put `textStyleModel` as the + // root ancestor of the `richTextStyle`. But that would be a break change. + setTokenTextStyle(richResult[name_1] = {}, richTextStyle, globalTextStyle, opt, isNotNormal, isAttached, false, true); + } + } + } + if (richResult) { + textStyle.rich = richResult; + } + var overflow = textStyleModel.get('overflow'); + if (overflow) { + textStyle.overflow = overflow; + } + var margin = textStyleModel.get('minMargin'); + if (margin != null) { + textStyle.margin = margin; + } + setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, true, false); + } + // Consider case: + // { + // data: [{ + // value: 12, + // label: { + // rich: { + // // no 'a' here but using parent 'a'. + // } + // } + // }], + // rich: { + // a: { ... } + // } + // } + // TODO TextStyleModel + function getRichItemNames(textStyleModel) { + // Use object to remove duplicated names. + var richItemNameMap; + while (textStyleModel && textStyleModel !== textStyleModel.ecModel) { + var rich = (textStyleModel.option || EMPTY_OBJ).rich; + if (rich) { + richItemNameMap = richItemNameMap || {}; + var richKeys = keys(rich); + for (var i = 0; i < richKeys.length; i++) { + var richKey = richKeys[i]; + richItemNameMap[richKey] = 1; + } + } + textStyleModel = textStyleModel.parentModel; + } + return richItemNameMap; + } + var TEXT_PROPS_WITH_GLOBAL = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY']; + var TEXT_PROPS_SELF = ['align', 'lineHeight', 'width', 'height', 'tag', 'verticalAlign', 'ellipsis']; + var TEXT_PROPS_BOX = ['padding', 'borderWidth', 'borderRadius', 'borderDashOffset', 'backgroundColor', 'borderColor', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY']; + function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, isBlock, inRich) { + // In merge mode, default value should not be given. + globalTextStyle = !isNotNormal && globalTextStyle || EMPTY_OBJ; + var inheritColor = opt && opt.inheritColor; + var fillColor = textStyleModel.getShallow('color'); + var strokeColor = textStyleModel.getShallow('textBorderColor'); + var opacity = retrieve2(textStyleModel.getShallow('opacity'), globalTextStyle.opacity); + if (fillColor === 'inherit' || fillColor === 'auto') { + if ("development" !== 'production') { + if (fillColor === 'auto') { + deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\''); + } + } + if (inheritColor) { + fillColor = inheritColor; + } else { + fillColor = null; + } + } + if (strokeColor === 'inherit' || strokeColor === 'auto') { + if ("development" !== 'production') { + if (strokeColor === 'auto') { + deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\''); + } + } + if (inheritColor) { + strokeColor = inheritColor; + } else { + strokeColor = null; + } + } + if (!isAttached) { + // Only use default global textStyle.color if text is individual. + // Otherwise it will use the strategy of attached text color because text may be on a path. + fillColor = fillColor || globalTextStyle.color; + strokeColor = strokeColor || globalTextStyle.textBorderColor; + } + if (fillColor != null) { + textStyle.fill = fillColor; + } + if (strokeColor != null) { + textStyle.stroke = strokeColor; + } + var textBorderWidth = retrieve2(textStyleModel.getShallow('textBorderWidth'), globalTextStyle.textBorderWidth); + if (textBorderWidth != null) { + textStyle.lineWidth = textBorderWidth; + } + var textBorderType = retrieve2(textStyleModel.getShallow('textBorderType'), globalTextStyle.textBorderType); + if (textBorderType != null) { + textStyle.lineDash = textBorderType; + } + var textBorderDashOffset = retrieve2(textStyleModel.getShallow('textBorderDashOffset'), globalTextStyle.textBorderDashOffset); + if (textBorderDashOffset != null) { + textStyle.lineDashOffset = textBorderDashOffset; + } + if (!isNotNormal && opacity == null && !inRich) { + opacity = opt && opt.defaultOpacity; + } + if (opacity != null) { + textStyle.opacity = opacity; + } + // TODO + if (!isNotNormal && !isAttached) { + // Set default finally. + if (textStyle.fill == null && opt.inheritColor) { + textStyle.fill = opt.inheritColor; + } + } + // Do not use `getFont` here, because merge should be supported, where + // part of these properties may be changed in emphasis style, and the + // others should remain their original value got from normal style. + for (var i = 0; i < TEXT_PROPS_WITH_GLOBAL.length; i++) { + var key = TEXT_PROPS_WITH_GLOBAL[i]; + var val = retrieve2(textStyleModel.getShallow(key), globalTextStyle[key]); + if (val != null) { + textStyle[key] = val; + } + } + for (var i = 0; i < TEXT_PROPS_SELF.length; i++) { + var key = TEXT_PROPS_SELF[i]; + var val = textStyleModel.getShallow(key); + if (val != null) { + textStyle[key] = val; + } + } + if (textStyle.verticalAlign == null) { + var baseline = textStyleModel.getShallow('baseline'); + if (baseline != null) { + textStyle.verticalAlign = baseline; + } + } + if (!isBlock || !opt.disableBox) { + for (var i = 0; i < TEXT_PROPS_BOX.length; i++) { + var key = TEXT_PROPS_BOX[i]; + var val = textStyleModel.getShallow(key); + if (val != null) { + textStyle[key] = val; + } + } + var borderType = textStyleModel.getShallow('borderType'); + if (borderType != null) { + textStyle.borderDash = borderType; + } + if ((textStyle.backgroundColor === 'auto' || textStyle.backgroundColor === 'inherit') && inheritColor) { + if ("development" !== 'production') { + if (textStyle.backgroundColor === 'auto') { + deprecateReplaceLog('backgroundColor: \'auto\'', 'backgroundColor: \'inherit\''); + } + } + textStyle.backgroundColor = inheritColor; + } + if ((textStyle.borderColor === 'auto' || textStyle.borderColor === 'inherit') && inheritColor) { + if ("development" !== 'production') { + if (textStyle.borderColor === 'auto') { + deprecateReplaceLog('borderColor: \'auto\'', 'borderColor: \'inherit\''); + } + } + textStyle.borderColor = inheritColor; + } + } + } + function getFont(opt, ecModel) { + var gTextStyleModel = ecModel && ecModel.getModel('textStyle'); + return trim([ + // FIXME in node-canvas fontWeight is before fontStyle + opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '', opt.fontWeight || gTextStyleModel && gTextStyleModel.getShallow('fontWeight') || '', (opt.fontSize || gTextStyleModel && gTextStyleModel.getShallow('fontSize') || 12) + 'px', opt.fontFamily || gTextStyleModel && gTextStyleModel.getShallow('fontFamily') || 'sans-serif'].join(' ')); + } + var labelInner = makeInner(); + function setLabelValueAnimation(label, labelStatesModels, value, getDefaultText) { + if (!label) { + return; + } + var obj = labelInner(label); + obj.prevValue = obj.value; + obj.value = value; + var normalLabelModel = labelStatesModels.normal; + obj.valueAnimation = normalLabelModel.get('valueAnimation'); + if (obj.valueAnimation) { + obj.precision = normalLabelModel.get('precision'); + obj.defaultInterpolatedText = getDefaultText; + obj.statesModels = labelStatesModels; + } + } + function animateLabelValue(textEl, dataIndex, data, animatableModel, labelFetcher) { + var labelInnerStore = labelInner(textEl); + if (!labelInnerStore.valueAnimation || labelInnerStore.prevValue === labelInnerStore.value) { + // Value not changed, no new label animation + return; + } + var defaultInterpolatedText = labelInnerStore.defaultInterpolatedText; + // Consider the case that being animating, do not use the `obj.value`, + // Otherwise it will jump to the `obj.value` when this new animation started. + var currValue = retrieve2(labelInnerStore.interpolatedValue, labelInnerStore.prevValue); + var targetValue = labelInnerStore.value; + function during(percent) { + var interpolated = interpolateRawValues(data, labelInnerStore.precision, currValue, targetValue, percent); + labelInnerStore.interpolatedValue = percent === 1 ? null : interpolated; + var labelText = getLabelText({ + labelDataIndex: dataIndex, + labelFetcher: labelFetcher, + defaultText: defaultInterpolatedText ? defaultInterpolatedText(interpolated) : interpolated + '' + }, labelInnerStore.statesModels, interpolated); + setLabelText(textEl, labelText); + } + textEl.percent = 0; + (labelInnerStore.prevValue == null ? initProps : updateProps)(textEl, { + // percent is used to prevent animation from being aborted #15916 + percent: 1 + }, animatableModel, dataIndex, null, during); + } + + var PATH_COLOR = ['textStyle', 'color']; + var textStyleParams = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'padding', 'lineHeight', 'rich', 'width', 'height', 'overflow']; + // TODO Performance improvement? + var tmpText = new ZRText(); + var TextStyleMixin = /** @class */function () { + function TextStyleMixin() {} + /** + * Get color property or get color from option.textStyle.color + */ + // TODO Callback + TextStyleMixin.prototype.getTextColor = function (isEmphasis) { + var ecModel = this.ecModel; + return this.getShallow('color') || (!isEmphasis && ecModel ? ecModel.get(PATH_COLOR) : null); + }; + /** + * Create font string from fontStyle, fontWeight, fontSize, fontFamily + * @return {string} + */ + TextStyleMixin.prototype.getFont = function () { + return getFont({ + fontStyle: this.getShallow('fontStyle'), + fontWeight: this.getShallow('fontWeight'), + fontSize: this.getShallow('fontSize'), + fontFamily: this.getShallow('fontFamily') + }, this.ecModel); + }; + TextStyleMixin.prototype.getTextRect = function (text) { + var style = { + text: text, + verticalAlign: this.getShallow('verticalAlign') || this.getShallow('baseline') + }; + for (var i = 0; i < textStyleParams.length; i++) { + style[textStyleParams[i]] = this.getShallow(textStyleParams[i]); + } + tmpText.useStyle(style); + tmpText.update(); + return tmpText.getBoundingRect(); + }; + return TextStyleMixin; + }(); + + var LINE_STYLE_KEY_MAP = [['lineWidth', 'width'], ['stroke', 'color'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'type'], ['lineDashOffset', 'dashOffset'], ['lineCap', 'cap'], ['lineJoin', 'join'], ['miterLimit'] + // Option decal is in `DecalObject` but style.decal is in `PatternObject`. + // So do not transfer decal directly. + ]; + + var getLineStyle = makeStyleMapper(LINE_STYLE_KEY_MAP); + var LineStyleMixin = /** @class */function () { + function LineStyleMixin() {} + LineStyleMixin.prototype.getLineStyle = function (excludes) { + return getLineStyle(this, excludes); + }; + return LineStyleMixin; + }(); + + var ITEM_STYLE_KEY_MAP = [['fill', 'color'], ['stroke', 'borderColor'], ['lineWidth', 'borderWidth'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'borderType'], ['lineDashOffset', 'borderDashOffset'], ['lineCap', 'borderCap'], ['lineJoin', 'borderJoin'], ['miterLimit', 'borderMiterLimit'] + // Option decal is in `DecalObject` but style.decal is in `PatternObject`. + // So do not transfer decal directly. + ]; + + var getItemStyle = makeStyleMapper(ITEM_STYLE_KEY_MAP); + var ItemStyleMixin = /** @class */function () { + function ItemStyleMixin() {} + ItemStyleMixin.prototype.getItemStyle = function (excludes, includes) { + return getItemStyle(this, excludes, includes); + }; + return ItemStyleMixin; + }(); + + var Model = /** @class */function () { + function Model(option, parentModel, ecModel) { + this.parentModel = parentModel; + this.ecModel = ecModel; + this.option = option; + // Simple optimization + // if (this.init) { + // if (arguments.length <= 4) { + // this.init(option, parentModel, ecModel, extraOpt); + // } + // else { + // this.init.apply(this, arguments); + // } + // } + } + + Model.prototype.init = function (option, parentModel, ecModel) { + var rest = []; + for (var _i = 3; _i < arguments.length; _i++) { + rest[_i - 3] = arguments[_i]; + } + }; + /** + * Merge the input option to me. + */ + Model.prototype.mergeOption = function (option, ecModel) { + merge(this.option, option, true); + }; + // `path` can be 'a.b.c', so the return value type have to be `ModelOption` + // TODO: TYPE strict key check? + // get(path: string | string[], ignoreParent?: boolean): ModelOption; + Model.prototype.get = function (path, ignoreParent) { + if (path == null) { + return this.option; + } + return this._doGet(this.parsePath(path), !ignoreParent && this.parentModel); + }; + Model.prototype.getShallow = function (key, ignoreParent) { + var option = this.option; + var val = option == null ? option : option[key]; + if (val == null && !ignoreParent) { + var parentModel = this.parentModel; + if (parentModel) { + // FIXME:TS do not know how to make it works + val = parentModel.getShallow(key); + } + } + return val; + }; + // `path` can be 'a.b.c', so the return value type have to be `Model` + // getModel(path: string | string[], parentModel?: Model): Model; + // TODO 'a.b.c' is deprecated + Model.prototype.getModel = function (path, parentModel) { + var hasPath = path != null; + var pathFinal = hasPath ? this.parsePath(path) : null; + var obj = hasPath ? this._doGet(pathFinal) : this.option; + parentModel = parentModel || this.parentModel && this.parentModel.getModel(this.resolveParentPath(pathFinal)); + return new Model(obj, parentModel, this.ecModel); + }; + /** + * If model has option + */ + Model.prototype.isEmpty = function () { + return this.option == null; + }; + Model.prototype.restoreData = function () {}; + // Pending + Model.prototype.clone = function () { + var Ctor = this.constructor; + return new Ctor(clone(this.option)); + }; + // setReadOnly(properties): void { + // clazzUtil.setReadOnly(this, properties); + // } + // If path is null/undefined, return null/undefined. + Model.prototype.parsePath = function (path) { + if (typeof path === 'string') { + return path.split('.'); + } + return path; + }; + // Resolve path for parent. Perhaps useful when parent use a different property. + // Default to be a identity resolver. + // Can be modified to a different resolver. + Model.prototype.resolveParentPath = function (path) { + return path; + }; + // FIXME:TS check whether put this method here + Model.prototype.isAnimationEnabled = function () { + if (!env.node && this.option) { + if (this.option.animation != null) { + return !!this.option.animation; + } else if (this.parentModel) { + return this.parentModel.isAnimationEnabled(); + } + } + }; + Model.prototype._doGet = function (pathArr, parentModel) { + var obj = this.option; + if (!pathArr) { + return obj; + } + for (var i = 0; i < pathArr.length; i++) { + // Ignore empty + if (!pathArr[i]) { + continue; + } + // obj could be number/string/... (like 0) + obj = obj && typeof obj === 'object' ? obj[pathArr[i]] : null; + if (obj == null) { + break; + } + } + if (obj == null && parentModel) { + obj = parentModel._doGet(this.resolveParentPath(pathArr), parentModel.parentModel); + } + return obj; + }; + return Model; + }(); + // Enable Model.extend. + enableClassExtend(Model); + enableClassCheck(Model); + mixin(Model, LineStyleMixin); + mixin(Model, ItemStyleMixin); + mixin(Model, AreaStyleMixin); + mixin(Model, TextStyleMixin); + + // A random offset + var base = Math.round(Math.random() * 10); + /** + * @public + * @param {string} type + * @return {string} + */ + function getUID(type) { + // Considering the case of crossing js context, + // use Math.random to make id as unique as possible. + return [type || '', base++].join('_'); + } + /** + * Implements `SubTypeDefaulterManager` for `target`. + */ + function enableSubTypeDefaulter(target) { + var subTypeDefaulters = {}; + target.registerSubTypeDefaulter = function (componentType, defaulter) { + var componentTypeInfo = parseClassType(componentType); + subTypeDefaulters[componentTypeInfo.main] = defaulter; + }; + target.determineSubType = function (componentType, option) { + var type = option.type; + if (!type) { + var componentTypeMain = parseClassType(componentType).main; + if (target.hasSubTypes(componentType) && subTypeDefaulters[componentTypeMain]) { + type = subTypeDefaulters[componentTypeMain](option); + } + } + return type; + }; + } + /** + * Implements `TopologicalTravelable` for `entity`. + * + * Topological travel on Activity Network (Activity On Vertices). + * Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis']. + * If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology. + * If there is circular dependencey, Error will be thrown. + */ + function enableTopologicalTravel(entity, dependencyGetter) { + /** + * @param targetNameList Target Component type list. + * Can be ['aa', 'bb', 'aa.xx'] + * @param fullNameList By which we can build dependency graph. + * @param callback Params: componentType, dependencies. + * @param context Scope of callback. + */ + entity.topologicalTravel = function (targetNameList, fullNameList, callback, context) { + if (!targetNameList.length) { + return; + } + var result = makeDepndencyGraph(fullNameList); + var graph = result.graph; + var noEntryList = result.noEntryList; + var targetNameSet = {}; + each(targetNameList, function (name) { + targetNameSet[name] = true; + }); + while (noEntryList.length) { + var currComponentType = noEntryList.pop(); + var currVertex = graph[currComponentType]; + var isInTargetNameSet = !!targetNameSet[currComponentType]; + if (isInTargetNameSet) { + callback.call(context, currComponentType, currVertex.originalDeps.slice()); + delete targetNameSet[currComponentType]; + } + each(currVertex.successor, isInTargetNameSet ? removeEdgeAndAdd : removeEdge); + } + each(targetNameSet, function () { + var errMsg = ''; + if ("development" !== 'production') { + errMsg = makePrintable('Circular dependency may exists: ', targetNameSet, targetNameList, fullNameList); + } + throw new Error(errMsg); + }); + function removeEdge(succComponentType) { + graph[succComponentType].entryCount--; + if (graph[succComponentType].entryCount === 0) { + noEntryList.push(succComponentType); + } + } + // Consider this case: legend depends on series, and we call + // chart.setOption({series: [...]}), where only series is in option. + // If we do not have 'removeEdgeAndAdd', legendModel.mergeOption will + // not be called, but only sereis.mergeOption is called. Thus legend + // have no chance to update its local record about series (like which + // name of series is available in legend). + function removeEdgeAndAdd(succComponentType) { + targetNameSet[succComponentType] = true; + removeEdge(succComponentType); + } + }; + function makeDepndencyGraph(fullNameList) { + var graph = {}; + var noEntryList = []; + each(fullNameList, function (name) { + var thisItem = createDependencyGraphItem(graph, name); + var originalDeps = thisItem.originalDeps = dependencyGetter(name); + var availableDeps = getAvailableDependencies(originalDeps, fullNameList); + thisItem.entryCount = availableDeps.length; + if (thisItem.entryCount === 0) { + noEntryList.push(name); + } + each(availableDeps, function (dependentName) { + if (indexOf(thisItem.predecessor, dependentName) < 0) { + thisItem.predecessor.push(dependentName); + } + var thatItem = createDependencyGraphItem(graph, dependentName); + if (indexOf(thatItem.successor, dependentName) < 0) { + thatItem.successor.push(name); + } + }); + }); + return { + graph: graph, + noEntryList: noEntryList + }; + } + function createDependencyGraphItem(graph, name) { + if (!graph[name]) { + graph[name] = { + predecessor: [], + successor: [] + }; + } + return graph[name]; + } + function getAvailableDependencies(originalDeps, fullNameList) { + var availableDeps = []; + each(originalDeps, function (dep) { + indexOf(fullNameList, dep) >= 0 && availableDeps.push(dep); + }); + return availableDeps; + } + } + function inheritDefaultOption(superOption, subOption) { + // See also `model/Component.ts#getDefaultOption` + return merge(merge({}, superOption, true), subOption, true); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /** + * Language: English. + */ + var langEN = { + time: { + month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], + monthAbbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + dayOfWeekAbbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] + }, + legend: { + selector: { + all: 'All', + inverse: 'Inv' + } + }, + toolbox: { + brush: { + title: { + rect: 'Box Select', + polygon: 'Lasso Select', + lineX: 'Horizontally Select', + lineY: 'Vertically Select', + keep: 'Keep Selections', + clear: 'Clear Selections' + } + }, + dataView: { + title: 'Data View', + lang: ['Data View', 'Close', 'Refresh'] + }, + dataZoom: { + title: { + zoom: 'Zoom', + back: 'Zoom Reset' + } + }, + magicType: { + title: { + line: 'Switch to Line Chart', + bar: 'Switch to Bar Chart', + stack: 'Stack', + tiled: 'Tile' + } + }, + restore: { + title: 'Restore' + }, + saveAsImage: { + title: 'Save as Image', + lang: ['Right Click to Save Image'] + } + }, + series: { + typeNames: { + pie: 'Pie chart', + bar: 'Bar chart', + line: 'Line chart', + scatter: 'Scatter plot', + effectScatter: 'Ripple scatter plot', + radar: 'Radar chart', + tree: 'Tree', + treemap: 'Treemap', + boxplot: 'Boxplot', + candlestick: 'Candlestick', + k: 'K line chart', + heatmap: 'Heat map', + map: 'Map', + parallel: 'Parallel coordinate map', + lines: 'Line graph', + graph: 'Relationship graph', + sankey: 'Sankey diagram', + funnel: 'Funnel chart', + gauge: 'Gauge', + pictorialBar: 'Pictorial bar', + themeRiver: 'Theme River Map', + sunburst: 'Sunburst', + custom: 'Custom chart', + chart: 'Chart' + } + }, + aria: { + general: { + withTitle: 'This is a chart about "{title}"', + withoutTitle: 'This is a chart' + }, + series: { + single: { + prefix: '', + withName: ' with type {seriesType} named {seriesName}.', + withoutName: ' with type {seriesType}.' + }, + multiple: { + prefix: '. It consists of {seriesCount} series count.', + withName: ' The {seriesId} series is a {seriesType} representing {seriesName}.', + withoutName: ' The {seriesId} series is a {seriesType}.', + separator: { + middle: '', + end: '' + } + } + }, + data: { + allData: 'The data is as follows: ', + partialData: 'The first {displayCnt} items are: ', + withName: 'the data for {name} is {value}', + withoutName: '{value}', + separator: { + middle: ', ', + end: '. ' + } + } + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var langZH = { + time: { + month: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'], + monthAbbr: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], + dayOfWeek: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'], + dayOfWeekAbbr: ['日', '一', '二', '三', '四', '五', '六'] + }, + legend: { + selector: { + all: '全选', + inverse: '反选' + } + }, + toolbox: { + brush: { + title: { + rect: '矩形选择', + polygon: '圈选', + lineX: '横向选择', + lineY: '纵向选择', + keep: '保持选择', + clear: '清除选择' + } + }, + dataView: { + title: '数据视图', + lang: ['数据视图', '关闭', '刷新'] + }, + dataZoom: { + title: { + zoom: '区域缩放', + back: '区域缩放还原' + } + }, + magicType: { + title: { + line: '切换为折线图', + bar: '切换为柱状图', + stack: '切换为堆叠', + tiled: '切换为平铺' + } + }, + restore: { + title: '还原' + }, + saveAsImage: { + title: '保存为图片', + lang: ['右键另存为图片'] + } + }, + series: { + typeNames: { + pie: '饼图', + bar: '柱状图', + line: '折线图', + scatter: '散点图', + effectScatter: '涟漪散点图', + radar: '雷达图', + tree: '树图', + treemap: '矩形树图', + boxplot: '箱型图', + candlestick: 'K线图', + k: 'K线图', + heatmap: '热力图', + map: '地图', + parallel: '平行坐标图', + lines: '线图', + graph: '关系图', + sankey: '桑基图', + funnel: '漏斗图', + gauge: '仪表盘图', + pictorialBar: '象形柱图', + themeRiver: '主题河流图', + sunburst: '旭日图', + custom: '自定义图表', + chart: '图表' + } + }, + aria: { + general: { + withTitle: '这是一个关于“{title}”的图表。', + withoutTitle: '这是一个图表,' + }, + series: { + single: { + prefix: '', + withName: '图表类型是{seriesType},表示{seriesName}。', + withoutName: '图表类型是{seriesType}。' + }, + multiple: { + prefix: '它由{seriesCount}个图表系列组成。', + withName: '第{seriesId}个系列是一个表示{seriesName}的{seriesType},', + withoutName: '第{seriesId}个系列是一个{seriesType},', + separator: { + middle: ';', + end: '。' + } + } + }, + data: { + allData: '其数据是——', + partialData: '其中,前{displayCnt}项是——', + withName: '{name}的数据是{value}', + withoutName: '{value}', + separator: { + middle: ',', + end: '' + } + } + } + }; + + var LOCALE_ZH = 'ZH'; + var LOCALE_EN = 'EN'; + var DEFAULT_LOCALE = LOCALE_EN; + var localeStorage = {}; + var localeModels = {}; + var SYSTEM_LANG = !env.domSupported ? DEFAULT_LOCALE : function () { + var langStr = ( /* eslint-disable-next-line */ + document.documentElement.lang || navigator.language || navigator.browserLanguage || DEFAULT_LOCALE).toUpperCase(); + return langStr.indexOf(LOCALE_ZH) > -1 ? LOCALE_ZH : DEFAULT_LOCALE; + }(); + function registerLocale(locale, localeObj) { + locale = locale.toUpperCase(); + localeModels[locale] = new Model(localeObj); + localeStorage[locale] = localeObj; + } + // export function getLocale(locale: string) { + // return localeStorage[locale]; + // } + function createLocaleObject(locale) { + if (isString(locale)) { + var localeObj = localeStorage[locale.toUpperCase()] || {}; + if (locale === LOCALE_ZH || locale === LOCALE_EN) { + return clone(localeObj); + } else { + return merge(clone(localeObj), clone(localeStorage[DEFAULT_LOCALE]), false); + } + } else { + return merge(clone(locale), clone(localeStorage[DEFAULT_LOCALE]), false); + } + } + function getLocaleModel(lang) { + return localeModels[lang]; + } + function getDefaultLocaleModel() { + return localeModels[DEFAULT_LOCALE]; + } + // Default locale + registerLocale(LOCALE_EN, langEN); + registerLocale(LOCALE_ZH, langZH); + + var ONE_SECOND = 1000; + var ONE_MINUTE = ONE_SECOND * 60; + var ONE_HOUR = ONE_MINUTE * 60; + var ONE_DAY = ONE_HOUR * 24; + var ONE_YEAR = ONE_DAY * 365; + var defaultLeveledFormatter = { + year: '{yyyy}', + month: '{MMM}', + day: '{d}', + hour: '{HH}:{mm}', + minute: '{HH}:{mm}', + second: '{HH}:{mm}:{ss}', + millisecond: '{HH}:{mm}:{ss} {SSS}', + none: '{yyyy}-{MM}-{dd} {HH}:{mm}:{ss} {SSS}' + }; + var fullDayFormatter = '{yyyy}-{MM}-{dd}'; + var fullLeveledFormatter = { + year: '{yyyy}', + month: '{yyyy}-{MM}', + day: fullDayFormatter, + hour: fullDayFormatter + ' ' + defaultLeveledFormatter.hour, + minute: fullDayFormatter + ' ' + defaultLeveledFormatter.minute, + second: fullDayFormatter + ' ' + defaultLeveledFormatter.second, + millisecond: defaultLeveledFormatter.none + }; + var primaryTimeUnits = ['year', 'month', 'day', 'hour', 'minute', 'second', 'millisecond']; + var timeUnits = ['year', 'half-year', 'quarter', 'month', 'week', 'half-week', 'day', 'half-day', 'quarter-day', 'hour', 'minute', 'second', 'millisecond']; + function pad(str, len) { + str += ''; + return '0000'.substr(0, len - str.length) + str; + } + function getPrimaryTimeUnit(timeUnit) { + switch (timeUnit) { + case 'half-year': + case 'quarter': + return 'month'; + case 'week': + case 'half-week': + return 'day'; + case 'half-day': + case 'quarter-day': + return 'hour'; + default: + // year, minutes, second, milliseconds + return timeUnit; + } + } + function isPrimaryTimeUnit(timeUnit) { + return timeUnit === getPrimaryTimeUnit(timeUnit); + } + function getDefaultFormatPrecisionOfInterval(timeUnit) { + switch (timeUnit) { + case 'year': + case 'month': + return 'day'; + case 'millisecond': + return 'millisecond'; + default: + // Also for day, hour, minute, second + return 'second'; + } + } + function format( + // Note: The result based on `isUTC` are totally different, which can not be just simply + // substituted by the result without `isUTC`. So we make the param `isUTC` mandatory. + time, template, isUTC, lang) { + var date = parseDate(time); + var y = date[fullYearGetterName(isUTC)](); + var M = date[monthGetterName(isUTC)]() + 1; + var q = Math.floor((M - 1) / 3) + 1; + var d = date[dateGetterName(isUTC)](); + var e = date['get' + (isUTC ? 'UTC' : '') + 'Day'](); + var H = date[hoursGetterName(isUTC)](); + var h = (H - 1) % 12 + 1; + var m = date[minutesGetterName(isUTC)](); + var s = date[secondsGetterName(isUTC)](); + var S = date[millisecondsGetterName(isUTC)](); + var localeModel = lang instanceof Model ? lang : getLocaleModel(lang || SYSTEM_LANG) || getDefaultLocaleModel(); + var timeModel = localeModel.getModel('time'); + var month = timeModel.get('month'); + var monthAbbr = timeModel.get('monthAbbr'); + var dayOfWeek = timeModel.get('dayOfWeek'); + var dayOfWeekAbbr = timeModel.get('dayOfWeekAbbr'); + return (template || '').replace(/{yyyy}/g, y + '').replace(/{yy}/g, pad(y % 100 + '', 2)).replace(/{Q}/g, q + '').replace(/{MMMM}/g, month[M - 1]).replace(/{MMM}/g, monthAbbr[M - 1]).replace(/{MM}/g, pad(M, 2)).replace(/{M}/g, M + '').replace(/{dd}/g, pad(d, 2)).replace(/{d}/g, d + '').replace(/{eeee}/g, dayOfWeek[e]).replace(/{ee}/g, dayOfWeekAbbr[e]).replace(/{e}/g, e + '').replace(/{HH}/g, pad(H, 2)).replace(/{H}/g, H + '').replace(/{hh}/g, pad(h + '', 2)).replace(/{h}/g, h + '').replace(/{mm}/g, pad(m, 2)).replace(/{m}/g, m + '').replace(/{ss}/g, pad(s, 2)).replace(/{s}/g, s + '').replace(/{SSS}/g, pad(S, 3)).replace(/{S}/g, S + ''); + } + function leveledFormat(tick, idx, formatter, lang, isUTC) { + var template = null; + if (isString(formatter)) { + // Single formatter for all units at all levels + template = formatter; + } else if (isFunction(formatter)) { + // Callback formatter + template = formatter(tick.value, idx, { + level: tick.level + }); + } else { + var defaults$1 = extend({}, defaultLeveledFormatter); + if (tick.level > 0) { + for (var i = 0; i < primaryTimeUnits.length; ++i) { + defaults$1[primaryTimeUnits[i]] = "{primary|" + defaults$1[primaryTimeUnits[i]] + "}"; + } + } + var mergedFormatter = formatter ? formatter.inherit === false ? formatter // Use formatter with bigger units + : defaults(formatter, defaults$1) : defaults$1; + var unit = getUnitFromValue(tick.value, isUTC); + if (mergedFormatter[unit]) { + template = mergedFormatter[unit]; + } else if (mergedFormatter.inherit) { + // Unit formatter is not defined and should inherit from bigger units + var targetId = timeUnits.indexOf(unit); + for (var i = targetId - 1; i >= 0; --i) { + if (mergedFormatter[unit]) { + template = mergedFormatter[unit]; + break; + } + } + template = template || defaults$1.none; + } + if (isArray(template)) { + var levelId = tick.level == null ? 0 : tick.level >= 0 ? tick.level : template.length + tick.level; + levelId = Math.min(levelId, template.length - 1); + template = template[levelId]; + } + } + return format(new Date(tick.value), template, isUTC, lang); + } + function getUnitFromValue(value, isUTC) { + var date = parseDate(value); + var M = date[monthGetterName(isUTC)]() + 1; + var d = date[dateGetterName(isUTC)](); + var h = date[hoursGetterName(isUTC)](); + var m = date[minutesGetterName(isUTC)](); + var s = date[secondsGetterName(isUTC)](); + var S = date[millisecondsGetterName(isUTC)](); + var isSecond = S === 0; + var isMinute = isSecond && s === 0; + var isHour = isMinute && m === 0; + var isDay = isHour && h === 0; + var isMonth = isDay && d === 1; + var isYear = isMonth && M === 1; + if (isYear) { + return 'year'; + } else if (isMonth) { + return 'month'; + } else if (isDay) { + return 'day'; + } else if (isHour) { + return 'hour'; + } else if (isMinute) { + return 'minute'; + } else if (isSecond) { + return 'second'; + } else { + return 'millisecond'; + } + } + function getUnitValue(value, unit, isUTC) { + var date = isNumber(value) ? parseDate(value) : value; + unit = unit || getUnitFromValue(value, isUTC); + switch (unit) { + case 'year': + return date[fullYearGetterName(isUTC)](); + case 'half-year': + return date[monthGetterName(isUTC)]() >= 6 ? 1 : 0; + case 'quarter': + return Math.floor((date[monthGetterName(isUTC)]() + 1) / 4); + case 'month': + return date[monthGetterName(isUTC)](); + case 'day': + return date[dateGetterName(isUTC)](); + case 'half-day': + return date[hoursGetterName(isUTC)]() / 24; + case 'hour': + return date[hoursGetterName(isUTC)](); + case 'minute': + return date[minutesGetterName(isUTC)](); + case 'second': + return date[secondsGetterName(isUTC)](); + case 'millisecond': + return date[millisecondsGetterName(isUTC)](); + } + } + function fullYearGetterName(isUTC) { + return isUTC ? 'getUTCFullYear' : 'getFullYear'; + } + function monthGetterName(isUTC) { + return isUTC ? 'getUTCMonth' : 'getMonth'; + } + function dateGetterName(isUTC) { + return isUTC ? 'getUTCDate' : 'getDate'; + } + function hoursGetterName(isUTC) { + return isUTC ? 'getUTCHours' : 'getHours'; + } + function minutesGetterName(isUTC) { + return isUTC ? 'getUTCMinutes' : 'getMinutes'; + } + function secondsGetterName(isUTC) { + return isUTC ? 'getUTCSeconds' : 'getSeconds'; + } + function millisecondsGetterName(isUTC) { + return isUTC ? 'getUTCMilliseconds' : 'getMilliseconds'; + } + function fullYearSetterName(isUTC) { + return isUTC ? 'setUTCFullYear' : 'setFullYear'; + } + function monthSetterName(isUTC) { + return isUTC ? 'setUTCMonth' : 'setMonth'; + } + function dateSetterName(isUTC) { + return isUTC ? 'setUTCDate' : 'setDate'; + } + function hoursSetterName(isUTC) { + return isUTC ? 'setUTCHours' : 'setHours'; + } + function minutesSetterName(isUTC) { + return isUTC ? 'setUTCMinutes' : 'setMinutes'; + } + function secondsSetterName(isUTC) { + return isUTC ? 'setUTCSeconds' : 'setSeconds'; + } + function millisecondsSetterName(isUTC) { + return isUTC ? 'setUTCMilliseconds' : 'setMilliseconds'; + } + + function getTextRect(text, font, align, verticalAlign, padding, rich, truncate, lineHeight) { + var textEl = new ZRText({ + style: { + text: text, + font: font, + align: align, + verticalAlign: verticalAlign, + padding: padding, + rich: rich, + overflow: truncate ? 'truncate' : null, + lineHeight: lineHeight + } + }); + return textEl.getBoundingRect(); + } + + /** + * Add a comma each three digit. + */ + function addCommas(x) { + if (!isNumeric(x)) { + return isString(x) ? x : '-'; + } + var parts = (x + '').split('.'); + return parts[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,') + (parts.length > 1 ? '.' + parts[1] : ''); + } + function toCamelCase(str, upperCaseFirst) { + str = (str || '').toLowerCase().replace(/-(.)/g, function (match, group1) { + return group1.toUpperCase(); + }); + if (upperCaseFirst && str) { + str = str.charAt(0).toUpperCase() + str.slice(1); + } + return str; + } + var normalizeCssArray$1 = normalizeCssArray; + /** + * Make value user readable for tooltip and label. + * "User readable": + * Try to not print programmer-specific text like NaN, Infinity, null, undefined. + * Avoid to display an empty string, which users can not recognize there is + * a value and it might look like a bug. + */ + function makeValueReadable(value, valueType, useUTC) { + var USER_READABLE_DEFUALT_TIME_PATTERN = '{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}'; + function stringToUserReadable(str) { + return str && trim(str) ? str : '-'; + } + function isNumberUserReadable(num) { + return !!(num != null && !isNaN(num) && isFinite(num)); + } + var isTypeTime = valueType === 'time'; + var isValueDate = value instanceof Date; + if (isTypeTime || isValueDate) { + var date = isTypeTime ? parseDate(value) : value; + if (!isNaN(+date)) { + return format(date, USER_READABLE_DEFUALT_TIME_PATTERN, useUTC); + } else if (isValueDate) { + return '-'; + } + // In other cases, continue to try to display the value in the following code. + } + + if (valueType === 'ordinal') { + return isStringSafe(value) ? stringToUserReadable(value) : isNumber(value) ? isNumberUserReadable(value) ? value + '' : '-' : '-'; + } + // By default. + var numericResult = numericToNumber(value); + return isNumberUserReadable(numericResult) ? addCommas(numericResult) : isStringSafe(value) ? stringToUserReadable(value) : typeof value === 'boolean' ? value + '' : '-'; + } + var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g']; + var wrapVar = function (varName, seriesIdx) { + return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}'; + }; + /** + * Template formatter + * @param {Array.|Object} paramsList + */ + function formatTpl(tpl, paramsList, encode) { + if (!isArray(paramsList)) { + paramsList = [paramsList]; + } + var seriesLen = paramsList.length; + if (!seriesLen) { + return ''; + } + var $vars = paramsList[0].$vars || []; + for (var i = 0; i < $vars.length; i++) { + var alias = TPL_VAR_ALIAS[i]; + tpl = tpl.replace(wrapVar(alias), wrapVar(alias, 0)); + } + for (var seriesIdx = 0; seriesIdx < seriesLen; seriesIdx++) { + for (var k = 0; k < $vars.length; k++) { + var val = paramsList[seriesIdx][$vars[k]]; + tpl = tpl.replace(wrapVar(TPL_VAR_ALIAS[k], seriesIdx), encode ? encodeHTML(val) : val); + } + } + return tpl; + } + /** + * simple Template formatter + */ + function formatTplSimple(tpl, param, encode) { + each(param, function (value, key) { + tpl = tpl.replace('{' + key + '}', encode ? encodeHTML(value) : value); + }); + return tpl; + } + function getTooltipMarker(inOpt, extraCssText) { + var opt = isString(inOpt) ? { + color: inOpt, + extraCssText: extraCssText + } : inOpt || {}; + var color = opt.color; + var type = opt.type; + extraCssText = opt.extraCssText; + var renderMode = opt.renderMode || 'html'; + if (!color) { + return ''; + } + if (renderMode === 'html') { + return type === 'subItem' ? '' : ''; + } else { + // Should better not to auto generate style name by auto-increment number here. + // Because this util is usually called in tooltip formatter, which is probably + // called repeatedly when mouse move and the auto-increment number increases fast. + // Users can make their own style name by theirselves, make it unique and readable. + var markerId = opt.markerId || 'markerX'; + return { + renderMode: renderMode, + content: '{' + markerId + '|} ', + style: type === 'subItem' ? { + width: 4, + height: 4, + borderRadius: 2, + backgroundColor: color + } : { + width: 10, + height: 10, + borderRadius: 5, + backgroundColor: color + } + }; + } + } + /** + * @deprecated Use `time/format` instead. + * ISO Date format + * @param {string} tpl + * @param {number} value + * @param {boolean} [isUTC=false] Default in local time. + * see `module:echarts/scale/Time` + * and `module:echarts/util/number#parseDate`. + * @inner + */ + function formatTime(tpl, value, isUTC) { + if ("development" !== 'production') { + deprecateReplaceLog('echarts.format.formatTime', 'echarts.time.format'); + } + if (tpl === 'week' || tpl === 'month' || tpl === 'quarter' || tpl === 'half-year' || tpl === 'year') { + tpl = 'MM-dd\nyyyy'; + } + var date = parseDate(value); + var getUTC = isUTC ? 'getUTC' : 'get'; + var y = date[getUTC + 'FullYear'](); + var M = date[getUTC + 'Month']() + 1; + var d = date[getUTC + 'Date'](); + var h = date[getUTC + 'Hours'](); + var m = date[getUTC + 'Minutes'](); + var s = date[getUTC + 'Seconds'](); + var S = date[getUTC + 'Milliseconds'](); + tpl = tpl.replace('MM', pad(M, 2)).replace('M', M).replace('yyyy', y).replace('yy', pad(y % 100 + '', 2)).replace('dd', pad(d, 2)).replace('d', d).replace('hh', pad(h, 2)).replace('h', h).replace('mm', pad(m, 2)).replace('m', m).replace('ss', pad(s, 2)).replace('s', s).replace('SSS', pad(S, 3)); + return tpl; + } + /** + * Capital first + * @param {string} str + * @return {string} + */ + function capitalFirst(str) { + return str ? str.charAt(0).toUpperCase() + str.substr(1) : str; + } + /** + * @return Never be null/undefined. + */ + function convertToColorString(color, defaultColor) { + defaultColor = defaultColor || 'transparent'; + return isString(color) ? color : isObject(color) ? color.colorStops && (color.colorStops[0] || {}).color || defaultColor : defaultColor; + } + /** + * open new tab + * @param link url + * @param target blank or self + */ + function windowOpen(link, target) { + /* global window */ + if (target === '_blank' || target === 'blank') { + var blank = window.open(); + blank.opener = null; + blank.location.href = link; + } else { + window.open(link, target); + } + } + + var each$1 = each; + /** + * @public + */ + var LOCATION_PARAMS = ['left', 'right', 'top', 'bottom', 'width', 'height']; + /** + * @public + */ + var HV_NAMES = [['width', 'left', 'right'], ['height', 'top', 'bottom']]; + function boxLayout(orient, group, gap, maxWidth, maxHeight) { + var x = 0; + var y = 0; + if (maxWidth == null) { + maxWidth = Infinity; + } + if (maxHeight == null) { + maxHeight = Infinity; + } + var currentLineMaxSize = 0; + group.eachChild(function (child, idx) { + var rect = child.getBoundingRect(); + var nextChild = group.childAt(idx + 1); + var nextChildRect = nextChild && nextChild.getBoundingRect(); + var nextX; + var nextY; + if (orient === 'horizontal') { + var moveX = rect.width + (nextChildRect ? -nextChildRect.x + rect.x : 0); + nextX = x + moveX; + // Wrap when width exceeds maxWidth or meet a `newline` group + // FIXME compare before adding gap? + if (nextX > maxWidth || child.newline) { + x = 0; + nextX = moveX; + y += currentLineMaxSize + gap; + currentLineMaxSize = rect.height; + } else { + // FIXME: consider rect.y is not `0`? + currentLineMaxSize = Math.max(currentLineMaxSize, rect.height); + } + } else { + var moveY = rect.height + (nextChildRect ? -nextChildRect.y + rect.y : 0); + nextY = y + moveY; + // Wrap when width exceeds maxHeight or meet a `newline` group + if (nextY > maxHeight || child.newline) { + x += currentLineMaxSize + gap; + y = 0; + nextY = moveY; + currentLineMaxSize = rect.width; + } else { + currentLineMaxSize = Math.max(currentLineMaxSize, rect.width); + } + } + if (child.newline) { + return; + } + child.x = x; + child.y = y; + child.markRedraw(); + orient === 'horizontal' ? x = nextX + gap : y = nextY + gap; + }); + } + /** + * VBox or HBox layouting + * @param {string} orient + * @param {module:zrender/graphic/Group} group + * @param {number} gap + * @param {number} [width=Infinity] + * @param {number} [height=Infinity] + */ + var box = boxLayout; + /** + * VBox layouting + * @param {module:zrender/graphic/Group} group + * @param {number} gap + * @param {number} [width=Infinity] + * @param {number} [height=Infinity] + */ + var vbox = curry(boxLayout, 'vertical'); + /** + * HBox layouting + * @param {module:zrender/graphic/Group} group + * @param {number} gap + * @param {number} [width=Infinity] + * @param {number} [height=Infinity] + */ + var hbox = curry(boxLayout, 'horizontal'); + /** + * If x or x2 is not specified or 'center' 'left' 'right', + * the width would be as long as possible. + * If y or y2 is not specified or 'middle' 'top' 'bottom', + * the height would be as long as possible. + */ + function getAvailableSize(positionInfo, containerRect, margin) { + var containerWidth = containerRect.width; + var containerHeight = containerRect.height; + var x = parsePercent$1(positionInfo.left, containerWidth); + var y = parsePercent$1(positionInfo.top, containerHeight); + var x2 = parsePercent$1(positionInfo.right, containerWidth); + var y2 = parsePercent$1(positionInfo.bottom, containerHeight); + (isNaN(x) || isNaN(parseFloat(positionInfo.left))) && (x = 0); + (isNaN(x2) || isNaN(parseFloat(positionInfo.right))) && (x2 = containerWidth); + (isNaN(y) || isNaN(parseFloat(positionInfo.top))) && (y = 0); + (isNaN(y2) || isNaN(parseFloat(positionInfo.bottom))) && (y2 = containerHeight); + margin = normalizeCssArray$1(margin || 0); + return { + width: Math.max(x2 - x - margin[1] - margin[3], 0), + height: Math.max(y2 - y - margin[0] - margin[2], 0) + }; + } + /** + * Parse position info. + */ + function getLayoutRect(positionInfo, containerRect, margin) { + margin = normalizeCssArray$1(margin || 0); + var containerWidth = containerRect.width; + var containerHeight = containerRect.height; + var left = parsePercent$1(positionInfo.left, containerWidth); + var top = parsePercent$1(positionInfo.top, containerHeight); + var right = parsePercent$1(positionInfo.right, containerWidth); + var bottom = parsePercent$1(positionInfo.bottom, containerHeight); + var width = parsePercent$1(positionInfo.width, containerWidth); + var height = parsePercent$1(positionInfo.height, containerHeight); + var verticalMargin = margin[2] + margin[0]; + var horizontalMargin = margin[1] + margin[3]; + var aspect = positionInfo.aspect; + // If width is not specified, calculate width from left and right + if (isNaN(width)) { + width = containerWidth - right - horizontalMargin - left; + } + if (isNaN(height)) { + height = containerHeight - bottom - verticalMargin - top; + } + if (aspect != null) { + // If width and height are not given + // 1. Graph should not exceeds the container + // 2. Aspect must be keeped + // 3. Graph should take the space as more as possible + // FIXME + // Margin is not considered, because there is no case that both + // using margin and aspect so far. + if (isNaN(width) && isNaN(height)) { + if (aspect > containerWidth / containerHeight) { + width = containerWidth * 0.8; + } else { + height = containerHeight * 0.8; + } + } + // Calculate width or height with given aspect + if (isNaN(width)) { + width = aspect * height; + } + if (isNaN(height)) { + height = width / aspect; + } + } + // If left is not specified, calculate left from right and width + if (isNaN(left)) { + left = containerWidth - right - width - horizontalMargin; + } + if (isNaN(top)) { + top = containerHeight - bottom - height - verticalMargin; + } + // Align left and top + switch (positionInfo.left || positionInfo.right) { + case 'center': + left = containerWidth / 2 - width / 2 - margin[3]; + break; + case 'right': + left = containerWidth - width - horizontalMargin; + break; + } + switch (positionInfo.top || positionInfo.bottom) { + case 'middle': + case 'center': + top = containerHeight / 2 - height / 2 - margin[0]; + break; + case 'bottom': + top = containerHeight - height - verticalMargin; + break; + } + // If something is wrong and left, top, width, height are calculated as NaN + left = left || 0; + top = top || 0; + if (isNaN(width)) { + // Width may be NaN if only one value is given except width + width = containerWidth - horizontalMargin - left - (right || 0); + } + if (isNaN(height)) { + // Height may be NaN if only one value is given except height + height = containerHeight - verticalMargin - top - (bottom || 0); + } + var rect = new BoundingRect(left + margin[3], top + margin[0], width, height); + rect.margin = margin; + return rect; + } + /** + * Position a zr element in viewport + * Group position is specified by either + * {left, top}, {right, bottom} + * If all properties exists, right and bottom will be igonred. + * + * Logic: + * 1. Scale (against origin point in parent coord) + * 2. Rotate (against origin point in parent coord) + * 3. Translate (with el.position by this method) + * So this method only fixes the last step 'Translate', which does not affect + * scaling and rotating. + * + * If be called repeatedly with the same input el, the same result will be gotten. + * + * Return true if the layout happened. + * + * @param el Should have `getBoundingRect` method. + * @param positionInfo + * @param positionInfo.left + * @param positionInfo.top + * @param positionInfo.right + * @param positionInfo.bottom + * @param positionInfo.width Only for opt.boundingModel: 'raw' + * @param positionInfo.height Only for opt.boundingModel: 'raw' + * @param containerRect + * @param margin + * @param opt + * @param opt.hv Only horizontal or only vertical. Default to be [1, 1] + * @param opt.boundingMode + * Specify how to calculate boundingRect when locating. + * 'all': Position the boundingRect that is transformed and uioned + * both itself and its descendants. + * This mode simplies confine the elements in the bounding + * of their container (e.g., using 'right: 0'). + * 'raw': Position the boundingRect that is not transformed and only itself. + * This mode is useful when you want a element can overflow its + * container. (Consider a rotated circle needs to be located in a corner.) + * In this mode positionInfo.width/height can only be number. + */ + function positionElement(el, positionInfo, containerRect, margin, opt, out) { + var h = !opt || !opt.hv || opt.hv[0]; + var v = !opt || !opt.hv || opt.hv[1]; + var boundingMode = opt && opt.boundingMode || 'all'; + out = out || el; + out.x = el.x; + out.y = el.y; + if (!h && !v) { + return false; + } + var rect; + if (boundingMode === 'raw') { + rect = el.type === 'group' ? new BoundingRect(0, 0, +positionInfo.width || 0, +positionInfo.height || 0) : el.getBoundingRect(); + } else { + rect = el.getBoundingRect(); + if (el.needLocalTransform()) { + var transform = el.getLocalTransform(); + // Notice: raw rect may be inner object of el, + // which should not be modified. + rect = rect.clone(); + rect.applyTransform(transform); + } + } + // The real width and height can not be specified but calculated by the given el. + var layoutRect = getLayoutRect(defaults({ + width: rect.width, + height: rect.height + }, positionInfo), containerRect, margin); + // Because 'tranlate' is the last step in transform + // (see zrender/core/Transformable#getLocalTransform), + // we can just only modify el.position to get final result. + var dx = h ? layoutRect.x - rect.x : 0; + var dy = v ? layoutRect.y - rect.y : 0; + if (boundingMode === 'raw') { + out.x = dx; + out.y = dy; + } else { + out.x += dx; + out.y += dy; + } + if (out === el) { + el.markRedraw(); + } + return true; + } + /** + * @param option Contains some of the properties in HV_NAMES. + * @param hvIdx 0: horizontal; 1: vertical. + */ + function sizeCalculable(option, hvIdx) { + return option[HV_NAMES[hvIdx][0]] != null || option[HV_NAMES[hvIdx][1]] != null && option[HV_NAMES[hvIdx][2]] != null; + } + function fetchLayoutMode(ins) { + var layoutMode = ins.layoutMode || ins.constructor.layoutMode; + return isObject(layoutMode) ? layoutMode : layoutMode ? { + type: layoutMode + } : null; + } + /** + * Consider Case: + * When default option has {left: 0, width: 100}, and we set {right: 0} + * through setOption or media query, using normal zrUtil.merge will cause + * {right: 0} does not take effect. + * + * @example + * ComponentModel.extend({ + * init: function () { + * ... + * let inputPositionParams = layout.getLayoutParams(option); + * this.mergeOption(inputPositionParams); + * }, + * mergeOption: function (newOption) { + * newOption && zrUtil.merge(thisOption, newOption, true); + * layout.mergeLayoutParam(thisOption, newOption); + * } + * }); + * + * @param targetOption + * @param newOption + * @param opt + */ + function mergeLayoutParam(targetOption, newOption, opt) { + var ignoreSize = opt && opt.ignoreSize; + !isArray(ignoreSize) && (ignoreSize = [ignoreSize, ignoreSize]); + var hResult = merge(HV_NAMES[0], 0); + var vResult = merge(HV_NAMES[1], 1); + copy(HV_NAMES[0], targetOption, hResult); + copy(HV_NAMES[1], targetOption, vResult); + function merge(names, hvIdx) { + var newParams = {}; + var newValueCount = 0; + var merged = {}; + var mergedValueCount = 0; + var enoughParamNumber = 2; + each$1(names, function (name) { + merged[name] = targetOption[name]; + }); + each$1(names, function (name) { + // Consider case: newOption.width is null, which is + // set by user for removing width setting. + hasProp(newOption, name) && (newParams[name] = merged[name] = newOption[name]); + hasValue(newParams, name) && newValueCount++; + hasValue(merged, name) && mergedValueCount++; + }); + if (ignoreSize[hvIdx]) { + // Only one of left/right is premitted to exist. + if (hasValue(newOption, names[1])) { + merged[names[2]] = null; + } else if (hasValue(newOption, names[2])) { + merged[names[1]] = null; + } + return merged; + } + // Case: newOption: {width: ..., right: ...}, + // or targetOption: {right: ...} and newOption: {width: ...}, + // There is no conflict when merged only has params count + // little than enoughParamNumber. + if (mergedValueCount === enoughParamNumber || !newValueCount) { + return merged; + } + // Case: newOption: {width: ..., right: ...}, + // Than we can make sure user only want those two, and ignore + // all origin params in targetOption. + else if (newValueCount >= enoughParamNumber) { + return newParams; + } else { + // Chose another param from targetOption by priority. + for (var i = 0; i < names.length; i++) { + var name_1 = names[i]; + if (!hasProp(newParams, name_1) && hasProp(targetOption, name_1)) { + newParams[name_1] = targetOption[name_1]; + break; + } + } + return newParams; + } + } + function hasProp(obj, name) { + return obj.hasOwnProperty(name); + } + function hasValue(obj, name) { + return obj[name] != null && obj[name] !== 'auto'; + } + function copy(names, target, source) { + each$1(names, function (name) { + target[name] = source[name]; + }); + } + } + /** + * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object. + */ + function getLayoutParams(source) { + return copyLayoutParams({}, source); + } + /** + * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object. + * @param {Object} source + * @return {Object} Result contains those props. + */ + function copyLayoutParams(target, source) { + source && target && each$1(LOCATION_PARAMS, function (name) { + source.hasOwnProperty(name) && (target[name] = source[name]); + }); + return target; + } + + var inner = makeInner(); + var ComponentModel = /** @class */function (_super) { + __extends(ComponentModel, _super); + function ComponentModel(option, parentModel, ecModel) { + var _this = _super.call(this, option, parentModel, ecModel) || this; + _this.uid = getUID('ec_cpt_model'); + return _this; + } + ComponentModel.prototype.init = function (option, parentModel, ecModel) { + this.mergeDefaultAndTheme(option, ecModel); + }; + ComponentModel.prototype.mergeDefaultAndTheme = function (option, ecModel) { + var layoutMode = fetchLayoutMode(this); + var inputPositionParams = layoutMode ? getLayoutParams(option) : {}; + var themeModel = ecModel.getTheme(); + merge(option, themeModel.get(this.mainType)); + merge(option, this.getDefaultOption()); + if (layoutMode) { + mergeLayoutParam(option, inputPositionParams, layoutMode); + } + }; + ComponentModel.prototype.mergeOption = function (option, ecModel) { + merge(this.option, option, true); + var layoutMode = fetchLayoutMode(this); + if (layoutMode) { + mergeLayoutParam(this.option, option, layoutMode); + } + }; + /** + * Called immediately after `init` or `mergeOption` of this instance called. + */ + ComponentModel.prototype.optionUpdated = function (newCptOption, isInit) {}; + /** + * [How to declare defaultOption]: + * + * (A) If using class declaration in typescript (since echarts 5): + * ```ts + * import {ComponentOption} from '../model/option.js'; + * export interface XxxOption extends ComponentOption { + * aaa: number + * } + * export class XxxModel extends Component { + * static type = 'xxx'; + * static defaultOption: XxxOption = { + * aaa: 123 + * } + * } + * Component.registerClass(XxxModel); + * ``` + * ```ts + * import {inheritDefaultOption} from '../util/component.js'; + * import {XxxModel, XxxOption} from './XxxModel.js'; + * export interface XxxSubOption extends XxxOption { + * bbb: number + * } + * class XxxSubModel extends XxxModel { + * static defaultOption: XxxSubOption = inheritDefaultOption(XxxModel.defaultOption, { + * bbb: 456 + * }) + * fn() { + * let opt = this.getDefaultOption(); + * // opt is {aaa: 123, bbb: 456} + * } + * } + * ``` + * + * (B) If using class extend (previous approach in echarts 3 & 4): + * ```js + * let XxxComponent = Component.extend({ + * defaultOption: { + * xx: 123 + * } + * }) + * ``` + * ```js + * let XxxSubComponent = XxxComponent.extend({ + * defaultOption: { + * yy: 456 + * }, + * fn: function () { + * let opt = this.getDefaultOption(); + * // opt is {xx: 123, yy: 456} + * } + * }) + * ``` + */ + ComponentModel.prototype.getDefaultOption = function () { + var ctor = this.constructor; + // If using class declaration, it is different to travel super class + // in legacy env and auto merge defaultOption. So if using class + // declaration, defaultOption should be merged manually. + if (!isExtendedClass(ctor)) { + // When using ts class, defaultOption must be declared as static. + return ctor.defaultOption; + } + // FIXME: remove this approach? + var fields = inner(this); + if (!fields.defaultOption) { + var optList = []; + var clz = ctor; + while (clz) { + var opt = clz.prototype.defaultOption; + opt && optList.push(opt); + clz = clz.superClass; + } + var defaultOption = {}; + for (var i = optList.length - 1; i >= 0; i--) { + defaultOption = merge(defaultOption, optList[i], true); + } + fields.defaultOption = defaultOption; + } + return fields.defaultOption; + }; + /** + * Notice: always force to input param `useDefault` in case that forget to consider it. + * The same behavior as `modelUtil.parseFinder`. + * + * @param useDefault In many cases like series refer axis and axis refer grid, + * If axis index / axis id not specified, use the first target as default. + * In other cases like dataZoom refer axis, if not specified, measn no refer. + */ + ComponentModel.prototype.getReferringComponents = function (mainType, opt) { + var indexKey = mainType + 'Index'; + var idKey = mainType + 'Id'; + return queryReferringComponents(this.ecModel, mainType, { + index: this.get(indexKey, true), + id: this.get(idKey, true) + }, opt); + }; + ComponentModel.prototype.getBoxLayoutParams = function () { + // Consider itself having box layout configs. + var boxLayoutModel = this; + return { + left: boxLayoutModel.get('left'), + top: boxLayoutModel.get('top'), + right: boxLayoutModel.get('right'), + bottom: boxLayoutModel.get('bottom'), + width: boxLayoutModel.get('width'), + height: boxLayoutModel.get('height') + }; + }; + /** + * Get key for zlevel. + * If developers don't configure zlevel. We will assign zlevel to series based on the key. + * For example, lines with trail effect and progressive series will in an individual zlevel. + */ + ComponentModel.prototype.getZLevelKey = function () { + return ''; + }; + ComponentModel.prototype.setZLevel = function (zlevel) { + this.option.zlevel = zlevel; + }; + ComponentModel.protoInitialize = function () { + var proto = ComponentModel.prototype; + proto.type = 'component'; + proto.id = ''; + proto.name = ''; + proto.mainType = ''; + proto.subType = ''; + proto.componentIndex = 0; + }(); + return ComponentModel; + }(Model); + mountExtend(ComponentModel, Model); + enableClassManagement(ComponentModel); + enableSubTypeDefaulter(ComponentModel); + enableTopologicalTravel(ComponentModel, getDependencies); + function getDependencies(componentType) { + var deps = []; + each(ComponentModel.getClassesByMainType(componentType), function (clz) { + deps = deps.concat(clz.dependencies || clz.prototype.dependencies || []); + }); + // Ensure main type. + deps = map(deps, function (type) { + return parseClassType(type).main; + }); + // Hack dataset for convenience. + if (componentType !== 'dataset' && indexOf(deps, 'dataset') <= 0) { + deps.unshift('dataset'); + } + return deps; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var platform = ''; + // Navigator not exists in node + if (typeof navigator !== 'undefined') { + /* global navigator */ + platform = navigator.platform || ''; + } + var decalColor = 'rgba(0, 0, 0, 0.2)'; + var globalDefault = { + darkMode: 'auto', + // backgroundColor: 'rgba(0,0,0,0)', + colorBy: 'series', + color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'], + gradientColor: ['#f6efa6', '#d88273', '#bf444c'], + aria: { + decal: { + decals: [{ + color: decalColor, + dashArrayX: [1, 0], + dashArrayY: [2, 5], + symbolSize: 1, + rotation: Math.PI / 6 + }, { + color: decalColor, + symbol: 'circle', + dashArrayX: [[8, 8], [0, 8, 8, 0]], + dashArrayY: [6, 0], + symbolSize: 0.8 + }, { + color: decalColor, + dashArrayX: [1, 0], + dashArrayY: [4, 3], + rotation: -Math.PI / 4 + }, { + color: decalColor, + dashArrayX: [[6, 6], [0, 6, 6, 0]], + dashArrayY: [6, 0] + }, { + color: decalColor, + dashArrayX: [[1, 0], [1, 6]], + dashArrayY: [1, 0, 6, 0], + rotation: Math.PI / 4 + }, { + color: decalColor, + symbol: 'triangle', + dashArrayX: [[9, 9], [0, 9, 9, 0]], + dashArrayY: [7, 2], + symbolSize: 0.75 + }] + } + }, + // If xAxis and yAxis declared, grid is created by default. + // grid: {}, + textStyle: { + // color: '#000', + // decoration: 'none', + // PENDING + fontFamily: platform.match(/^Win/) ? 'Microsoft YaHei' : 'sans-serif', + // fontFamily: 'Arial, Verdana, sans-serif', + fontSize: 12, + fontStyle: 'normal', + fontWeight: 'normal' + }, + // http://blogs.adobe.com/webplatform/2014/02/24/using-blend-modes-in-html-canvas/ + // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation + // Default is source-over + blendMode: null, + stateAnimation: { + duration: 300, + easing: 'cubicOut' + }, + animation: 'auto', + animationDuration: 1000, + animationDurationUpdate: 500, + animationEasing: 'cubicInOut', + animationEasingUpdate: 'cubicInOut', + animationThreshold: 2000, + // Configuration for progressive/incremental rendering + progressiveThreshold: 3000, + progressive: 400, + // Threshold of if use single hover layer to optimize. + // It is recommended that `hoverLayerThreshold` is equivalent to or less than + // `progressiveThreshold`, otherwise hover will cause restart of progressive, + // which is unexpected. + // see example . + hoverLayerThreshold: 3000, + // See: module:echarts/scale/Time + useUTC: false + }; + + var VISUAL_DIMENSIONS = createHashMap(['tooltip', 'label', 'itemName', 'itemId', 'itemGroupId', 'itemChildGroupId', 'seriesName']); + var SOURCE_FORMAT_ORIGINAL = 'original'; + var SOURCE_FORMAT_ARRAY_ROWS = 'arrayRows'; + var SOURCE_FORMAT_OBJECT_ROWS = 'objectRows'; + var SOURCE_FORMAT_KEYED_COLUMNS = 'keyedColumns'; + var SOURCE_FORMAT_TYPED_ARRAY = 'typedArray'; + var SOURCE_FORMAT_UNKNOWN = 'unknown'; + var SERIES_LAYOUT_BY_COLUMN = 'column'; + var SERIES_LAYOUT_BY_ROW = 'row'; + + // The result of `guessOrdinal`. + var BE_ORDINAL = { + Must: 1, + Might: 2, + Not: 3 // Other cases + }; + + var innerGlobalModel = makeInner(); + /** + * MUST be called before mergeOption of all series. + */ + function resetSourceDefaulter(ecModel) { + // `datasetMap` is used to make default encode. + innerGlobalModel(ecModel).datasetMap = createHashMap(); + } + /** + * [The strategy of the arrengment of data dimensions for dataset]: + * "value way": all axes are non-category axes. So series one by one take + * several (the number is coordSysDims.length) dimensions from dataset. + * The result of data arrengment of data dimensions like: + * | ser0_x | ser0_y | ser1_x | ser1_y | ser2_x | ser2_y | + * "category way": at least one axis is category axis. So the the first data + * dimension is always mapped to the first category axis and shared by + * all of the series. The other data dimensions are taken by series like + * "value way" does. + * The result of data arrengment of data dimensions like: + * | ser_shared_x | ser0_y | ser1_y | ser2_y | + * + * @return encode Never be `null/undefined`. + */ + function makeSeriesEncodeForAxisCoordSys(coordDimensions, seriesModel, source) { + var encode = {}; + var datasetModel = querySeriesUpstreamDatasetModel(seriesModel); + // Currently only make default when using dataset, util more reqirements occur. + if (!datasetModel || !coordDimensions) { + return encode; + } + var encodeItemName = []; + var encodeSeriesName = []; + var ecModel = seriesModel.ecModel; + var datasetMap = innerGlobalModel(ecModel).datasetMap; + var key = datasetModel.uid + '_' + source.seriesLayoutBy; + var baseCategoryDimIndex; + var categoryWayValueDimStart; + coordDimensions = coordDimensions.slice(); + each(coordDimensions, function (coordDimInfoLoose, coordDimIdx) { + var coordDimInfo = isObject(coordDimInfoLoose) ? coordDimInfoLoose : coordDimensions[coordDimIdx] = { + name: coordDimInfoLoose + }; + if (coordDimInfo.type === 'ordinal' && baseCategoryDimIndex == null) { + baseCategoryDimIndex = coordDimIdx; + categoryWayValueDimStart = getDataDimCountOnCoordDim(coordDimInfo); + } + encode[coordDimInfo.name] = []; + }); + var datasetRecord = datasetMap.get(key) || datasetMap.set(key, { + categoryWayDim: categoryWayValueDimStart, + valueWayDim: 0 + }); + // TODO + // Auto detect first time axis and do arrangement. + each(coordDimensions, function (coordDimInfo, coordDimIdx) { + var coordDimName = coordDimInfo.name; + var count = getDataDimCountOnCoordDim(coordDimInfo); + // In value way. + if (baseCategoryDimIndex == null) { + var start = datasetRecord.valueWayDim; + pushDim(encode[coordDimName], start, count); + pushDim(encodeSeriesName, start, count); + datasetRecord.valueWayDim += count; + // ??? TODO give a better default series name rule? + // especially when encode x y specified. + // consider: when multiple series share one dimension + // category axis, series name should better use + // the other dimension name. On the other hand, use + // both dimensions name. + } + // In category way, the first category axis. + else if (baseCategoryDimIndex === coordDimIdx) { + pushDim(encode[coordDimName], 0, count); + pushDim(encodeItemName, 0, count); + } + // In category way, the other axis. + else { + var start = datasetRecord.categoryWayDim; + pushDim(encode[coordDimName], start, count); + pushDim(encodeSeriesName, start, count); + datasetRecord.categoryWayDim += count; + } + }); + function pushDim(dimIdxArr, idxFrom, idxCount) { + for (var i = 0; i < idxCount; i++) { + dimIdxArr.push(idxFrom + i); + } + } + function getDataDimCountOnCoordDim(coordDimInfo) { + var dimsDef = coordDimInfo.dimsDef; + return dimsDef ? dimsDef.length : 1; + } + encodeItemName.length && (encode.itemName = encodeItemName); + encodeSeriesName.length && (encode.seriesName = encodeSeriesName); + return encode; + } + /** + * Work for data like [{name: ..., value: ...}, ...]. + * + * @return encode Never be `null/undefined`. + */ + function makeSeriesEncodeForNameBased(seriesModel, source, dimCount) { + var encode = {}; + var datasetModel = querySeriesUpstreamDatasetModel(seriesModel); + // Currently only make default when using dataset, util more reqirements occur. + if (!datasetModel) { + return encode; + } + var sourceFormat = source.sourceFormat; + var dimensionsDefine = source.dimensionsDefine; + var potentialNameDimIndex; + if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { + each(dimensionsDefine, function (dim, idx) { + if ((isObject(dim) ? dim.name : dim) === 'name') { + potentialNameDimIndex = idx; + } + }); + } + var idxResult = function () { + var idxRes0 = {}; + var idxRes1 = {}; + var guessRecords = []; + // 5 is an experience value. + for (var i = 0, len = Math.min(5, dimCount); i < len; i++) { + var guessResult = doGuessOrdinal(source.data, sourceFormat, source.seriesLayoutBy, dimensionsDefine, source.startIndex, i); + guessRecords.push(guessResult); + var isPureNumber = guessResult === BE_ORDINAL.Not; + // [Strategy of idxRes0]: find the first BE_ORDINAL.Not as the value dim, + // and then find a name dim with the priority: + // "BE_ORDINAL.Might|BE_ORDINAL.Must" > "other dim" > "the value dim itself". + if (isPureNumber && idxRes0.v == null && i !== potentialNameDimIndex) { + idxRes0.v = i; + } + if (idxRes0.n == null || idxRes0.n === idxRes0.v || !isPureNumber && guessRecords[idxRes0.n] === BE_ORDINAL.Not) { + idxRes0.n = i; + } + if (fulfilled(idxRes0) && guessRecords[idxRes0.n] !== BE_ORDINAL.Not) { + return idxRes0; + } + // [Strategy of idxRes1]: if idxRes0 not satisfied (that is, no BE_ORDINAL.Not), + // find the first BE_ORDINAL.Might as the value dim, + // and then find a name dim with the priority: + // "other dim" > "the value dim itself". + // That is for backward compat: number-like (e.g., `'3'`, `'55'`) can be + // treated as number. + if (!isPureNumber) { + if (guessResult === BE_ORDINAL.Might && idxRes1.v == null && i !== potentialNameDimIndex) { + idxRes1.v = i; + } + if (idxRes1.n == null || idxRes1.n === idxRes1.v) { + idxRes1.n = i; + } + } + } + function fulfilled(idxResult) { + return idxResult.v != null && idxResult.n != null; + } + return fulfilled(idxRes0) ? idxRes0 : fulfilled(idxRes1) ? idxRes1 : null; + }(); + if (idxResult) { + encode.value = [idxResult.v]; + // `potentialNameDimIndex` has highest priority. + var nameDimIndex = potentialNameDimIndex != null ? potentialNameDimIndex : idxResult.n; + // By default, label uses itemName in charts. + // So we don't set encodeLabel here. + encode.itemName = [nameDimIndex]; + encode.seriesName = [nameDimIndex]; + } + return encode; + } + /** + * @return If return null/undefined, indicate that should not use datasetModel. + */ + function querySeriesUpstreamDatasetModel(seriesModel) { + // Caution: consider the scenario: + // A dataset is declared and a series is not expected to use the dataset, + // and at the beginning `setOption({series: { noData })` (just prepare other + // option but no data), then `setOption({series: {data: [...]}); In this case, + // the user should set an empty array to avoid that dataset is used by default. + var thisData = seriesModel.get('data', true); + if (!thisData) { + return queryReferringComponents(seriesModel.ecModel, 'dataset', { + index: seriesModel.get('datasetIndex', true), + id: seriesModel.get('datasetId', true) + }, SINGLE_REFERRING).models[0]; + } + } + /** + * @return Always return an array event empty. + */ + function queryDatasetUpstreamDatasetModels(datasetModel) { + // Only these attributes declared, we by default reference to `datasetIndex: 0`. + // Otherwise, no reference. + if (!datasetModel.get('transform', true) && !datasetModel.get('fromTransformResult', true)) { + return []; + } + return queryReferringComponents(datasetModel.ecModel, 'dataset', { + index: datasetModel.get('fromDatasetIndex', true), + id: datasetModel.get('fromDatasetId', true) + }, SINGLE_REFERRING).models; + } + /** + * The rule should not be complex, otherwise user might not + * be able to known where the data is wrong. + * The code is ugly, but how to make it neat? + */ + function guessOrdinal(source, dimIndex) { + return doGuessOrdinal(source.data, source.sourceFormat, source.seriesLayoutBy, source.dimensionsDefine, source.startIndex, dimIndex); + } + // dimIndex may be overflow source data. + // return {BE_ORDINAL} + function doGuessOrdinal(data, sourceFormat, seriesLayoutBy, dimensionsDefine, startIndex, dimIndex) { + var result; + // Experience value. + var maxLoop = 5; + if (isTypedArray(data)) { + return BE_ORDINAL.Not; + } + // When sourceType is 'objectRows' or 'keyedColumns', dimensionsDefine + // always exists in source. + var dimName; + var dimType; + if (dimensionsDefine) { + var dimDefItem = dimensionsDefine[dimIndex]; + if (isObject(dimDefItem)) { + dimName = dimDefItem.name; + dimType = dimDefItem.type; + } else if (isString(dimDefItem)) { + dimName = dimDefItem; + } + } + if (dimType != null) { + return dimType === 'ordinal' ? BE_ORDINAL.Must : BE_ORDINAL.Not; + } + if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { + var dataArrayRows = data; + if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) { + var sample = dataArrayRows[dimIndex]; + for (var i = 0; i < (sample || []).length && i < maxLoop; i++) { + if ((result = detectValue(sample[startIndex + i])) != null) { + return result; + } + } + } else { + for (var i = 0; i < dataArrayRows.length && i < maxLoop; i++) { + var row = dataArrayRows[startIndex + i]; + if (row && (result = detectValue(row[dimIndex])) != null) { + return result; + } + } + } + } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { + var dataObjectRows = data; + if (!dimName) { + return BE_ORDINAL.Not; + } + for (var i = 0; i < dataObjectRows.length && i < maxLoop; i++) { + var item = dataObjectRows[i]; + if (item && (result = detectValue(item[dimName])) != null) { + return result; + } + } + } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { + var dataKeyedColumns = data; + if (!dimName) { + return BE_ORDINAL.Not; + } + var sample = dataKeyedColumns[dimName]; + if (!sample || isTypedArray(sample)) { + return BE_ORDINAL.Not; + } + for (var i = 0; i < sample.length && i < maxLoop; i++) { + if ((result = detectValue(sample[i])) != null) { + return result; + } + } + } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { + var dataOriginal = data; + for (var i = 0; i < dataOriginal.length && i < maxLoop; i++) { + var item = dataOriginal[i]; + var val = getDataItemValue(item); + if (!isArray(val)) { + return BE_ORDINAL.Not; + } + if ((result = detectValue(val[dimIndex])) != null) { + return result; + } + } + } + function detectValue(val) { + var beStr = isString(val); + // Consider usage convenience, '1', '2' will be treated as "number". + // `isFinit('')` get `true`. + if (val != null && isFinite(val) && val !== '') { + return beStr ? BE_ORDINAL.Might : BE_ORDINAL.Not; + } else if (beStr && val !== '-') { + return BE_ORDINAL.Must; + } + } + return BE_ORDINAL.Not; + } + + var internalOptionCreatorMap = createHashMap(); + function registerInternalOptionCreator(mainType, creator) { + assert(internalOptionCreatorMap.get(mainType) == null && creator); + internalOptionCreatorMap.set(mainType, creator); + } + function concatInternalOptions(ecModel, mainType, newCmptOptionList) { + var internalOptionCreator = internalOptionCreatorMap.get(mainType); + if (!internalOptionCreator) { + return newCmptOptionList; + } + var internalOptions = internalOptionCreator(ecModel); + if (!internalOptions) { + return newCmptOptionList; + } + if ("development" !== 'production') { + for (var i = 0; i < internalOptions.length; i++) { + assert(isComponentIdInternal(internalOptions[i])); + } + } + return newCmptOptionList.concat(internalOptions); + } + + var innerColor = makeInner(); + var innerDecal = makeInner(); + var PaletteMixin = /** @class */function () { + function PaletteMixin() {} + PaletteMixin.prototype.getColorFromPalette = function (name, scope, requestNum) { + var defaultPalette = normalizeToArray(this.get('color', true)); + var layeredPalette = this.get('colorLayer', true); + return getFromPalette(this, innerColor, defaultPalette, layeredPalette, name, scope, requestNum); + }; + PaletteMixin.prototype.clearColorPalette = function () { + clearPalette(this, innerColor); + }; + return PaletteMixin; + }(); + function getDecalFromPalette(ecModel, name, scope, requestNum) { + var defaultDecals = normalizeToArray(ecModel.get(['aria', 'decal', 'decals'])); + return getFromPalette(ecModel, innerDecal, defaultDecals, null, name, scope, requestNum); + } + function getNearestPalette(palettes, requestColorNum) { + var paletteNum = palettes.length; + // TODO palettes must be in order + for (var i = 0; i < paletteNum; i++) { + if (palettes[i].length > requestColorNum) { + return palettes[i]; + } + } + return palettes[paletteNum - 1]; + } + /** + * @param name MUST NOT be null/undefined. Otherwise call this function + * twise with the same parameters will get different result. + * @param scope default this. + * @return Can be null/undefined + */ + function getFromPalette(that, inner, defaultPalette, layeredPalette, name, scope, requestNum) { + scope = scope || that; + var scopeFields = inner(scope); + var paletteIdx = scopeFields.paletteIdx || 0; + var paletteNameMap = scopeFields.paletteNameMap = scopeFields.paletteNameMap || {}; + // Use `hasOwnProperty` to avoid conflict with Object.prototype. + if (paletteNameMap.hasOwnProperty(name)) { + return paletteNameMap[name]; + } + var palette = requestNum == null || !layeredPalette ? defaultPalette : getNearestPalette(layeredPalette, requestNum); + // In case can't find in layered color palette. + palette = palette || defaultPalette; + if (!palette || !palette.length) { + return; + } + var pickedPaletteItem = palette[paletteIdx]; + if (name) { + paletteNameMap[name] = pickedPaletteItem; + } + scopeFields.paletteIdx = (paletteIdx + 1) % palette.length; + return pickedPaletteItem; + } + function clearPalette(that, inner) { + inner(that).paletteIdx = 0; + inner(that).paletteNameMap = {}; + } + + // ----------------------- + // Internal method names: + // ----------------------- + var reCreateSeriesIndices; + var assertSeriesInitialized; + var initBase; + var OPTION_INNER_KEY = '\0_ec_inner'; + var OPTION_INNER_VALUE = 1; + var BUITIN_COMPONENTS_MAP = { + grid: 'GridComponent', + polar: 'PolarComponent', + geo: 'GeoComponent', + singleAxis: 'SingleAxisComponent', + parallel: 'ParallelComponent', + calendar: 'CalendarComponent', + graphic: 'GraphicComponent', + toolbox: 'ToolboxComponent', + tooltip: 'TooltipComponent', + axisPointer: 'AxisPointerComponent', + brush: 'BrushComponent', + title: 'TitleComponent', + timeline: 'TimelineComponent', + markPoint: 'MarkPointComponent', + markLine: 'MarkLineComponent', + markArea: 'MarkAreaComponent', + legend: 'LegendComponent', + dataZoom: 'DataZoomComponent', + visualMap: 'VisualMapComponent', + // aria: 'AriaComponent', + // dataset: 'DatasetComponent', + // Dependencies + xAxis: 'GridComponent', + yAxis: 'GridComponent', + angleAxis: 'PolarComponent', + radiusAxis: 'PolarComponent' + }; + var BUILTIN_CHARTS_MAP = { + line: 'LineChart', + bar: 'BarChart', + pie: 'PieChart', + scatter: 'ScatterChart', + radar: 'RadarChart', + map: 'MapChart', + tree: 'TreeChart', + treemap: 'TreemapChart', + graph: 'GraphChart', + gauge: 'GaugeChart', + funnel: 'FunnelChart', + parallel: 'ParallelChart', + sankey: 'SankeyChart', + boxplot: 'BoxplotChart', + candlestick: 'CandlestickChart', + effectScatter: 'EffectScatterChart', + lines: 'LinesChart', + heatmap: 'HeatmapChart', + pictorialBar: 'PictorialBarChart', + themeRiver: 'ThemeRiverChart', + sunburst: 'SunburstChart', + custom: 'CustomChart' + }; + var componetsMissingLogPrinted = {}; + function checkMissingComponents(option) { + each(option, function (componentOption, mainType) { + if (!ComponentModel.hasClass(mainType)) { + var componentImportName = BUITIN_COMPONENTS_MAP[mainType]; + if (componentImportName && !componetsMissingLogPrinted[componentImportName]) { + error("Component " + mainType + " is used but not imported.\nimport { " + componentImportName + " } from 'echarts/components';\necharts.use([" + componentImportName + "]);"); + componetsMissingLogPrinted[componentImportName] = true; + } + } + }); + } + var GlobalModel = /** @class */function (_super) { + __extends(GlobalModel, _super); + function GlobalModel() { + return _super !== null && _super.apply(this, arguments) || this; + } + GlobalModel.prototype.init = function (option, parentModel, ecModel, theme, locale, optionManager) { + theme = theme || {}; + this.option = null; // Mark as not initialized. + this._theme = new Model(theme); + this._locale = new Model(locale); + this._optionManager = optionManager; + }; + GlobalModel.prototype.setOption = function (option, opts, optionPreprocessorFuncs) { + if ("development" !== 'production') { + assert(option != null, 'option is null/undefined'); + assert(option[OPTION_INNER_KEY] !== OPTION_INNER_VALUE, 'please use chart.getOption()'); + } + var innerOpt = normalizeSetOptionInput(opts); + this._optionManager.setOption(option, optionPreprocessorFuncs, innerOpt); + this._resetOption(null, innerOpt); + }; + /** + * @param type null/undefined: reset all. + * 'recreate': force recreate all. + * 'timeline': only reset timeline option + * 'media': only reset media query option + * @return Whether option changed. + */ + GlobalModel.prototype.resetOption = function (type, opt) { + return this._resetOption(type, normalizeSetOptionInput(opt)); + }; + GlobalModel.prototype._resetOption = function (type, opt) { + var optionChanged = false; + var optionManager = this._optionManager; + if (!type || type === 'recreate') { + var baseOption = optionManager.mountOption(type === 'recreate'); + if ("development" !== 'production') { + checkMissingComponents(baseOption); + } + if (!this.option || type === 'recreate') { + initBase(this, baseOption); + } else { + this.restoreData(); + this._mergeOption(baseOption, opt); + } + optionChanged = true; + } + if (type === 'timeline' || type === 'media') { + this.restoreData(); + } + // By design, if `setOption(option2)` at the second time, and `option2` is a `ECUnitOption`, + // it should better not have the same props with `MediaUnit['option']`. + // Because either `option2` or `MediaUnit['option']` will be always merged to "current option" + // rather than original "baseOption". If they both override a prop, the result might be + // unexpected when media state changed after `setOption` called. + // If we really need to modify a props in each `MediaUnit['option']`, use the full version + // (`{baseOption, media}`) in `setOption`. + // For `timeline`, the case is the same. + if (!type || type === 'recreate' || type === 'timeline') { + var timelineOption = optionManager.getTimelineOption(this); + if (timelineOption) { + optionChanged = true; + this._mergeOption(timelineOption, opt); + } + } + if (!type || type === 'recreate' || type === 'media') { + var mediaOptions = optionManager.getMediaOption(this); + if (mediaOptions.length) { + each(mediaOptions, function (mediaOption) { + optionChanged = true; + this._mergeOption(mediaOption, opt); + }, this); + } + } + return optionChanged; + }; + GlobalModel.prototype.mergeOption = function (option) { + this._mergeOption(option, null); + }; + GlobalModel.prototype._mergeOption = function (newOption, opt) { + var option = this.option; + var componentsMap = this._componentsMap; + var componentsCount = this._componentsCount; + var newCmptTypes = []; + var newCmptTypeMap = createHashMap(); + var replaceMergeMainTypeMap = opt && opt.replaceMergeMainTypeMap; + resetSourceDefaulter(this); + // If no component class, merge directly. + // For example: color, animaiton options, etc. + each(newOption, function (componentOption, mainType) { + if (componentOption == null) { + return; + } + if (!ComponentModel.hasClass(mainType)) { + // globalSettingTask.dirty(); + option[mainType] = option[mainType] == null ? clone(componentOption) : merge(option[mainType], componentOption, true); + } else if (mainType) { + newCmptTypes.push(mainType); + newCmptTypeMap.set(mainType, true); + } + }); + if (replaceMergeMainTypeMap) { + // If there is a mainType `xxx` in `replaceMerge` but not declared in option, + // we trade it as it is declared in option as `{xxx: []}`. Because: + // (1) for normal merge, `{xxx: null/undefined}` are the same meaning as `{xxx: []}`. + // (2) some preprocessor may convert some of `{xxx: null/undefined}` to `{xxx: []}`. + replaceMergeMainTypeMap.each(function (val, mainTypeInReplaceMerge) { + if (ComponentModel.hasClass(mainTypeInReplaceMerge) && !newCmptTypeMap.get(mainTypeInReplaceMerge)) { + newCmptTypes.push(mainTypeInReplaceMerge); + newCmptTypeMap.set(mainTypeInReplaceMerge, true); + } + }); + } + ComponentModel.topologicalTravel(newCmptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this); + function visitComponent(mainType) { + var newCmptOptionList = concatInternalOptions(this, mainType, normalizeToArray(newOption[mainType])); + var oldCmptList = componentsMap.get(mainType); + var mergeMode = + // `!oldCmptList` means init. See the comment in `mappingToExists` + !oldCmptList ? 'replaceAll' : replaceMergeMainTypeMap && replaceMergeMainTypeMap.get(mainType) ? 'replaceMerge' : 'normalMerge'; + var mappingResult = mappingToExists(oldCmptList, newCmptOptionList, mergeMode); + // Set mainType and complete subType. + setComponentTypeToKeyInfo(mappingResult, mainType, ComponentModel); + // Empty it before the travel, in order to prevent `this._componentsMap` + // from being used in the `init`/`mergeOption`/`optionUpdated` of some + // components, which is probably incorrect logic. + option[mainType] = null; + componentsMap.set(mainType, null); + componentsCount.set(mainType, 0); + var optionsByMainType = []; + var cmptsByMainType = []; + var cmptsCountByMainType = 0; + var tooltipExists; + var tooltipWarningLogged; + each(mappingResult, function (resultItem, index) { + var componentModel = resultItem.existing; + var newCmptOption = resultItem.newOption; + if (!newCmptOption) { + if (componentModel) { + // Consider where is no new option and should be merged using {}, + // see removeEdgeAndAdd in topologicalTravel and + // ComponentModel.getAllClassMainTypes. + componentModel.mergeOption({}, this); + componentModel.optionUpdated({}, false); + } + // If no both `resultItem.exist` and `resultItem.option`, + // either it is in `replaceMerge` and not matched by any id, + // or it has been removed in previous `replaceMerge` and left a "hole" in this component index. + } else { + var isSeriesType = mainType === 'series'; + var ComponentModelClass = ComponentModel.getClass(mainType, resultItem.keyInfo.subType, !isSeriesType // Give a more detailed warn later if series don't exists + ); + + if (!ComponentModelClass) { + if ("development" !== 'production') { + var subType = resultItem.keyInfo.subType; + var seriesImportName = BUILTIN_CHARTS_MAP[subType]; + if (!componetsMissingLogPrinted[subType]) { + componetsMissingLogPrinted[subType] = true; + if (seriesImportName) { + error("Series " + subType + " is used but not imported.\nimport { " + seriesImportName + " } from 'echarts/charts';\necharts.use([" + seriesImportName + "]);"); + } else { + error("Unknown series " + subType); + } + } + } + return; + } + // TODO Before multiple tooltips get supported, we do this check to avoid unexpected exception. + if (mainType === 'tooltip') { + if (tooltipExists) { + if ("development" !== 'production') { + if (!tooltipWarningLogged) { + warn('Currently only one tooltip component is allowed.'); + tooltipWarningLogged = true; + } + } + return; + } + tooltipExists = true; + } + if (componentModel && componentModel.constructor === ComponentModelClass) { + componentModel.name = resultItem.keyInfo.name; + // componentModel.settingTask && componentModel.settingTask.dirty(); + componentModel.mergeOption(newCmptOption, this); + componentModel.optionUpdated(newCmptOption, false); + } else { + // PENDING Global as parent ? + var extraOpt = extend({ + componentIndex: index + }, resultItem.keyInfo); + componentModel = new ComponentModelClass(newCmptOption, this, this, extraOpt); + // Assign `keyInfo` + extend(componentModel, extraOpt); + if (resultItem.brandNew) { + componentModel.__requireNewView = true; + } + componentModel.init(newCmptOption, this, this); + // Call optionUpdated after init. + // newCmptOption has been used as componentModel.option + // and may be merged with theme and default, so pass null + // to avoid confusion. + componentModel.optionUpdated(null, true); + } + } + if (componentModel) { + optionsByMainType.push(componentModel.option); + cmptsByMainType.push(componentModel); + cmptsCountByMainType++; + } else { + // Always do assign to avoid elided item in array. + optionsByMainType.push(void 0); + cmptsByMainType.push(void 0); + } + }, this); + option[mainType] = optionsByMainType; + componentsMap.set(mainType, cmptsByMainType); + componentsCount.set(mainType, cmptsCountByMainType); + // Backup series for filtering. + if (mainType === 'series') { + reCreateSeriesIndices(this); + } + } + // If no series declared, ensure `_seriesIndices` initialized. + if (!this._seriesIndices) { + reCreateSeriesIndices(this); + } + }; + /** + * Get option for output (cloned option and inner info removed) + */ + GlobalModel.prototype.getOption = function () { + var option = clone(this.option); + each(option, function (optInMainType, mainType) { + if (ComponentModel.hasClass(mainType)) { + var opts = normalizeToArray(optInMainType); + // Inner cmpts need to be removed. + // Inner cmpts might not be at last since ec5.0, but still + // compatible for users: if inner cmpt at last, splice the returned array. + var realLen = opts.length; + var metNonInner = false; + for (var i = realLen - 1; i >= 0; i--) { + // Remove options with inner id. + if (opts[i] && !isComponentIdInternal(opts[i])) { + metNonInner = true; + } else { + opts[i] = null; + !metNonInner && realLen--; + } + } + opts.length = realLen; + option[mainType] = opts; + } + }); + delete option[OPTION_INNER_KEY]; + return option; + }; + GlobalModel.prototype.getTheme = function () { + return this._theme; + }; + GlobalModel.prototype.getLocaleModel = function () { + return this._locale; + }; + GlobalModel.prototype.setUpdatePayload = function (payload) { + this._payload = payload; + }; + GlobalModel.prototype.getUpdatePayload = function () { + return this._payload; + }; + /** + * @param idx If not specified, return the first one. + */ + GlobalModel.prototype.getComponent = function (mainType, idx) { + var list = this._componentsMap.get(mainType); + if (list) { + var cmpt = list[idx || 0]; + if (cmpt) { + return cmpt; + } else if (idx == null) { + for (var i = 0; i < list.length; i++) { + if (list[i]) { + return list[i]; + } + } + } + } + }; + /** + * @return Never be null/undefined. + */ + GlobalModel.prototype.queryComponents = function (condition) { + var mainType = condition.mainType; + if (!mainType) { + return []; + } + var index = condition.index; + var id = condition.id; + var name = condition.name; + var cmpts = this._componentsMap.get(mainType); + if (!cmpts || !cmpts.length) { + return []; + } + var result; + if (index != null) { + result = []; + each(normalizeToArray(index), function (idx) { + cmpts[idx] && result.push(cmpts[idx]); + }); + } else if (id != null) { + result = queryByIdOrName('id', id, cmpts); + } else if (name != null) { + result = queryByIdOrName('name', name, cmpts); + } else { + // Return all non-empty components in that mainType + result = filter(cmpts, function (cmpt) { + return !!cmpt; + }); + } + return filterBySubType(result, condition); + }; + /** + * The interface is different from queryComponents, + * which is convenient for inner usage. + * + * @usage + * let result = findComponents( + * {mainType: 'dataZoom', query: {dataZoomId: 'abc'}} + * ); + * let result = findComponents( + * {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}} + * ); + * let result = findComponents( + * {mainType: 'series', + * filter: function (model, index) {...}} + * ); + * // result like [component0, componnet1, ...] + */ + GlobalModel.prototype.findComponents = function (condition) { + var query = condition.query; + var mainType = condition.mainType; + var queryCond = getQueryCond(query); + var result = queryCond ? this.queryComponents(queryCond) + // Retrieve all non-empty components. + : filter(this._componentsMap.get(mainType), function (cmpt) { + return !!cmpt; + }); + return doFilter(filterBySubType(result, condition)); + function getQueryCond(q) { + var indexAttr = mainType + 'Index'; + var idAttr = mainType + 'Id'; + var nameAttr = mainType + 'Name'; + return q && (q[indexAttr] != null || q[idAttr] != null || q[nameAttr] != null) ? { + mainType: mainType, + // subType will be filtered finally. + index: q[indexAttr], + id: q[idAttr], + name: q[nameAttr] + } : null; + } + function doFilter(res) { + return condition.filter ? filter(res, condition.filter) : res; + } + }; + GlobalModel.prototype.eachComponent = function (mainType, cb, context) { + var componentsMap = this._componentsMap; + if (isFunction(mainType)) { + var ctxForAll_1 = cb; + var cbForAll_1 = mainType; + componentsMap.each(function (cmpts, componentType) { + for (var i = 0; cmpts && i < cmpts.length; i++) { + var cmpt = cmpts[i]; + cmpt && cbForAll_1.call(ctxForAll_1, componentType, cmpt, cmpt.componentIndex); + } + }); + } else { + var cmpts = isString(mainType) ? componentsMap.get(mainType) : isObject(mainType) ? this.findComponents(mainType) : null; + for (var i = 0; cmpts && i < cmpts.length; i++) { + var cmpt = cmpts[i]; + cmpt && cb.call(context, cmpt, cmpt.componentIndex); + } + } + }; + /** + * Get series list before filtered by name. + */ + GlobalModel.prototype.getSeriesByName = function (name) { + var nameStr = convertOptionIdName(name, null); + return filter(this._componentsMap.get('series'), function (oneSeries) { + return !!oneSeries && nameStr != null && oneSeries.name === nameStr; + }); + }; + /** + * Get series list before filtered by index. + */ + GlobalModel.prototype.getSeriesByIndex = function (seriesIndex) { + return this._componentsMap.get('series')[seriesIndex]; + }; + /** + * Get series list before filtered by type. + * FIXME: rename to getRawSeriesByType? + */ + GlobalModel.prototype.getSeriesByType = function (subType) { + return filter(this._componentsMap.get('series'), function (oneSeries) { + return !!oneSeries && oneSeries.subType === subType; + }); + }; + /** + * Get all series before filtered. + */ + GlobalModel.prototype.getSeries = function () { + return filter(this._componentsMap.get('series'), function (oneSeries) { + return !!oneSeries; + }); + }; + /** + * Count series before filtered. + */ + GlobalModel.prototype.getSeriesCount = function () { + return this._componentsCount.get('series'); + }; + /** + * After filtering, series may be different + * from raw series. + */ + GlobalModel.prototype.eachSeries = function (cb, context) { + assertSeriesInitialized(this); + each(this._seriesIndices, function (rawSeriesIndex) { + var series = this._componentsMap.get('series')[rawSeriesIndex]; + cb.call(context, series, rawSeriesIndex); + }, this); + }; + /** + * Iterate raw series before filtered. + * + * @param {Function} cb + * @param {*} context + */ + GlobalModel.prototype.eachRawSeries = function (cb, context) { + each(this._componentsMap.get('series'), function (series) { + series && cb.call(context, series, series.componentIndex); + }); + }; + /** + * After filtering, series may be different. + * from raw series. + */ + GlobalModel.prototype.eachSeriesByType = function (subType, cb, context) { + assertSeriesInitialized(this); + each(this._seriesIndices, function (rawSeriesIndex) { + var series = this._componentsMap.get('series')[rawSeriesIndex]; + if (series.subType === subType) { + cb.call(context, series, rawSeriesIndex); + } + }, this); + }; + /** + * Iterate raw series before filtered of given type. + */ + GlobalModel.prototype.eachRawSeriesByType = function (subType, cb, context) { + return each(this.getSeriesByType(subType), cb, context); + }; + GlobalModel.prototype.isSeriesFiltered = function (seriesModel) { + assertSeriesInitialized(this); + return this._seriesIndicesMap.get(seriesModel.componentIndex) == null; + }; + GlobalModel.prototype.getCurrentSeriesIndices = function () { + return (this._seriesIndices || []).slice(); + }; + GlobalModel.prototype.filterSeries = function (cb, context) { + assertSeriesInitialized(this); + var newSeriesIndices = []; + each(this._seriesIndices, function (seriesRawIdx) { + var series = this._componentsMap.get('series')[seriesRawIdx]; + cb.call(context, series, seriesRawIdx) && newSeriesIndices.push(seriesRawIdx); + }, this); + this._seriesIndices = newSeriesIndices; + this._seriesIndicesMap = createHashMap(newSeriesIndices); + }; + GlobalModel.prototype.restoreData = function (payload) { + reCreateSeriesIndices(this); + var componentsMap = this._componentsMap; + var componentTypes = []; + componentsMap.each(function (components, componentType) { + if (ComponentModel.hasClass(componentType)) { + componentTypes.push(componentType); + } + }); + ComponentModel.topologicalTravel(componentTypes, ComponentModel.getAllClassMainTypes(), function (componentType) { + each(componentsMap.get(componentType), function (component) { + if (component && (componentType !== 'series' || !isNotTargetSeries(component, payload))) { + component.restoreData(); + } + }); + }); + }; + GlobalModel.internalField = function () { + reCreateSeriesIndices = function (ecModel) { + var seriesIndices = ecModel._seriesIndices = []; + each(ecModel._componentsMap.get('series'), function (series) { + // series may have been removed by `replaceMerge`. + series && seriesIndices.push(series.componentIndex); + }); + ecModel._seriesIndicesMap = createHashMap(seriesIndices); + }; + assertSeriesInitialized = function (ecModel) { + // Components that use _seriesIndices should depends on series component, + // which make sure that their initialization is after series. + if ("development" !== 'production') { + if (!ecModel._seriesIndices) { + throw new Error('Option should contains series.'); + } + } + }; + initBase = function (ecModel, baseOption) { + // Using OPTION_INNER_KEY to mark that this option cannot be used outside, + // i.e. `chart.setOption(chart.getModel().option);` is forbidden. + ecModel.option = {}; + ecModel.option[OPTION_INNER_KEY] = OPTION_INNER_VALUE; + // Init with series: [], in case of calling findSeries method + // before series initialized. + ecModel._componentsMap = createHashMap({ + series: [] + }); + ecModel._componentsCount = createHashMap(); + // If user spefied `option.aria`, aria will be enable. This detection should be + // performed before theme and globalDefault merge. + var airaOption = baseOption.aria; + if (isObject(airaOption) && airaOption.enabled == null) { + airaOption.enabled = true; + } + mergeTheme(baseOption, ecModel._theme.option); + // TODO Needs clone when merging to the unexisted property + merge(baseOption, globalDefault, false); + ecModel._mergeOption(baseOption, null); + }; + }(); + return GlobalModel; + }(Model); + function isNotTargetSeries(seriesModel, payload) { + if (payload) { + var index = payload.seriesIndex; + var id = payload.seriesId; + var name_1 = payload.seriesName; + return index != null && seriesModel.componentIndex !== index || id != null && seriesModel.id !== id || name_1 != null && seriesModel.name !== name_1; + } + } + function mergeTheme(option, theme) { + // PENDING + // NOT use `colorLayer` in theme if option has `color` + var notMergeColorLayer = option.color && !option.colorLayer; + each(theme, function (themeItem, name) { + if (name === 'colorLayer' && notMergeColorLayer) { + return; + } + // If it is component model mainType, the model handles that merge later. + // otherwise, merge them here. + if (!ComponentModel.hasClass(name)) { + if (typeof themeItem === 'object') { + option[name] = !option[name] ? clone(themeItem) : merge(option[name], themeItem, false); + } else { + if (option[name] == null) { + option[name] = themeItem; + } + } + } + }); + } + function queryByIdOrName(attr, idOrName, cmpts) { + // Here is a break from echarts4: string and number are + // treated as equal. + if (isArray(idOrName)) { + var keyMap_1 = createHashMap(); + each(idOrName, function (idOrNameItem) { + if (idOrNameItem != null) { + var idName = convertOptionIdName(idOrNameItem, null); + idName != null && keyMap_1.set(idOrNameItem, true); + } + }); + return filter(cmpts, function (cmpt) { + return cmpt && keyMap_1.get(cmpt[attr]); + }); + } else { + var idName_1 = convertOptionIdName(idOrName, null); + return filter(cmpts, function (cmpt) { + return cmpt && idName_1 != null && cmpt[attr] === idName_1; + }); + } + } + function filterBySubType(components, condition) { + // Using hasOwnProperty for restrict. Consider + // subType is undefined in user payload. + return condition.hasOwnProperty('subType') ? filter(components, function (cmpt) { + return cmpt && cmpt.subType === condition.subType; + }) : components; + } + function normalizeSetOptionInput(opts) { + var replaceMergeMainTypeMap = createHashMap(); + opts && each(normalizeToArray(opts.replaceMerge), function (mainType) { + if ("development" !== 'production') { + assert(ComponentModel.hasClass(mainType), '"' + mainType + '" is not valid component main type in "replaceMerge"'); + } + replaceMergeMainTypeMap.set(mainType, true); + }); + return { + replaceMergeMainTypeMap: replaceMergeMainTypeMap + }; + } + mixin(GlobalModel, PaletteMixin); + + var availableMethods = ['getDom', 'getZr', 'getWidth', 'getHeight', 'getDevicePixelRatio', 'dispatchAction', 'isSSR', 'isDisposed', 'on', 'off', 'getDataURL', 'getConnectedDataURL', + // 'getModel', + 'getOption', + // 'getViewOfComponentModel', + // 'getViewOfSeriesModel', + 'getId', 'updateLabelLayout']; + var ExtensionAPI = /** @class */function () { + function ExtensionAPI(ecInstance) { + each(availableMethods, function (methodName) { + this[methodName] = bind(ecInstance[methodName], ecInstance); + }, this); + } + return ExtensionAPI; + }(); + + var coordinateSystemCreators = {}; + var CoordinateSystemManager = /** @class */function () { + function CoordinateSystemManager() { + this._coordinateSystems = []; + } + CoordinateSystemManager.prototype.create = function (ecModel, api) { + var coordinateSystems = []; + each(coordinateSystemCreators, function (creator, type) { + var list = creator.create(ecModel, api); + coordinateSystems = coordinateSystems.concat(list || []); + }); + this._coordinateSystems = coordinateSystems; + }; + CoordinateSystemManager.prototype.update = function (ecModel, api) { + each(this._coordinateSystems, function (coordSys) { + coordSys.update && coordSys.update(ecModel, api); + }); + }; + CoordinateSystemManager.prototype.getCoordinateSystems = function () { + return this._coordinateSystems.slice(); + }; + CoordinateSystemManager.register = function (type, creator) { + coordinateSystemCreators[type] = creator; + }; + CoordinateSystemManager.get = function (type) { + return coordinateSystemCreators[type]; + }; + return CoordinateSystemManager; + }(); + + var QUERY_REG = /^(min|max)?(.+)$/; + // Key: mainType + // type FakeComponentsMap = HashMap<(MappingExistingItem & { subType: string })[]>; + /** + * TERM EXPLANATIONS: + * See `ECOption` and `ECUnitOption` in `src/util/types.ts`. + */ + var OptionManager = /** @class */function () { + // timeline.notMerge is not supported in ec3. Firstly there is rearly + // case that notMerge is needed. Secondly supporting 'notMerge' requires + // rawOption cloned and backuped when timeline changed, which does no + // good to performance. What's more, that both timeline and setOption + // method supply 'notMerge' brings complex and some problems. + // Consider this case: + // (step1) chart.setOption({timeline: {notMerge: false}, ...}, false); + // (step2) chart.setOption({timeline: {notMerge: true}, ...}, false); + function OptionManager(api) { + this._timelineOptions = []; + this._mediaList = []; + /** + * -1, means default. + * empty means no media. + */ + this._currentMediaIndices = []; + this._api = api; + } + OptionManager.prototype.setOption = function (rawOption, optionPreprocessorFuncs, opt) { + if (rawOption) { + // That set dat primitive is dangerous if user reuse the data when setOption again. + each(normalizeToArray(rawOption.series), function (series) { + series && series.data && isTypedArray(series.data) && setAsPrimitive(series.data); + }); + each(normalizeToArray(rawOption.dataset), function (dataset) { + dataset && dataset.source && isTypedArray(dataset.source) && setAsPrimitive(dataset.source); + }); + } + // Caution: some series modify option data, if do not clone, + // it should ensure that the repeat modify correctly + // (create a new object when modify itself). + rawOption = clone(rawOption); + // FIXME + // If some property is set in timeline options or media option but + // not set in baseOption, a warning should be given. + var optionBackup = this._optionBackup; + var newParsedOption = parseRawOption(rawOption, optionPreprocessorFuncs, !optionBackup); + this._newBaseOption = newParsedOption.baseOption; + // For setOption at second time (using merge mode); + if (optionBackup) { + // FIXME + // the restore merge solution is essentially incorrect. + // the mapping can not be 100% consistent with ecModel, which probably brings + // potential bug! + // The first merge is delayed, because in most cases, users do not call `setOption` twice. + // let fakeCmptsMap = this._fakeCmptsMap; + // if (!fakeCmptsMap) { + // fakeCmptsMap = this._fakeCmptsMap = createHashMap(); + // mergeToBackupOption(fakeCmptsMap, null, optionBackup.baseOption, null); + // } + // mergeToBackupOption( + // fakeCmptsMap, optionBackup.baseOption, newParsedOption.baseOption, opt + // ); + // For simplicity, timeline options and media options do not support merge, + // that is, if you `setOption` twice and both has timeline options, the latter + // timeline options will not be merged to the former, but just substitute them. + if (newParsedOption.timelineOptions.length) { + optionBackup.timelineOptions = newParsedOption.timelineOptions; + } + if (newParsedOption.mediaList.length) { + optionBackup.mediaList = newParsedOption.mediaList; + } + if (newParsedOption.mediaDefault) { + optionBackup.mediaDefault = newParsedOption.mediaDefault; + } + } else { + this._optionBackup = newParsedOption; + } + }; + OptionManager.prototype.mountOption = function (isRecreate) { + var optionBackup = this._optionBackup; + this._timelineOptions = optionBackup.timelineOptions; + this._mediaList = optionBackup.mediaList; + this._mediaDefault = optionBackup.mediaDefault; + this._currentMediaIndices = []; + return clone(isRecreate + // this._optionBackup.baseOption, which is created at the first `setOption` + // called, and is merged into every new option by inner method `mergeToBackupOption` + // each time `setOption` called, can be only used in `isRecreate`, because + // its reliability is under suspicion. In other cases option merge is + // performed by `model.mergeOption`. + ? optionBackup.baseOption : this._newBaseOption); + }; + OptionManager.prototype.getTimelineOption = function (ecModel) { + var option; + var timelineOptions = this._timelineOptions; + if (timelineOptions.length) { + // getTimelineOption can only be called after ecModel inited, + // so we can get currentIndex from timelineModel. + var timelineModel = ecModel.getComponent('timeline'); + if (timelineModel) { + option = clone( + // FIXME:TS as TimelineModel or quivlant interface + timelineOptions[timelineModel.getCurrentIndex()]); + } + } + return option; + }; + OptionManager.prototype.getMediaOption = function (ecModel) { + var ecWidth = this._api.getWidth(); + var ecHeight = this._api.getHeight(); + var mediaList = this._mediaList; + var mediaDefault = this._mediaDefault; + var indices = []; + var result = []; + // No media defined. + if (!mediaList.length && !mediaDefault) { + return result; + } + // Multi media may be applied, the latter defined media has higher priority. + for (var i = 0, len = mediaList.length; i < len; i++) { + if (applyMediaQuery(mediaList[i].query, ecWidth, ecHeight)) { + indices.push(i); + } + } + // FIXME + // Whether mediaDefault should force users to provide? Otherwise + // the change by media query can not be recorvered. + if (!indices.length && mediaDefault) { + indices = [-1]; + } + if (indices.length && !indicesEquals(indices, this._currentMediaIndices)) { + result = map(indices, function (index) { + return clone(index === -1 ? mediaDefault.option : mediaList[index].option); + }); + } + // Otherwise return nothing. + this._currentMediaIndices = indices; + return result; + }; + return OptionManager; + }(); + /** + * [RAW_OPTION_PATTERNS] + * (Note: "series: []" represents all other props in `ECUnitOption`) + * + * (1) No prop "baseOption" declared: + * Root option is used as "baseOption" (except prop "options" and "media"). + * ```js + * option = { + * series: [], + * timeline: {}, + * options: [], + * }; + * option = { + * series: [], + * media: {}, + * }; + * option = { + * series: [], + * timeline: {}, + * options: [], + * media: {}, + * } + * ``` + * + * (2) Prop "baseOption" declared: + * If "baseOption" declared, `ECUnitOption` props can only be declared + * inside "baseOption" except prop "timeline" (compat ec2). + * ```js + * option = { + * baseOption: { + * timeline: {}, + * series: [], + * }, + * options: [] + * }; + * option = { + * baseOption: { + * series: [], + * }, + * media: [] + * }; + * option = { + * baseOption: { + * timeline: {}, + * series: [], + * }, + * options: [] + * media: [] + * }; + * option = { + * // ec3 compat ec2: allow (only) `timeline` declared + * // outside baseOption. Keep this setting for compat. + * timeline: {}, + * baseOption: { + * series: [], + * }, + * options: [], + * media: [] + * }; + * ``` + */ + function parseRawOption( + // `rawOption` May be modified + rawOption, optionPreprocessorFuncs, isNew) { + var mediaList = []; + var mediaDefault; + var baseOption; + var declaredBaseOption = rawOption.baseOption; + // Compatible with ec2, [RAW_OPTION_PATTERNS] above. + var timelineOnRoot = rawOption.timeline; + var timelineOptionsOnRoot = rawOption.options; + var mediaOnRoot = rawOption.media; + var hasMedia = !!rawOption.media; + var hasTimeline = !!(timelineOptionsOnRoot || timelineOnRoot || declaredBaseOption && declaredBaseOption.timeline); + if (declaredBaseOption) { + baseOption = declaredBaseOption; + // For merge option. + if (!baseOption.timeline) { + baseOption.timeline = timelineOnRoot; + } + } + // For convenience, enable to use the root option as the `baseOption`: + // `{ ...normalOptionProps, media: [{ ... }, { ... }] }` + else { + if (hasTimeline || hasMedia) { + rawOption.options = rawOption.media = null; + } + baseOption = rawOption; + } + if (hasMedia) { + if (isArray(mediaOnRoot)) { + each(mediaOnRoot, function (singleMedia) { + if ("development" !== 'production') { + // Real case of wrong config. + if (singleMedia && !singleMedia.option && isObject(singleMedia.query) && isObject(singleMedia.query.option)) { + error('Illegal media option. Must be like { media: [ { query: {}, option: {} } ] }'); + } + } + if (singleMedia && singleMedia.option) { + if (singleMedia.query) { + mediaList.push(singleMedia); + } else if (!mediaDefault) { + // Use the first media default. + mediaDefault = singleMedia; + } + } + }); + } else { + if ("development" !== 'production') { + // Real case of wrong config. + error('Illegal media option. Must be an array. Like { media: [ {...}, {...} ] }'); + } + } + } + doPreprocess(baseOption); + each(timelineOptionsOnRoot, function (option) { + return doPreprocess(option); + }); + each(mediaList, function (media) { + return doPreprocess(media.option); + }); + function doPreprocess(option) { + each(optionPreprocessorFuncs, function (preProcess) { + preProcess(option, isNew); + }); + } + return { + baseOption: baseOption, + timelineOptions: timelineOptionsOnRoot || [], + mediaDefault: mediaDefault, + mediaList: mediaList + }; + } + /** + * @see + * Support: width, height, aspectRatio + * Can use max or min as prefix. + */ + function applyMediaQuery(query, ecWidth, ecHeight) { + var realMap = { + width: ecWidth, + height: ecHeight, + aspectratio: ecWidth / ecHeight // lower case for convenience. + }; + + var applicable = true; + each(query, function (value, attr) { + var matched = attr.match(QUERY_REG); + if (!matched || !matched[1] || !matched[2]) { + return; + } + var operator = matched[1]; + var realAttr = matched[2].toLowerCase(); + if (!compare(realMap[realAttr], value, operator)) { + applicable = false; + } + }); + return applicable; + } + function compare(real, expect, operator) { + if (operator === 'min') { + return real >= expect; + } else if (operator === 'max') { + return real <= expect; + } else { + // Equals + return real === expect; + } + } + function indicesEquals(indices1, indices2) { + // indices is always order by asc and has only finite number. + return indices1.join(',') === indices2.join(','); + } + + var each$2 = each; + var isObject$1 = isObject; + var POSSIBLE_STYLES = ['areaStyle', 'lineStyle', 'nodeStyle', 'linkStyle', 'chordStyle', 'label', 'labelLine']; + function compatEC2ItemStyle(opt) { + var itemStyleOpt = opt && opt.itemStyle; + if (!itemStyleOpt) { + return; + } + for (var i = 0, len = POSSIBLE_STYLES.length; i < len; i++) { + var styleName = POSSIBLE_STYLES[i]; + var normalItemStyleOpt = itemStyleOpt.normal; + var emphasisItemStyleOpt = itemStyleOpt.emphasis; + if (normalItemStyleOpt && normalItemStyleOpt[styleName]) { + if ("development" !== 'production') { + deprecateReplaceLog("itemStyle.normal." + styleName, styleName); + } + opt[styleName] = opt[styleName] || {}; + if (!opt[styleName].normal) { + opt[styleName].normal = normalItemStyleOpt[styleName]; + } else { + merge(opt[styleName].normal, normalItemStyleOpt[styleName]); + } + normalItemStyleOpt[styleName] = null; + } + if (emphasisItemStyleOpt && emphasisItemStyleOpt[styleName]) { + if ("development" !== 'production') { + deprecateReplaceLog("itemStyle.emphasis." + styleName, "emphasis." + styleName); + } + opt[styleName] = opt[styleName] || {}; + if (!opt[styleName].emphasis) { + opt[styleName].emphasis = emphasisItemStyleOpt[styleName]; + } else { + merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]); + } + emphasisItemStyleOpt[styleName] = null; + } + } + } + function convertNormalEmphasis(opt, optType, useExtend) { + if (opt && opt[optType] && (opt[optType].normal || opt[optType].emphasis)) { + var normalOpt = opt[optType].normal; + var emphasisOpt = opt[optType].emphasis; + if (normalOpt) { + if ("development" !== 'production') { + // eslint-disable-next-line max-len + deprecateLog("'normal' hierarchy in " + optType + " has been removed since 4.0. All style properties are configured in " + optType + " directly now."); + } + // Timeline controlStyle has other properties besides normal and emphasis + if (useExtend) { + opt[optType].normal = opt[optType].emphasis = null; + defaults(opt[optType], normalOpt); + } else { + opt[optType] = normalOpt; + } + } + if (emphasisOpt) { + if ("development" !== 'production') { + deprecateLog(optType + ".emphasis has been changed to emphasis." + optType + " since 4.0"); + } + opt.emphasis = opt.emphasis || {}; + opt.emphasis[optType] = emphasisOpt; + // Also compat the case user mix the style and focus together in ec3 style + // for example: { itemStyle: { normal: {}, emphasis: {focus, shadowBlur} } } + if (emphasisOpt.focus) { + opt.emphasis.focus = emphasisOpt.focus; + } + if (emphasisOpt.blurScope) { + opt.emphasis.blurScope = emphasisOpt.blurScope; + } + } + } + } + function removeEC3NormalStatus(opt) { + convertNormalEmphasis(opt, 'itemStyle'); + convertNormalEmphasis(opt, 'lineStyle'); + convertNormalEmphasis(opt, 'areaStyle'); + convertNormalEmphasis(opt, 'label'); + convertNormalEmphasis(opt, 'labelLine'); + // treemap + convertNormalEmphasis(opt, 'upperLabel'); + // graph + convertNormalEmphasis(opt, 'edgeLabel'); + } + function compatTextStyle(opt, propName) { + // Check whether is not object (string\null\undefined ...) + var labelOptSingle = isObject$1(opt) && opt[propName]; + var textStyle = isObject$1(labelOptSingle) && labelOptSingle.textStyle; + if (textStyle) { + if ("development" !== 'production') { + // eslint-disable-next-line max-len + deprecateLog("textStyle hierarchy in " + propName + " has been removed since 4.0. All textStyle properties are configured in " + propName + " directly now."); + } + for (var i = 0, len = TEXT_STYLE_OPTIONS.length; i < len; i++) { + var textPropName = TEXT_STYLE_OPTIONS[i]; + if (textStyle.hasOwnProperty(textPropName)) { + labelOptSingle[textPropName] = textStyle[textPropName]; + } + } + } + } + function compatEC3CommonStyles(opt) { + if (opt) { + removeEC3NormalStatus(opt); + compatTextStyle(opt, 'label'); + opt.emphasis && compatTextStyle(opt.emphasis, 'label'); + } + } + function processSeries(seriesOpt) { + if (!isObject$1(seriesOpt)) { + return; + } + compatEC2ItemStyle(seriesOpt); + removeEC3NormalStatus(seriesOpt); + compatTextStyle(seriesOpt, 'label'); + // treemap + compatTextStyle(seriesOpt, 'upperLabel'); + // graph + compatTextStyle(seriesOpt, 'edgeLabel'); + if (seriesOpt.emphasis) { + compatTextStyle(seriesOpt.emphasis, 'label'); + // treemap + compatTextStyle(seriesOpt.emphasis, 'upperLabel'); + // graph + compatTextStyle(seriesOpt.emphasis, 'edgeLabel'); + } + var markPoint = seriesOpt.markPoint; + if (markPoint) { + compatEC2ItemStyle(markPoint); + compatEC3CommonStyles(markPoint); + } + var markLine = seriesOpt.markLine; + if (markLine) { + compatEC2ItemStyle(markLine); + compatEC3CommonStyles(markLine); + } + var markArea = seriesOpt.markArea; + if (markArea) { + compatEC3CommonStyles(markArea); + } + var data = seriesOpt.data; + // Break with ec3: if `setOption` again, there may be no `type` in option, + // then the backward compat based on option type will not be performed. + if (seriesOpt.type === 'graph') { + data = data || seriesOpt.nodes; + var edgeData = seriesOpt.links || seriesOpt.edges; + if (edgeData && !isTypedArray(edgeData)) { + for (var i = 0; i < edgeData.length; i++) { + compatEC3CommonStyles(edgeData[i]); + } + } + each(seriesOpt.categories, function (opt) { + removeEC3NormalStatus(opt); + }); + } + if (data && !isTypedArray(data)) { + for (var i = 0; i < data.length; i++) { + compatEC3CommonStyles(data[i]); + } + } + // mark point data + markPoint = seriesOpt.markPoint; + if (markPoint && markPoint.data) { + var mpData = markPoint.data; + for (var i = 0; i < mpData.length; i++) { + compatEC3CommonStyles(mpData[i]); + } + } + // mark line data + markLine = seriesOpt.markLine; + if (markLine && markLine.data) { + var mlData = markLine.data; + for (var i = 0; i < mlData.length; i++) { + if (isArray(mlData[i])) { + compatEC3CommonStyles(mlData[i][0]); + compatEC3CommonStyles(mlData[i][1]); + } else { + compatEC3CommonStyles(mlData[i]); + } + } + } + // Series + if (seriesOpt.type === 'gauge') { + compatTextStyle(seriesOpt, 'axisLabel'); + compatTextStyle(seriesOpt, 'title'); + compatTextStyle(seriesOpt, 'detail'); + } else if (seriesOpt.type === 'treemap') { + convertNormalEmphasis(seriesOpt.breadcrumb, 'itemStyle'); + each(seriesOpt.levels, function (opt) { + removeEC3NormalStatus(opt); + }); + } else if (seriesOpt.type === 'tree') { + removeEC3NormalStatus(seriesOpt.leaves); + } + // sunburst starts from ec4, so it does not need to compat levels. + } + + function toArr(o) { + return isArray(o) ? o : o ? [o] : []; + } + function toObj(o) { + return (isArray(o) ? o[0] : o) || {}; + } + function globalCompatStyle(option, isTheme) { + each$2(toArr(option.series), function (seriesOpt) { + isObject$1(seriesOpt) && processSeries(seriesOpt); + }); + var axes = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'parallelAxis', 'radar']; + isTheme && axes.push('valueAxis', 'categoryAxis', 'logAxis', 'timeAxis'); + each$2(axes, function (axisName) { + each$2(toArr(option[axisName]), function (axisOpt) { + if (axisOpt) { + compatTextStyle(axisOpt, 'axisLabel'); + compatTextStyle(axisOpt.axisPointer, 'label'); + } + }); + }); + each$2(toArr(option.parallel), function (parallelOpt) { + var parallelAxisDefault = parallelOpt && parallelOpt.parallelAxisDefault; + compatTextStyle(parallelAxisDefault, 'axisLabel'); + compatTextStyle(parallelAxisDefault && parallelAxisDefault.axisPointer, 'label'); + }); + each$2(toArr(option.calendar), function (calendarOpt) { + convertNormalEmphasis(calendarOpt, 'itemStyle'); + compatTextStyle(calendarOpt, 'dayLabel'); + compatTextStyle(calendarOpt, 'monthLabel'); + compatTextStyle(calendarOpt, 'yearLabel'); + }); + // radar.name.textStyle + each$2(toArr(option.radar), function (radarOpt) { + compatTextStyle(radarOpt, 'name'); + // Use axisName instead of name because component has name property + if (radarOpt.name && radarOpt.axisName == null) { + radarOpt.axisName = radarOpt.name; + delete radarOpt.name; + if ("development" !== 'production') { + deprecateLog('name property in radar component has been changed to axisName'); + } + } + if (radarOpt.nameGap != null && radarOpt.axisNameGap == null) { + radarOpt.axisNameGap = radarOpt.nameGap; + delete radarOpt.nameGap; + if ("development" !== 'production') { + deprecateLog('nameGap property in radar component has been changed to axisNameGap'); + } + } + if ("development" !== 'production') { + each$2(radarOpt.indicator, function (indicatorOpt) { + if (indicatorOpt.text) { + deprecateReplaceLog('text', 'name', 'radar.indicator'); + } + }); + } + }); + each$2(toArr(option.geo), function (geoOpt) { + if (isObject$1(geoOpt)) { + compatEC3CommonStyles(geoOpt); + each$2(toArr(geoOpt.regions), function (regionObj) { + compatEC3CommonStyles(regionObj); + }); + } + }); + each$2(toArr(option.timeline), function (timelineOpt) { + compatEC3CommonStyles(timelineOpt); + convertNormalEmphasis(timelineOpt, 'label'); + convertNormalEmphasis(timelineOpt, 'itemStyle'); + convertNormalEmphasis(timelineOpt, 'controlStyle', true); + var data = timelineOpt.data; + isArray(data) && each(data, function (item) { + if (isObject(item)) { + convertNormalEmphasis(item, 'label'); + convertNormalEmphasis(item, 'itemStyle'); + } + }); + }); + each$2(toArr(option.toolbox), function (toolboxOpt) { + convertNormalEmphasis(toolboxOpt, 'iconStyle'); + each$2(toolboxOpt.feature, function (featureOpt) { + convertNormalEmphasis(featureOpt, 'iconStyle'); + }); + }); + compatTextStyle(toObj(option.axisPointer), 'label'); + compatTextStyle(toObj(option.tooltip).axisPointer, 'label'); + // Clean logs + // storedLogs = {}; + } + + function get(opt, path) { + var pathArr = path.split(','); + var obj = opt; + for (var i = 0; i < pathArr.length; i++) { + obj = obj && obj[pathArr[i]]; + if (obj == null) { + break; + } + } + return obj; + } + function set$1(opt, path, val, overwrite) { + var pathArr = path.split(','); + var obj = opt; + var key; + var i = 0; + for (; i < pathArr.length - 1; i++) { + key = pathArr[i]; + if (obj[key] == null) { + obj[key] = {}; + } + obj = obj[key]; + } + if (overwrite || obj[pathArr[i]] == null) { + obj[pathArr[i]] = val; + } + } + function compatLayoutProperties(option) { + option && each(LAYOUT_PROPERTIES, function (prop) { + if (prop[0] in option && !(prop[1] in option)) { + option[prop[1]] = option[prop[0]]; + } + }); + } + var LAYOUT_PROPERTIES = [['x', 'left'], ['y', 'top'], ['x2', 'right'], ['y2', 'bottom']]; + var COMPATITABLE_COMPONENTS = ['grid', 'geo', 'parallel', 'legend', 'toolbox', 'title', 'visualMap', 'dataZoom', 'timeline']; + var BAR_ITEM_STYLE_MAP = [['borderRadius', 'barBorderRadius'], ['borderColor', 'barBorderColor'], ['borderWidth', 'barBorderWidth']]; + function compatBarItemStyle(option) { + var itemStyle = option && option.itemStyle; + if (itemStyle) { + for (var i = 0; i < BAR_ITEM_STYLE_MAP.length; i++) { + var oldName = BAR_ITEM_STYLE_MAP[i][1]; + var newName = BAR_ITEM_STYLE_MAP[i][0]; + if (itemStyle[oldName] != null) { + itemStyle[newName] = itemStyle[oldName]; + if ("development" !== 'production') { + deprecateReplaceLog(oldName, newName); + } + } + } + } + } + function compatPieLabel(option) { + if (!option) { + return; + } + if (option.alignTo === 'edge' && option.margin != null && option.edgeDistance == null) { + if ("development" !== 'production') { + deprecateReplaceLog('label.margin', 'label.edgeDistance', 'pie'); + } + option.edgeDistance = option.margin; + } + } + function compatSunburstState(option) { + if (!option) { + return; + } + if (option.downplay && !option.blur) { + option.blur = option.downplay; + if ("development" !== 'production') { + deprecateReplaceLog('downplay', 'blur', 'sunburst'); + } + } + } + function compatGraphFocus(option) { + if (!option) { + return; + } + if (option.focusNodeAdjacency != null) { + option.emphasis = option.emphasis || {}; + if (option.emphasis.focus == null) { + if ("development" !== 'production') { + deprecateReplaceLog('focusNodeAdjacency', 'emphasis: { focus: \'adjacency\'}', 'graph/sankey'); + } + option.emphasis.focus = 'adjacency'; + } + } + } + function traverseTree(data, cb) { + if (data) { + for (var i = 0; i < data.length; i++) { + cb(data[i]); + data[i] && traverseTree(data[i].children, cb); + } + } + } + function globalBackwardCompat(option, isTheme) { + globalCompatStyle(option, isTheme); + // Make sure series array for model initialization. + option.series = normalizeToArray(option.series); + each(option.series, function (seriesOpt) { + if (!isObject(seriesOpt)) { + return; + } + var seriesType = seriesOpt.type; + if (seriesType === 'line') { + if (seriesOpt.clipOverflow != null) { + seriesOpt.clip = seriesOpt.clipOverflow; + if ("development" !== 'production') { + deprecateReplaceLog('clipOverflow', 'clip', 'line'); + } + } + } else if (seriesType === 'pie' || seriesType === 'gauge') { + if (seriesOpt.clockWise != null) { + seriesOpt.clockwise = seriesOpt.clockWise; + if ("development" !== 'production') { + deprecateReplaceLog('clockWise', 'clockwise'); + } + } + compatPieLabel(seriesOpt.label); + var data = seriesOpt.data; + if (data && !isTypedArray(data)) { + for (var i = 0; i < data.length; i++) { + compatPieLabel(data[i]); + } + } + if (seriesOpt.hoverOffset != null) { + seriesOpt.emphasis = seriesOpt.emphasis || {}; + if (seriesOpt.emphasis.scaleSize = null) { + if ("development" !== 'production') { + deprecateReplaceLog('hoverOffset', 'emphasis.scaleSize'); + } + seriesOpt.emphasis.scaleSize = seriesOpt.hoverOffset; + } + } + } else if (seriesType === 'gauge') { + var pointerColor = get(seriesOpt, 'pointer.color'); + pointerColor != null && set$1(seriesOpt, 'itemStyle.color', pointerColor); + } else if (seriesType === 'bar') { + compatBarItemStyle(seriesOpt); + compatBarItemStyle(seriesOpt.backgroundStyle); + compatBarItemStyle(seriesOpt.emphasis); + var data = seriesOpt.data; + if (data && !isTypedArray(data)) { + for (var i = 0; i < data.length; i++) { + if (typeof data[i] === 'object') { + compatBarItemStyle(data[i]); + compatBarItemStyle(data[i] && data[i].emphasis); + } + } + } + } else if (seriesType === 'sunburst') { + var highlightPolicy = seriesOpt.highlightPolicy; + if (highlightPolicy) { + seriesOpt.emphasis = seriesOpt.emphasis || {}; + if (!seriesOpt.emphasis.focus) { + seriesOpt.emphasis.focus = highlightPolicy; + if ("development" !== 'production') { + deprecateReplaceLog('highlightPolicy', 'emphasis.focus', 'sunburst'); + } + } + } + compatSunburstState(seriesOpt); + traverseTree(seriesOpt.data, compatSunburstState); + } else if (seriesType === 'graph' || seriesType === 'sankey') { + compatGraphFocus(seriesOpt); + // TODO nodes, edges? + } else if (seriesType === 'map') { + if (seriesOpt.mapType && !seriesOpt.map) { + if ("development" !== 'production') { + deprecateReplaceLog('mapType', 'map', 'map'); + } + seriesOpt.map = seriesOpt.mapType; + } + if (seriesOpt.mapLocation) { + if ("development" !== 'production') { + deprecateLog('`mapLocation` is not used anymore.'); + } + defaults(seriesOpt, seriesOpt.mapLocation); + } + } + if (seriesOpt.hoverAnimation != null) { + seriesOpt.emphasis = seriesOpt.emphasis || {}; + if (seriesOpt.emphasis && seriesOpt.emphasis.scale == null) { + if ("development" !== 'production') { + deprecateReplaceLog('hoverAnimation', 'emphasis.scale'); + } + seriesOpt.emphasis.scale = seriesOpt.hoverAnimation; + } + } + compatLayoutProperties(seriesOpt); + }); + // dataRange has changed to visualMap + if (option.dataRange) { + option.visualMap = option.dataRange; + } + each(COMPATITABLE_COMPONENTS, function (componentName) { + var options = option[componentName]; + if (options) { + if (!isArray(options)) { + options = [options]; + } + each(options, function (option) { + compatLayoutProperties(option); + }); + } + }); + } + + // (1) [Caution]: the logic is correct based on the premises: + // data processing stage is blocked in stream. + // See + // (2) Only register once when import repeatedly. + // Should be executed after series is filtered and before stack calculation. + function dataStack(ecModel) { + var stackInfoMap = createHashMap(); + ecModel.eachSeries(function (seriesModel) { + var stack = seriesModel.get('stack'); + // Compatible: when `stack` is set as '', do not stack. + if (stack) { + var stackInfoList = stackInfoMap.get(stack) || stackInfoMap.set(stack, []); + var data = seriesModel.getData(); + var stackInfo = { + // Used for calculate axis extent automatically. + // TODO: Type getCalculationInfo return more specific type? + stackResultDimension: data.getCalculationInfo('stackResultDimension'), + stackedOverDimension: data.getCalculationInfo('stackedOverDimension'), + stackedDimension: data.getCalculationInfo('stackedDimension'), + stackedByDimension: data.getCalculationInfo('stackedByDimension'), + isStackedByIndex: data.getCalculationInfo('isStackedByIndex'), + data: data, + seriesModel: seriesModel + }; + // If stacked on axis that do not support data stack. + if (!stackInfo.stackedDimension || !(stackInfo.isStackedByIndex || stackInfo.stackedByDimension)) { + return; + } + stackInfoList.length && data.setCalculationInfo('stackedOnSeries', stackInfoList[stackInfoList.length - 1].seriesModel); + stackInfoList.push(stackInfo); + } + }); + stackInfoMap.each(calculateStack); + } + function calculateStack(stackInfoList) { + each(stackInfoList, function (targetStackInfo, idxInStack) { + var resultVal = []; + var resultNaN = [NaN, NaN]; + var dims = [targetStackInfo.stackResultDimension, targetStackInfo.stackedOverDimension]; + var targetData = targetStackInfo.data; + var isStackedByIndex = targetStackInfo.isStackedByIndex; + var stackStrategy = targetStackInfo.seriesModel.get('stackStrategy') || 'samesign'; + // Should not write on raw data, because stack series model list changes + // depending on legend selection. + targetData.modify(dims, function (v0, v1, dataIndex) { + var sum = targetData.get(targetStackInfo.stackedDimension, dataIndex); + // Consider `connectNulls` of line area, if value is NaN, stackedOver + // should also be NaN, to draw a appropriate belt area. + if (isNaN(sum)) { + return resultNaN; + } + var byValue; + var stackedDataRawIndex; + if (isStackedByIndex) { + stackedDataRawIndex = targetData.getRawIndex(dataIndex); + } else { + byValue = targetData.get(targetStackInfo.stackedByDimension, dataIndex); + } + // If stackOver is NaN, chart view will render point on value start. + var stackedOver = NaN; + for (var j = idxInStack - 1; j >= 0; j--) { + var stackInfo = stackInfoList[j]; + // Has been optimized by inverted indices on `stackedByDimension`. + if (!isStackedByIndex) { + stackedDataRawIndex = stackInfo.data.rawIndexOf(stackInfo.stackedByDimension, byValue); + } + if (stackedDataRawIndex >= 0) { + var val = stackInfo.data.getByRawIndex(stackInfo.stackResultDimension, stackedDataRawIndex); + // Considering positive stack, negative stack and empty data + if (stackStrategy === 'all' // single stack group + || stackStrategy === 'positive' && val > 0 || stackStrategy === 'negative' && val < 0 || stackStrategy === 'samesign' && sum >= 0 && val > 0 // All positive stack + || stackStrategy === 'samesign' && sum <= 0 && val < 0 // All negative stack + ) { + // The sum has to be very small to be affected by the + // floating arithmetic problem. An incorrect result will probably + // cause axis min/max to be filtered incorrectly. + sum = addSafe(sum, val); + stackedOver = val; + break; + } + } + } + resultVal[0] = sum; + resultVal[1] = stackedOver; + return resultVal; + }); + }); + } + + // @inner + var SourceImpl = /** @class */function () { + function SourceImpl(fields) { + this.data = fields.data || (fields.sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS ? {} : []); + this.sourceFormat = fields.sourceFormat || SOURCE_FORMAT_UNKNOWN; + // Visit config + this.seriesLayoutBy = fields.seriesLayoutBy || SERIES_LAYOUT_BY_COLUMN; + this.startIndex = fields.startIndex || 0; + this.dimensionsDetectedCount = fields.dimensionsDetectedCount; + this.metaRawOption = fields.metaRawOption; + var dimensionsDefine = this.dimensionsDefine = fields.dimensionsDefine; + if (dimensionsDefine) { + for (var i = 0; i < dimensionsDefine.length; i++) { + var dim = dimensionsDefine[i]; + if (dim.type == null) { + if (guessOrdinal(this, i) === BE_ORDINAL.Must) { + dim.type = 'ordinal'; + } + } + } + } + } + return SourceImpl; + }(); + function isSourceInstance(val) { + return val instanceof SourceImpl; + } + /** + * Create a source from option. + * NOTE: Created source is immutable. Don't change any properties in it. + */ + function createSource(sourceData, thisMetaRawOption, + // can be null. If not provided, auto detect it from `sourceData`. + sourceFormat) { + sourceFormat = sourceFormat || detectSourceFormat(sourceData); + var seriesLayoutBy = thisMetaRawOption.seriesLayoutBy; + var determined = determineSourceDimensions(sourceData, sourceFormat, seriesLayoutBy, thisMetaRawOption.sourceHeader, thisMetaRawOption.dimensions); + var source = new SourceImpl({ + data: sourceData, + sourceFormat: sourceFormat, + seriesLayoutBy: seriesLayoutBy, + dimensionsDefine: determined.dimensionsDefine, + startIndex: determined.startIndex, + dimensionsDetectedCount: determined.dimensionsDetectedCount, + metaRawOption: clone(thisMetaRawOption) + }); + return source; + } + /** + * Wrap original series data for some compatibility cases. + */ + function createSourceFromSeriesDataOption(data) { + return new SourceImpl({ + data: data, + sourceFormat: isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL + }); + } + /** + * Clone source but excludes source data. + */ + function cloneSourceShallow(source) { + return new SourceImpl({ + data: source.data, + sourceFormat: source.sourceFormat, + seriesLayoutBy: source.seriesLayoutBy, + dimensionsDefine: clone(source.dimensionsDefine), + startIndex: source.startIndex, + dimensionsDetectedCount: source.dimensionsDetectedCount + }); + } + /** + * Note: An empty array will be detected as `SOURCE_FORMAT_ARRAY_ROWS`. + */ + function detectSourceFormat(data) { + var sourceFormat = SOURCE_FORMAT_UNKNOWN; + if (isTypedArray(data)) { + sourceFormat = SOURCE_FORMAT_TYPED_ARRAY; + } else if (isArray(data)) { + // FIXME Whether tolerate null in top level array? + if (data.length === 0) { + sourceFormat = SOURCE_FORMAT_ARRAY_ROWS; + } + for (var i = 0, len = data.length; i < len; i++) { + var item = data[i]; + if (item == null) { + continue; + } else if (isArray(item) || isTypedArray(item)) { + sourceFormat = SOURCE_FORMAT_ARRAY_ROWS; + break; + } else if (isObject(item)) { + sourceFormat = SOURCE_FORMAT_OBJECT_ROWS; + break; + } + } + } else if (isObject(data)) { + for (var key in data) { + if (hasOwn(data, key) && isArrayLike(data[key])) { + sourceFormat = SOURCE_FORMAT_KEYED_COLUMNS; + break; + } + } + } + return sourceFormat; + } + /** + * Determine the source definitions from data standalone dimensions definitions + * are not specified. + */ + function determineSourceDimensions(data, sourceFormat, seriesLayoutBy, sourceHeader, + // standalone raw dimensions definition, like: + // { + // dimensions: ['aa', 'bb', { name: 'cc', type: 'time' }] + // } + // in `dataset` or `series` + dimensionsDefine) { + var dimensionsDetectedCount; + var startIndex; + // PENDING: Could data be null/undefined here? + // currently, if `dataset.source` not specified, error thrown. + // if `series.data` not specified, nothing rendered without error thrown. + // Should test these cases. + if (!data) { + return { + dimensionsDefine: normalizeDimensionsOption(dimensionsDefine), + startIndex: startIndex, + dimensionsDetectedCount: dimensionsDetectedCount + }; + } + if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { + var dataArrayRows = data; + // Rule: Most of the first line are string: it is header. + // Caution: consider a line with 5 string and 1 number, + // it still can not be sure it is a head, because the + // 5 string may be 5 values of category columns. + if (sourceHeader === 'auto' || sourceHeader == null) { + arrayRowsTravelFirst(function (val) { + // '-' is regarded as null/undefined. + if (val != null && val !== '-') { + if (isString(val)) { + startIndex == null && (startIndex = 1); + } else { + startIndex = 0; + } + } + // 10 is an experience number, avoid long loop. + }, seriesLayoutBy, dataArrayRows, 10); + } else { + startIndex = isNumber(sourceHeader) ? sourceHeader : sourceHeader ? 1 : 0; + } + if (!dimensionsDefine && startIndex === 1) { + dimensionsDefine = []; + arrayRowsTravelFirst(function (val, index) { + dimensionsDefine[index] = val != null ? val + '' : ''; + }, seriesLayoutBy, dataArrayRows, Infinity); + } + dimensionsDetectedCount = dimensionsDefine ? dimensionsDefine.length : seriesLayoutBy === SERIES_LAYOUT_BY_ROW ? dataArrayRows.length : dataArrayRows[0] ? dataArrayRows[0].length : null; + } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { + if (!dimensionsDefine) { + dimensionsDefine = objectRowsCollectDimensions(data); + } + } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) { + if (!dimensionsDefine) { + dimensionsDefine = []; + each(data, function (colArr, key) { + dimensionsDefine.push(key); + }); + } + } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { + var value0 = getDataItemValue(data[0]); + dimensionsDetectedCount = isArray(value0) && value0.length || 1; + } else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { + if ("development" !== 'production') { + assert(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.'); + } + } + return { + startIndex: startIndex, + dimensionsDefine: normalizeDimensionsOption(dimensionsDefine), + dimensionsDetectedCount: dimensionsDetectedCount + }; + } + function objectRowsCollectDimensions(data) { + var firstIndex = 0; + var obj; + while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line + if (obj) { + return keys(obj); + } + } + // Consider dimensions defined like ['A', 'price', 'B', 'price', 'C', 'price'], + // which is reasonable. But dimension name is duplicated. + // Returns undefined or an array contains only object without null/undefined or string. + function normalizeDimensionsOption(dimensionsDefine) { + if (!dimensionsDefine) { + // The meaning of null/undefined is different from empty array. + return; + } + var nameMap = createHashMap(); + return map(dimensionsDefine, function (rawItem, index) { + rawItem = isObject(rawItem) ? rawItem : { + name: rawItem + }; + // Other fields will be discarded. + var item = { + name: rawItem.name, + displayName: rawItem.displayName, + type: rawItem.type + }; + // User can set null in dimensions. + // We don't auto specify name, otherwise a given name may + // cause it to be referred unexpectedly. + if (item.name == null) { + return item; + } + // Also consider number form like 2012. + item.name += ''; + // User may also specify displayName. + // displayName will always exists except user not + // specified or dim name is not specified or detected. + // (A auto generated dim name will not be used as + // displayName). + if (item.displayName == null) { + item.displayName = item.name; + } + var exist = nameMap.get(item.name); + if (!exist) { + nameMap.set(item.name, { + count: 1 + }); + } else { + item.name += '-' + exist.count++; + } + return item; + }); + } + function arrayRowsTravelFirst(cb, seriesLayoutBy, data, maxLoop) { + if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) { + for (var i = 0; i < data.length && i < maxLoop; i++) { + cb(data[i] ? data[i][0] : null, i); + } + } else { + var value0 = data[0] || []; + for (var i = 0; i < value0.length && i < maxLoop; i++) { + cb(value0[i], i); + } + } + } + function shouldRetrieveDataByName(source) { + var sourceFormat = source.sourceFormat; + return sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var _a, _b, _c; + var providerMethods; + var mountMethods; + /** + * If normal array used, mutable chunk size is supported. + * If typed array used, chunk size must be fixed. + */ + var DefaultDataProvider = /** @class */function () { + function DefaultDataProvider(sourceParam, dimSize) { + // let source: Source; + var source = !isSourceInstance(sourceParam) ? createSourceFromSeriesDataOption(sourceParam) : sourceParam; + // declare source is Source; + this._source = source; + var data = this._data = source.data; + // Typed array. TODO IE10+? + if (source.sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { + if ("development" !== 'production') { + if (dimSize == null) { + throw new Error('Typed array data must specify dimension size'); + } + } + this._offset = 0; + this._dimSize = dimSize; + this._data = data; + } + mountMethods(this, data, source); + } + DefaultDataProvider.prototype.getSource = function () { + return this._source; + }; + DefaultDataProvider.prototype.count = function () { + return 0; + }; + DefaultDataProvider.prototype.getItem = function (idx, out) { + return; + }; + DefaultDataProvider.prototype.appendData = function (newData) {}; + DefaultDataProvider.prototype.clean = function () {}; + DefaultDataProvider.protoInitialize = function () { + // PENDING: To avoid potential incompat (e.g., prototype + // is visited somewhere), still init them on prototype. + var proto = DefaultDataProvider.prototype; + proto.pure = false; + proto.persistent = true; + }(); + DefaultDataProvider.internalField = function () { + var _a; + mountMethods = function (provider, data, source) { + var sourceFormat = source.sourceFormat; + var seriesLayoutBy = source.seriesLayoutBy; + var startIndex = source.startIndex; + var dimsDef = source.dimensionsDefine; + var methods = providerMethods[getMethodMapKey(sourceFormat, seriesLayoutBy)]; + if ("development" !== 'production') { + assert(methods, 'Invalide sourceFormat: ' + sourceFormat); + } + extend(provider, methods); + if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) { + provider.getItem = getItemForTypedArray; + provider.count = countForTypedArray; + provider.fillStorage = fillStorageForTypedArray; + } else { + var rawItemGetter = getRawSourceItemGetter(sourceFormat, seriesLayoutBy); + provider.getItem = bind(rawItemGetter, null, data, startIndex, dimsDef); + var rawCounter = getRawSourceDataCounter(sourceFormat, seriesLayoutBy); + provider.count = bind(rawCounter, null, data, startIndex, dimsDef); + } + }; + var getItemForTypedArray = function (idx, out) { + idx = idx - this._offset; + out = out || []; + var data = this._data; + var dimSize = this._dimSize; + var offset = dimSize * idx; + for (var i = 0; i < dimSize; i++) { + out[i] = data[offset + i]; + } + return out; + }; + var fillStorageForTypedArray = function (start, end, storage, extent) { + var data = this._data; + var dimSize = this._dimSize; + for (var dim = 0; dim < dimSize; dim++) { + var dimExtent = extent[dim]; + var min = dimExtent[0] == null ? Infinity : dimExtent[0]; + var max = dimExtent[1] == null ? -Infinity : dimExtent[1]; + var count = end - start; + var arr = storage[dim]; + for (var i = 0; i < count; i++) { + // appendData with TypedArray will always do replace in provider. + var val = data[i * dimSize + dim]; + arr[start + i] = val; + val < min && (min = val); + val > max && (max = val); + } + dimExtent[0] = min; + dimExtent[1] = max; + } + }; + var countForTypedArray = function () { + return this._data ? this._data.length / this._dimSize : 0; + }; + providerMethods = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = { + pure: true, + appendData: appendDataSimply + }, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = { + pure: true, + appendData: function () { + throw new Error('Do not support appendData when set seriesLayoutBy: "row".'); + } + }, _a[SOURCE_FORMAT_OBJECT_ROWS] = { + pure: true, + appendData: appendDataSimply + }, _a[SOURCE_FORMAT_KEYED_COLUMNS] = { + pure: true, + appendData: function (newData) { + var data = this._data; + each(newData, function (newCol, key) { + var oldCol = data[key] || (data[key] = []); + for (var i = 0; i < (newCol || []).length; i++) { + oldCol.push(newCol[i]); + } + }); + } + }, _a[SOURCE_FORMAT_ORIGINAL] = { + appendData: appendDataSimply + }, _a[SOURCE_FORMAT_TYPED_ARRAY] = { + persistent: false, + pure: true, + appendData: function (newData) { + if ("development" !== 'production') { + assert(isTypedArray(newData), 'Added data must be TypedArray if data in initialization is TypedArray'); + } + this._data = newData; + }, + // Clean self if data is already used. + clean: function () { + // PENDING + this._offset += this.count(); + this._data = null; + } + }, _a); + function appendDataSimply(newData) { + for (var i = 0; i < newData.length; i++) { + this._data.push(newData[i]); + } + } + }(); + return DefaultDataProvider; + }(); + var getItemSimply = function (rawData, startIndex, dimsDef, idx) { + return rawData[idx]; + }; + var rawSourceItemGetterMap = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef, idx) { + return rawData[idx + startIndex]; + }, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef, idx, out) { + idx += startIndex; + var item = out || []; + var data = rawData; + for (var i = 0; i < data.length; i++) { + var row = data[i]; + item[i] = row ? row[idx] : null; + } + return item; + }, _a[SOURCE_FORMAT_OBJECT_ROWS] = getItemSimply, _a[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef, idx, out) { + var item = out || []; + for (var i = 0; i < dimsDef.length; i++) { + var dimName = dimsDef[i].name; + if ("development" !== 'production') { + if (dimName == null) { + throw new Error(); + } + } + var col = rawData[dimName]; + item[i] = col ? col[idx] : null; + } + return item; + }, _a[SOURCE_FORMAT_ORIGINAL] = getItemSimply, _a); + function getRawSourceItemGetter(sourceFormat, seriesLayoutBy) { + var method = rawSourceItemGetterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)]; + if ("development" !== 'production') { + assert(method, 'Do not support get item on "' + sourceFormat + '", "' + seriesLayoutBy + '".'); + } + return method; + } + var countSimply = function (rawData, startIndex, dimsDef) { + return rawData.length; + }; + var rawSourceDataCounterMap = (_b = {}, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef) { + return Math.max(0, rawData.length - startIndex); + }, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef) { + var row = rawData[0]; + return row ? Math.max(0, row.length - startIndex) : 0; + }, _b[SOURCE_FORMAT_OBJECT_ROWS] = countSimply, _b[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef) { + var dimName = dimsDef[0].name; + if ("development" !== 'production') { + if (dimName == null) { + throw new Error(); + } + } + var col = rawData[dimName]; + return col ? col.length : 0; + }, _b[SOURCE_FORMAT_ORIGINAL] = countSimply, _b); + function getRawSourceDataCounter(sourceFormat, seriesLayoutBy) { + var method = rawSourceDataCounterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)]; + if ("development" !== 'production') { + assert(method, 'Do not support count on "' + sourceFormat + '", "' + seriesLayoutBy + '".'); + } + return method; + } + var getRawValueSimply = function (dataItem, dimIndex, property) { + return dataItem[dimIndex]; + }; + var rawSourceValueGetterMap = (_c = {}, _c[SOURCE_FORMAT_ARRAY_ROWS] = getRawValueSimply, _c[SOURCE_FORMAT_OBJECT_ROWS] = function (dataItem, dimIndex, property) { + return dataItem[property]; + }, _c[SOURCE_FORMAT_KEYED_COLUMNS] = getRawValueSimply, _c[SOURCE_FORMAT_ORIGINAL] = function (dataItem, dimIndex, property) { + // FIXME: In some case (markpoint in geo (geo-map.html)), + // dataItem is {coord: [...]} + var value = getDataItemValue(dataItem); + return !(value instanceof Array) ? value : value[dimIndex]; + }, _c[SOURCE_FORMAT_TYPED_ARRAY] = getRawValueSimply, _c); + function getRawSourceValueGetter(sourceFormat) { + var method = rawSourceValueGetterMap[sourceFormat]; + if ("development" !== 'production') { + assert(method, 'Do not support get value on "' + sourceFormat + '".'); + } + return method; + } + function getMethodMapKey(sourceFormat, seriesLayoutBy) { + return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS ? sourceFormat + '_' + seriesLayoutBy : sourceFormat; + } + // ??? FIXME can these logic be more neat: getRawValue, getRawDataItem, + // Consider persistent. + // Caution: why use raw value to display on label or tooltip? + // A reason is to avoid format. For example time value we do not know + // how to format is expected. More over, if stack is used, calculated + // value may be 0.91000000001, which have brings trouble to display. + // TODO: consider how to treat null/undefined/NaN when display? + function retrieveRawValue(data, dataIndex, + // If dimIndex is null/undefined, return OptionDataItem. + // Otherwise, return OptionDataValue. + dim) { + if (!data) { + return; + } + // Consider data may be not persistent. + var dataItem = data.getRawDataItem(dataIndex); + if (dataItem == null) { + return; + } + var store = data.getStore(); + var sourceFormat = store.getSource().sourceFormat; + if (dim != null) { + var dimIndex = data.getDimensionIndex(dim); + var property = store.getDimensionProperty(dimIndex); + return getRawSourceValueGetter(sourceFormat)(dataItem, dimIndex, property); + } else { + var result = dataItem; + if (sourceFormat === SOURCE_FORMAT_ORIGINAL) { + result = getDataItemValue(dataItem); + } + return result; + } + } + + var DIMENSION_LABEL_REG = /\{@(.+?)\}/g; + var DataFormatMixin = /** @class */function () { + function DataFormatMixin() {} + /** + * Get params for formatter + */ + DataFormatMixin.prototype.getDataParams = function (dataIndex, dataType) { + var data = this.getData(dataType); + var rawValue = this.getRawValue(dataIndex, dataType); + var rawDataIndex = data.getRawIndex(dataIndex); + var name = data.getName(dataIndex); + var itemOpt = data.getRawDataItem(dataIndex); + var style = data.getItemVisual(dataIndex, 'style'); + var color = style && style[data.getItemVisual(dataIndex, 'drawType') || 'fill']; + var borderColor = style && style.stroke; + var mainType = this.mainType; + var isSeries = mainType === 'series'; + var userOutput = data.userOutput && data.userOutput.get(); + return { + componentType: mainType, + componentSubType: this.subType, + componentIndex: this.componentIndex, + seriesType: isSeries ? this.subType : null, + seriesIndex: this.seriesIndex, + seriesId: isSeries ? this.id : null, + seriesName: isSeries ? this.name : null, + name: name, + dataIndex: rawDataIndex, + data: itemOpt, + dataType: dataType, + value: rawValue, + color: color, + borderColor: borderColor, + dimensionNames: userOutput ? userOutput.fullDimensions : null, + encode: userOutput ? userOutput.encode : null, + // Param name list for mapping `a`, `b`, `c`, `d`, `e` + $vars: ['seriesName', 'name', 'value'] + }; + }; + /** + * Format label + * @param dataIndex + * @param status 'normal' by default + * @param dataType + * @param labelDimIndex Only used in some chart that + * use formatter in different dimensions, like radar. + * @param formatter Formatter given outside. + * @return return null/undefined if no formatter + */ + DataFormatMixin.prototype.getFormattedLabel = function (dataIndex, status, dataType, labelDimIndex, formatter, extendParams) { + status = status || 'normal'; + var data = this.getData(dataType); + var params = this.getDataParams(dataIndex, dataType); + if (extendParams) { + params.value = extendParams.interpolatedValue; + } + if (labelDimIndex != null && isArray(params.value)) { + params.value = params.value[labelDimIndex]; + } + if (!formatter) { + var itemModel = data.getItemModel(dataIndex); + // @ts-ignore + formatter = itemModel.get(status === 'normal' ? ['label', 'formatter'] : [status, 'label', 'formatter']); + } + if (isFunction(formatter)) { + params.status = status; + params.dimensionIndex = labelDimIndex; + return formatter(params); + } else if (isString(formatter)) { + var str = formatTpl(formatter, params); + // Support 'aaa{@[3]}bbb{@product}ccc'. + // Do not support '}' in dim name util have to. + return str.replace(DIMENSION_LABEL_REG, function (origin, dimStr) { + var len = dimStr.length; + var dimLoose = dimStr; + if (dimLoose.charAt(0) === '[' && dimLoose.charAt(len - 1) === ']') { + dimLoose = +dimLoose.slice(1, len - 1); // Also support: '[]' => 0 + if ("development" !== 'production') { + if (isNaN(dimLoose)) { + error("Invalide label formatter: @" + dimStr + ", only support @[0], @[1], @[2], ..."); + } + } + } + var val = retrieveRawValue(data, dataIndex, dimLoose); + if (extendParams && isArray(extendParams.interpolatedValue)) { + var dimIndex = data.getDimensionIndex(dimLoose); + if (dimIndex >= 0) { + val = extendParams.interpolatedValue[dimIndex]; + } + } + return val != null ? val + '' : ''; + }); + } + }; + /** + * Get raw value in option + */ + DataFormatMixin.prototype.getRawValue = function (idx, dataType) { + return retrieveRawValue(this.getData(dataType), idx); + }; + /** + * Should be implemented. + * @param {number} dataIndex + * @param {boolean} [multipleSeries=false] + * @param {string} [dataType] + */ + DataFormatMixin.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + // Empty function + return; + }; + return DataFormatMixin; + }(); + // PENDING: previously we accept this type when calling `formatTooltip`, + // but guess little chance has been used outside. Do we need to backward + // compat it? + // type TooltipFormatResultLegacyObject = { + // // `html` means the markup language text, either in 'html' or 'richText'. + // // The name `html` is not appropriate because in 'richText' it is not a HTML + // // string. But still support it for backward compatibility. + // html: string; + // markers: Dictionary; + // }; + /** + * For backward compat, normalize the return from `formatTooltip`. + */ + function normalizeTooltipFormatResult(result) { + var markupText; + // let markers: Dictionary; + var markupFragment; + if (isObject(result)) { + if (result.type) { + markupFragment = result; + } else { + if ("development" !== 'production') { + console.warn('The return type of `formatTooltip` is not supported: ' + makePrintable(result)); + } + } + // else { + // markupText = (result as TooltipFormatResultLegacyObject).html; + // markers = (result as TooltipFormatResultLegacyObject).markers; + // if (markersExisting) { + // markers = zrUtil.merge(markersExisting, markers); + // } + // } + } else { + markupText = result; + } + return { + text: markupText, + // markers: markers || markersExisting, + frag: markupFragment + }; + } + + /** + * @param {Object} define + * @return See the return of `createTask`. + */ + function createTask(define) { + return new Task(define); + } + var Task = /** @class */function () { + function Task(define) { + define = define || {}; + this._reset = define.reset; + this._plan = define.plan; + this._count = define.count; + this._onDirty = define.onDirty; + this._dirty = true; + } + /** + * @param step Specified step. + * @param skip Skip customer perform call. + * @param modBy Sampling window size. + * @param modDataCount Sampling count. + * @return whether unfinished. + */ + Task.prototype.perform = function (performArgs) { + var upTask = this._upstream; + var skip = performArgs && performArgs.skip; + // TODO some refactor. + // Pull data. Must pull data each time, because context.data + // may be updated by Series.setData. + if (this._dirty && upTask) { + var context = this.context; + context.data = context.outputData = upTask.context.outputData; + } + if (this.__pipeline) { + this.__pipeline.currentTask = this; + } + var planResult; + if (this._plan && !skip) { + planResult = this._plan(this.context); + } + // Support sharding by mod, which changes the render sequence and makes the rendered graphic + // elements uniformed distributed when progress, especially when moving or zooming. + var lastModBy = normalizeModBy(this._modBy); + var lastModDataCount = this._modDataCount || 0; + var modBy = normalizeModBy(performArgs && performArgs.modBy); + var modDataCount = performArgs && performArgs.modDataCount || 0; + if (lastModBy !== modBy || lastModDataCount !== modDataCount) { + planResult = 'reset'; + } + function normalizeModBy(val) { + !(val >= 1) && (val = 1); // jshint ignore:line + return val; + } + var forceFirstProgress; + if (this._dirty || planResult === 'reset') { + this._dirty = false; + forceFirstProgress = this._doReset(skip); + } + this._modBy = modBy; + this._modDataCount = modDataCount; + var step = performArgs && performArgs.step; + if (upTask) { + if ("development" !== 'production') { + assert(upTask._outputDueEnd != null); + } + this._dueEnd = upTask._outputDueEnd; + } + // DataTask or overallTask + else { + if ("development" !== 'production') { + assert(!this._progress || this._count); + } + this._dueEnd = this._count ? this._count(this.context) : Infinity; + } + // Note: Stubs, that its host overall task let it has progress, has progress. + // If no progress, pass index from upstream to downstream each time plan called. + if (this._progress) { + var start = this._dueIndex; + var end = Math.min(step != null ? this._dueIndex + step : Infinity, this._dueEnd); + if (!skip && (forceFirstProgress || start < end)) { + var progress = this._progress; + if (isArray(progress)) { + for (var i = 0; i < progress.length; i++) { + this._doProgress(progress[i], start, end, modBy, modDataCount); + } + } else { + this._doProgress(progress, start, end, modBy, modDataCount); + } + } + this._dueIndex = end; + // If no `outputDueEnd`, assume that output data and + // input data is the same, so use `dueIndex` as `outputDueEnd`. + var outputDueEnd = this._settedOutputEnd != null ? this._settedOutputEnd : end; + if ("development" !== 'production') { + // ??? Can not rollback. + assert(outputDueEnd >= this._outputDueEnd); + } + this._outputDueEnd = outputDueEnd; + } else { + // (1) Some overall task has no progress. + // (2) Stubs, that its host overall task do not let it has progress, has no progress. + // This should always be performed so it can be passed to downstream. + this._dueIndex = this._outputDueEnd = this._settedOutputEnd != null ? this._settedOutputEnd : this._dueEnd; + } + return this.unfinished(); + }; + Task.prototype.dirty = function () { + this._dirty = true; + this._onDirty && this._onDirty(this.context); + }; + Task.prototype._doProgress = function (progress, start, end, modBy, modDataCount) { + iterator.reset(start, end, modBy, modDataCount); + this._callingProgress = progress; + this._callingProgress({ + start: start, + end: end, + count: end - start, + next: iterator.next + }, this.context); + }; + Task.prototype._doReset = function (skip) { + this._dueIndex = this._outputDueEnd = this._dueEnd = 0; + this._settedOutputEnd = null; + var progress; + var forceFirstProgress; + if (!skip && this._reset) { + progress = this._reset(this.context); + if (progress && progress.progress) { + forceFirstProgress = progress.forceFirstProgress; + progress = progress.progress; + } + // To simplify no progress checking, array must has item. + if (isArray(progress) && !progress.length) { + progress = null; + } + } + this._progress = progress; + this._modBy = this._modDataCount = null; + var downstream = this._downstream; + downstream && downstream.dirty(); + return forceFirstProgress; + }; + Task.prototype.unfinished = function () { + return this._progress && this._dueIndex < this._dueEnd; + }; + /** + * @param downTask The downstream task. + * @return The downstream task. + */ + Task.prototype.pipe = function (downTask) { + if ("development" !== 'production') { + assert(downTask && !downTask._disposed && downTask !== this); + } + // If already downstream, do not dirty downTask. + if (this._downstream !== downTask || this._dirty) { + this._downstream = downTask; + downTask._upstream = this; + downTask.dirty(); + } + }; + Task.prototype.dispose = function () { + if (this._disposed) { + return; + } + this._upstream && (this._upstream._downstream = null); + this._downstream && (this._downstream._upstream = null); + this._dirty = false; + this._disposed = true; + }; + Task.prototype.getUpstream = function () { + return this._upstream; + }; + Task.prototype.getDownstream = function () { + return this._downstream; + }; + Task.prototype.setOutputEnd = function (end) { + // This only happens in dataTask, dataZoom, map, currently. + // where dataZoom do not set end each time, but only set + // when reset. So we should record the set end, in case + // that the stub of dataZoom perform again and earse the + // set end by upstream. + this._outputDueEnd = this._settedOutputEnd = end; + }; + return Task; + }(); + var iterator = function () { + var end; + var current; + var modBy; + var modDataCount; + var winCount; + var it = { + reset: function (s, e, sStep, sCount) { + current = s; + end = e; + modBy = sStep; + modDataCount = sCount; + winCount = Math.ceil(modDataCount / modBy); + it.next = modBy > 1 && modDataCount > 0 ? modNext : sequentialNext; + } + }; + return it; + function sequentialNext() { + return current < end ? current++ : null; + } + function modNext() { + var dataIndex = current % winCount * modBy + Math.ceil(current / winCount); + var result = current >= end ? null : dataIndex < modDataCount ? dataIndex + // If modDataCount is smaller than data.count() (consider `appendData` case), + // Use normal linear rendering mode. + : current; + current++; + return result; + } + }(); + // ----------------------------------------------------------------------------- + // For stream debug (Should be commented out after used!) + // @usage: printTask(this, 'begin'); + // @usage: printTask(this, null, {someExtraProp}); + // @usage: Use `__idxInPipeline` as conditional breakpiont. + // + // window.printTask = function (task: any, prefix: string, extra: { [key: string]: unknown }): void { + // window.ecTaskUID == null && (window.ecTaskUID = 0); + // task.uidDebug == null && (task.uidDebug = `task_${window.ecTaskUID++}`); + // task.agent && task.agent.uidDebug == null && (task.agent.uidDebug = `task_${window.ecTaskUID++}`); + // let props = []; + // if (task.__pipeline) { + // let val = `${task.__idxInPipeline}/${task.__pipeline.tail.__idxInPipeline} ${task.agent ? '(stub)' : ''}`; + // props.push({text: '__idxInPipeline/total', value: val}); + // } else { + // let stubCount = 0; + // task.agentStubMap.each(() => stubCount++); + // props.push({text: 'idx', value: `overall (stubs: ${stubCount})`}); + // } + // props.push({text: 'uid', value: task.uidDebug}); + // if (task.__pipeline) { + // props.push({text: 'pipelineId', value: task.__pipeline.id}); + // task.agent && props.push( + // {text: 'stubFor', value: task.agent.uidDebug} + // ); + // } + // props.push( + // {text: 'dirty', value: task._dirty}, + // {text: 'dueIndex', value: task._dueIndex}, + // {text: 'dueEnd', value: task._dueEnd}, + // {text: 'outputDueEnd', value: task._outputDueEnd} + // ); + // if (extra) { + // Object.keys(extra).forEach(key => { + // props.push({text: key, value: extra[key]}); + // }); + // } + // let args = ['color: blue']; + // let msg = `%c[${prefix || 'T'}] %c` + props.map(item => ( + // args.push('color: green', 'color: red'), + // `${item.text}: %c${item.value}` + // )).join('%c, '); + // console.log.apply(console, [msg].concat(args)); + // // console.log(this); + // }; + // window.printPipeline = function (task: any, prefix: string) { + // const pipeline = task.__pipeline; + // let currTask = pipeline.head; + // while (currTask) { + // window.printTask(currTask, prefix); + // currTask = currTask._downstream; + // } + // }; + // window.showChain = function (chainHeadTask) { + // var chain = []; + // var task = chainHeadTask; + // while (task) { + // chain.push({ + // task: task, + // up: task._upstream, + // down: task._downstream, + // idxInPipeline: task.__idxInPipeline + // }); + // task = task._downstream; + // } + // return chain; + // }; + // window.findTaskInChain = function (task, chainHeadTask) { + // let chain = window.showChain(chainHeadTask); + // let result = []; + // for (let i = 0; i < chain.length; i++) { + // let chainItem = chain[i]; + // if (chainItem.task === task) { + // result.push(i); + // } + // } + // return result; + // }; + // window.printChainAEachInChainB = function (chainHeadTaskA, chainHeadTaskB) { + // let chainA = window.showChain(chainHeadTaskA); + // for (let i = 0; i < chainA.length; i++) { + // console.log('chainAIdx:', i, 'inChainB:', window.findTaskInChain(chainA[i].task, chainHeadTaskB)); + // } + // }; + + /** + * Convert raw the value in to inner value in List. + * + * [Performance sensitive] + * + * [Caution]: this is the key logic of user value parser. + * For backward compatibility, do not modify it until you have to! + */ + function parseDataValue(value, + // For high performance, do not omit the second param. + opt) { + // Performance sensitive. + var dimType = opt && opt.type; + if (dimType === 'ordinal') { + // If given value is a category string + return value; + } + if (dimType === 'time' + // spead up when using timestamp + && !isNumber(value) && value != null && value !== '-') { + value = +parseDate(value); + } + // dimType defaults 'number'. + // If dimType is not ordinal and value is null or undefined or NaN or '-', + // parse to NaN. + // number-like string (like ' 123 ') can be converted to a number. + // where null/undefined or other string will be converted to NaN. + return value == null || value === '' ? NaN + // If string (like '-'), using '+' parse to NaN + // If object, also parse to NaN + : +value; + } + var valueParserMap = createHashMap({ + 'number': function (val) { + // Do not use `numericToNumber` here. We have `numericToNumber` by default. + // Here the number parser can have loose rule: + // enable to cut suffix: "120px" => 120, "14%" => 14. + return parseFloat(val); + }, + 'time': function (val) { + // return timestamp. + return +parseDate(val); + }, + 'trim': function (val) { + return isString(val) ? trim(val) : val; + } + }); + function getRawValueParser(type) { + return valueParserMap.get(type); + } + var ORDER_COMPARISON_OP_MAP = { + lt: function (lval, rval) { + return lval < rval; + }, + lte: function (lval, rval) { + return lval <= rval; + }, + gt: function (lval, rval) { + return lval > rval; + }, + gte: function (lval, rval) { + return lval >= rval; + } + }; + var FilterOrderComparator = /** @class */function () { + function FilterOrderComparator(op, rval) { + if (!isNumber(rval)) { + var errMsg = ''; + if ("development" !== 'production') { + errMsg = 'rvalue of "<", ">", "<=", ">=" can only be number in filter.'; + } + throwError(errMsg); + } + this._opFn = ORDER_COMPARISON_OP_MAP[op]; + this._rvalFloat = numericToNumber(rval); + } + // Performance sensitive. + FilterOrderComparator.prototype.evaluate = function (lval) { + // Most cases is 'number', and typeof maybe 10 times faseter than parseFloat. + return isNumber(lval) ? this._opFn(lval, this._rvalFloat) : this._opFn(numericToNumber(lval), this._rvalFloat); + }; + return FilterOrderComparator; + }(); + var SortOrderComparator = /** @class */function () { + /** + * @param order by default: 'asc' + * @param incomparable by default: Always on the tail. + * That is, if 'asc' => 'max', if 'desc' => 'min' + * See the definition of "incomparable" in [SORT_COMPARISON_RULE]. + */ + function SortOrderComparator(order, incomparable) { + var isDesc = order === 'desc'; + this._resultLT = isDesc ? 1 : -1; + if (incomparable == null) { + incomparable = isDesc ? 'min' : 'max'; + } + this._incomparable = incomparable === 'min' ? -Infinity : Infinity; + } + // See [SORT_COMPARISON_RULE]. + // Performance sensitive. + SortOrderComparator.prototype.evaluate = function (lval, rval) { + // Most cases is 'number', and typeof maybe 10 times faseter than parseFloat. + var lvalFloat = isNumber(lval) ? lval : numericToNumber(lval); + var rvalFloat = isNumber(rval) ? rval : numericToNumber(rval); + var lvalNotNumeric = isNaN(lvalFloat); + var rvalNotNumeric = isNaN(rvalFloat); + if (lvalNotNumeric) { + lvalFloat = this._incomparable; + } + if (rvalNotNumeric) { + rvalFloat = this._incomparable; + } + if (lvalNotNumeric && rvalNotNumeric) { + var lvalIsStr = isString(lval); + var rvalIsStr = isString(rval); + if (lvalIsStr) { + lvalFloat = rvalIsStr ? lval : 0; + } + if (rvalIsStr) { + rvalFloat = lvalIsStr ? rval : 0; + } + } + return lvalFloat < rvalFloat ? this._resultLT : lvalFloat > rvalFloat ? -this._resultLT : 0; + }; + return SortOrderComparator; + }(); + var FilterEqualityComparator = /** @class */function () { + function FilterEqualityComparator(isEq, rval) { + this._rval = rval; + this._isEQ = isEq; + this._rvalTypeof = typeof rval; + this._rvalFloat = numericToNumber(rval); + } + // Performance sensitive. + FilterEqualityComparator.prototype.evaluate = function (lval) { + var eqResult = lval === this._rval; + if (!eqResult) { + var lvalTypeof = typeof lval; + if (lvalTypeof !== this._rvalTypeof && (lvalTypeof === 'number' || this._rvalTypeof === 'number')) { + eqResult = numericToNumber(lval) === this._rvalFloat; + } + } + return this._isEQ ? eqResult : !eqResult; + }; + return FilterEqualityComparator; + }(); + /** + * [FILTER_COMPARISON_RULE] + * `lt`|`lte`|`gt`|`gte`: + * + rval must be a number. And lval will be converted to number (`numericToNumber`) to compare. + * `eq`: + * + If same type, compare with `===`. + * + If there is one number, convert to number (`numericToNumber`) to compare. + * + Else return `false`. + * `ne`: + * + Not `eq`. + * + * + * [SORT_COMPARISON_RULE] + * All the values are grouped into three categories: + * + "numeric" (number and numeric string) + * + "non-numeric-string" (string that excluding numeric string) + * + "others" + * "numeric" vs "numeric": values are ordered by number order. + * "non-numeric-string" vs "non-numeric-string": values are ordered by ES spec (#sec-abstract-relational-comparison). + * "others" vs "others": do not change order (always return 0). + * "numeric" vs "non-numeric-string": "non-numeric-string" is treated as "incomparable". + * "number" vs "others": "others" is treated as "incomparable". + * "non-numeric-string" vs "others": "others" is treated as "incomparable". + * "incomparable" will be seen as -Infinity or Infinity (depends on the settings). + * MEMO: + * Non-numeric string sort makes sense when we need to put the items with the same tag together. + * But if we support string sort, we still need to avoid the misleading like `'2' > '12'`, + * So we treat "numeric-string" sorted by number order rather than string comparison. + * + * + * [CHECK_LIST_OF_THE_RULE_DESIGN] + * + Do not support string comparison until required. And also need to + * avoid the misleading of "2" > "12". + * + Should avoid the misleading case: + * `" 22 " gte "22"` is `true` but `" 22 " eq "22"` is `false`. + * + JS bad case should be avoided: null <= 0, [] <= 0, ' ' <= 0, ... + * + Only "numeric" can be converted to comparable number, otherwise converted to NaN. + * See `util/number.ts#numericToNumber`. + * + * @return If `op` is not `RelationalOperator`, return null; + */ + function createFilterComparator(op, rval) { + return op === 'eq' || op === 'ne' ? new FilterEqualityComparator(op === 'eq', rval) : hasOwn(ORDER_COMPARISON_OP_MAP, op) ? new FilterOrderComparator(op, rval) : null; + } + + /** + * TODO: disable writable. + * This structure will be exposed to users. + */ + var ExternalSource = /** @class */function () { + function ExternalSource() {} + ExternalSource.prototype.getRawData = function () { + // Only built-in transform available. + throw new Error('not supported'); + }; + ExternalSource.prototype.getRawDataItem = function (dataIndex) { + // Only built-in transform available. + throw new Error('not supported'); + }; + ExternalSource.prototype.cloneRawData = function () { + return; + }; + /** + * @return If dimension not found, return null/undefined. + */ + ExternalSource.prototype.getDimensionInfo = function (dim) { + return; + }; + /** + * dimensions defined if and only if either: + * (a) dataset.dimensions are declared. + * (b) dataset data include dimensions definitions in data (detected or via specified `sourceHeader`). + * If dimensions are defined, `dimensionInfoAll` is corresponding to + * the defined dimensions. + * Otherwise, `dimensionInfoAll` is determined by data columns. + * @return Always return an array (even empty array). + */ + ExternalSource.prototype.cloneAllDimensionInfo = function () { + return; + }; + ExternalSource.prototype.count = function () { + return; + }; + /** + * Only support by dimension index. + * No need to support by dimension name in transform function, + * because transform function is not case-specific, no need to use name literally. + */ + ExternalSource.prototype.retrieveValue = function (dataIndex, dimIndex) { + return; + }; + ExternalSource.prototype.retrieveValueFromItem = function (dataItem, dimIndex) { + return; + }; + ExternalSource.prototype.convertValue = function (rawVal, dimInfo) { + return parseDataValue(rawVal, dimInfo); + }; + return ExternalSource; + }(); + function createExternalSource(internalSource, externalTransform) { + var extSource = new ExternalSource(); + var data = internalSource.data; + var sourceFormat = extSource.sourceFormat = internalSource.sourceFormat; + var sourceHeaderCount = internalSource.startIndex; + var errMsg = ''; + if (internalSource.seriesLayoutBy !== SERIES_LAYOUT_BY_COLUMN) { + // For the logic simplicity in transformer, only 'culumn' is + // supported in data transform. Otherwise, the `dimensionsDefine` + // might be detected by 'row', which probably confuses users. + if ("development" !== 'production') { + errMsg = '`seriesLayoutBy` of upstream dataset can only be "column" in data transform.'; + } + throwError(errMsg); + } + // [MEMO] + // Create a new dimensions structure for exposing. + // Do not expose all dimension info to users directly. + // Because the dimension is probably auto detected from data and not might reliable. + // Should not lead the transformers to think that is reliable and return it. + // See [DIMENSION_INHERIT_RULE] in `sourceManager.ts`. + var dimensions = []; + var dimsByName = {}; + var dimsDef = internalSource.dimensionsDefine; + if (dimsDef) { + each(dimsDef, function (dimDef, idx) { + var name = dimDef.name; + var dimDefExt = { + index: idx, + name: name, + displayName: dimDef.displayName + }; + dimensions.push(dimDefExt); + // Users probably do not specify dimension name. For simplicity, data transform + // does not generate dimension name. + if (name != null) { + // Dimension name should not be duplicated. + // For simplicity, data transform forbids name duplication, do not generate + // new name like module `completeDimensions.ts` did, but just tell users. + var errMsg_1 = ''; + if (hasOwn(dimsByName, name)) { + if ("development" !== 'production') { + errMsg_1 = 'dimension name "' + name + '" duplicated.'; + } + throwError(errMsg_1); + } + dimsByName[name] = dimDefExt; + } + }); + } + // If dimension definitions are not defined and can not be detected. + // e.g., pure data `[[11, 22], ...]`. + else { + for (var i = 0; i < internalSource.dimensionsDetectedCount || 0; i++) { + // Do not generete name or anything others. The consequence process in + // `transform` or `series` probably have there own name generation strategry. + dimensions.push({ + index: i + }); + } + } + // Implement public methods: + var rawItemGetter = getRawSourceItemGetter(sourceFormat, SERIES_LAYOUT_BY_COLUMN); + if (externalTransform.__isBuiltIn) { + extSource.getRawDataItem = function (dataIndex) { + return rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex); + }; + extSource.getRawData = bind(getRawData, null, internalSource); + } + extSource.cloneRawData = bind(cloneRawData, null, internalSource); + var rawCounter = getRawSourceDataCounter(sourceFormat, SERIES_LAYOUT_BY_COLUMN); + extSource.count = bind(rawCounter, null, data, sourceHeaderCount, dimensions); + var rawValueGetter = getRawSourceValueGetter(sourceFormat); + extSource.retrieveValue = function (dataIndex, dimIndex) { + var rawItem = rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex); + return retrieveValueFromItem(rawItem, dimIndex); + }; + var retrieveValueFromItem = extSource.retrieveValueFromItem = function (dataItem, dimIndex) { + if (dataItem == null) { + return; + } + var dimDef = dimensions[dimIndex]; + // When `dimIndex` is `null`, `rawValueGetter` return the whole item. + if (dimDef) { + return rawValueGetter(dataItem, dimIndex, dimDef.name); + } + }; + extSource.getDimensionInfo = bind(getDimensionInfo, null, dimensions, dimsByName); + extSource.cloneAllDimensionInfo = bind(cloneAllDimensionInfo, null, dimensions); + return extSource; + } + function getRawData(upstream) { + var sourceFormat = upstream.sourceFormat; + if (!isSupportedSourceFormat(sourceFormat)) { + var errMsg = ''; + if ("development" !== 'production') { + errMsg = '`getRawData` is not supported in source format ' + sourceFormat; + } + throwError(errMsg); + } + return upstream.data; + } + function cloneRawData(upstream) { + var sourceFormat = upstream.sourceFormat; + var data = upstream.data; + if (!isSupportedSourceFormat(sourceFormat)) { + var errMsg = ''; + if ("development" !== 'production') { + errMsg = '`cloneRawData` is not supported in source format ' + sourceFormat; + } + throwError(errMsg); + } + if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) { + var result = []; + for (var i = 0, len = data.length; i < len; i++) { + // Not strictly clone for performance + result.push(data[i].slice()); + } + return result; + } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) { + var result = []; + for (var i = 0, len = data.length; i < len; i++) { + // Not strictly clone for performance + result.push(extend({}, data[i])); + } + return result; + } + } + function getDimensionInfo(dimensions, dimsByName, dim) { + if (dim == null) { + return; + } + // Keep the same logic as `List::getDimension` did. + if (isNumber(dim) + // If being a number-like string but not being defined a dimension name. + || !isNaN(dim) && !hasOwn(dimsByName, dim)) { + return dimensions[dim]; + } else if (hasOwn(dimsByName, dim)) { + return dimsByName[dim]; + } + } + function cloneAllDimensionInfo(dimensions) { + return clone(dimensions); + } + var externalTransformMap = createHashMap(); + function registerExternalTransform(externalTransform) { + externalTransform = clone(externalTransform); + var type = externalTransform.type; + var errMsg = ''; + if (!type) { + if ("development" !== 'production') { + errMsg = 'Must have a `type` when `registerTransform`.'; + } + throwError(errMsg); + } + var typeParsed = type.split(':'); + if (typeParsed.length !== 2) { + if ("development" !== 'production') { + errMsg = 'Name must include namespace like "ns:regression".'; + } + throwError(errMsg); + } + // Namespace 'echarts:xxx' is official namespace, where the transforms should + // be called directly via 'xxx' rather than 'echarts:xxx'. + var isBuiltIn = false; + if (typeParsed[0] === 'echarts') { + type = typeParsed[1]; + isBuiltIn = true; + } + externalTransform.__isBuiltIn = isBuiltIn; + externalTransformMap.set(type, externalTransform); + } + function applyDataTransform(rawTransOption, sourceList, infoForPrint) { + var pipedTransOption = normalizeToArray(rawTransOption); + var pipeLen = pipedTransOption.length; + var errMsg = ''; + if (!pipeLen) { + if ("development" !== 'production') { + errMsg = 'If `transform` declared, it should at least contain one transform.'; + } + throwError(errMsg); + } + for (var i = 0, len = pipeLen; i < len; i++) { + var transOption = pipedTransOption[i]; + sourceList = applySingleDataTransform(transOption, sourceList, infoForPrint, pipeLen === 1 ? null : i); + // piped transform only support single input, except the fist one. + // piped transform only support single output, except the last one. + if (i !== len - 1) { + sourceList.length = Math.max(sourceList.length, 1); + } + } + return sourceList; + } + function applySingleDataTransform(transOption, upSourceList, infoForPrint, + // If `pipeIndex` is null/undefined, no piped transform. + pipeIndex) { + var errMsg = ''; + if (!upSourceList.length) { + if ("development" !== 'production') { + errMsg = 'Must have at least one upstream dataset.'; + } + throwError(errMsg); + } + if (!isObject(transOption)) { + if ("development" !== 'production') { + errMsg = 'transform declaration must be an object rather than ' + typeof transOption + '.'; + } + throwError(errMsg); + } + var transType = transOption.type; + var externalTransform = externalTransformMap.get(transType); + if (!externalTransform) { + if ("development" !== 'production') { + errMsg = 'Can not find transform on type "' + transType + '".'; + } + throwError(errMsg); + } + // Prepare source + var extUpSourceList = map(upSourceList, function (upSource) { + return createExternalSource(upSource, externalTransform); + }); + var resultList = normalizeToArray(externalTransform.transform({ + upstream: extUpSourceList[0], + upstreamList: extUpSourceList, + config: clone(transOption.config) + })); + if ("development" !== 'production') { + if (transOption.print) { + var printStrArr = map(resultList, function (extSource) { + var pipeIndexStr = pipeIndex != null ? ' === pipe index: ' + pipeIndex : ''; + return ['=== dataset index: ' + infoForPrint.datasetIndex + pipeIndexStr + ' ===', '- transform result data:', makePrintable(extSource.data), '- transform result dimensions:', makePrintable(extSource.dimensions)].join('\n'); + }).join('\n'); + log(printStrArr); + } + } + return map(resultList, function (result, resultIndex) { + var errMsg = ''; + if (!isObject(result)) { + if ("development" !== 'production') { + errMsg = 'A transform should not return some empty results.'; + } + throwError(errMsg); + } + if (!result.data) { + if ("development" !== 'production') { + errMsg = 'Transform result data should be not be null or undefined'; + } + throwError(errMsg); + } + var sourceFormat = detectSourceFormat(result.data); + if (!isSupportedSourceFormat(sourceFormat)) { + if ("development" !== 'production') { + errMsg = 'Transform result data should be array rows or object rows.'; + } + throwError(errMsg); + } + var resultMetaRawOption; + var firstUpSource = upSourceList[0]; + /** + * Intuitively, the end users known the content of the original `dataset.source`, + * calucating the transform result in mind. + * Suppose the original `dataset.source` is: + * ```js + * [ + * ['product', '2012', '2013', '2014', '2015'], + * ['AAA', 41.1, 30.4, 65.1, 53.3], + * ['BBB', 86.5, 92.1, 85.7, 83.1], + * ['CCC', 24.1, 67.2, 79.5, 86.4] + * ] + * ``` + * The dimension info have to be detected from the source data. + * Some of the transformers (like filter, sort) will follow the dimension info + * of upstream, while others use new dimensions (like aggregate). + * Transformer can output a field `dimensions` to define the its own output dimensions. + * We also allow transformers to ignore the output `dimensions` field, and + * inherit the upstream dimensions definition. It can reduce the burden of handling + * dimensions in transformers. + * + * See also [DIMENSION_INHERIT_RULE] in `sourceManager.ts`. + */ + if (firstUpSource && resultIndex === 0 + // If transformer returns `dimensions`, it means that the transformer has different + // dimensions definitions. We do not inherit anything from upstream. + && !result.dimensions) { + var startIndex = firstUpSource.startIndex; + // We copy the header of upstream to the result, because: + // (1) The returned data always does not contain header line and can not be used + // as dimension-detection. In this case we can not use "detected dimensions" of + // upstream directly, because it might be detected based on different `seriesLayoutBy`. + // (2) We should support that the series read the upstream source in `seriesLayoutBy: 'row'`. + // So the original detected header should be add to the result, otherwise they can not be read. + if (startIndex) { + result.data = firstUpSource.data.slice(0, startIndex).concat(result.data); + } + resultMetaRawOption = { + seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN, + sourceHeader: startIndex, + dimensions: firstUpSource.metaRawOption.dimensions + }; + } else { + resultMetaRawOption = { + seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN, + sourceHeader: 0, + dimensions: result.dimensions + }; + } + return createSource(result.data, resultMetaRawOption, null); + }); + } + function isSupportedSourceFormat(sourceFormat) { + return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS || sourceFormat === SOURCE_FORMAT_OBJECT_ROWS; + } + + var UNDEFINED = 'undefined'; + /* global Float64Array, Int32Array, Uint32Array, Uint16Array */ + // Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is + // different from the Ctor of typed array. + var CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array; + var CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array; + var CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array; + var CtorFloat64Array = typeof Float64Array === UNDEFINED ? Array : Float64Array; + /** + * Multi dimensional data store + */ + var dataCtors = { + 'float': CtorFloat64Array, + 'int': CtorInt32Array, + // Ordinal data type can be string or int + 'ordinal': Array, + 'number': Array, + 'time': CtorFloat64Array + }; + var defaultDimValueGetters; + function getIndicesCtor(rawCount) { + // The possible max value in this._indicies is always this._rawCount despite of filtering. + return rawCount > 65535 ? CtorUint32Array : CtorUint16Array; + } + function getInitialExtent() { + return [Infinity, -Infinity]; + } + function cloneChunk(originalChunk) { + var Ctor = originalChunk.constructor; + // Only shallow clone is enough when Array. + return Ctor === Array ? originalChunk.slice() : new Ctor(originalChunk); + } + function prepareStore(store, dimIdx, dimType, end, append) { + var DataCtor = dataCtors[dimType || 'float']; + if (append) { + var oldStore = store[dimIdx]; + var oldLen = oldStore && oldStore.length; + if (!(oldLen === end)) { + var newStore = new DataCtor(end); + // The cost of the copy is probably inconsiderable + // within the initial chunkSize. + for (var j = 0; j < oldLen; j++) { + newStore[j] = oldStore[j]; + } + store[dimIdx] = newStore; + } + } else { + store[dimIdx] = new DataCtor(end); + } + } + /** + * Basically, DataStore API keep immutable. + */ + var DataStore = /** @class */function () { + function DataStore() { + this._chunks = []; + // It will not be calculated until needed. + this._rawExtent = []; + this._extent = []; + this._count = 0; + this._rawCount = 0; + this._calcDimNameToIdx = createHashMap(); + } + /** + * Initialize from data + */ + DataStore.prototype.initData = function (provider, inputDimensions, dimValueGetter) { + if ("development" !== 'production') { + assert(isFunction(provider.getItem) && isFunction(provider.count), 'Invalid data provider.'); + } + this._provider = provider; + // Clear + this._chunks = []; + this._indices = null; + this.getRawIndex = this._getRawIdxIdentity; + var source = provider.getSource(); + var defaultGetter = this.defaultDimValueGetter = defaultDimValueGetters[source.sourceFormat]; + // Default dim value getter + this._dimValueGetter = dimValueGetter || defaultGetter; + // Reset raw extent. + this._rawExtent = []; + var willRetrieveDataByName = shouldRetrieveDataByName(source); + this._dimensions = map(inputDimensions, function (dim) { + if ("development" !== 'production') { + if (willRetrieveDataByName) { + assert(dim.property != null); + } + } + return { + // Only pick these two props. Not leak other properties like orderMeta. + type: dim.type, + property: dim.property + }; + }); + this._initDataFromProvider(0, provider.count()); + }; + DataStore.prototype.getProvider = function () { + return this._provider; + }; + /** + * Caution: even when a `source` instance owned by a series, the created data store + * may still be shared by different sereis (the source hash does not use all `source` + * props, see `sourceManager`). In this case, the `source` props that are not used in + * hash (like `source.dimensionDefine`) probably only belongs to a certain series and + * thus should not be fetch here. + */ + DataStore.prototype.getSource = function () { + return this._provider.getSource(); + }; + /** + * @caution Only used in dataStack. + */ + DataStore.prototype.ensureCalculationDimension = function (dimName, type) { + var calcDimNameToIdx = this._calcDimNameToIdx; + var dimensions = this._dimensions; + var calcDimIdx = calcDimNameToIdx.get(dimName); + if (calcDimIdx != null) { + if (dimensions[calcDimIdx].type === type) { + return calcDimIdx; + } + } else { + calcDimIdx = dimensions.length; + } + dimensions[calcDimIdx] = { + type: type + }; + calcDimNameToIdx.set(dimName, calcDimIdx); + this._chunks[calcDimIdx] = new dataCtors[type || 'float'](this._rawCount); + this._rawExtent[calcDimIdx] = getInitialExtent(); + return calcDimIdx; + }; + DataStore.prototype.collectOrdinalMeta = function (dimIdx, ordinalMeta) { + var chunk = this._chunks[dimIdx]; + var dim = this._dimensions[dimIdx]; + var rawExtents = this._rawExtent; + var offset = dim.ordinalOffset || 0; + var len = chunk.length; + if (offset === 0) { + // We need to reset the rawExtent if collect is from start. + // Because this dimension may be guessed as number and calcuating a wrong extent. + rawExtents[dimIdx] = getInitialExtent(); + } + var dimRawExtent = rawExtents[dimIdx]; + // Parse from previous data offset. len may be changed after appendData + for (var i = offset; i < len; i++) { + var val = chunk[i] = ordinalMeta.parseAndCollect(chunk[i]); + if (!isNaN(val)) { + dimRawExtent[0] = Math.min(val, dimRawExtent[0]); + dimRawExtent[1] = Math.max(val, dimRawExtent[1]); + } + } + dim.ordinalMeta = ordinalMeta; + dim.ordinalOffset = len; + dim.type = 'ordinal'; // Force to be ordinal + }; + + DataStore.prototype.getOrdinalMeta = function (dimIdx) { + var dimInfo = this._dimensions[dimIdx]; + var ordinalMeta = dimInfo.ordinalMeta; + return ordinalMeta; + }; + DataStore.prototype.getDimensionProperty = function (dimIndex) { + var item = this._dimensions[dimIndex]; + return item && item.property; + }; + /** + * Caution: Can be only called on raw data (before `this._indices` created). + */ + DataStore.prototype.appendData = function (data) { + if ("development" !== 'production') { + assert(!this._indices, 'appendData can only be called on raw data.'); + } + var provider = this._provider; + var start = this.count(); + provider.appendData(data); + var end = provider.count(); + if (!provider.persistent) { + end += start; + } + if (start < end) { + this._initDataFromProvider(start, end, true); + } + return [start, end]; + }; + DataStore.prototype.appendValues = function (values, minFillLen) { + var chunks = this._chunks; + var dimensions = this._dimensions; + var dimLen = dimensions.length; + var rawExtent = this._rawExtent; + var start = this.count(); + var end = start + Math.max(values.length, minFillLen || 0); + for (var i = 0; i < dimLen; i++) { + var dim = dimensions[i]; + prepareStore(chunks, i, dim.type, end, true); + } + var emptyDataItem = []; + for (var idx = start; idx < end; idx++) { + var sourceIdx = idx - start; + // Store the data by dimensions + for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) { + var dim = dimensions[dimIdx]; + var val = defaultDimValueGetters.arrayRows.call(this, values[sourceIdx] || emptyDataItem, dim.property, sourceIdx, dimIdx); + chunks[dimIdx][idx] = val; + var dimRawExtent = rawExtent[dimIdx]; + val < dimRawExtent[0] && (dimRawExtent[0] = val); + val > dimRawExtent[1] && (dimRawExtent[1] = val); + } + } + this._rawCount = this._count = end; + return { + start: start, + end: end + }; + }; + DataStore.prototype._initDataFromProvider = function (start, end, append) { + var provider = this._provider; + var chunks = this._chunks; + var dimensions = this._dimensions; + var dimLen = dimensions.length; + var rawExtent = this._rawExtent; + var dimNames = map(dimensions, function (dim) { + return dim.property; + }); + for (var i = 0; i < dimLen; i++) { + var dim = dimensions[i]; + if (!rawExtent[i]) { + rawExtent[i] = getInitialExtent(); + } + prepareStore(chunks, i, dim.type, end, append); + } + if (provider.fillStorage) { + provider.fillStorage(start, end, chunks, rawExtent); + } else { + var dataItem = []; + for (var idx = start; idx < end; idx++) { + // NOTICE: Try not to write things into dataItem + dataItem = provider.getItem(idx, dataItem); + // Each data item is value + // [1, 2] + // 2 + // Bar chart, line chart which uses category axis + // only gives the 'y' value. 'x' value is the indices of category + // Use a tempValue to normalize the value to be a (x, y) value + // Store the data by dimensions + for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) { + var dimStorage = chunks[dimIdx]; + // PENDING NULL is empty or zero + var val = this._dimValueGetter(dataItem, dimNames[dimIdx], idx, dimIdx); + dimStorage[idx] = val; + var dimRawExtent = rawExtent[dimIdx]; + val < dimRawExtent[0] && (dimRawExtent[0] = val); + val > dimRawExtent[1] && (dimRawExtent[1] = val); + } + } + } + if (!provider.persistent && provider.clean) { + // Clean unused data if data source is typed array. + provider.clean(); + } + this._rawCount = this._count = end; + // Reset data extent + this._extent = []; + }; + DataStore.prototype.count = function () { + return this._count; + }; + /** + * Get value. Return NaN if idx is out of range. + */ + DataStore.prototype.get = function (dim, idx) { + if (!(idx >= 0 && idx < this._count)) { + return NaN; + } + var dimStore = this._chunks[dim]; + return dimStore ? dimStore[this.getRawIndex(idx)] : NaN; + }; + DataStore.prototype.getValues = function (dimensions, idx) { + var values = []; + var dimArr = []; + if (idx == null) { + idx = dimensions; + // TODO get all from store? + dimensions = []; + // All dimensions + for (var i = 0; i < this._dimensions.length; i++) { + dimArr.push(i); + } + } else { + dimArr = dimensions; + } + for (var i = 0, len = dimArr.length; i < len; i++) { + values.push(this.get(dimArr[i], idx)); + } + return values; + }; + /** + * @param dim concrete dim + */ + DataStore.prototype.getByRawIndex = function (dim, rawIdx) { + if (!(rawIdx >= 0 && rawIdx < this._rawCount)) { + return NaN; + } + var dimStore = this._chunks[dim]; + return dimStore ? dimStore[rawIdx] : NaN; + }; + /** + * Get sum of data in one dimension + */ + DataStore.prototype.getSum = function (dim) { + var dimData = this._chunks[dim]; + var sum = 0; + if (dimData) { + for (var i = 0, len = this.count(); i < len; i++) { + var value = this.get(dim, i); + if (!isNaN(value)) { + sum += value; + } + } + } + return sum; + }; + /** + * Get median of data in one dimension + */ + DataStore.prototype.getMedian = function (dim) { + var dimDataArray = []; + // map all data of one dimension + this.each([dim], function (val) { + if (!isNaN(val)) { + dimDataArray.push(val); + } + }); + // TODO + // Use quick select? + var sortedDimDataArray = dimDataArray.sort(function (a, b) { + return a - b; + }); + var len = this.count(); + // calculate median + return len === 0 ? 0 : len % 2 === 1 ? sortedDimDataArray[(len - 1) / 2] : (sortedDimDataArray[len / 2] + sortedDimDataArray[len / 2 - 1]) / 2; + }; + /** + * Retrieve the index with given raw data index. + */ + DataStore.prototype.indexOfRawIndex = function (rawIndex) { + if (rawIndex >= this._rawCount || rawIndex < 0) { + return -1; + } + if (!this._indices) { + return rawIndex; + } + // Indices are ascending + var indices = this._indices; + // If rawIndex === dataIndex + var rawDataIndex = indices[rawIndex]; + if (rawDataIndex != null && rawDataIndex < this._count && rawDataIndex === rawIndex) { + return rawIndex; + } + var left = 0; + var right = this._count - 1; + while (left <= right) { + var mid = (left + right) / 2 | 0; + if (indices[mid] < rawIndex) { + left = mid + 1; + } else if (indices[mid] > rawIndex) { + right = mid - 1; + } else { + return mid; + } + } + return -1; + }; + /** + * Retrieve the index of nearest value. + * @param dim + * @param value + * @param [maxDistance=Infinity] + * @return If and only if multiple indices have + * the same value, they are put to the result. + */ + DataStore.prototype.indicesOfNearest = function (dim, value, maxDistance) { + var chunks = this._chunks; + var dimData = chunks[dim]; + var nearestIndices = []; + if (!dimData) { + return nearestIndices; + } + if (maxDistance == null) { + maxDistance = Infinity; + } + var minDist = Infinity; + var minDiff = -1; + var nearestIndicesLen = 0; + // Check the test case of `test/ut/spec/data/SeriesData.js`. + for (var i = 0, len = this.count(); i < len; i++) { + var dataIndex = this.getRawIndex(i); + var diff = value - dimData[dataIndex]; + var dist = Math.abs(diff); + if (dist <= maxDistance) { + // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`, + // we'd better not push both of them to `nearestIndices`, otherwise it is easy to + // get more than one item in `nearestIndices` (more specifically, in `tooltip`). + // So we choose the one that `diff >= 0` in this case. + // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them + // should be push to `nearestIndices`. + if (dist < minDist || dist === minDist && diff >= 0 && minDiff < 0) { + minDist = dist; + minDiff = diff; + nearestIndicesLen = 0; + } + if (diff === minDiff) { + nearestIndices[nearestIndicesLen++] = i; + } + } + } + nearestIndices.length = nearestIndicesLen; + return nearestIndices; + }; + DataStore.prototype.getIndices = function () { + var newIndices; + var indices = this._indices; + if (indices) { + var Ctor = indices.constructor; + var thisCount = this._count; + // `new Array(a, b, c)` is different from `new Uint32Array(a, b, c)`. + if (Ctor === Array) { + newIndices = new Ctor(thisCount); + for (var i = 0; i < thisCount; i++) { + newIndices[i] = indices[i]; + } + } else { + newIndices = new Ctor(indices.buffer, 0, thisCount); + } + } else { + var Ctor = getIndicesCtor(this._rawCount); + newIndices = new Ctor(this.count()); + for (var i = 0; i < newIndices.length; i++) { + newIndices[i] = i; + } + } + return newIndices; + }; + /** + * Data filter. + */ + DataStore.prototype.filter = function (dims, cb) { + if (!this._count) { + return this; + } + var newStore = this.clone(); + var count = newStore.count(); + var Ctor = getIndicesCtor(newStore._rawCount); + var newIndices = new Ctor(count); + var value = []; + var dimSize = dims.length; + var offset = 0; + var dim0 = dims[0]; + var chunks = newStore._chunks; + for (var i = 0; i < count; i++) { + var keep = void 0; + var rawIdx = newStore.getRawIndex(i); + // Simple optimization + if (dimSize === 0) { + keep = cb(i); + } else if (dimSize === 1) { + var val = chunks[dim0][rawIdx]; + keep = cb(val, i); + } else { + var k = 0; + for (; k < dimSize; k++) { + value[k] = chunks[dims[k]][rawIdx]; + } + value[k] = i; + keep = cb.apply(null, value); + } + if (keep) { + newIndices[offset++] = rawIdx; + } + } + // Set indices after filtered. + if (offset < count) { + newStore._indices = newIndices; + } + newStore._count = offset; + // Reset data extent + newStore._extent = []; + newStore._updateGetRawIdx(); + return newStore; + }; + /** + * Select data in range. (For optimization of filter) + * (Manually inline code, support 5 million data filtering in data zoom.) + */ + DataStore.prototype.selectRange = function (range) { + var newStore = this.clone(); + var len = newStore._count; + if (!len) { + return this; + } + var dims = keys(range); + var dimSize = dims.length; + if (!dimSize) { + return this; + } + var originalCount = newStore.count(); + var Ctor = getIndicesCtor(newStore._rawCount); + var newIndices = new Ctor(originalCount); + var offset = 0; + var dim0 = dims[0]; + var min = range[dim0][0]; + var max = range[dim0][1]; + var storeArr = newStore._chunks; + var quickFinished = false; + if (!newStore._indices) { + // Extreme optimization for common case. About 2x faster in chrome. + var idx = 0; + if (dimSize === 1) { + var dimStorage = storeArr[dims[0]]; + for (var i = 0; i < len; i++) { + var val = dimStorage[i]; + // NaN will not be filtered. Consider the case, in line chart, empty + // value indicates the line should be broken. But for the case like + // scatter plot, a data item with empty value will not be rendered, + // but the axis extent may be effected if some other dim of the data + // item has value. Fortunately it is not a significant negative effect. + if (val >= min && val <= max || isNaN(val)) { + newIndices[offset++] = idx; + } + idx++; + } + quickFinished = true; + } else if (dimSize === 2) { + var dimStorage = storeArr[dims[0]]; + var dimStorage2 = storeArr[dims[1]]; + var min2 = range[dims[1]][0]; + var max2 = range[dims[1]][1]; + for (var i = 0; i < len; i++) { + var val = dimStorage[i]; + var val2 = dimStorage2[i]; + // Do not filter NaN, see comment above. + if ((val >= min && val <= max || isNaN(val)) && (val2 >= min2 && val2 <= max2 || isNaN(val2))) { + newIndices[offset++] = idx; + } + idx++; + } + quickFinished = true; + } + } + if (!quickFinished) { + if (dimSize === 1) { + for (var i = 0; i < originalCount; i++) { + var rawIndex = newStore.getRawIndex(i); + var val = storeArr[dims[0]][rawIndex]; + // Do not filter NaN, see comment above. + if (val >= min && val <= max || isNaN(val)) { + newIndices[offset++] = rawIndex; + } + } + } else { + for (var i = 0; i < originalCount; i++) { + var keep = true; + var rawIndex = newStore.getRawIndex(i); + for (var k = 0; k < dimSize; k++) { + var dimk = dims[k]; + var val = storeArr[dimk][rawIndex]; + // Do not filter NaN, see comment above. + if (val < range[dimk][0] || val > range[dimk][1]) { + keep = false; + } + } + if (keep) { + newIndices[offset++] = newStore.getRawIndex(i); + } + } + } + } + // Set indices after filtered. + if (offset < originalCount) { + newStore._indices = newIndices; + } + newStore._count = offset; + // Reset data extent + newStore._extent = []; + newStore._updateGetRawIdx(); + return newStore; + }; + // /** + // * Data mapping to a plain array + // */ + // mapArray(dims: DimensionIndex[], cb: MapArrayCb): any[] { + // const result: any[] = []; + // this.each(dims, function () { + // result.push(cb && (cb as MapArrayCb).apply(null, arguments)); + // }); + // return result; + // } + /** + * Data mapping to a new List with given dimensions + */ + DataStore.prototype.map = function (dims, cb) { + // TODO only clone picked chunks. + var target = this.clone(dims); + this._updateDims(target, dims, cb); + return target; + }; + /** + * @caution Danger!! Only used in dataStack. + */ + DataStore.prototype.modify = function (dims, cb) { + this._updateDims(this, dims, cb); + }; + DataStore.prototype._updateDims = function (target, dims, cb) { + var targetChunks = target._chunks; + var tmpRetValue = []; + var dimSize = dims.length; + var dataCount = target.count(); + var values = []; + var rawExtent = target._rawExtent; + for (var i = 0; i < dims.length; i++) { + rawExtent[dims[i]] = getInitialExtent(); + } + for (var dataIndex = 0; dataIndex < dataCount; dataIndex++) { + var rawIndex = target.getRawIndex(dataIndex); + for (var k = 0; k < dimSize; k++) { + values[k] = targetChunks[dims[k]][rawIndex]; + } + values[dimSize] = dataIndex; + var retValue = cb && cb.apply(null, values); + if (retValue != null) { + // a number or string (in oridinal dimension)? + if (typeof retValue !== 'object') { + tmpRetValue[0] = retValue; + retValue = tmpRetValue; + } + for (var i = 0; i < retValue.length; i++) { + var dim = dims[i]; + var val = retValue[i]; + var rawExtentOnDim = rawExtent[dim]; + var dimStore = targetChunks[dim]; + if (dimStore) { + dimStore[rawIndex] = val; + } + if (val < rawExtentOnDim[0]) { + rawExtentOnDim[0] = val; + } + if (val > rawExtentOnDim[1]) { + rawExtentOnDim[1] = val; + } + } + } + } + }; + /** + * Large data down sampling using largest-triangle-three-buckets + * @param {string} valueDimension + * @param {number} targetCount + */ + DataStore.prototype.lttbDownSample = function (valueDimension, rate) { + var target = this.clone([valueDimension], true); + var targetStorage = target._chunks; + var dimStore = targetStorage[valueDimension]; + var len = this.count(); + var sampledIndex = 0; + var frameSize = Math.floor(1 / rate); + var currentRawIndex = this.getRawIndex(0); + var maxArea; + var area; + var nextRawIndex; + var newIndices = new (getIndicesCtor(this._rawCount))(Math.min((Math.ceil(len / frameSize) + 2) * 2, len)); + // First frame use the first data. + newIndices[sampledIndex++] = currentRawIndex; + for (var i = 1; i < len - 1; i += frameSize) { + var nextFrameStart = Math.min(i + frameSize, len - 1); + var nextFrameEnd = Math.min(i + frameSize * 2, len); + var avgX = (nextFrameEnd + nextFrameStart) / 2; + var avgY = 0; + for (var idx = nextFrameStart; idx < nextFrameEnd; idx++) { + var rawIndex = this.getRawIndex(idx); + var y = dimStore[rawIndex]; + if (isNaN(y)) { + continue; + } + avgY += y; + } + avgY /= nextFrameEnd - nextFrameStart; + var frameStart = i; + var frameEnd = Math.min(i + frameSize, len); + var pointAX = i - 1; + var pointAY = dimStore[currentRawIndex]; + maxArea = -1; + nextRawIndex = frameStart; + var firstNaNIndex = -1; + var countNaN = 0; + // Find a point from current frame that construct a triangle with largest area with previous selected point + // And the average of next frame. + for (var idx = frameStart; idx < frameEnd; idx++) { + var rawIndex = this.getRawIndex(idx); + var y = dimStore[rawIndex]; + if (isNaN(y)) { + countNaN++; + if (firstNaNIndex < 0) { + firstNaNIndex = rawIndex; + } + continue; + } + // Calculate triangle area over three buckets + area = Math.abs((pointAX - avgX) * (y - pointAY) - (pointAX - idx) * (avgY - pointAY)); + if (area > maxArea) { + maxArea = area; + nextRawIndex = rawIndex; // Next a is this b + } + } + + if (countNaN > 0 && countNaN < frameEnd - frameStart) { + // Append first NaN point in every bucket. + // It is necessary to ensure the correct order of indices. + newIndices[sampledIndex++] = Math.min(firstNaNIndex, nextRawIndex); + nextRawIndex = Math.max(firstNaNIndex, nextRawIndex); + } + newIndices[sampledIndex++] = nextRawIndex; + currentRawIndex = nextRawIndex; // This a is the next a (chosen b) + } + // First frame use the last data. + newIndices[sampledIndex++] = this.getRawIndex(len - 1); + target._count = sampledIndex; + target._indices = newIndices; + target.getRawIndex = this._getRawIdx; + return target; + }; + /** + * Large data down sampling on given dimension + * @param sampleIndex Sample index for name and id + */ + DataStore.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) { + var target = this.clone([dimension], true); + var targetStorage = target._chunks; + var frameValues = []; + var frameSize = Math.floor(1 / rate); + var dimStore = targetStorage[dimension]; + var len = this.count(); + var rawExtentOnDim = target._rawExtent[dimension] = getInitialExtent(); + var newIndices = new (getIndicesCtor(this._rawCount))(Math.ceil(len / frameSize)); + var offset = 0; + for (var i = 0; i < len; i += frameSize) { + // Last frame + if (frameSize > len - i) { + frameSize = len - i; + frameValues.length = frameSize; + } + for (var k = 0; k < frameSize; k++) { + var dataIdx = this.getRawIndex(i + k); + frameValues[k] = dimStore[dataIdx]; + } + var value = sampleValue(frameValues); + var sampleFrameIdx = this.getRawIndex(Math.min(i + sampleIndex(frameValues, value) || 0, len - 1)); + // Only write value on the filtered data + dimStore[sampleFrameIdx] = value; + if (value < rawExtentOnDim[0]) { + rawExtentOnDim[0] = value; + } + if (value > rawExtentOnDim[1]) { + rawExtentOnDim[1] = value; + } + newIndices[offset++] = sampleFrameIdx; + } + target._count = offset; + target._indices = newIndices; + target._updateGetRawIdx(); + return target; + }; + /** + * Data iteration + * @param ctx default this + * @example + * list.each('x', function (x, idx) {}); + * list.each(['x', 'y'], function (x, y, idx) {}); + * list.each(function (idx) {}) + */ + DataStore.prototype.each = function (dims, cb) { + if (!this._count) { + return; + } + var dimSize = dims.length; + var chunks = this._chunks; + for (var i = 0, len = this.count(); i < len; i++) { + var rawIdx = this.getRawIndex(i); + // Simple optimization + switch (dimSize) { + case 0: + cb(i); + break; + case 1: + cb(chunks[dims[0]][rawIdx], i); + break; + case 2: + cb(chunks[dims[0]][rawIdx], chunks[dims[1]][rawIdx], i); + break; + default: + var k = 0; + var value = []; + for (; k < dimSize; k++) { + value[k] = chunks[dims[k]][rawIdx]; + } + // Index + value[k] = i; + cb.apply(null, value); + } + } + }; + /** + * Get extent of data in one dimension + */ + DataStore.prototype.getDataExtent = function (dim) { + // Make sure use concrete dim as cache name. + var dimData = this._chunks[dim]; + var initialExtent = getInitialExtent(); + if (!dimData) { + return initialExtent; + } + // Make more strict checkings to ensure hitting cache. + var currEnd = this.count(); + // Consider the most cases when using data zoom, `getDataExtent` + // happened before filtering. We cache raw extent, which is not + // necessary to be cleared and recalculated when restore data. + var useRaw = !this._indices; + var dimExtent; + if (useRaw) { + return this._rawExtent[dim].slice(); + } + dimExtent = this._extent[dim]; + if (dimExtent) { + return dimExtent.slice(); + } + dimExtent = initialExtent; + var min = dimExtent[0]; + var max = dimExtent[1]; + for (var i = 0; i < currEnd; i++) { + var rawIdx = this.getRawIndex(i); + var value = dimData[rawIdx]; + value < min && (min = value); + value > max && (max = value); + } + dimExtent = [min, max]; + this._extent[dim] = dimExtent; + return dimExtent; + }; + /** + * Get raw data item + */ + DataStore.prototype.getRawDataItem = function (idx) { + var rawIdx = this.getRawIndex(idx); + if (!this._provider.persistent) { + var val = []; + var chunks = this._chunks; + for (var i = 0; i < chunks.length; i++) { + val.push(chunks[i][rawIdx]); + } + return val; + } else { + return this._provider.getItem(rawIdx); + } + }; + /** + * Clone shallow. + * + * @param clonedDims Determine which dims to clone. Will share the data if not specified. + */ + DataStore.prototype.clone = function (clonedDims, ignoreIndices) { + var target = new DataStore(); + var chunks = this._chunks; + var clonedDimsMap = clonedDims && reduce(clonedDims, function (obj, dimIdx) { + obj[dimIdx] = true; + return obj; + }, {}); + if (clonedDimsMap) { + for (var i = 0; i < chunks.length; i++) { + // Not clone if dim is not picked. + target._chunks[i] = !clonedDimsMap[i] ? chunks[i] : cloneChunk(chunks[i]); + } + } else { + target._chunks = chunks; + } + this._copyCommonProps(target); + if (!ignoreIndices) { + target._indices = this._cloneIndices(); + } + target._updateGetRawIdx(); + return target; + }; + DataStore.prototype._copyCommonProps = function (target) { + target._count = this._count; + target._rawCount = this._rawCount; + target._provider = this._provider; + target._dimensions = this._dimensions; + target._extent = clone(this._extent); + target._rawExtent = clone(this._rawExtent); + }; + DataStore.prototype._cloneIndices = function () { + if (this._indices) { + var Ctor = this._indices.constructor; + var indices = void 0; + if (Ctor === Array) { + var thisCount = this._indices.length; + indices = new Ctor(thisCount); + for (var i = 0; i < thisCount; i++) { + indices[i] = this._indices[i]; + } + } else { + indices = new Ctor(this._indices); + } + return indices; + } + return null; + }; + DataStore.prototype._getRawIdxIdentity = function (idx) { + return idx; + }; + DataStore.prototype._getRawIdx = function (idx) { + if (idx < this._count && idx >= 0) { + return this._indices[idx]; + } + return -1; + }; + DataStore.prototype._updateGetRawIdx = function () { + this.getRawIndex = this._indices ? this._getRawIdx : this._getRawIdxIdentity; + }; + DataStore.internalField = function () { + function getDimValueSimply(dataItem, property, dataIndex, dimIndex) { + return parseDataValue(dataItem[dimIndex], this._dimensions[dimIndex]); + } + defaultDimValueGetters = { + arrayRows: getDimValueSimply, + objectRows: function (dataItem, property, dataIndex, dimIndex) { + return parseDataValue(dataItem[property], this._dimensions[dimIndex]); + }, + keyedColumns: getDimValueSimply, + original: function (dataItem, property, dataIndex, dimIndex) { + // Performance sensitive, do not use modelUtil.getDataItemValue. + // If dataItem is an plain object with no value field, the let `value` + // will be assigned with the object, but it will be tread correctly + // in the `convertValue`. + var value = dataItem && (dataItem.value == null ? dataItem : dataItem.value); + return parseDataValue(value instanceof Array ? value[dimIndex] + // If value is a single number or something else not array. + : value, this._dimensions[dimIndex]); + }, + typedArray: function (dataItem, property, dataIndex, dimIndex) { + return dataItem[dimIndex]; + } + }; + }(); + return DataStore; + }(); + + /** + * [REQUIREMENT_MEMO]: + * (0) `metaRawOption` means `dimensions`/`sourceHeader`/`seriesLayoutBy` in raw option. + * (1) Keep support the feature: `metaRawOption` can be specified both on `series` and + * `root-dataset`. Them on `series` has higher priority. + * (2) Do not support to set `metaRawOption` on a `non-root-dataset`, because it might + * confuse users: whether those props indicate how to visit the upstream source or visit + * the transform result source, and some transforms has nothing to do with these props, + * and some transforms might have multiple upstream. + * (3) Transforms should specify `metaRawOption` in each output, just like they can be + * declared in `root-dataset`. + * (4) At present only support visit source in `SERIES_LAYOUT_BY_COLUMN` in transforms. + * That is for reducing complexity in transforms. + * PENDING: Whether to provide transposition transform? + * + * [IMPLEMENTAION_MEMO]: + * "sourceVisitConfig" are calculated from `metaRawOption` and `data`. + * They will not be calculated until `source` is about to be visited (to prevent from + * duplicate calcuation). `source` is visited only in series and input to transforms. + * + * [DIMENSION_INHERIT_RULE]: + * By default the dimensions are inherited from ancestors, unless a transform return + * a new dimensions definition. + * Consider the case: + * ```js + * dataset: [{ + * source: [ ['Product', 'Sales', 'Prise'], ['Cookies', 321, 44.21], ...] + * }, { + * transform: { type: 'filter', ... } + * }] + * dataset: [{ + * dimension: ['Product', 'Sales', 'Prise'], + * source: [ ['Cookies', 321, 44.21], ...] + * }, { + * transform: { type: 'filter', ... } + * }] + * ``` + * The two types of option should have the same behavior after transform. + * + * + * [SCENARIO]: + * (1) Provide source data directly: + * ```js + * series: { + * encode: {...}, + * dimensions: [...] + * seriesLayoutBy: 'row', + * data: [[...]] + * } + * ``` + * (2) Series refer to dataset. + * ```js + * series: [{ + * encode: {...} + * // Ignore datasetIndex means `datasetIndex: 0` + * // and the dimensions defination in dataset is used + * }, { + * encode: {...}, + * seriesLayoutBy: 'column', + * datasetIndex: 1 + * }] + * ``` + * (3) dataset transform + * ```js + * dataset: [{ + * source: [...] + * }, { + * source: [...] + * }, { + * // By default from 0. + * transform: { type: 'filter', config: {...} } + * }, { + * // Piped. + * transform: [ + * { type: 'filter', config: {...} }, + * { type: 'sort', config: {...} } + * ] + * }, { + * id: 'regressionData', + * fromDatasetIndex: 1, + * // Third-party transform + * transform: { type: 'ecStat:regression', config: {...} } + * }, { + * // retrieve the extra result. + * id: 'regressionFormula', + * fromDatasetId: 'regressionData', + * fromTransformResult: 1 + * }] + * ``` + */ + var SourceManager = /** @class */function () { + function SourceManager(sourceHost) { + // Cached source. Do not repeat calculating if not dirty. + this._sourceList = []; + this._storeList = []; + // version sign of each upstream source manager. + this._upstreamSignList = []; + this._versionSignBase = 0; + this._dirty = true; + this._sourceHost = sourceHost; + } + /** + * Mark dirty. + */ + SourceManager.prototype.dirty = function () { + this._setLocalSource([], []); + this._storeList = []; + this._dirty = true; + }; + SourceManager.prototype._setLocalSource = function (sourceList, upstreamSignList) { + this._sourceList = sourceList; + this._upstreamSignList = upstreamSignList; + this._versionSignBase++; + if (this._versionSignBase > 9e10) { + this._versionSignBase = 0; + } + }; + /** + * For detecting whether the upstream source is dirty, so that + * the local cached source (in `_sourceList`) should be discarded. + */ + SourceManager.prototype._getVersionSign = function () { + return this._sourceHost.uid + '_' + this._versionSignBase; + }; + /** + * Always return a source instance. Otherwise throw error. + */ + SourceManager.prototype.prepareSource = function () { + // For the case that call `setOption` multiple time but no data changed, + // cache the result source to prevent from repeating transform. + if (this._isDirty()) { + this._createSource(); + this._dirty = false; + } + }; + SourceManager.prototype._createSource = function () { + this._setLocalSource([], []); + var sourceHost = this._sourceHost; + var upSourceMgrList = this._getUpstreamSourceManagers(); + var hasUpstream = !!upSourceMgrList.length; + var resultSourceList; + var upstreamSignList; + if (isSeries(sourceHost)) { + var seriesModel = sourceHost; + var data = void 0; + var sourceFormat = void 0; + var upSource = void 0; + // Has upstream dataset + if (hasUpstream) { + var upSourceMgr = upSourceMgrList[0]; + upSourceMgr.prepareSource(); + upSource = upSourceMgr.getSource(); + data = upSource.data; + sourceFormat = upSource.sourceFormat; + upstreamSignList = [upSourceMgr._getVersionSign()]; + } + // Series data is from own. + else { + data = seriesModel.get('data', true); + sourceFormat = isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL; + upstreamSignList = []; + } + // See [REQUIREMENT_MEMO], merge settings on series and parent dataset if it is root. + var newMetaRawOption = this._getSourceMetaRawOption() || {}; + var upMetaRawOption = upSource && upSource.metaRawOption || {}; + var seriesLayoutBy = retrieve2(newMetaRawOption.seriesLayoutBy, upMetaRawOption.seriesLayoutBy) || null; + var sourceHeader = retrieve2(newMetaRawOption.sourceHeader, upMetaRawOption.sourceHeader); + // Note here we should not use `upSource.dimensionsDefine`. Consider the case: + // `upSource.dimensionsDefine` is detected by `seriesLayoutBy: 'column'`, + // but series need `seriesLayoutBy: 'row'`. + var dimensions = retrieve2(newMetaRawOption.dimensions, upMetaRawOption.dimensions); + // We share source with dataset as much as possible + // to avoid extra memory cost of high dimensional data. + var needsCreateSource = seriesLayoutBy !== upMetaRawOption.seriesLayoutBy || !!sourceHeader !== !!upMetaRawOption.sourceHeader || dimensions; + resultSourceList = needsCreateSource ? [createSource(data, { + seriesLayoutBy: seriesLayoutBy, + sourceHeader: sourceHeader, + dimensions: dimensions + }, sourceFormat)] : []; + } else { + var datasetModel = sourceHost; + // Has upstream dataset. + if (hasUpstream) { + var result = this._applyTransform(upSourceMgrList); + resultSourceList = result.sourceList; + upstreamSignList = result.upstreamSignList; + } + // Is root dataset. + else { + var sourceData = datasetModel.get('source', true); + resultSourceList = [createSource(sourceData, this._getSourceMetaRawOption(), null)]; + upstreamSignList = []; + } + } + if ("development" !== 'production') { + assert(resultSourceList && upstreamSignList); + } + this._setLocalSource(resultSourceList, upstreamSignList); + }; + SourceManager.prototype._applyTransform = function (upMgrList) { + var datasetModel = this._sourceHost; + var transformOption = datasetModel.get('transform', true); + var fromTransformResult = datasetModel.get('fromTransformResult', true); + if ("development" !== 'production') { + assert(fromTransformResult != null || transformOption != null); + } + if (fromTransformResult != null) { + var errMsg = ''; + if (upMgrList.length !== 1) { + if ("development" !== 'production') { + errMsg = 'When using `fromTransformResult`, there should be only one upstream dataset'; + } + doThrow(errMsg); + } + } + var sourceList; + var upSourceList = []; + var upstreamSignList = []; + each(upMgrList, function (upMgr) { + upMgr.prepareSource(); + var upSource = upMgr.getSource(fromTransformResult || 0); + var errMsg = ''; + if (fromTransformResult != null && !upSource) { + if ("development" !== 'production') { + errMsg = 'Can not retrieve result by `fromTransformResult`: ' + fromTransformResult; + } + doThrow(errMsg); + } + upSourceList.push(upSource); + upstreamSignList.push(upMgr._getVersionSign()); + }); + if (transformOption) { + sourceList = applyDataTransform(transformOption, upSourceList, { + datasetIndex: datasetModel.componentIndex + }); + } else if (fromTransformResult != null) { + sourceList = [cloneSourceShallow(upSourceList[0])]; + } + return { + sourceList: sourceList, + upstreamSignList: upstreamSignList + }; + }; + SourceManager.prototype._isDirty = function () { + if (this._dirty) { + return true; + } + // All sourceList is from the some upstream. + var upSourceMgrList = this._getUpstreamSourceManagers(); + for (var i = 0; i < upSourceMgrList.length; i++) { + var upSrcMgr = upSourceMgrList[i]; + if ( + // Consider the case that there is ancestor diry, call it recursively. + // The performance is probably not an issue because usually the chain is not long. + upSrcMgr._isDirty() || this._upstreamSignList[i] !== upSrcMgr._getVersionSign()) { + return true; + } + } + }; + /** + * @param sourceIndex By default 0, means "main source". + * In most cases there is only one source. + */ + SourceManager.prototype.getSource = function (sourceIndex) { + sourceIndex = sourceIndex || 0; + var source = this._sourceList[sourceIndex]; + if (!source) { + // Series may share source instance with dataset. + var upSourceMgrList = this._getUpstreamSourceManagers(); + return upSourceMgrList[0] && upSourceMgrList[0].getSource(sourceIndex); + } + return source; + }; + /** + * + * Get a data store which can be shared across series. + * Only available for series. + * + * @param seriesDimRequest Dimensions that are generated in series. + * Should have been sorted by `storeDimIndex` asc. + */ + SourceManager.prototype.getSharedDataStore = function (seriesDimRequest) { + if ("development" !== 'production') { + assert(isSeries(this._sourceHost), 'Can only call getDataStore on series source manager.'); + } + var schema = seriesDimRequest.makeStoreSchema(); + return this._innerGetDataStore(schema.dimensions, seriesDimRequest.source, schema.hash); + }; + SourceManager.prototype._innerGetDataStore = function (storeDims, seriesSource, sourceReadKey) { + // TODO Can use other sourceIndex? + var sourceIndex = 0; + var storeList = this._storeList; + var cachedStoreMap = storeList[sourceIndex]; + if (!cachedStoreMap) { + cachedStoreMap = storeList[sourceIndex] = {}; + } + var cachedStore = cachedStoreMap[sourceReadKey]; + if (!cachedStore) { + var upSourceMgr = this._getUpstreamSourceManagers()[0]; + if (isSeries(this._sourceHost) && upSourceMgr) { + cachedStore = upSourceMgr._innerGetDataStore(storeDims, seriesSource, sourceReadKey); + } else { + cachedStore = new DataStore(); + // Always create store from source of series. + cachedStore.initData(new DefaultDataProvider(seriesSource, storeDims.length), storeDims); + } + cachedStoreMap[sourceReadKey] = cachedStore; + } + return cachedStore; + }; + /** + * PENDING: Is it fast enough? + * If no upstream, return empty array. + */ + SourceManager.prototype._getUpstreamSourceManagers = function () { + // Always get the relationship from the raw option. + // Do not cache the link of the dependency graph, so that + // there is no need to update them when change happens. + var sourceHost = this._sourceHost; + if (isSeries(sourceHost)) { + var datasetModel = querySeriesUpstreamDatasetModel(sourceHost); + return !datasetModel ? [] : [datasetModel.getSourceManager()]; + } else { + return map(queryDatasetUpstreamDatasetModels(sourceHost), function (datasetModel) { + return datasetModel.getSourceManager(); + }); + } + }; + SourceManager.prototype._getSourceMetaRawOption = function () { + var sourceHost = this._sourceHost; + var seriesLayoutBy; + var sourceHeader; + var dimensions; + if (isSeries(sourceHost)) { + seriesLayoutBy = sourceHost.get('seriesLayoutBy', true); + sourceHeader = sourceHost.get('sourceHeader', true); + dimensions = sourceHost.get('dimensions', true); + } + // See [REQUIREMENT_MEMO], `non-root-dataset` do not support them. + else if (!this._getUpstreamSourceManagers().length) { + var model = sourceHost; + seriesLayoutBy = model.get('seriesLayoutBy', true); + sourceHeader = model.get('sourceHeader', true); + dimensions = model.get('dimensions', true); + } + return { + seriesLayoutBy: seriesLayoutBy, + sourceHeader: sourceHeader, + dimensions: dimensions + }; + }; + return SourceManager; + }(); + // Call this method after `super.init` and `super.mergeOption` to + // disable the transform merge, but do not disable transform clone from rawOption. + function disableTransformOptionMerge(datasetModel) { + var transformOption = datasetModel.option.transform; + transformOption && setAsPrimitive(datasetModel.option.transform); + } + function isSeries(sourceHost) { + // Avoid circular dependency with Series.ts + return sourceHost.mainType === 'series'; + } + function doThrow(errMsg) { + throw new Error(errMsg); + } + + var TOOLTIP_LINE_HEIGHT_CSS = 'line-height:1'; + // TODO: more textStyle option + function getTooltipTextStyle(textStyle, renderMode) { + var nameFontColor = textStyle.color || '#6e7079'; + var nameFontSize = textStyle.fontSize || 12; + var nameFontWeight = textStyle.fontWeight || '400'; + var valueFontColor = textStyle.color || '#464646'; + var valueFontSize = textStyle.fontSize || 14; + var valueFontWeight = textStyle.fontWeight || '900'; + if (renderMode === 'html') { + // `textStyle` is probably from user input, should be encoded to reduce security risk. + return { + // eslint-disable-next-line max-len + nameStyle: "font-size:" + encodeHTML(nameFontSize + '') + "px;color:" + encodeHTML(nameFontColor) + ";font-weight:" + encodeHTML(nameFontWeight + ''), + // eslint-disable-next-line max-len + valueStyle: "font-size:" + encodeHTML(valueFontSize + '') + "px;color:" + encodeHTML(valueFontColor) + ";font-weight:" + encodeHTML(valueFontWeight + '') + }; + } else { + return { + nameStyle: { + fontSize: nameFontSize, + fill: nameFontColor, + fontWeight: nameFontWeight + }, + valueStyle: { + fontSize: valueFontSize, + fill: valueFontColor, + fontWeight: valueFontWeight + } + }; + } + } + // See `TooltipMarkupLayoutIntent['innerGapLevel']`. + // (value from UI design) + var HTML_GAPS = [0, 10, 20, 30]; + var RICH_TEXT_GAPS = ['', '\n', '\n\n', '\n\n\n']; + // eslint-disable-next-line max-len + function createTooltipMarkup(type, option) { + option.type = type; + return option; + } + function isSectionFragment(frag) { + return frag.type === 'section'; + } + function getBuilder(frag) { + return isSectionFragment(frag) ? buildSection : buildNameValue; + } + function getBlockGapLevel(frag) { + if (isSectionFragment(frag)) { + var gapLevel_1 = 0; + var subBlockLen = frag.blocks.length; + var hasInnerGap_1 = subBlockLen > 1 || subBlockLen > 0 && !frag.noHeader; + each(frag.blocks, function (subBlock) { + var subGapLevel = getBlockGapLevel(subBlock); + // If the some of the sub-blocks have some gaps (like 10px) inside, this block + // should use a larger gap (like 20px) to distinguish those sub-blocks. + if (subGapLevel >= gapLevel_1) { + gapLevel_1 = subGapLevel + +(hasInnerGap_1 && ( + // 0 always can not be readable gap level. + !subGapLevel + // If no header, always keep the sub gap level. Otherwise + // look weird in case `multipleSeries`. + || isSectionFragment(subBlock) && !subBlock.noHeader)); + } + }); + return gapLevel_1; + } + return 0; + } + function buildSection(ctx, fragment, topMarginForOuterGap, toolTipTextStyle) { + var noHeader = fragment.noHeader; + var gaps = getGap(getBlockGapLevel(fragment)); + var subMarkupTextList = []; + var subBlocks = fragment.blocks || []; + assert(!subBlocks || isArray(subBlocks)); + subBlocks = subBlocks || []; + var orderMode = ctx.orderMode; + if (fragment.sortBlocks && orderMode) { + subBlocks = subBlocks.slice(); + var orderMap = { + valueAsc: 'asc', + valueDesc: 'desc' + }; + if (hasOwn(orderMap, orderMode)) { + var comparator_1 = new SortOrderComparator(orderMap[orderMode], null); + subBlocks.sort(function (a, b) { + return comparator_1.evaluate(a.sortParam, b.sortParam); + }); + } + // FIXME 'seriesDesc' necessary? + else if (orderMode === 'seriesDesc') { + subBlocks.reverse(); + } + } + each(subBlocks, function (subBlock, idx) { + var valueFormatter = fragment.valueFormatter; + var subMarkupText = getBuilder(subBlock)( + // Inherit valueFormatter + valueFormatter ? extend(extend({}, ctx), { + valueFormatter: valueFormatter + }) : ctx, subBlock, idx > 0 ? gaps.html : 0, toolTipTextStyle); + subMarkupText != null && subMarkupTextList.push(subMarkupText); + }); + var subMarkupText = ctx.renderMode === 'richText' ? subMarkupTextList.join(gaps.richText) : wrapBlockHTML(subMarkupTextList.join(''), noHeader ? topMarginForOuterGap : gaps.html); + if (noHeader) { + return subMarkupText; + } + var displayableHeader = makeValueReadable(fragment.header, 'ordinal', ctx.useUTC); + var nameStyle = getTooltipTextStyle(toolTipTextStyle, ctx.renderMode).nameStyle; + if (ctx.renderMode === 'richText') { + return wrapInlineNameRichText(ctx, displayableHeader, nameStyle) + gaps.richText + subMarkupText; + } else { + return wrapBlockHTML("
    " + encodeHTML(displayableHeader) + '
    ' + subMarkupText, topMarginForOuterGap); + } + } + function buildNameValue(ctx, fragment, topMarginForOuterGap, toolTipTextStyle) { + var renderMode = ctx.renderMode; + var noName = fragment.noName; + var noValue = fragment.noValue; + var noMarker = !fragment.markerType; + var name = fragment.name; + var useUTC = ctx.useUTC; + var valueFormatter = fragment.valueFormatter || ctx.valueFormatter || function (value) { + value = isArray(value) ? value : [value]; + return map(value, function (val, idx) { + return makeValueReadable(val, isArray(valueTypeOption) ? valueTypeOption[idx] : valueTypeOption, useUTC); + }); + }; + if (noName && noValue) { + return; + } + var markerStr = noMarker ? '' : ctx.markupStyleCreator.makeTooltipMarker(fragment.markerType, fragment.markerColor || '#333', renderMode); + var readableName = noName ? '' : makeValueReadable(name, 'ordinal', useUTC); + var valueTypeOption = fragment.valueType; + var readableValueList = noValue ? [] : valueFormatter(fragment.value, fragment.dataIndex); + var valueAlignRight = !noMarker || !noName; + // It little weird if only value next to marker but far from marker. + var valueCloseToMarker = !noMarker && noName; + var _a = getTooltipTextStyle(toolTipTextStyle, renderMode), + nameStyle = _a.nameStyle, + valueStyle = _a.valueStyle; + return renderMode === 'richText' ? (noMarker ? '' : markerStr) + (noName ? '' : wrapInlineNameRichText(ctx, readableName, nameStyle)) + // Value has commas inside, so use ' ' as delimiter for multiple values. + + (noValue ? '' : wrapInlineValueRichText(ctx, readableValueList, valueAlignRight, valueCloseToMarker, valueStyle)) : wrapBlockHTML((noMarker ? '' : markerStr) + (noName ? '' : wrapInlineNameHTML(readableName, !noMarker, nameStyle)) + (noValue ? '' : wrapInlineValueHTML(readableValueList, valueAlignRight, valueCloseToMarker, valueStyle)), topMarginForOuterGap); + } + /** + * @return markupText. null/undefined means no content. + */ + function buildTooltipMarkup(fragment, markupStyleCreator, renderMode, orderMode, useUTC, toolTipTextStyle) { + if (!fragment) { + return; + } + var builder = getBuilder(fragment); + var ctx = { + useUTC: useUTC, + renderMode: renderMode, + orderMode: orderMode, + markupStyleCreator: markupStyleCreator, + valueFormatter: fragment.valueFormatter + }; + return builder(ctx, fragment, 0, toolTipTextStyle); + } + function getGap(gapLevel) { + return { + html: HTML_GAPS[gapLevel], + richText: RICH_TEXT_GAPS[gapLevel] + }; + } + function wrapBlockHTML(encodedContent, topGap) { + var clearfix = '
    '; + var marginCSS = "margin: " + topGap + "px 0 0"; + return "
    " + encodedContent + clearfix + '
    '; + } + function wrapInlineNameHTML(name, leftHasMarker, style) { + var marginCss = leftHasMarker ? 'margin-left:2px' : ''; + return "" + encodeHTML(name) + ''; + } + function wrapInlineValueHTML(valueList, alignRight, valueCloseToMarker, style) { + // Do not too close to marker, considering there are multiple values separated by spaces. + var paddingStr = valueCloseToMarker ? '10px' : '20px'; + var alignCSS = alignRight ? "float:right;margin-left:" + paddingStr : ''; + valueList = isArray(valueList) ? valueList : [valueList]; + return "" + // Value has commas inside, so use ' ' as delimiter for multiple values. + + map(valueList, function (value) { + return encodeHTML(value); + }).join('  ') + ''; + } + function wrapInlineNameRichText(ctx, name, style) { + return ctx.markupStyleCreator.wrapRichTextStyle(name, style); + } + function wrapInlineValueRichText(ctx, values, alignRight, valueCloseToMarker, style) { + var styles = [style]; + var paddingLeft = valueCloseToMarker ? 10 : 20; + alignRight && styles.push({ + padding: [0, 0, 0, paddingLeft], + align: 'right' + }); + // Value has commas inside, so use ' ' as delimiter for multiple values. + return ctx.markupStyleCreator.wrapRichTextStyle(isArray(values) ? values.join(' ') : values, styles); + } + function retrieveVisualColorForTooltipMarker(series, dataIndex) { + var style = series.getData().getItemVisual(dataIndex, 'style'); + var color = style[series.visualDrawType]; + return convertToColorString(color); + } + function getPaddingFromTooltipModel(model, renderMode) { + var padding = model.get('padding'); + return padding != null ? padding + // We give slightly different to look pretty. + : renderMode === 'richText' ? [8, 10] : 10; + } + /** + * The major feature is generate styles for `renderMode: 'richText'`. + * But it also serves `renderMode: 'html'` to provide + * "renderMode-independent" API. + */ + var TooltipMarkupStyleCreator = /** @class */function () { + function TooltipMarkupStyleCreator() { + this.richTextStyles = {}; + // Notice that "generate a style name" usually happens repeatedly when mouse is moving and + // a tooltip is displayed. So we put the `_nextStyleNameId` as a member of each creator + // rather than static shared by all creators (which will cause it increase to fast). + this._nextStyleNameId = getRandomIdBase(); + } + TooltipMarkupStyleCreator.prototype._generateStyleName = function () { + return '__EC_aUTo_' + this._nextStyleNameId++; + }; + TooltipMarkupStyleCreator.prototype.makeTooltipMarker = function (markerType, colorStr, renderMode) { + var markerId = renderMode === 'richText' ? this._generateStyleName() : null; + var marker = getTooltipMarker({ + color: colorStr, + type: markerType, + renderMode: renderMode, + markerId: markerId + }); + if (isString(marker)) { + return marker; + } else { + if ("development" !== 'production') { + assert(markerId); + } + this.richTextStyles[markerId] = marker.style; + return marker.content; + } + }; + /** + * @usage + * ```ts + * const styledText = markupStyleCreator.wrapRichTextStyle([ + * // The styles will be auto merged. + * { + * fontSize: 12, + * color: 'blue' + * }, + * { + * padding: 20 + * } + * ]); + * ``` + */ + TooltipMarkupStyleCreator.prototype.wrapRichTextStyle = function (text, styles) { + var finalStl = {}; + if (isArray(styles)) { + each(styles, function (stl) { + return extend(finalStl, stl); + }); + } else { + extend(finalStl, styles); + } + var styleName = this._generateStyleName(); + this.richTextStyles[styleName] = finalStl; + return "{" + styleName + "|" + text + "}"; + }; + return TooltipMarkupStyleCreator; + }(); + + function defaultSeriesFormatTooltip(opt) { + var series = opt.series; + var dataIndex = opt.dataIndex; + var multipleSeries = opt.multipleSeries; + var data = series.getData(); + var tooltipDims = data.mapDimensionsAll('defaultedTooltip'); + var tooltipDimLen = tooltipDims.length; + var value = series.getRawValue(dataIndex); + var isValueArr = isArray(value); + var markerColor = retrieveVisualColorForTooltipMarker(series, dataIndex); + // Complicated rule for pretty tooltip. + var inlineValue; + var inlineValueType; + var subBlocks; + var sortParam; + if (tooltipDimLen > 1 || isValueArr && !tooltipDimLen) { + var formatArrResult = formatTooltipArrayValue(value, series, dataIndex, tooltipDims, markerColor); + inlineValue = formatArrResult.inlineValues; + inlineValueType = formatArrResult.inlineValueTypes; + subBlocks = formatArrResult.blocks; + // Only support tooltip sort by the first inline value. It's enough in most cases. + sortParam = formatArrResult.inlineValues[0]; + } else if (tooltipDimLen) { + var dimInfo = data.getDimensionInfo(tooltipDims[0]); + sortParam = inlineValue = retrieveRawValue(data, dataIndex, tooltipDims[0]); + inlineValueType = dimInfo.type; + } else { + sortParam = inlineValue = isValueArr ? value[0] : value; + } + // Do not show generated series name. It might not be readable. + var seriesNameSpecified = isNameSpecified(series); + var seriesName = seriesNameSpecified && series.name || ''; + var itemName = data.getName(dataIndex); + var inlineName = multipleSeries ? seriesName : itemName; + return createTooltipMarkup('section', { + header: seriesName, + // When series name is not specified, do not show a header line with only '-'. + // This case always happens in tooltip.trigger: 'item'. + noHeader: multipleSeries || !seriesNameSpecified, + sortParam: sortParam, + blocks: [createTooltipMarkup('nameValue', { + markerType: 'item', + markerColor: markerColor, + // Do not mix display seriesName and itemName in one tooltip, + // which might confuses users. + name: inlineName, + // name dimension might be auto assigned, where the name might + // be not readable. So we check trim here. + noName: !trim(inlineName), + value: inlineValue, + valueType: inlineValueType, + dataIndex: dataIndex + })].concat(subBlocks || []) + }); + } + function formatTooltipArrayValue(value, series, dataIndex, tooltipDims, colorStr) { + // check: category-no-encode-has-axis-data in dataset.html + var data = series.getData(); + var isValueMultipleLine = reduce(value, function (isValueMultipleLine, val, idx) { + var dimItem = data.getDimensionInfo(idx); + return isValueMultipleLine = isValueMultipleLine || dimItem && dimItem.tooltip !== false && dimItem.displayName != null; + }, false); + var inlineValues = []; + var inlineValueTypes = []; + var blocks = []; + tooltipDims.length ? each(tooltipDims, function (dim) { + setEachItem(retrieveRawValue(data, dataIndex, dim), dim); + }) + // By default, all dims is used on tooltip. + : each(value, setEachItem); + function setEachItem(val, dim) { + var dimInfo = data.getDimensionInfo(dim); + // If `dimInfo.tooltip` is not set, show tooltip. + if (!dimInfo || dimInfo.otherDims.tooltip === false) { + return; + } + if (isValueMultipleLine) { + blocks.push(createTooltipMarkup('nameValue', { + markerType: 'subItem', + markerColor: colorStr, + name: dimInfo.displayName, + value: val, + valueType: dimInfo.type + })); + } else { + inlineValues.push(val); + inlineValueTypes.push(dimInfo.type); + } + } + return { + inlineValues: inlineValues, + inlineValueTypes: inlineValueTypes, + blocks: blocks + }; + } + + var inner$1 = makeInner(); + function getSelectionKey(data, dataIndex) { + return data.getName(dataIndex) || data.getId(dataIndex); + } + var SERIES_UNIVERSAL_TRANSITION_PROP = '__universalTransitionEnabled'; + var SeriesModel = /** @class */function (_super) { + __extends(SeriesModel, _super); + function SeriesModel() { + // [Caution]: Because this class or desecendants can be used as `XXX.extend(subProto)`, + // the class members must not be initialized in constructor or declaration place. + // Otherwise there is bad case: + // class A {xxx = 1;} + // enableClassExtend(A); + // class B extends A {} + // var C = B.extend({xxx: 5}); + // var c = new C(); + // console.log(c.xxx); // expect 5 but always 1. + var _this = _super !== null && _super.apply(this, arguments) || this; + // --------------------------------------- + // Props about data selection + // --------------------------------------- + _this._selectedDataIndicesMap = {}; + return _this; + } + SeriesModel.prototype.init = function (option, parentModel, ecModel) { + this.seriesIndex = this.componentIndex; + this.dataTask = createTask({ + count: dataTaskCount, + reset: dataTaskReset + }); + this.dataTask.context = { + model: this + }; + this.mergeDefaultAndTheme(option, ecModel); + var sourceManager = inner$1(this).sourceManager = new SourceManager(this); + sourceManager.prepareSource(); + var data = this.getInitialData(option, ecModel); + wrapData(data, this); + this.dataTask.context.data = data; + if ("development" !== 'production') { + assert(data, 'getInitialData returned invalid data.'); + } + inner$1(this).dataBeforeProcessed = data; + // If we reverse the order (make data firstly, and then make + // dataBeforeProcessed by cloneShallow), cloneShallow will + // cause data.graph.data !== data when using + // module:echarts/data/Graph or module:echarts/data/Tree. + // See module:echarts/data/helper/linkSeriesData + // Theoretically, it is unreasonable to call `seriesModel.getData()` in the model + // init or merge stage, because the data can be restored. So we do not `restoreData` + // and `setData` here, which forbids calling `seriesModel.getData()` in this stage. + // Call `seriesModel.getRawData()` instead. + // this.restoreData(); + autoSeriesName(this); + this._initSelectedMapFromData(data); + }; + /** + * Util for merge default and theme to option + */ + SeriesModel.prototype.mergeDefaultAndTheme = function (option, ecModel) { + var layoutMode = fetchLayoutMode(this); + var inputPositionParams = layoutMode ? getLayoutParams(option) : {}; + // Backward compat: using subType on theme. + // But if name duplicate between series subType + // (for example: parallel) add component mainType, + // add suffix 'Series'. + var themeSubType = this.subType; + if (ComponentModel.hasClass(themeSubType)) { + themeSubType += 'Series'; + } + merge(option, ecModel.getTheme().get(this.subType)); + merge(option, this.getDefaultOption()); + // Default label emphasis `show` + defaultEmphasis(option, 'label', ['show']); + this.fillDataTextStyle(option.data); + if (layoutMode) { + mergeLayoutParam(option, inputPositionParams, layoutMode); + } + }; + SeriesModel.prototype.mergeOption = function (newSeriesOption, ecModel) { + // this.settingTask.dirty(); + newSeriesOption = merge(this.option, newSeriesOption, true); + this.fillDataTextStyle(newSeriesOption.data); + var layoutMode = fetchLayoutMode(this); + if (layoutMode) { + mergeLayoutParam(this.option, newSeriesOption, layoutMode); + } + var sourceManager = inner$1(this).sourceManager; + sourceManager.dirty(); + sourceManager.prepareSource(); + var data = this.getInitialData(newSeriesOption, ecModel); + wrapData(data, this); + this.dataTask.dirty(); + this.dataTask.context.data = data; + inner$1(this).dataBeforeProcessed = data; + autoSeriesName(this); + this._initSelectedMapFromData(data); + }; + SeriesModel.prototype.fillDataTextStyle = function (data) { + // Default data label emphasis `show` + // FIXME Tree structure data ? + // FIXME Performance ? + if (data && !isTypedArray(data)) { + var props = ['show']; + for (var i = 0; i < data.length; i++) { + if (data[i] && data[i].label) { + defaultEmphasis(data[i], 'label', props); + } + } + } + }; + /** + * Init a data structure from data related option in series + * Must be overridden. + */ + SeriesModel.prototype.getInitialData = function (option, ecModel) { + return; + }; + /** + * Append data to list + */ + SeriesModel.prototype.appendData = function (params) { + // FIXME ??? + // (1) If data from dataset, forbidden append. + // (2) support append data of dataset. + var data = this.getRawData(); + data.appendData(params.data); + }; + /** + * Consider some method like `filter`, `map` need make new data, + * We should make sure that `seriesModel.getData()` get correct + * data in the stream procedure. So we fetch data from upstream + * each time `task.perform` called. + */ + SeriesModel.prototype.getData = function (dataType) { + var task = getCurrentTask(this); + if (task) { + var data = task.context.data; + return dataType == null ? data : data.getLinkedData(dataType); + } else { + // When series is not alive (that may happen when click toolbox + // restore or setOption with not merge mode), series data may + // be still need to judge animation or something when graphic + // elements want to know whether fade out. + return inner$1(this).data; + } + }; + SeriesModel.prototype.getAllData = function () { + var mainData = this.getData(); + return mainData && mainData.getLinkedDataAll ? mainData.getLinkedDataAll() : [{ + data: mainData + }]; + }; + SeriesModel.prototype.setData = function (data) { + var task = getCurrentTask(this); + if (task) { + var context = task.context; + // Consider case: filter, data sample. + // FIXME:TS never used, so comment it + // if (context.data !== data && task.modifyOutputEnd) { + // task.setOutputEnd(data.count()); + // } + context.outputData = data; + // Caution: setData should update context.data, + // Because getData may be called multiply in a + // single stage and expect to get the data just + // set. (For example, AxisProxy, x y both call + // getData and setDate sequentially). + // So the context.data should be fetched from + // upstream each time when a stage starts to be + // performed. + if (task !== this.dataTask) { + context.data = data; + } + } + inner$1(this).data = data; + }; + SeriesModel.prototype.getEncode = function () { + var encode = this.get('encode', true); + if (encode) { + return createHashMap(encode); + } + }; + SeriesModel.prototype.getSourceManager = function () { + return inner$1(this).sourceManager; + }; + SeriesModel.prototype.getSource = function () { + return this.getSourceManager().getSource(); + }; + /** + * Get data before processed + */ + SeriesModel.prototype.getRawData = function () { + return inner$1(this).dataBeforeProcessed; + }; + SeriesModel.prototype.getColorBy = function () { + var colorBy = this.get('colorBy'); + return colorBy || 'series'; + }; + SeriesModel.prototype.isColorBySeries = function () { + return this.getColorBy() === 'series'; + }; + /** + * Get base axis if has coordinate system and has axis. + * By default use coordSys.getBaseAxis(); + * Can be overridden for some chart. + * @return {type} description + */ + SeriesModel.prototype.getBaseAxis = function () { + var coordSys = this.coordinateSystem; + // @ts-ignore + return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis(); + }; + /** + * Default tooltip formatter + * + * @param dataIndex + * @param multipleSeries + * @param dataType + * @param renderMode valid values: 'html'(by default) and 'richText'. + * 'html' is used for rendering tooltip in extra DOM form, and the result + * string is used as DOM HTML content. + * 'richText' is used for rendering tooltip in rich text form, for those where + * DOM operation is not supported. + * @return formatted tooltip with `html` and `markers` + * Notice: The override method can also return string + */ + SeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + return defaultSeriesFormatTooltip({ + series: this, + dataIndex: dataIndex, + multipleSeries: multipleSeries + }); + }; + SeriesModel.prototype.isAnimationEnabled = function () { + var ecModel = this.ecModel; + // Disable animation if using echarts in node but not give ssr flag. + // In ssr mode, renderToString will generate svg with css animation. + if (env.node && !(ecModel && ecModel.ssr)) { + return false; + } + var animationEnabled = this.getShallow('animation'); + if (animationEnabled) { + if (this.getData().count() > this.getShallow('animationThreshold')) { + animationEnabled = false; + } + } + return !!animationEnabled; + }; + SeriesModel.prototype.restoreData = function () { + this.dataTask.dirty(); + }; + SeriesModel.prototype.getColorFromPalette = function (name, scope, requestColorNum) { + var ecModel = this.ecModel; + // PENDING + var color = PaletteMixin.prototype.getColorFromPalette.call(this, name, scope, requestColorNum); + if (!color) { + color = ecModel.getColorFromPalette(name, scope, requestColorNum); + } + return color; + }; + /** + * Use `data.mapDimensionsAll(coordDim)` instead. + * @deprecated + */ + SeriesModel.prototype.coordDimToDataDim = function (coordDim) { + return this.getRawData().mapDimensionsAll(coordDim); + }; + /** + * Get progressive rendering count each step + */ + SeriesModel.prototype.getProgressive = function () { + return this.get('progressive'); + }; + /** + * Get progressive rendering count each step + */ + SeriesModel.prototype.getProgressiveThreshold = function () { + return this.get('progressiveThreshold'); + }; + // PENGING If selectedMode is null ? + SeriesModel.prototype.select = function (innerDataIndices, dataType) { + this._innerSelect(this.getData(dataType), innerDataIndices); + }; + SeriesModel.prototype.unselect = function (innerDataIndices, dataType) { + var selectedMap = this.option.selectedMap; + if (!selectedMap) { + return; + } + var selectedMode = this.option.selectedMode; + var data = this.getData(dataType); + if (selectedMode === 'series' || selectedMap === 'all') { + this.option.selectedMap = {}; + this._selectedDataIndicesMap = {}; + return; + } + for (var i = 0; i < innerDataIndices.length; i++) { + var dataIndex = innerDataIndices[i]; + var nameOrId = getSelectionKey(data, dataIndex); + selectedMap[nameOrId] = false; + this._selectedDataIndicesMap[nameOrId] = -1; + } + }; + SeriesModel.prototype.toggleSelect = function (innerDataIndices, dataType) { + var tmpArr = []; + for (var i = 0; i < innerDataIndices.length; i++) { + tmpArr[0] = innerDataIndices[i]; + this.isSelected(innerDataIndices[i], dataType) ? this.unselect(tmpArr, dataType) : this.select(tmpArr, dataType); + } + }; + SeriesModel.prototype.getSelectedDataIndices = function () { + if (this.option.selectedMap === 'all') { + return [].slice.call(this.getData().getIndices()); + } + var selectedDataIndicesMap = this._selectedDataIndicesMap; + var nameOrIds = keys(selectedDataIndicesMap); + var dataIndices = []; + for (var i = 0; i < nameOrIds.length; i++) { + var dataIndex = selectedDataIndicesMap[nameOrIds[i]]; + if (dataIndex >= 0) { + dataIndices.push(dataIndex); + } + } + return dataIndices; + }; + SeriesModel.prototype.isSelected = function (dataIndex, dataType) { + var selectedMap = this.option.selectedMap; + if (!selectedMap) { + return false; + } + var data = this.getData(dataType); + return (selectedMap === 'all' || selectedMap[getSelectionKey(data, dataIndex)]) && !data.getItemModel(dataIndex).get(['select', 'disabled']); + }; + SeriesModel.prototype.isUniversalTransitionEnabled = function () { + if (this[SERIES_UNIVERSAL_TRANSITION_PROP]) { + return true; + } + var universalTransitionOpt = this.option.universalTransition; + // Quick reject + if (!universalTransitionOpt) { + return false; + } + if (universalTransitionOpt === true) { + return true; + } + // Can be simply 'universalTransition: true' + return universalTransitionOpt && universalTransitionOpt.enabled; + }; + SeriesModel.prototype._innerSelect = function (data, innerDataIndices) { + var _a, _b; + var option = this.option; + var selectedMode = option.selectedMode; + var len = innerDataIndices.length; + if (!selectedMode || !len) { + return; + } + if (selectedMode === 'series') { + option.selectedMap = 'all'; + } else if (selectedMode === 'multiple') { + if (!isObject(option.selectedMap)) { + option.selectedMap = {}; + } + var selectedMap = option.selectedMap; + for (var i = 0; i < len; i++) { + var dataIndex = innerDataIndices[i]; + // TODO different types of data share same object. + var nameOrId = getSelectionKey(data, dataIndex); + selectedMap[nameOrId] = true; + this._selectedDataIndicesMap[nameOrId] = data.getRawIndex(dataIndex); + } + } else if (selectedMode === 'single' || selectedMode === true) { + var lastDataIndex = innerDataIndices[len - 1]; + var nameOrId = getSelectionKey(data, lastDataIndex); + option.selectedMap = (_a = {}, _a[nameOrId] = true, _a); + this._selectedDataIndicesMap = (_b = {}, _b[nameOrId] = data.getRawIndex(lastDataIndex), _b); + } + }; + SeriesModel.prototype._initSelectedMapFromData = function (data) { + // Ignore select info in data if selectedMap exists. + // NOTE It's only for legacy usage. edge data is not supported. + if (this.option.selectedMap) { + return; + } + var dataIndices = []; + if (data.hasItemOption) { + data.each(function (idx) { + var rawItem = data.getRawDataItem(idx); + if (rawItem && rawItem.selected) { + dataIndices.push(idx); + } + }); + } + if (dataIndices.length > 0) { + this._innerSelect(data, dataIndices); + } + }; + // /** + // * @see {module:echarts/stream/Scheduler} + // */ + // abstract pipeTask: null + SeriesModel.registerClass = function (clz) { + return ComponentModel.registerClass(clz); + }; + SeriesModel.protoInitialize = function () { + var proto = SeriesModel.prototype; + proto.type = 'series.__base__'; + proto.seriesIndex = 0; + proto.ignoreStyleOnData = false; + proto.hasSymbolVisual = false; + proto.defaultSymbol = 'circle'; + // Make sure the values can be accessed! + proto.visualStyleAccessPath = 'itemStyle'; + proto.visualDrawType = 'fill'; + }(); + return SeriesModel; + }(ComponentModel); + mixin(SeriesModel, DataFormatMixin); + mixin(SeriesModel, PaletteMixin); + mountExtend(SeriesModel, ComponentModel); + /** + * MUST be called after `prepareSource` called + * Here we need to make auto series, especially for auto legend. But we + * do not modify series.name in option to avoid side effects. + */ + function autoSeriesName(seriesModel) { + // User specified name has higher priority, otherwise it may cause + // series can not be queried unexpectedly. + var name = seriesModel.name; + if (!isNameSpecified(seriesModel)) { + seriesModel.name = getSeriesAutoName(seriesModel) || name; + } + } + function getSeriesAutoName(seriesModel) { + var data = seriesModel.getRawData(); + var dataDims = data.mapDimensionsAll('seriesName'); + var nameArr = []; + each(dataDims, function (dataDim) { + var dimInfo = data.getDimensionInfo(dataDim); + dimInfo.displayName && nameArr.push(dimInfo.displayName); + }); + return nameArr.join(' '); + } + function dataTaskCount(context) { + return context.model.getRawData().count(); + } + function dataTaskReset(context) { + var seriesModel = context.model; + seriesModel.setData(seriesModel.getRawData().cloneShallow()); + return dataTaskProgress; + } + function dataTaskProgress(param, context) { + // Avoid repeat cloneShallow when data just created in reset. + if (context.outputData && param.end > context.outputData.count()) { + context.model.getRawData().cloneShallow(context.outputData); + } + } + // TODO refactor + function wrapData(data, seriesModel) { + each(concatArray(data.CHANGABLE_METHODS, data.DOWNSAMPLE_METHODS), function (methodName) { + data.wrapMethod(methodName, curry(onDataChange, seriesModel)); + }); + } + function onDataChange(seriesModel, newList) { + var task = getCurrentTask(seriesModel); + if (task) { + // Consider case: filter, selectRange + task.setOutputEnd((newList || this).count()); + } + return newList; + } + function getCurrentTask(seriesModel) { + var scheduler = (seriesModel.ecModel || {}).scheduler; + var pipeline = scheduler && scheduler.getPipeline(seriesModel.uid); + if (pipeline) { + // When pipline finished, the currrentTask keep the last + // task (renderTask). + var task = pipeline.currentTask; + if (task) { + var agentStubMap = task.agentStubMap; + if (agentStubMap) { + task = agentStubMap.get(seriesModel.uid); + } + } + return task; + } + } + + var ComponentView = /** @class */function () { + function ComponentView() { + this.group = new Group(); + this.uid = getUID('viewComponent'); + } + ComponentView.prototype.init = function (ecModel, api) {}; + ComponentView.prototype.render = function (model, ecModel, api, payload) {}; + ComponentView.prototype.dispose = function (ecModel, api) {}; + ComponentView.prototype.updateView = function (model, ecModel, api, payload) { + // Do nothing; + }; + ComponentView.prototype.updateLayout = function (model, ecModel, api, payload) { + // Do nothing; + }; + ComponentView.prototype.updateVisual = function (model, ecModel, api, payload) { + // Do nothing; + }; + /** + * Hook for toggle blur target series. + * Can be used in marker for blur or leave blur the markers + */ + ComponentView.prototype.toggleBlurSeries = function (seriesModels, isBlur, ecModel) { + // Do nothing; + }; + /** + * Traverse the new rendered elements. + * + * It will traverse the new added element in progressive rendering. + * And traverse all in normal rendering. + */ + ComponentView.prototype.eachRendered = function (cb) { + var group = this.group; + if (group) { + group.traverse(cb); + } + }; + return ComponentView; + }(); + enableClassExtend(ComponentView); + enableClassManagement(ComponentView); + + /** + * @return {string} If large mode changed, return string 'reset'; + */ + function createRenderPlanner() { + var inner = makeInner(); + return function (seriesModel) { + var fields = inner(seriesModel); + var pipelineContext = seriesModel.pipelineContext; + var originalLarge = !!fields.large; + var originalProgressive = !!fields.progressiveRender; + // FIXME: if the planner works on a filtered series, `pipelineContext` does not + // exists. See #11611 . Probably we need to modify this structure, see the comment + // on `performRawSeries` in `Schedular.js`. + var large = fields.large = !!(pipelineContext && pipelineContext.large); + var progressive = fields.progressiveRender = !!(pipelineContext && pipelineContext.progressiveRender); + return !!(originalLarge !== large || originalProgressive !== progressive) && 'reset'; + }; + } + + var inner$2 = makeInner(); + var renderPlanner = createRenderPlanner(); + var ChartView = /** @class */function () { + function ChartView() { + this.group = new Group(); + this.uid = getUID('viewChart'); + this.renderTask = createTask({ + plan: renderTaskPlan, + reset: renderTaskReset + }); + this.renderTask.context = { + view: this + }; + } + ChartView.prototype.init = function (ecModel, api) {}; + ChartView.prototype.render = function (seriesModel, ecModel, api, payload) { + if ("development" !== 'production') { + throw new Error('render method must been implemented'); + } + }; + /** + * Highlight series or specified data item. + */ + ChartView.prototype.highlight = function (seriesModel, ecModel, api, payload) { + var data = seriesModel.getData(payload && payload.dataType); + if (!data) { + if ("development" !== 'production') { + error("Unknown dataType " + payload.dataType); + } + return; + } + toggleHighlight(data, payload, 'emphasis'); + }; + /** + * Downplay series or specified data item. + */ + ChartView.prototype.downplay = function (seriesModel, ecModel, api, payload) { + var data = seriesModel.getData(payload && payload.dataType); + if (!data) { + if ("development" !== 'production') { + error("Unknown dataType " + payload.dataType); + } + return; + } + toggleHighlight(data, payload, 'normal'); + }; + /** + * Remove self. + */ + ChartView.prototype.remove = function (ecModel, api) { + this.group.removeAll(); + }; + /** + * Dispose self. + */ + ChartView.prototype.dispose = function (ecModel, api) {}; + ChartView.prototype.updateView = function (seriesModel, ecModel, api, payload) { + this.render(seriesModel, ecModel, api, payload); + }; + // FIXME never used? + ChartView.prototype.updateLayout = function (seriesModel, ecModel, api, payload) { + this.render(seriesModel, ecModel, api, payload); + }; + // FIXME never used? + ChartView.prototype.updateVisual = function (seriesModel, ecModel, api, payload) { + this.render(seriesModel, ecModel, api, payload); + }; + /** + * Traverse the new rendered elements. + * + * It will traverse the new added element in progressive rendering. + * And traverse all in normal rendering. + */ + ChartView.prototype.eachRendered = function (cb) { + traverseElements(this.group, cb); + }; + ChartView.markUpdateMethod = function (payload, methodName) { + inner$2(payload).updateMethod = methodName; + }; + ChartView.protoInitialize = function () { + var proto = ChartView.prototype; + proto.type = 'chart'; + }(); + return ChartView; + }(); + /** + * Set state of single element + */ + function elSetState(el, state, highlightDigit) { + if (el && isHighDownDispatcher(el)) { + (state === 'emphasis' ? enterEmphasis : leaveEmphasis)(el, highlightDigit); + } + } + function toggleHighlight(data, payload, state) { + var dataIndex = queryDataIndex(data, payload); + var highlightDigit = payload && payload.highlightKey != null ? getHighlightDigit(payload.highlightKey) : null; + if (dataIndex != null) { + each(normalizeToArray(dataIndex), function (dataIdx) { + elSetState(data.getItemGraphicEl(dataIdx), state, highlightDigit); + }); + } else { + data.eachItemGraphicEl(function (el) { + elSetState(el, state, highlightDigit); + }); + } + } + enableClassExtend(ChartView, ['dispose']); + enableClassManagement(ChartView); + function renderTaskPlan(context) { + return renderPlanner(context.model); + } + function renderTaskReset(context) { + var seriesModel = context.model; + var ecModel = context.ecModel; + var api = context.api; + var payload = context.payload; + // FIXME: remove updateView updateVisual + var progressiveRender = seriesModel.pipelineContext.progressiveRender; + var view = context.view; + var updateMethod = payload && inner$2(payload).updateMethod; + var methodName = progressiveRender ? 'incrementalPrepareRender' : updateMethod && view[updateMethod] ? updateMethod + // `appendData` is also supported when data amount + // is less than progressive threshold. + : 'render'; + if (methodName !== 'render') { + view[methodName](seriesModel, ecModel, api, payload); + } + return progressMethodMap[methodName]; + } + var progressMethodMap = { + incrementalPrepareRender: { + progress: function (params, context) { + context.view.incrementalRender(params, context.model, context.ecModel, context.api, context.payload); + } + }, + render: { + // Put view.render in `progress` to support appendData. But in this case + // view.render should not be called in reset, otherwise it will be called + // twise. Use `forceFirstProgress` to make sure that view.render is called + // in any cases. + forceFirstProgress: true, + progress: function (params, context) { + context.view.render(context.model, context.ecModel, context.api, context.payload); + } + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var ORIGIN_METHOD = '\0__throttleOriginMethod'; + var RATE = '\0__throttleRate'; + var THROTTLE_TYPE = '\0__throttleType'; + /** + * @public + * @param {(Function)} fn + * @param {number} [delay=0] Unit: ms. + * @param {boolean} [debounce=false] + * true: If call interval less than `delay`, only the last call works. + * false: If call interval less than `delay, call works on fixed rate. + * @return {(Function)} throttled fn. + */ + function throttle(fn, delay, debounce) { + var currCall; + var lastCall = 0; + var lastExec = 0; + var timer = null; + var diff; + var scope; + var args; + var debounceNextCall; + delay = delay || 0; + function exec() { + lastExec = new Date().getTime(); + timer = null; + fn.apply(scope, args || []); + } + var cb = function () { + var cbArgs = []; + for (var _i = 0; _i < arguments.length; _i++) { + cbArgs[_i] = arguments[_i]; + } + currCall = new Date().getTime(); + scope = this; + args = cbArgs; + var thisDelay = debounceNextCall || delay; + var thisDebounce = debounceNextCall || debounce; + debounceNextCall = null; + diff = currCall - (thisDebounce ? lastCall : lastExec) - thisDelay; + clearTimeout(timer); + // Here we should make sure that: the `exec` SHOULD NOT be called later + // than a new call of `cb`, that is, preserving the command order. Consider + // calculating "scale rate" when roaming as an example. When a call of `cb` + // happens, either the `exec` is called dierectly, or the call is delayed. + // But the delayed call should never be later than next call of `cb`. Under + // this assurance, we can simply update view state each time `dispatchAction` + // triggered by user roaming, but not need to add extra code to avoid the + // state being "rolled-back". + if (thisDebounce) { + timer = setTimeout(exec, thisDelay); + } else { + if (diff >= 0) { + exec(); + } else { + timer = setTimeout(exec, -diff); + } + } + lastCall = currCall; + }; + /** + * Clear throttle. + * @public + */ + cb.clear = function () { + if (timer) { + clearTimeout(timer); + timer = null; + } + }; + /** + * Enable debounce once. + */ + cb.debounceNextCall = function (debounceDelay) { + debounceNextCall = debounceDelay; + }; + return cb; + } + /** + * Create throttle method or update throttle rate. + * + * @example + * ComponentView.prototype.render = function () { + * ... + * throttle.createOrUpdate( + * this, + * '_dispatchAction', + * this.model.get('throttle'), + * 'fixRate' + * ); + * }; + * ComponentView.prototype.remove = function () { + * throttle.clear(this, '_dispatchAction'); + * }; + * ComponentView.prototype.dispose = function () { + * throttle.clear(this, '_dispatchAction'); + * }; + * + */ + function createOrUpdate(obj, fnAttr, rate, throttleType) { + var fn = obj[fnAttr]; + if (!fn) { + return; + } + var originFn = fn[ORIGIN_METHOD] || fn; + var lastThrottleType = fn[THROTTLE_TYPE]; + var lastRate = fn[RATE]; + if (lastRate !== rate || lastThrottleType !== throttleType) { + if (rate == null || !throttleType) { + return obj[fnAttr] = originFn; + } + fn = obj[fnAttr] = throttle(originFn, rate, throttleType === 'debounce'); + fn[ORIGIN_METHOD] = originFn; + fn[THROTTLE_TYPE] = throttleType; + fn[RATE] = rate; + } + return fn; + } + /** + * Clear throttle. Example see throttle.createOrUpdate. + */ + function clear(obj, fnAttr) { + var fn = obj[fnAttr]; + if (fn && fn[ORIGIN_METHOD]) { + // Clear throttle + fn.clear && fn.clear(); + obj[fnAttr] = fn[ORIGIN_METHOD]; + } + } + + var inner$3 = makeInner(); + var defaultStyleMappers = { + itemStyle: makeStyleMapper(ITEM_STYLE_KEY_MAP, true), + lineStyle: makeStyleMapper(LINE_STYLE_KEY_MAP, true) + }; + var defaultColorKey = { + lineStyle: 'stroke', + itemStyle: 'fill' + }; + function getStyleMapper(seriesModel, stylePath) { + var styleMapper = seriesModel.visualStyleMapper || defaultStyleMappers[stylePath]; + if (!styleMapper) { + console.warn("Unknown style type '" + stylePath + "'."); + return defaultStyleMappers.itemStyle; + } + return styleMapper; + } + function getDefaultColorKey(seriesModel, stylePath) { + // return defaultColorKey[stylePath] || + var colorKey = seriesModel.visualDrawType || defaultColorKey[stylePath]; + if (!colorKey) { + console.warn("Unknown style type '" + stylePath + "'."); + return 'fill'; + } + return colorKey; + } + var seriesStyleTask = { + createOnAllSeries: true, + performRawSeries: true, + reset: function (seriesModel, ecModel) { + var data = seriesModel.getData(); + var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; + // Set in itemStyle + var styleModel = seriesModel.getModel(stylePath); + var getStyle = getStyleMapper(seriesModel, stylePath); + var globalStyle = getStyle(styleModel); + var decalOption = styleModel.getShallow('decal'); + if (decalOption) { + data.setVisual('decal', decalOption); + decalOption.dirty = true; + } + // TODO + var colorKey = getDefaultColorKey(seriesModel, stylePath); + var color = globalStyle[colorKey]; + // TODO style callback + var colorCallback = isFunction(color) ? color : null; + var hasAutoColor = globalStyle.fill === 'auto' || globalStyle.stroke === 'auto'; + // Get from color palette by default. + if (!globalStyle[colorKey] || colorCallback || hasAutoColor) { + // Note: If some series has color specified (e.g., by itemStyle.color), we DO NOT + // make it effect palette. Because some scenarios users need to make some series + // transparent or as background, which should better not effect the palette. + var colorPalette = seriesModel.getColorFromPalette( + // TODO series count changed. + seriesModel.name, null, ecModel.getSeriesCount()); + if (!globalStyle[colorKey]) { + globalStyle[colorKey] = colorPalette; + data.setVisual('colorFromPalette', true); + } + globalStyle.fill = globalStyle.fill === 'auto' || isFunction(globalStyle.fill) ? colorPalette : globalStyle.fill; + globalStyle.stroke = globalStyle.stroke === 'auto' || isFunction(globalStyle.stroke) ? colorPalette : globalStyle.stroke; + } + data.setVisual('style', globalStyle); + data.setVisual('drawType', colorKey); + // Only visible series has each data be visual encoded + if (!ecModel.isSeriesFiltered(seriesModel) && colorCallback) { + data.setVisual('colorFromPalette', false); + return { + dataEach: function (data, idx) { + var dataParams = seriesModel.getDataParams(idx); + var itemStyle = extend({}, globalStyle); + itemStyle[colorKey] = colorCallback(dataParams); + data.setItemVisual(idx, 'style', itemStyle); + } + }; + } + } + }; + var sharedModel = new Model(); + var dataStyleTask = { + createOnAllSeries: true, + performRawSeries: true, + reset: function (seriesModel, ecModel) { + if (seriesModel.ignoreStyleOnData || ecModel.isSeriesFiltered(seriesModel)) { + return; + } + var data = seriesModel.getData(); + var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; + // Set in itemStyle + var getStyle = getStyleMapper(seriesModel, stylePath); + var colorKey = data.getVisual('drawType'); + return { + dataEach: data.hasItemOption ? function (data, idx) { + // Not use getItemModel for performance considuration + var rawItem = data.getRawDataItem(idx); + if (rawItem && rawItem[stylePath]) { + sharedModel.option = rawItem[stylePath]; + var style = getStyle(sharedModel); + var existsStyle = data.ensureUniqueItemVisual(idx, 'style'); + extend(existsStyle, style); + if (sharedModel.option.decal) { + data.setItemVisual(idx, 'decal', sharedModel.option.decal); + sharedModel.option.decal.dirty = true; + } + if (colorKey in style) { + data.setItemVisual(idx, 'colorFromPalette', false); + } + } + } : null + }; + } + }; + // Pick color from palette for the data which has not been set with color yet. + // Note: do not support stream rendering. No such cases yet. + var dataColorPaletteTask = { + performRawSeries: true, + overallReset: function (ecModel) { + // Each type of series uses one scope. + // Pie and funnel are using different scopes. + var paletteScopeGroupByType = createHashMap(); + ecModel.eachSeries(function (seriesModel) { + var colorBy = seriesModel.getColorBy(); + if (seriesModel.isColorBySeries()) { + return; + } + var key = seriesModel.type + '-' + colorBy; + var colorScope = paletteScopeGroupByType.get(key); + if (!colorScope) { + colorScope = {}; + paletteScopeGroupByType.set(key, colorScope); + } + inner$3(seriesModel).scope = colorScope; + }); + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.isColorBySeries() || ecModel.isSeriesFiltered(seriesModel)) { + return; + } + var dataAll = seriesModel.getRawData(); + var idxMap = {}; + var data = seriesModel.getData(); + var colorScope = inner$3(seriesModel).scope; + var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; + var colorKey = getDefaultColorKey(seriesModel, stylePath); + data.each(function (idx) { + var rawIdx = data.getRawIndex(idx); + idxMap[rawIdx] = idx; + }); + // Iterate on data before filtered. To make sure color from palette can be + // Consistent when toggling legend. + dataAll.each(function (rawIdx) { + var idx = idxMap[rawIdx]; + var fromPalette = data.getItemVisual(idx, 'colorFromPalette'); + // Get color from palette for each data only when the color is inherited from series color, which is + // also picked from color palette. So following situation is not in the case: + // 1. series.itemStyle.color is set + // 2. color is encoded by visualMap + if (fromPalette) { + var itemStyle = data.ensureUniqueItemVisual(idx, 'style'); + var name_1 = dataAll.getName(rawIdx) || rawIdx + ''; + var dataCount = dataAll.count(); + itemStyle[colorKey] = seriesModel.getColorFromPalette(name_1, colorScope, dataCount); + } + }); + }); + } + }; + + var PI$3 = Math.PI; + /** + * @param {module:echarts/ExtensionAPI} api + * @param {Object} [opts] + * @param {string} [opts.text] + * @param {string} [opts.color] + * @param {string} [opts.textColor] + * @return {module:zrender/Element} + */ + function defaultLoading(api, opts) { + opts = opts || {}; + defaults(opts, { + text: 'loading', + textColor: '#000', + fontSize: 12, + fontWeight: 'normal', + fontStyle: 'normal', + fontFamily: 'sans-serif', + maskColor: 'rgba(255, 255, 255, 0.8)', + showSpinner: true, + color: '#5470c6', + spinnerRadius: 10, + lineWidth: 5, + zlevel: 0 + }); + var group = new Group(); + var mask = new Rect({ + style: { + fill: opts.maskColor + }, + zlevel: opts.zlevel, + z: 10000 + }); + group.add(mask); + var textContent = new ZRText({ + style: { + text: opts.text, + fill: opts.textColor, + fontSize: opts.fontSize, + fontWeight: opts.fontWeight, + fontStyle: opts.fontStyle, + fontFamily: opts.fontFamily + }, + zlevel: opts.zlevel, + z: 10001 + }); + var labelRect = new Rect({ + style: { + fill: 'none' + }, + textContent: textContent, + textConfig: { + position: 'right', + distance: 10 + }, + zlevel: opts.zlevel, + z: 10001 + }); + group.add(labelRect); + var arc; + if (opts.showSpinner) { + arc = new Arc({ + shape: { + startAngle: -PI$3 / 2, + endAngle: -PI$3 / 2 + 0.1, + r: opts.spinnerRadius + }, + style: { + stroke: opts.color, + lineCap: 'round', + lineWidth: opts.lineWidth + }, + zlevel: opts.zlevel, + z: 10001 + }); + arc.animateShape(true).when(1000, { + endAngle: PI$3 * 3 / 2 + }).start('circularInOut'); + arc.animateShape(true).when(1000, { + startAngle: PI$3 * 3 / 2 + }).delay(300).start('circularInOut'); + group.add(arc); + } + // Inject resize + group.resize = function () { + var textWidth = textContent.getBoundingRect().width; + var r = opts.showSpinner ? opts.spinnerRadius : 0; + // cx = (containerWidth - arcDiameter - textDistance - textWidth) / 2 + // textDistance needs to be calculated when both animation and text exist + var cx = (api.getWidth() - r * 2 - (opts.showSpinner && textWidth ? 10 : 0) - textWidth) / 2 - (opts.showSpinner && textWidth ? 0 : 5 + textWidth / 2) + // only show the text + + (opts.showSpinner ? 0 : textWidth / 2) + // only show the spinner + + (textWidth ? 0 : r); + var cy = api.getHeight() / 2; + opts.showSpinner && arc.setShape({ + cx: cx, + cy: cy + }); + labelRect.setShape({ + x: cx - r, + y: cy - r, + width: r * 2, + height: r * 2 + }); + mask.setShape({ + x: 0, + y: 0, + width: api.getWidth(), + height: api.getHeight() + }); + }; + group.resize(); + return group; + } + + var Scheduler = /** @class */function () { + function Scheduler(ecInstance, api, dataProcessorHandlers, visualHandlers) { + // key: handlerUID + this._stageTaskMap = createHashMap(); + this.ecInstance = ecInstance; + this.api = api; + // Fix current processors in case that in some rear cases that + // processors might be registered after echarts instance created. + // Register processors incrementally for a echarts instance is + // not supported by this stream architecture. + dataProcessorHandlers = this._dataProcessorHandlers = dataProcessorHandlers.slice(); + visualHandlers = this._visualHandlers = visualHandlers.slice(); + this._allHandlers = dataProcessorHandlers.concat(visualHandlers); + } + Scheduler.prototype.restoreData = function (ecModel, payload) { + // TODO: Only restore needed series and components, but not all components. + // Currently `restoreData` of all of the series and component will be called. + // But some independent components like `title`, `legend`, `graphic`, `toolbox`, + // `tooltip`, `axisPointer`, etc, do not need series refresh when `setOption`, + // and some components like coordinate system, axes, dataZoom, visualMap only + // need their target series refresh. + // (1) If we are implementing this feature some day, we should consider these cases: + // if a data processor depends on a component (e.g., dataZoomProcessor depends + // on the settings of `dataZoom`), it should be re-performed if the component + // is modified by `setOption`. + // (2) If a processor depends on sevral series, speicified by its `getTargetSeries`, + // it should be re-performed when the result array of `getTargetSeries` changed. + // We use `dependencies` to cover these issues. + // (3) How to update target series when coordinate system related components modified. + // TODO: simply the dirty mechanism? Check whether only the case here can set tasks dirty, + // and this case all of the tasks will be set as dirty. + ecModel.restoreData(payload); + // Theoretically an overall task not only depends on each of its target series, but also + // depends on all of the series. + // The overall task is not in pipeline, and `ecModel.restoreData` only set pipeline tasks + // dirty. If `getTargetSeries` of an overall task returns nothing, we should also ensure + // that the overall task is set as dirty and to be performed, otherwise it probably cause + // state chaos. So we have to set dirty of all of the overall tasks manually, otherwise it + // probably cause state chaos (consider `dataZoomProcessor`). + this._stageTaskMap.each(function (taskRecord) { + var overallTask = taskRecord.overallTask; + overallTask && overallTask.dirty(); + }); + }; + // If seriesModel provided, incremental threshold is check by series data. + Scheduler.prototype.getPerformArgs = function (task, isBlock) { + // For overall task + if (!task.__pipeline) { + return; + } + var pipeline = this._pipelineMap.get(task.__pipeline.id); + var pCtx = pipeline.context; + var incremental = !isBlock && pipeline.progressiveEnabled && (!pCtx || pCtx.progressiveRender) && task.__idxInPipeline > pipeline.blockIndex; + var step = incremental ? pipeline.step : null; + var modDataCount = pCtx && pCtx.modDataCount; + var modBy = modDataCount != null ? Math.ceil(modDataCount / step) : null; + return { + step: step, + modBy: modBy, + modDataCount: modDataCount + }; + }; + Scheduler.prototype.getPipeline = function (pipelineId) { + return this._pipelineMap.get(pipelineId); + }; + /** + * Current, progressive rendering starts from visual and layout. + * Always detect render mode in the same stage, avoiding that incorrect + * detection caused by data filtering. + * Caution: + * `updateStreamModes` use `seriesModel.getData()`. + */ + Scheduler.prototype.updateStreamModes = function (seriesModel, view) { + var pipeline = this._pipelineMap.get(seriesModel.uid); + var data = seriesModel.getData(); + var dataLen = data.count(); + // `progressiveRender` means that can render progressively in each + // animation frame. Note that some types of series do not provide + // `view.incrementalPrepareRender` but support `chart.appendData`. We + // use the term `incremental` but not `progressive` to describe the + // case that `chart.appendData`. + var progressiveRender = pipeline.progressiveEnabled && view.incrementalPrepareRender && dataLen >= pipeline.threshold; + var large = seriesModel.get('large') && dataLen >= seriesModel.get('largeThreshold'); + // TODO: modDataCount should not updated if `appendData`, otherwise cause whole repaint. + // see `test/candlestick-large3.html` + var modDataCount = seriesModel.get('progressiveChunkMode') === 'mod' ? dataLen : null; + seriesModel.pipelineContext = pipeline.context = { + progressiveRender: progressiveRender, + modDataCount: modDataCount, + large: large + }; + }; + Scheduler.prototype.restorePipelines = function (ecModel) { + var scheduler = this; + var pipelineMap = scheduler._pipelineMap = createHashMap(); + ecModel.eachSeries(function (seriesModel) { + var progressive = seriesModel.getProgressive(); + var pipelineId = seriesModel.uid; + pipelineMap.set(pipelineId, { + id: pipelineId, + head: null, + tail: null, + threshold: seriesModel.getProgressiveThreshold(), + progressiveEnabled: progressive && !(seriesModel.preventIncremental && seriesModel.preventIncremental()), + blockIndex: -1, + step: Math.round(progressive || 700), + count: 0 + }); + scheduler._pipe(seriesModel, seriesModel.dataTask); + }); + }; + Scheduler.prototype.prepareStageTasks = function () { + var stageTaskMap = this._stageTaskMap; + var ecModel = this.api.getModel(); + var api = this.api; + each(this._allHandlers, function (handler) { + var record = stageTaskMap.get(handler.uid) || stageTaskMap.set(handler.uid, {}); + var errMsg = ''; + if ("development" !== 'production') { + // Currently do not need to support to sepecify them both. + errMsg = '"reset" and "overallReset" must not be both specified.'; + } + assert(!(handler.reset && handler.overallReset), errMsg); + handler.reset && this._createSeriesStageTask(handler, record, ecModel, api); + handler.overallReset && this._createOverallStageTask(handler, record, ecModel, api); + }, this); + }; + Scheduler.prototype.prepareView = function (view, model, ecModel, api) { + var renderTask = view.renderTask; + var context = renderTask.context; + context.model = model; + context.ecModel = ecModel; + context.api = api; + renderTask.__block = !view.incrementalPrepareRender; + this._pipe(model, renderTask); + }; + Scheduler.prototype.performDataProcessorTasks = function (ecModel, payload) { + // If we do not use `block` here, it should be considered when to update modes. + this._performStageTasks(this._dataProcessorHandlers, ecModel, payload, { + block: true + }); + }; + Scheduler.prototype.performVisualTasks = function (ecModel, payload, opt) { + this._performStageTasks(this._visualHandlers, ecModel, payload, opt); + }; + Scheduler.prototype._performStageTasks = function (stageHandlers, ecModel, payload, opt) { + opt = opt || {}; + var unfinished = false; + var scheduler = this; + each(stageHandlers, function (stageHandler, idx) { + if (opt.visualType && opt.visualType !== stageHandler.visualType) { + return; + } + var stageHandlerRecord = scheduler._stageTaskMap.get(stageHandler.uid); + var seriesTaskMap = stageHandlerRecord.seriesTaskMap; + var overallTask = stageHandlerRecord.overallTask; + if (overallTask) { + var overallNeedDirty_1; + var agentStubMap = overallTask.agentStubMap; + agentStubMap.each(function (stub) { + if (needSetDirty(opt, stub)) { + stub.dirty(); + overallNeedDirty_1 = true; + } + }); + overallNeedDirty_1 && overallTask.dirty(); + scheduler.updatePayload(overallTask, payload); + var performArgs_1 = scheduler.getPerformArgs(overallTask, opt.block); + // Execute stubs firstly, which may set the overall task dirty, + // then execute the overall task. And stub will call seriesModel.setData, + // which ensures that in the overallTask seriesModel.getData() will not + // return incorrect data. + agentStubMap.each(function (stub) { + stub.perform(performArgs_1); + }); + if (overallTask.perform(performArgs_1)) { + unfinished = true; + } + } else if (seriesTaskMap) { + seriesTaskMap.each(function (task, pipelineId) { + if (needSetDirty(opt, task)) { + task.dirty(); + } + var performArgs = scheduler.getPerformArgs(task, opt.block); + // FIXME + // if intending to declare `performRawSeries` in handlers, only + // stream-independent (specifically, data item independent) operations can be + // performed. Because if a series is filtered, most of the tasks will not + // be performed. A stream-dependent operation probably cause wrong biz logic. + // Perhaps we should not provide a separate callback for this case instead + // of providing the config `performRawSeries`. The stream-dependent operations + // and stream-independent operations should better not be mixed. + performArgs.skip = !stageHandler.performRawSeries && ecModel.isSeriesFiltered(task.context.model); + scheduler.updatePayload(task, payload); + if (task.perform(performArgs)) { + unfinished = true; + } + }); + } + }); + function needSetDirty(opt, task) { + return opt.setDirty && (!opt.dirtyMap || opt.dirtyMap.get(task.__pipeline.id)); + } + this.unfinished = unfinished || this.unfinished; + }; + Scheduler.prototype.performSeriesTasks = function (ecModel) { + var unfinished; + ecModel.eachSeries(function (seriesModel) { + // Progress to the end for dataInit and dataRestore. + unfinished = seriesModel.dataTask.perform() || unfinished; + }); + this.unfinished = unfinished || this.unfinished; + }; + Scheduler.prototype.plan = function () { + // Travel pipelines, check block. + this._pipelineMap.each(function (pipeline) { + var task = pipeline.tail; + do { + if (task.__block) { + pipeline.blockIndex = task.__idxInPipeline; + break; + } + task = task.getUpstream(); + } while (task); + }); + }; + Scheduler.prototype.updatePayload = function (task, payload) { + payload !== 'remain' && (task.context.payload = payload); + }; + Scheduler.prototype._createSeriesStageTask = function (stageHandler, stageHandlerRecord, ecModel, api) { + var scheduler = this; + var oldSeriesTaskMap = stageHandlerRecord.seriesTaskMap; + // The count of stages are totally about only several dozen, so + // do not need to reuse the map. + var newSeriesTaskMap = stageHandlerRecord.seriesTaskMap = createHashMap(); + var seriesType = stageHandler.seriesType; + var getTargetSeries = stageHandler.getTargetSeries; + // If a stageHandler should cover all series, `createOnAllSeries` should be declared mandatorily, + // to avoid some typo or abuse. Otherwise if an extension do not specify a `seriesType`, + // it works but it may cause other irrelevant charts blocked. + if (stageHandler.createOnAllSeries) { + ecModel.eachRawSeries(create); + } else if (seriesType) { + ecModel.eachRawSeriesByType(seriesType, create); + } else if (getTargetSeries) { + getTargetSeries(ecModel, api).each(create); + } + function create(seriesModel) { + var pipelineId = seriesModel.uid; + // Init tasks for each seriesModel only once. + // Reuse original task instance. + var task = newSeriesTaskMap.set(pipelineId, oldSeriesTaskMap && oldSeriesTaskMap.get(pipelineId) || createTask({ + plan: seriesTaskPlan, + reset: seriesTaskReset, + count: seriesTaskCount + })); + task.context = { + model: seriesModel, + ecModel: ecModel, + api: api, + // PENDING: `useClearVisual` not used? + useClearVisual: stageHandler.isVisual && !stageHandler.isLayout, + plan: stageHandler.plan, + reset: stageHandler.reset, + scheduler: scheduler + }; + scheduler._pipe(seriesModel, task); + } + }; + Scheduler.prototype._createOverallStageTask = function (stageHandler, stageHandlerRecord, ecModel, api) { + var scheduler = this; + var overallTask = stageHandlerRecord.overallTask = stageHandlerRecord.overallTask + // For overall task, the function only be called on reset stage. + || createTask({ + reset: overallTaskReset + }); + overallTask.context = { + ecModel: ecModel, + api: api, + overallReset: stageHandler.overallReset, + scheduler: scheduler + }; + var oldAgentStubMap = overallTask.agentStubMap; + // The count of stages are totally about only several dozen, so + // do not need to reuse the map. + var newAgentStubMap = overallTask.agentStubMap = createHashMap(); + var seriesType = stageHandler.seriesType; + var getTargetSeries = stageHandler.getTargetSeries; + var overallProgress = true; + var shouldOverallTaskDirty = false; + // FIXME:TS never used, so comment it + // let modifyOutputEnd = stageHandler.modifyOutputEnd; + // An overall task with seriesType detected or has `getTargetSeries`, we add + // stub in each pipelines, it will set the overall task dirty when the pipeline + // progress. Moreover, to avoid call the overall task each frame (too frequent), + // we set the pipeline block. + var errMsg = ''; + if ("development" !== 'production') { + errMsg = '"createOnAllSeries" is not supported for "overallReset", ' + 'because it will block all streams.'; + } + assert(!stageHandler.createOnAllSeries, errMsg); + if (seriesType) { + ecModel.eachRawSeriesByType(seriesType, createStub); + } else if (getTargetSeries) { + getTargetSeries(ecModel, api).each(createStub); + } + // Otherwise, (usually it is legacy case), the overall task will only be + // executed when upstream is dirty. Otherwise the progressive rendering of all + // pipelines will be disabled unexpectedly. But it still needs stubs to receive + // dirty info from upstream. + else { + overallProgress = false; + each(ecModel.getSeries(), createStub); + } + function createStub(seriesModel) { + var pipelineId = seriesModel.uid; + var stub = newAgentStubMap.set(pipelineId, oldAgentStubMap && oldAgentStubMap.get(pipelineId) || ( + // When the result of `getTargetSeries` changed, the overallTask + // should be set as dirty and re-performed. + shouldOverallTaskDirty = true, createTask({ + reset: stubReset, + onDirty: stubOnDirty + }))); + stub.context = { + model: seriesModel, + overallProgress: overallProgress + // FIXME:TS never used, so comment it + // modifyOutputEnd: modifyOutputEnd + }; + + stub.agent = overallTask; + stub.__block = overallProgress; + scheduler._pipe(seriesModel, stub); + } + if (shouldOverallTaskDirty) { + overallTask.dirty(); + } + }; + Scheduler.prototype._pipe = function (seriesModel, task) { + var pipelineId = seriesModel.uid; + var pipeline = this._pipelineMap.get(pipelineId); + !pipeline.head && (pipeline.head = task); + pipeline.tail && pipeline.tail.pipe(task); + pipeline.tail = task; + task.__idxInPipeline = pipeline.count++; + task.__pipeline = pipeline; + }; + Scheduler.wrapStageHandler = function (stageHandler, visualType) { + if (isFunction(stageHandler)) { + stageHandler = { + overallReset: stageHandler, + seriesType: detectSeriseType(stageHandler) + }; + } + stageHandler.uid = getUID('stageHandler'); + visualType && (stageHandler.visualType = visualType); + return stageHandler; + }; + return Scheduler; + }(); + function overallTaskReset(context) { + context.overallReset(context.ecModel, context.api, context.payload); + } + function stubReset(context) { + return context.overallProgress && stubProgress; + } + function stubProgress() { + this.agent.dirty(); + this.getDownstream().dirty(); + } + function stubOnDirty() { + this.agent && this.agent.dirty(); + } + function seriesTaskPlan(context) { + return context.plan ? context.plan(context.model, context.ecModel, context.api, context.payload) : null; + } + function seriesTaskReset(context) { + if (context.useClearVisual) { + context.data.clearAllVisual(); + } + var resetDefines = context.resetDefines = normalizeToArray(context.reset(context.model, context.ecModel, context.api, context.payload)); + return resetDefines.length > 1 ? map(resetDefines, function (v, idx) { + return makeSeriesTaskProgress(idx); + }) : singleSeriesTaskProgress; + } + var singleSeriesTaskProgress = makeSeriesTaskProgress(0); + function makeSeriesTaskProgress(resetDefineIdx) { + return function (params, context) { + var data = context.data; + var resetDefine = context.resetDefines[resetDefineIdx]; + if (resetDefine && resetDefine.dataEach) { + for (var i = params.start; i < params.end; i++) { + resetDefine.dataEach(data, i); + } + } else if (resetDefine && resetDefine.progress) { + resetDefine.progress(params, data); + } + }; + } + function seriesTaskCount(context) { + return context.data.count(); + } + /** + * Only some legacy stage handlers (usually in echarts extensions) are pure function. + * To ensure that they can work normally, they should work in block mode, that is, + * they should not be started util the previous tasks finished. So they cause the + * progressive rendering disabled. We try to detect the series type, to narrow down + * the block range to only the series type they concern, but not all series. + */ + function detectSeriseType(legacyFunc) { + seriesType = null; + try { + // Assume there is no async when calling `eachSeriesByType`. + legacyFunc(ecModelMock, apiMock); + } catch (e) {} + return seriesType; + } + var ecModelMock = {}; + var apiMock = {}; + var seriesType; + mockMethods(ecModelMock, GlobalModel); + mockMethods(apiMock, ExtensionAPI); + ecModelMock.eachSeriesByType = ecModelMock.eachRawSeriesByType = function (type) { + seriesType = type; + }; + ecModelMock.eachComponent = function (cond) { + if (cond.mainType === 'series' && cond.subType) { + seriesType = cond.subType; + } + }; + function mockMethods(target, Clz) { + /* eslint-disable */ + for (var name_1 in Clz.prototype) { + // Do not use hasOwnProperty + target[name_1] = noop; + } + /* eslint-enable */ + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var colorAll = ['#37A2DA', '#32C5E9', '#67E0E3', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#E062AE', '#E690D1', '#e7bcf3', '#9d96f5', '#8378EA', '#96BFFF']; + var lightTheme = { + color: colorAll, + colorLayer: [['#37A2DA', '#ffd85c', '#fd7b5f'], ['#37A2DA', '#67E0E3', '#FFDB5C', '#ff9f7f', '#E062AE', '#9d96f5'], ['#37A2DA', '#32C5E9', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378EA', '#96BFFF'], colorAll] + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var contrastColor = '#B9B8CE'; + var backgroundColor = '#100C2A'; + var axisCommon = function () { + return { + axisLine: { + lineStyle: { + color: contrastColor + } + }, + splitLine: { + lineStyle: { + color: '#484753' + } + }, + splitArea: { + areaStyle: { + color: ['rgba(255,255,255,0.02)', 'rgba(255,255,255,0.05)'] + } + }, + minorSplitLine: { + lineStyle: { + color: '#20203B' + } + } + }; + }; + var colorPalette = ['#4992ff', '#7cffb2', '#fddd60', '#ff6e76', '#58d9f9', '#05c091', '#ff8a45', '#8d48e3', '#dd79ff']; + var theme = { + darkMode: true, + color: colorPalette, + backgroundColor: backgroundColor, + axisPointer: { + lineStyle: { + color: '#817f91' + }, + crossStyle: { + color: '#817f91' + }, + label: { + // TODO Contrast of label backgorundColor + color: '#fff' + } + }, + legend: { + textStyle: { + color: contrastColor + } + }, + textStyle: { + color: contrastColor + }, + title: { + textStyle: { + color: '#EEF1FA' + }, + subtextStyle: { + color: '#B9B8CE' + } + }, + toolbox: { + iconStyle: { + borderColor: contrastColor + } + }, + dataZoom: { + borderColor: '#71708A', + textStyle: { + color: contrastColor + }, + brushStyle: { + color: 'rgba(135,163,206,0.3)' + }, + handleStyle: { + color: '#353450', + borderColor: '#C5CBE3' + }, + moveHandleStyle: { + color: '#B0B6C3', + opacity: 0.3 + }, + fillerColor: 'rgba(135,163,206,0.2)', + emphasis: { + handleStyle: { + borderColor: '#91B7F2', + color: '#4D587D' + }, + moveHandleStyle: { + color: '#636D9A', + opacity: 0.7 + } + }, + dataBackground: { + lineStyle: { + color: '#71708A', + width: 1 + }, + areaStyle: { + color: '#71708A' + } + }, + selectedDataBackground: { + lineStyle: { + color: '#87A3CE' + }, + areaStyle: { + color: '#87A3CE' + } + } + }, + visualMap: { + textStyle: { + color: contrastColor + } + }, + timeline: { + lineStyle: { + color: contrastColor + }, + label: { + color: contrastColor + }, + controlStyle: { + color: contrastColor, + borderColor: contrastColor + } + }, + calendar: { + itemStyle: { + color: backgroundColor + }, + dayLabel: { + color: contrastColor + }, + monthLabel: { + color: contrastColor + }, + yearLabel: { + color: contrastColor + } + }, + timeAxis: axisCommon(), + logAxis: axisCommon(), + valueAxis: axisCommon(), + categoryAxis: axisCommon(), + line: { + symbol: 'circle' + }, + graph: { + color: colorPalette + }, + gauge: { + title: { + color: contrastColor + }, + axisLine: { + lineStyle: { + color: [[1, 'rgba(207,212,219,0.2)']] + } + }, + axisLabel: { + color: contrastColor + }, + detail: { + color: '#EEF1FA' + } + }, + candlestick: { + itemStyle: { + color: '#f64e56', + color0: '#54ea92', + borderColor: '#f64e56', + borderColor0: '#54ea92' + // borderColor: '#ca2824', + // borderColor0: '#09a443' + } + } + }; + + theme.categoryAxis.splitLine.show = false; + + /** + * Usage of query: + * `chart.on('click', query, handler);` + * The `query` can be: + * + The component type query string, only `mainType` or `mainType.subType`, + * like: 'xAxis', 'series', 'xAxis.category' or 'series.line'. + * + The component query object, like: + * `{seriesIndex: 2}`, `{seriesName: 'xx'}`, `{seriesId: 'some'}`, + * `{xAxisIndex: 2}`, `{xAxisName: 'xx'}`, `{xAxisId: 'some'}`. + * + The data query object, like: + * `{dataIndex: 123}`, `{dataType: 'link'}`, `{name: 'some'}`. + * + The other query object (cmponent customized query), like: + * `{element: 'some'}` (only available in custom series). + * + * Caveat: If a prop in the `query` object is `null/undefined`, it is the + * same as there is no such prop in the `query` object. + */ + var ECEventProcessor = /** @class */function () { + function ECEventProcessor() {} + ECEventProcessor.prototype.normalizeQuery = function (query) { + var cptQuery = {}; + var dataQuery = {}; + var otherQuery = {}; + // `query` is `mainType` or `mainType.subType` of component. + if (isString(query)) { + var condCptType = parseClassType(query); + // `.main` and `.sub` may be ''. + cptQuery.mainType = condCptType.main || null; + cptQuery.subType = condCptType.sub || null; + } + // `query` is an object, convert to {mainType, index, name, id}. + else { + // `xxxIndex`, `xxxName`, `xxxId`, `name`, `dataIndex`, `dataType` is reserved, + // can not be used in `compomentModel.filterForExposedEvent`. + var suffixes_1 = ['Index', 'Name', 'Id']; + var dataKeys_1 = { + name: 1, + dataIndex: 1, + dataType: 1 + }; + each(query, function (val, key) { + var reserved = false; + for (var i = 0; i < suffixes_1.length; i++) { + var propSuffix = suffixes_1[i]; + var suffixPos = key.lastIndexOf(propSuffix); + if (suffixPos > 0 && suffixPos === key.length - propSuffix.length) { + var mainType = key.slice(0, suffixPos); + // Consider `dataIndex`. + if (mainType !== 'data') { + cptQuery.mainType = mainType; + cptQuery[propSuffix.toLowerCase()] = val; + reserved = true; + } + } + } + if (dataKeys_1.hasOwnProperty(key)) { + dataQuery[key] = val; + reserved = true; + } + if (!reserved) { + otherQuery[key] = val; + } + }); + } + return { + cptQuery: cptQuery, + dataQuery: dataQuery, + otherQuery: otherQuery + }; + }; + ECEventProcessor.prototype.filter = function (eventType, query) { + // They should be assigned before each trigger call. + var eventInfo = this.eventInfo; + if (!eventInfo) { + return true; + } + var targetEl = eventInfo.targetEl; + var packedEvent = eventInfo.packedEvent; + var model = eventInfo.model; + var view = eventInfo.view; + // For event like 'globalout'. + if (!model || !view) { + return true; + } + var cptQuery = query.cptQuery; + var dataQuery = query.dataQuery; + return check(cptQuery, model, 'mainType') && check(cptQuery, model, 'subType') && check(cptQuery, model, 'index', 'componentIndex') && check(cptQuery, model, 'name') && check(cptQuery, model, 'id') && check(dataQuery, packedEvent, 'name') && check(dataQuery, packedEvent, 'dataIndex') && check(dataQuery, packedEvent, 'dataType') && (!view.filterForExposedEvent || view.filterForExposedEvent(eventType, query.otherQuery, targetEl, packedEvent)); + function check(query, host, prop, propOnHost) { + return query[prop] == null || host[propOnHost || prop] === query[prop]; + } + }; + ECEventProcessor.prototype.afterTrigger = function () { + // Make sure the eventInfo won't be used in next trigger. + this.eventInfo = null; + }; + return ECEventProcessor; + }(); + + var SYMBOL_PROPS_WITH_CB = ['symbol', 'symbolSize', 'symbolRotate', 'symbolOffset']; + var SYMBOL_PROPS = SYMBOL_PROPS_WITH_CB.concat(['symbolKeepAspect']); + // Encoding visual for all series include which is filtered for legend drawing + var seriesSymbolTask = { + createOnAllSeries: true, + // For legend. + performRawSeries: true, + reset: function (seriesModel, ecModel) { + var data = seriesModel.getData(); + if (seriesModel.legendIcon) { + data.setVisual('legendIcon', seriesModel.legendIcon); + } + if (!seriesModel.hasSymbolVisual) { + return; + } + var symbolOptions = {}; + var symbolOptionsCb = {}; + var hasCallback = false; + for (var i = 0; i < SYMBOL_PROPS_WITH_CB.length; i++) { + var symbolPropName = SYMBOL_PROPS_WITH_CB[i]; + var val = seriesModel.get(symbolPropName); + if (isFunction(val)) { + hasCallback = true; + symbolOptionsCb[symbolPropName] = val; + } else { + symbolOptions[symbolPropName] = val; + } + } + symbolOptions.symbol = symbolOptions.symbol || seriesModel.defaultSymbol; + data.setVisual(extend({ + legendIcon: seriesModel.legendIcon || symbolOptions.symbol, + symbolKeepAspect: seriesModel.get('symbolKeepAspect') + }, symbolOptions)); + // Only visible series has each data be visual encoded + if (ecModel.isSeriesFiltered(seriesModel)) { + return; + } + var symbolPropsCb = keys(symbolOptionsCb); + function dataEach(data, idx) { + var rawValue = seriesModel.getRawValue(idx); + var params = seriesModel.getDataParams(idx); + for (var i = 0; i < symbolPropsCb.length; i++) { + var symbolPropName = symbolPropsCb[i]; + data.setItemVisual(idx, symbolPropName, symbolOptionsCb[symbolPropName](rawValue, params)); + } + } + return { + dataEach: hasCallback ? dataEach : null + }; + } + }; + var dataSymbolTask = { + createOnAllSeries: true, + // For legend. + performRawSeries: true, + reset: function (seriesModel, ecModel) { + if (!seriesModel.hasSymbolVisual) { + return; + } + // Only visible series has each data be visual encoded + if (ecModel.isSeriesFiltered(seriesModel)) { + return; + } + var data = seriesModel.getData(); + function dataEach(data, idx) { + var itemModel = data.getItemModel(idx); + for (var i = 0; i < SYMBOL_PROPS.length; i++) { + var symbolPropName = SYMBOL_PROPS[i]; + var val = itemModel.getShallow(symbolPropName, true); + if (val != null) { + data.setItemVisual(idx, symbolPropName, val); + } + } + } + return { + dataEach: data.hasItemOption ? dataEach : null + }; + } + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function getItemVisualFromData(data, dataIndex, key) { + switch (key) { + case 'color': + var style = data.getItemVisual(dataIndex, 'style'); + return style[data.getVisual('drawType')]; + case 'opacity': + return data.getItemVisual(dataIndex, 'style').opacity; + case 'symbol': + case 'symbolSize': + case 'liftZ': + return data.getItemVisual(dataIndex, key); + default: + if ("development" !== 'production') { + console.warn("Unknown visual type " + key); + } + } + } + function getVisualFromData(data, key) { + switch (key) { + case 'color': + var style = data.getVisual('style'); + return style[data.getVisual('drawType')]; + case 'opacity': + return data.getVisual('style').opacity; + case 'symbol': + case 'symbolSize': + case 'liftZ': + return data.getVisual(key); + default: + if ("development" !== 'production') { + console.warn("Unknown visual type " + key); + } + } + } + function setItemVisualFromData(data, dataIndex, key, value) { + switch (key) { + case 'color': + // Make sure not sharing style object. + var style = data.ensureUniqueItemVisual(dataIndex, 'style'); + style[data.getVisual('drawType')] = value; + // Mark the color has been changed, not from palette anymore + data.setItemVisual(dataIndex, 'colorFromPalette', false); + break; + case 'opacity': + data.ensureUniqueItemVisual(dataIndex, 'style').opacity = value; + break; + case 'symbol': + case 'symbolSize': + case 'liftZ': + data.setItemVisual(dataIndex, key, value); + break; + default: + if ("development" !== 'production') { + console.warn("Unknown visual type " + key); + } + } + } + + // Legacy data selection action. + // Includes: pieSelect, pieUnSelect, pieToggleSelect, mapSelect, mapUnSelect, mapToggleSelect + function createLegacyDataSelectAction(seriesType, ecRegisterAction) { + function getSeriesIndices(ecModel, payload) { + var seriesIndices = []; + ecModel.eachComponent({ + mainType: 'series', + subType: seriesType, + query: payload + }, function (seriesModel) { + seriesIndices.push(seriesModel.seriesIndex); + }); + return seriesIndices; + } + each([[seriesType + 'ToggleSelect', 'toggleSelect'], [seriesType + 'Select', 'select'], [seriesType + 'UnSelect', 'unselect']], function (eventsMap) { + ecRegisterAction(eventsMap[0], function (payload, ecModel, api) { + payload = extend({}, payload); + if ("development" !== 'production') { + deprecateReplaceLog(payload.type, eventsMap[1]); + } + api.dispatchAction(extend(payload, { + type: eventsMap[1], + seriesIndex: getSeriesIndices(ecModel, payload) + })); + }); + }); + } + function handleSeriesLegacySelectEvents(type, eventPostfix, ecIns, ecModel, payload) { + var legacyEventName = type + eventPostfix; + if (!ecIns.isSilent(legacyEventName)) { + if ("development" !== 'production') { + deprecateLog("event " + legacyEventName + " is deprecated."); + } + ecModel.eachComponent({ + mainType: 'series', + subType: 'pie' + }, function (seriesModel) { + var seriesIndex = seriesModel.seriesIndex; + var selectedMap = seriesModel.option.selectedMap; + var selected = payload.selected; + for (var i = 0; i < selected.length; i++) { + if (selected[i].seriesIndex === seriesIndex) { + var data = seriesModel.getData(); + var dataIndex = queryDataIndex(data, payload.fromActionPayload); + ecIns.trigger(legacyEventName, { + type: legacyEventName, + seriesId: seriesModel.id, + name: isArray(dataIndex) ? data.getName(dataIndex[0]) : data.getName(dataIndex), + selected: isString(selectedMap) ? selectedMap : extend({}, selectedMap) + }); + } + } + }); + } + } + function handleLegacySelectEvents(messageCenter, ecIns, api) { + messageCenter.on('selectchanged', function (params) { + var ecModel = api.getModel(); + if (params.isFromClick) { + handleSeriesLegacySelectEvents('map', 'selectchanged', ecIns, ecModel, params); + handleSeriesLegacySelectEvents('pie', 'selectchanged', ecIns, ecModel, params); + } else if (params.fromAction === 'select') { + handleSeriesLegacySelectEvents('map', 'selected', ecIns, ecModel, params); + handleSeriesLegacySelectEvents('pie', 'selected', ecIns, ecModel, params); + } else if (params.fromAction === 'unselect') { + handleSeriesLegacySelectEvents('map', 'unselected', ecIns, ecModel, params); + handleSeriesLegacySelectEvents('pie', 'unselected', ecIns, ecModel, params); + } + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function findEventDispatcher(target, det, returnFirstMatch) { + var found; + while (target) { + if (det(target)) { + found = target; + if (returnFirstMatch) { + break; + } + } + target = target.__hostTarget || target.parent; + } + return found; + } + + var wmUniqueIndex = Math.round(Math.random() * 9); + var supportDefineProperty = typeof Object.defineProperty === 'function'; + var WeakMap = (function () { + function WeakMap() { + this._id = '__ec_inner_' + wmUniqueIndex++; + } + WeakMap.prototype.get = function (key) { + return this._guard(key)[this._id]; + }; + WeakMap.prototype.set = function (key, value) { + var target = this._guard(key); + if (supportDefineProperty) { + Object.defineProperty(target, this._id, { + value: value, + enumerable: false, + configurable: true + }); + } + else { + target[this._id] = value; + } + return this; + }; + WeakMap.prototype["delete"] = function (key) { + if (this.has(key)) { + delete this._guard(key)[this._id]; + return true; + } + return false; + }; + WeakMap.prototype.has = function (key) { + return !!this._guard(key)[this._id]; + }; + WeakMap.prototype._guard = function (key) { + if (key !== Object(key)) { + throw TypeError('Value of WeakMap is not a non-null object.'); + } + return key; + }; + return WeakMap; + }()); + + /** + * Triangle shape + * @inner + */ + var Triangle = Path.extend({ + type: 'triangle', + shape: { + cx: 0, + cy: 0, + width: 0, + height: 0 + }, + buildPath: function (path, shape) { + var cx = shape.cx; + var cy = shape.cy; + var width = shape.width / 2; + var height = shape.height / 2; + path.moveTo(cx, cy - height); + path.lineTo(cx + width, cy + height); + path.lineTo(cx - width, cy + height); + path.closePath(); + } + }); + /** + * Diamond shape + * @inner + */ + var Diamond = Path.extend({ + type: 'diamond', + shape: { + cx: 0, + cy: 0, + width: 0, + height: 0 + }, + buildPath: function (path, shape) { + var cx = shape.cx; + var cy = shape.cy; + var width = shape.width / 2; + var height = shape.height / 2; + path.moveTo(cx, cy - height); + path.lineTo(cx + width, cy); + path.lineTo(cx, cy + height); + path.lineTo(cx - width, cy); + path.closePath(); + } + }); + /** + * Pin shape + * @inner + */ + var Pin = Path.extend({ + type: 'pin', + shape: { + // x, y on the cusp + x: 0, + y: 0, + width: 0, + height: 0 + }, + buildPath: function (path, shape) { + var x = shape.x; + var y = shape.y; + var w = shape.width / 5 * 3; + // Height must be larger than width + var h = Math.max(w, shape.height); + var r = w / 2; + // Dist on y with tangent point and circle center + var dy = r * r / (h - r); + var cy = y - h + r + dy; + var angle = Math.asin(dy / r); + // Dist on x with tangent point and circle center + var dx = Math.cos(angle) * r; + var tanX = Math.sin(angle); + var tanY = Math.cos(angle); + var cpLen = r * 0.6; + var cpLen2 = r * 0.7; + path.moveTo(x - dx, cy + dy); + path.arc(x, cy, r, Math.PI - angle, Math.PI * 2 + angle); + path.bezierCurveTo(x + dx - tanX * cpLen, cy + dy + tanY * cpLen, x, y - cpLen2, x, y); + path.bezierCurveTo(x, y - cpLen2, x - dx + tanX * cpLen, cy + dy + tanY * cpLen, x - dx, cy + dy); + path.closePath(); + } + }); + /** + * Arrow shape + * @inner + */ + var Arrow = Path.extend({ + type: 'arrow', + shape: { + x: 0, + y: 0, + width: 0, + height: 0 + }, + buildPath: function (ctx, shape) { + var height = shape.height; + var width = shape.width; + var x = shape.x; + var y = shape.y; + var dx = width / 3 * 2; + ctx.moveTo(x, y); + ctx.lineTo(x + dx, y + height); + ctx.lineTo(x, y + height / 4 * 3); + ctx.lineTo(x - dx, y + height); + ctx.lineTo(x, y); + ctx.closePath(); + } + }); + /** + * Map of path constructors + */ + // TODO Use function to build symbol path. + var symbolCtors = { + line: Line, + rect: Rect, + roundRect: Rect, + square: Rect, + circle: Circle, + diamond: Diamond, + pin: Pin, + arrow: Arrow, + triangle: Triangle + }; + var symbolShapeMakers = { + line: function (x, y, w, h, shape) { + shape.x1 = x; + shape.y1 = y + h / 2; + shape.x2 = x + w; + shape.y2 = y + h / 2; + }, + rect: function (x, y, w, h, shape) { + shape.x = x; + shape.y = y; + shape.width = w; + shape.height = h; + }, + roundRect: function (x, y, w, h, shape) { + shape.x = x; + shape.y = y; + shape.width = w; + shape.height = h; + shape.r = Math.min(w, h) / 4; + }, + square: function (x, y, w, h, shape) { + var size = Math.min(w, h); + shape.x = x; + shape.y = y; + shape.width = size; + shape.height = size; + }, + circle: function (x, y, w, h, shape) { + // Put circle in the center of square + shape.cx = x + w / 2; + shape.cy = y + h / 2; + shape.r = Math.min(w, h) / 2; + }, + diamond: function (x, y, w, h, shape) { + shape.cx = x + w / 2; + shape.cy = y + h / 2; + shape.width = w; + shape.height = h; + }, + pin: function (x, y, w, h, shape) { + shape.x = x + w / 2; + shape.y = y + h / 2; + shape.width = w; + shape.height = h; + }, + arrow: function (x, y, w, h, shape) { + shape.x = x + w / 2; + shape.y = y + h / 2; + shape.width = w; + shape.height = h; + }, + triangle: function (x, y, w, h, shape) { + shape.cx = x + w / 2; + shape.cy = y + h / 2; + shape.width = w; + shape.height = h; + } + }; + var symbolBuildProxies = {}; + each(symbolCtors, function (Ctor, name) { + symbolBuildProxies[name] = new Ctor(); + }); + var SymbolClz = Path.extend({ + type: 'symbol', + shape: { + symbolType: '', + x: 0, + y: 0, + width: 0, + height: 0 + }, + calculateTextPosition: function (out, config, rect) { + var res = calculateTextPosition(out, config, rect); + var shape = this.shape; + if (shape && shape.symbolType === 'pin' && config.position === 'inside') { + res.y = rect.y + rect.height * 0.4; + } + return res; + }, + buildPath: function (ctx, shape, inBundle) { + var symbolType = shape.symbolType; + if (symbolType !== 'none') { + var proxySymbol = symbolBuildProxies[symbolType]; + if (!proxySymbol) { + // Default rect + symbolType = 'rect'; + proxySymbol = symbolBuildProxies[symbolType]; + } + symbolShapeMakers[symbolType](shape.x, shape.y, shape.width, shape.height, proxySymbol.shape); + proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle); + } + } + }); + // Provide setColor helper method to avoid determine if set the fill or stroke outside + function symbolPathSetColor(color, innerColor) { + if (this.type !== 'image') { + var symbolStyle = this.style; + if (this.__isEmptyBrush) { + symbolStyle.stroke = color; + symbolStyle.fill = innerColor || '#fff'; + // TODO Same width with lineStyle in LineView + symbolStyle.lineWidth = 2; + } else if (this.shape.symbolType === 'line') { + symbolStyle.stroke = color; + } else { + symbolStyle.fill = color; + } + this.markRedraw(); + } + } + /** + * Create a symbol element with given symbol configuration: shape, x, y, width, height, color + */ + function createSymbol(symbolType, x, y, w, h, color, + // whether to keep the ratio of w/h, + keepAspect) { + // TODO Support image object, DynamicImage. + var isEmpty = symbolType.indexOf('empty') === 0; + if (isEmpty) { + symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6); + } + var symbolPath; + if (symbolType.indexOf('image://') === 0) { + symbolPath = makeImage(symbolType.slice(8), new BoundingRect(x, y, w, h), keepAspect ? 'center' : 'cover'); + } else if (symbolType.indexOf('path://') === 0) { + symbolPath = makePath(symbolType.slice(7), {}, new BoundingRect(x, y, w, h), keepAspect ? 'center' : 'cover'); + } else { + symbolPath = new SymbolClz({ + shape: { + symbolType: symbolType, + x: x, + y: y, + width: w, + height: h + } + }); + } + symbolPath.__isEmptyBrush = isEmpty; + // TODO Should deprecate setColor + symbolPath.setColor = symbolPathSetColor; + if (color) { + symbolPath.setColor(color); + } + return symbolPath; + } + function normalizeSymbolSize(symbolSize) { + if (!isArray(symbolSize)) { + symbolSize = [+symbolSize, +symbolSize]; + } + return [symbolSize[0] || 0, symbolSize[1] || 0]; + } + function normalizeSymbolOffset(symbolOffset, symbolSize) { + if (symbolOffset == null) { + return; + } + if (!isArray(symbolOffset)) { + symbolOffset = [symbolOffset, symbolOffset]; + } + return [parsePercent$1(symbolOffset[0], symbolSize[0]) || 0, parsePercent$1(retrieve2(symbolOffset[1], symbolOffset[0]), symbolSize[1]) || 0]; + } + + function isSafeNum(num) { + return isFinite(num); + } + function createLinearGradient(ctx, obj, rect) { + var x = obj.x == null ? 0 : obj.x; + var x2 = obj.x2 == null ? 1 : obj.x2; + var y = obj.y == null ? 0 : obj.y; + var y2 = obj.y2 == null ? 0 : obj.y2; + if (!obj.global) { + x = x * rect.width + rect.x; + x2 = x2 * rect.width + rect.x; + y = y * rect.height + rect.y; + y2 = y2 * rect.height + rect.y; + } + x = isSafeNum(x) ? x : 0; + x2 = isSafeNum(x2) ? x2 : 1; + y = isSafeNum(y) ? y : 0; + y2 = isSafeNum(y2) ? y2 : 0; + var canvasGradient = ctx.createLinearGradient(x, y, x2, y2); + return canvasGradient; + } + function createRadialGradient(ctx, obj, rect) { + var width = rect.width; + var height = rect.height; + var min = Math.min(width, height); + var x = obj.x == null ? 0.5 : obj.x; + var y = obj.y == null ? 0.5 : obj.y; + var r = obj.r == null ? 0.5 : obj.r; + if (!obj.global) { + x = x * width + rect.x; + y = y * height + rect.y; + r = r * min; + } + x = isSafeNum(x) ? x : 0.5; + y = isSafeNum(y) ? y : 0.5; + r = r >= 0 && isSafeNum(r) ? r : 0.5; + var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r); + return canvasGradient; + } + function getCanvasGradient(ctx, obj, rect) { + var canvasGradient = obj.type === 'radial' + ? createRadialGradient(ctx, obj, rect) + : createLinearGradient(ctx, obj, rect); + var colorStops = obj.colorStops; + for (var i = 0; i < colorStops.length; i++) { + canvasGradient.addColorStop(colorStops[i].offset, colorStops[i].color); + } + return canvasGradient; + } + function isClipPathChanged(clipPaths, prevClipPaths) { + if (clipPaths === prevClipPaths || (!clipPaths && !prevClipPaths)) { + return false; + } + if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) { + return true; + } + for (var i = 0; i < clipPaths.length; i++) { + if (clipPaths[i] !== prevClipPaths[i]) { + return true; + } + } + return false; + } + function parseInt10(val) { + return parseInt(val, 10); + } + function getSize(root, whIdx, opts) { + var wh = ['width', 'height'][whIdx]; + var cwh = ['clientWidth', 'clientHeight'][whIdx]; + var plt = ['paddingLeft', 'paddingTop'][whIdx]; + var prb = ['paddingRight', 'paddingBottom'][whIdx]; + if (opts[wh] != null && opts[wh] !== 'auto') { + return parseFloat(opts[wh]); + } + var stl = document.defaultView.getComputedStyle(root); + return ((root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh])) + - (parseInt10(stl[plt]) || 0) + - (parseInt10(stl[prb]) || 0)) | 0; + } + + function normalizeLineDash(lineType, lineWidth) { + if (!lineType || lineType === 'solid' || !(lineWidth > 0)) { + return null; + } + return lineType === 'dashed' + ? [4 * lineWidth, 2 * lineWidth] + : lineType === 'dotted' + ? [lineWidth] + : isNumber(lineType) + ? [lineType] : isArray(lineType) ? lineType : null; + } + function getLineDash(el) { + var style = el.style; + var lineDash = style.lineDash && style.lineWidth > 0 && normalizeLineDash(style.lineDash, style.lineWidth); + var lineDashOffset = style.lineDashOffset; + if (lineDash) { + var lineScale_1 = (style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1; + if (lineScale_1 && lineScale_1 !== 1) { + lineDash = map(lineDash, function (rawVal) { + return rawVal / lineScale_1; + }); + lineDashOffset /= lineScale_1; + } + } + return [lineDash, lineDashOffset]; + } + + var pathProxyForDraw = new PathProxy(true); + function styleHasStroke(style) { + var stroke = style.stroke; + return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0)); + } + function isValidStrokeFillStyle(strokeOrFill) { + return typeof strokeOrFill === 'string' && strokeOrFill !== 'none'; + } + function styleHasFill(style) { + var fill = style.fill; + return fill != null && fill !== 'none'; + } + function doFillPath(ctx, style) { + if (style.fillOpacity != null && style.fillOpacity !== 1) { + var originalGlobalAlpha = ctx.globalAlpha; + ctx.globalAlpha = style.fillOpacity * style.opacity; + ctx.fill(); + ctx.globalAlpha = originalGlobalAlpha; + } + else { + ctx.fill(); + } + } + function doStrokePath(ctx, style) { + if (style.strokeOpacity != null && style.strokeOpacity !== 1) { + var originalGlobalAlpha = ctx.globalAlpha; + ctx.globalAlpha = style.strokeOpacity * style.opacity; + ctx.stroke(); + ctx.globalAlpha = originalGlobalAlpha; + } + else { + ctx.stroke(); + } + } + function createCanvasPattern(ctx, pattern, el) { + var image = createOrUpdateImage(pattern.image, pattern.__image, el); + if (isImageReady(image)) { + var canvasPattern = ctx.createPattern(image, pattern.repeat || 'repeat'); + if (typeof DOMMatrix === 'function' + && canvasPattern + && canvasPattern.setTransform) { + var matrix = new DOMMatrix(); + matrix.translateSelf((pattern.x || 0), (pattern.y || 0)); + matrix.rotateSelf(0, 0, (pattern.rotation || 0) * RADIAN_TO_DEGREE); + matrix.scaleSelf((pattern.scaleX || 1), (pattern.scaleY || 1)); + canvasPattern.setTransform(matrix); + } + return canvasPattern; + } + } + function brushPath(ctx, el, style, inBatch) { + var _a; + var hasStroke = styleHasStroke(style); + var hasFill = styleHasFill(style); + var strokePercent = style.strokePercent; + var strokePart = strokePercent < 1; + var firstDraw = !el.path; + if ((!el.silent || strokePart) && firstDraw) { + el.createPathProxy(); + } + var path = el.path || pathProxyForDraw; + var dirtyFlag = el.__dirty; + if (!inBatch) { + var fill = style.fill; + var stroke = style.stroke; + var hasFillGradient = hasFill && !!fill.colorStops; + var hasStrokeGradient = hasStroke && !!stroke.colorStops; + var hasFillPattern = hasFill && !!fill.image; + var hasStrokePattern = hasStroke && !!stroke.image; + var fillGradient = void 0; + var strokeGradient = void 0; + var fillPattern = void 0; + var strokePattern = void 0; + var rect = void 0; + if (hasFillGradient || hasStrokeGradient) { + rect = el.getBoundingRect(); + } + if (hasFillGradient) { + fillGradient = dirtyFlag + ? getCanvasGradient(ctx, fill, rect) + : el.__canvasFillGradient; + el.__canvasFillGradient = fillGradient; + } + if (hasStrokeGradient) { + strokeGradient = dirtyFlag + ? getCanvasGradient(ctx, stroke, rect) + : el.__canvasStrokeGradient; + el.__canvasStrokeGradient = strokeGradient; + } + if (hasFillPattern) { + fillPattern = (dirtyFlag || !el.__canvasFillPattern) + ? createCanvasPattern(ctx, fill, el) + : el.__canvasFillPattern; + el.__canvasFillPattern = fillPattern; + } + if (hasStrokePattern) { + strokePattern = (dirtyFlag || !el.__canvasStrokePattern) + ? createCanvasPattern(ctx, stroke, el) + : el.__canvasStrokePattern; + el.__canvasStrokePattern = fillPattern; + } + if (hasFillGradient) { + ctx.fillStyle = fillGradient; + } + else if (hasFillPattern) { + if (fillPattern) { + ctx.fillStyle = fillPattern; + } + else { + hasFill = false; + } + } + if (hasStrokeGradient) { + ctx.strokeStyle = strokeGradient; + } + else if (hasStrokePattern) { + if (strokePattern) { + ctx.strokeStyle = strokePattern; + } + else { + hasStroke = false; + } + } + } + var scale = el.getGlobalScale(); + path.setScale(scale[0], scale[1], el.segmentIgnoreThreshold); + var lineDash; + var lineDashOffset; + if (ctx.setLineDash && style.lineDash) { + _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1]; + } + var needsRebuild = true; + if (firstDraw || (dirtyFlag & SHAPE_CHANGED_BIT)) { + path.setDPR(ctx.dpr); + if (strokePart) { + path.setContext(null); + } + else { + path.setContext(ctx); + needsRebuild = false; + } + path.reset(); + el.buildPath(path, el.shape, inBatch); + path.toStatic(); + el.pathUpdated(); + } + if (needsRebuild) { + path.rebuildPath(ctx, strokePart ? strokePercent : 1); + } + if (lineDash) { + ctx.setLineDash(lineDash); + ctx.lineDashOffset = lineDashOffset; + } + if (!inBatch) { + if (style.strokeFirst) { + if (hasStroke) { + doStrokePath(ctx, style); + } + if (hasFill) { + doFillPath(ctx, style); + } + } + else { + if (hasFill) { + doFillPath(ctx, style); + } + if (hasStroke) { + doStrokePath(ctx, style); + } + } + } + if (lineDash) { + ctx.setLineDash([]); + } + } + function brushImage(ctx, el, style) { + var image = el.__image = createOrUpdateImage(style.image, el.__image, el, el.onload); + if (!image || !isImageReady(image)) { + return; + } + var x = style.x || 0; + var y = style.y || 0; + var width = el.getWidth(); + var height = el.getHeight(); + var aspect = image.width / image.height; + if (width == null && height != null) { + width = height * aspect; + } + else if (height == null && width != null) { + height = width / aspect; + } + else if (width == null && height == null) { + width = image.width; + height = image.height; + } + if (style.sWidth && style.sHeight) { + var sx = style.sx || 0; + var sy = style.sy || 0; + ctx.drawImage(image, sx, sy, style.sWidth, style.sHeight, x, y, width, height); + } + else if (style.sx && style.sy) { + var sx = style.sx; + var sy = style.sy; + var sWidth = width - sx; + var sHeight = height - sy; + ctx.drawImage(image, sx, sy, sWidth, sHeight, x, y, width, height); + } + else { + ctx.drawImage(image, x, y, width, height); + } + } + function brushText(ctx, el, style) { + var _a; + var text = style.text; + text != null && (text += ''); + if (text) { + ctx.font = style.font || DEFAULT_FONT; + ctx.textAlign = style.textAlign; + ctx.textBaseline = style.textBaseline; + var lineDash = void 0; + var lineDashOffset = void 0; + if (ctx.setLineDash && style.lineDash) { + _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1]; + } + if (lineDash) { + ctx.setLineDash(lineDash); + ctx.lineDashOffset = lineDashOffset; + } + if (style.strokeFirst) { + if (styleHasStroke(style)) { + ctx.strokeText(text, style.x, style.y); + } + if (styleHasFill(style)) { + ctx.fillText(text, style.x, style.y); + } + } + else { + if (styleHasFill(style)) { + ctx.fillText(text, style.x, style.y); + } + if (styleHasStroke(style)) { + ctx.strokeText(text, style.x, style.y); + } + } + if (lineDash) { + ctx.setLineDash([]); + } + } + } + var SHADOW_NUMBER_PROPS = ['shadowBlur', 'shadowOffsetX', 'shadowOffsetY']; + var STROKE_PROPS = [ + ['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10] + ]; + function bindCommonProps(ctx, style, prevStyle, forceSetAll, scope) { + var styleChanged = false; + if (!forceSetAll) { + prevStyle = prevStyle || {}; + if (style === prevStyle) { + return false; + } + } + if (forceSetAll || style.opacity !== prevStyle.opacity) { + flushPathDrawn(ctx, scope); + styleChanged = true; + var opacity = Math.max(Math.min(style.opacity, 1), 0); + ctx.globalAlpha = isNaN(opacity) ? DEFAULT_COMMON_STYLE.opacity : opacity; + } + if (forceSetAll || style.blend !== prevStyle.blend) { + if (!styleChanged) { + flushPathDrawn(ctx, scope); + styleChanged = true; + } + ctx.globalCompositeOperation = style.blend || DEFAULT_COMMON_STYLE.blend; + } + for (var i = 0; i < SHADOW_NUMBER_PROPS.length; i++) { + var propName = SHADOW_NUMBER_PROPS[i]; + if (forceSetAll || style[propName] !== prevStyle[propName]) { + if (!styleChanged) { + flushPathDrawn(ctx, scope); + styleChanged = true; + } + ctx[propName] = ctx.dpr * (style[propName] || 0); + } + } + if (forceSetAll || style.shadowColor !== prevStyle.shadowColor) { + if (!styleChanged) { + flushPathDrawn(ctx, scope); + styleChanged = true; + } + ctx.shadowColor = style.shadowColor || DEFAULT_COMMON_STYLE.shadowColor; + } + return styleChanged; + } + function bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetAll, scope) { + var style = getStyle(el, scope.inHover); + var prevStyle = forceSetAll + ? null + : (prevEl && getStyle(prevEl, scope.inHover) || {}); + if (style === prevStyle) { + return false; + } + var styleChanged = bindCommonProps(ctx, style, prevStyle, forceSetAll, scope); + if (forceSetAll || style.fill !== prevStyle.fill) { + if (!styleChanged) { + flushPathDrawn(ctx, scope); + styleChanged = true; + } + isValidStrokeFillStyle(style.fill) && (ctx.fillStyle = style.fill); + } + if (forceSetAll || style.stroke !== prevStyle.stroke) { + if (!styleChanged) { + flushPathDrawn(ctx, scope); + styleChanged = true; + } + isValidStrokeFillStyle(style.stroke) && (ctx.strokeStyle = style.stroke); + } + if (forceSetAll || style.opacity !== prevStyle.opacity) { + if (!styleChanged) { + flushPathDrawn(ctx, scope); + styleChanged = true; + } + ctx.globalAlpha = style.opacity == null ? 1 : style.opacity; + } + if (el.hasStroke()) { + var lineWidth = style.lineWidth; + var newLineWidth = lineWidth / ((style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1); + if (ctx.lineWidth !== newLineWidth) { + if (!styleChanged) { + flushPathDrawn(ctx, scope); + styleChanged = true; + } + ctx.lineWidth = newLineWidth; + } + } + for (var i = 0; i < STROKE_PROPS.length; i++) { + var prop = STROKE_PROPS[i]; + var propName = prop[0]; + if (forceSetAll || style[propName] !== prevStyle[propName]) { + if (!styleChanged) { + flushPathDrawn(ctx, scope); + styleChanged = true; + } + ctx[propName] = style[propName] || prop[1]; + } + } + return styleChanged; + } + function bindImageStyle(ctx, el, prevEl, forceSetAll, scope) { + return bindCommonProps(ctx, getStyle(el, scope.inHover), prevEl && getStyle(prevEl, scope.inHover), forceSetAll, scope); + } + function setContextTransform(ctx, el) { + var m = el.transform; + var dpr = ctx.dpr || 1; + if (m) { + ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]); + } + else { + ctx.setTransform(dpr, 0, 0, dpr, 0, 0); + } + } + function updateClipStatus(clipPaths, ctx, scope) { + var allClipped = false; + for (var i = 0; i < clipPaths.length; i++) { + var clipPath = clipPaths[i]; + allClipped = allClipped || clipPath.isZeroArea(); + setContextTransform(ctx, clipPath); + ctx.beginPath(); + clipPath.buildPath(ctx, clipPath.shape); + ctx.clip(); + } + scope.allClipped = allClipped; + } + function isTransformChanged(m0, m1) { + if (m0 && m1) { + return m0[0] !== m1[0] + || m0[1] !== m1[1] + || m0[2] !== m1[2] + || m0[3] !== m1[3] + || m0[4] !== m1[4] + || m0[5] !== m1[5]; + } + else if (!m0 && !m1) { + return false; + } + return true; + } + var DRAW_TYPE_PATH = 1; + var DRAW_TYPE_IMAGE = 2; + var DRAW_TYPE_TEXT = 3; + var DRAW_TYPE_INCREMENTAL = 4; + function canPathBatch(style) { + var hasFill = styleHasFill(style); + var hasStroke = styleHasStroke(style); + return !(style.lineDash + || !(+hasFill ^ +hasStroke) + || (hasFill && typeof style.fill !== 'string') + || (hasStroke && typeof style.stroke !== 'string') + || style.strokePercent < 1 + || style.strokeOpacity < 1 + || style.fillOpacity < 1); + } + function flushPathDrawn(ctx, scope) { + scope.batchFill && ctx.fill(); + scope.batchStroke && ctx.stroke(); + scope.batchFill = ''; + scope.batchStroke = ''; + } + function getStyle(el, inHover) { + return inHover ? (el.__hoverStyle || el.style) : el.style; + } + function brushSingle(ctx, el) { + brush(ctx, el, { inHover: false, viewWidth: 0, viewHeight: 0 }, true); + } + function brush(ctx, el, scope, isLast) { + var m = el.transform; + if (!el.shouldBePainted(scope.viewWidth, scope.viewHeight, false, false)) { + el.__dirty &= ~REDRAW_BIT; + el.__isRendered = false; + return; + } + var clipPaths = el.__clipPaths; + var prevElClipPaths = scope.prevElClipPaths; + var forceSetTransform = false; + var forceSetStyle = false; + if (!prevElClipPaths || isClipPathChanged(clipPaths, prevElClipPaths)) { + if (prevElClipPaths && prevElClipPaths.length) { + flushPathDrawn(ctx, scope); + ctx.restore(); + forceSetStyle = forceSetTransform = true; + scope.prevElClipPaths = null; + scope.allClipped = false; + scope.prevEl = null; + } + if (clipPaths && clipPaths.length) { + flushPathDrawn(ctx, scope); + ctx.save(); + updateClipStatus(clipPaths, ctx, scope); + forceSetTransform = true; + } + scope.prevElClipPaths = clipPaths; + } + if (scope.allClipped) { + el.__isRendered = false; + return; + } + el.beforeBrush && el.beforeBrush(); + el.innerBeforeBrush(); + var prevEl = scope.prevEl; + if (!prevEl) { + forceSetStyle = forceSetTransform = true; + } + var canBatchPath = el instanceof Path + && el.autoBatch + && canPathBatch(el.style); + if (forceSetTransform || isTransformChanged(m, prevEl.transform)) { + flushPathDrawn(ctx, scope); + setContextTransform(ctx, el); + } + else if (!canBatchPath) { + flushPathDrawn(ctx, scope); + } + var style = getStyle(el, scope.inHover); + if (el instanceof Path) { + if (scope.lastDrawType !== DRAW_TYPE_PATH) { + forceSetStyle = true; + scope.lastDrawType = DRAW_TYPE_PATH; + } + bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope); + if (!canBatchPath || (!scope.batchFill && !scope.batchStroke)) { + ctx.beginPath(); + } + brushPath(ctx, el, style, canBatchPath); + if (canBatchPath) { + scope.batchFill = style.fill || ''; + scope.batchStroke = style.stroke || ''; + } + } + else { + if (el instanceof TSpan) { + if (scope.lastDrawType !== DRAW_TYPE_TEXT) { + forceSetStyle = true; + scope.lastDrawType = DRAW_TYPE_TEXT; + } + bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope); + brushText(ctx, el, style); + } + else if (el instanceof ZRImage) { + if (scope.lastDrawType !== DRAW_TYPE_IMAGE) { + forceSetStyle = true; + scope.lastDrawType = DRAW_TYPE_IMAGE; + } + bindImageStyle(ctx, el, prevEl, forceSetStyle, scope); + brushImage(ctx, el, style); + } + else if (el.getTemporalDisplayables) { + if (scope.lastDrawType !== DRAW_TYPE_INCREMENTAL) { + forceSetStyle = true; + scope.lastDrawType = DRAW_TYPE_INCREMENTAL; + } + brushIncremental(ctx, el, scope); + } + } + if (canBatchPath && isLast) { + flushPathDrawn(ctx, scope); + } + el.innerAfterBrush(); + el.afterBrush && el.afterBrush(); + scope.prevEl = el; + el.__dirty = 0; + el.__isRendered = true; + } + function brushIncremental(ctx, el, scope) { + var displayables = el.getDisplayables(); + var temporalDisplayables = el.getTemporalDisplayables(); + ctx.save(); + var innerScope = { + prevElClipPaths: null, + prevEl: null, + allClipped: false, + viewWidth: scope.viewWidth, + viewHeight: scope.viewHeight, + inHover: scope.inHover + }; + var i; + var len; + for (i = el.getCursor(), len = displayables.length; i < len; i++) { + var displayable = displayables[i]; + displayable.beforeBrush && displayable.beforeBrush(); + displayable.innerBeforeBrush(); + brush(ctx, displayable, innerScope, i === len - 1); + displayable.innerAfterBrush(); + displayable.afterBrush && displayable.afterBrush(); + innerScope.prevEl = displayable; + } + for (var i_1 = 0, len_1 = temporalDisplayables.length; i_1 < len_1; i_1++) { + var displayable = temporalDisplayables[i_1]; + displayable.beforeBrush && displayable.beforeBrush(); + displayable.innerBeforeBrush(); + brush(ctx, displayable, innerScope, i_1 === len_1 - 1); + displayable.innerAfterBrush(); + displayable.afterBrush && displayable.afterBrush(); + innerScope.prevEl = displayable; + } + el.clearTemporalDisplayables(); + el.notClear = true; + ctx.restore(); + } + + var decalMap = new WeakMap(); + var decalCache = new LRU(100); + var decalKeys = ['symbol', 'symbolSize', 'symbolKeepAspect', 'color', 'backgroundColor', 'dashArrayX', 'dashArrayY', 'maxTileWidth', 'maxTileHeight']; + /** + * Create or update pattern image from decal options + * + * @param {InnerDecalObject | 'none'} decalObject decal options, 'none' if no decal + * @return {Pattern} pattern with generated image, null if no decal + */ + function createOrUpdatePatternFromDecal(decalObject, api) { + if (decalObject === 'none') { + return null; + } + var dpr = api.getDevicePixelRatio(); + var zr = api.getZr(); + var isSVG = zr.painter.type === 'svg'; + if (decalObject.dirty) { + decalMap["delete"](decalObject); + } + var oldPattern = decalMap.get(decalObject); + if (oldPattern) { + return oldPattern; + } + var decalOpt = defaults(decalObject, { + symbol: 'rect', + symbolSize: 1, + symbolKeepAspect: true, + color: 'rgba(0, 0, 0, 0.2)', + backgroundColor: null, + dashArrayX: 5, + dashArrayY: 5, + rotation: 0, + maxTileWidth: 512, + maxTileHeight: 512 + }); + if (decalOpt.backgroundColor === 'none') { + decalOpt.backgroundColor = null; + } + var pattern = { + repeat: 'repeat' + }; + setPatternnSource(pattern); + pattern.rotation = decalOpt.rotation; + pattern.scaleX = pattern.scaleY = isSVG ? 1 : 1 / dpr; + decalMap.set(decalObject, pattern); + decalObject.dirty = false; + return pattern; + function setPatternnSource(pattern) { + var keys = [dpr]; + var isValidKey = true; + for (var i = 0; i < decalKeys.length; ++i) { + var value = decalOpt[decalKeys[i]]; + if (value != null && !isArray(value) && !isString(value) && !isNumber(value) && typeof value !== 'boolean') { + isValidKey = false; + break; + } + keys.push(value); + } + var cacheKey; + if (isValidKey) { + cacheKey = keys.join(',') + (isSVG ? '-svg' : ''); + var cache = decalCache.get(cacheKey); + if (cache) { + isSVG ? pattern.svgElement = cache : pattern.image = cache; + } + } + var dashArrayX = normalizeDashArrayX(decalOpt.dashArrayX); + var dashArrayY = normalizeDashArrayY(decalOpt.dashArrayY); + var symbolArray = normalizeSymbolArray(decalOpt.symbol); + var lineBlockLengthsX = getLineBlockLengthX(dashArrayX); + var lineBlockLengthY = getLineBlockLengthY(dashArrayY); + var canvas = !isSVG && platformApi.createCanvas(); + var svgRoot = isSVG && { + tag: 'g', + attrs: {}, + key: 'dcl', + children: [] + }; + var pSize = getPatternSize(); + var ctx; + if (canvas) { + canvas.width = pSize.width * dpr; + canvas.height = pSize.height * dpr; + ctx = canvas.getContext('2d'); + } + brushDecal(); + if (isValidKey) { + decalCache.put(cacheKey, canvas || svgRoot); + } + pattern.image = canvas; + pattern.svgElement = svgRoot; + pattern.svgWidth = pSize.width; + pattern.svgHeight = pSize.height; + /** + * Get minimum length that can make a repeatable pattern. + * + * @return {Object} pattern width and height + */ + function getPatternSize() { + /** + * For example, if dash is [[3, 2], [2, 1]] for X, it looks like + * |--- --- --- --- --- ... + * |-- -- -- -- -- -- -- -- ... + * |--- --- --- --- --- ... + * |-- -- -- -- -- -- -- -- ... + * So the minimum length of X is 15, + * which is the least common multiple of `3 + 2` and `2 + 1` + * |--- --- --- |--- --- ... + * |-- -- -- -- -- |-- -- -- ... + */ + var width = 1; + for (var i = 0, xlen = lineBlockLengthsX.length; i < xlen; ++i) { + width = getLeastCommonMultiple(width, lineBlockLengthsX[i]); + } + var symbolRepeats = 1; + for (var i = 0, xlen = symbolArray.length; i < xlen; ++i) { + symbolRepeats = getLeastCommonMultiple(symbolRepeats, symbolArray[i].length); + } + width *= symbolRepeats; + var height = lineBlockLengthY * lineBlockLengthsX.length * symbolArray.length; + if ("development" !== 'production') { + var warn = function (attrName) { + /* eslint-disable-next-line */ + console.warn("Calculated decal size is greater than " + attrName + " due to decal option settings so " + attrName + " is used for the decal size. Please consider changing the decal option to make a smaller decal or set " + attrName + " to be larger to avoid incontinuity."); + }; + if (width > decalOpt.maxTileWidth) { + warn('maxTileWidth'); + } + if (height > decalOpt.maxTileHeight) { + warn('maxTileHeight'); + } + } + return { + width: Math.max(1, Math.min(width, decalOpt.maxTileWidth)), + height: Math.max(1, Math.min(height, decalOpt.maxTileHeight)) + }; + } + function brushDecal() { + if (ctx) { + ctx.clearRect(0, 0, canvas.width, canvas.height); + if (decalOpt.backgroundColor) { + ctx.fillStyle = decalOpt.backgroundColor; + ctx.fillRect(0, 0, canvas.width, canvas.height); + } + } + var ySum = 0; + for (var i = 0; i < dashArrayY.length; ++i) { + ySum += dashArrayY[i]; + } + if (ySum <= 0) { + // dashArrayY is 0, draw nothing + return; + } + var y = -lineBlockLengthY; + var yId = 0; + var yIdTotal = 0; + var xId0 = 0; + while (y < pSize.height) { + if (yId % 2 === 0) { + var symbolYId = yIdTotal / 2 % symbolArray.length; + var x = 0; + var xId1 = 0; + var xId1Total = 0; + while (x < pSize.width * 2) { + var xSum = 0; + for (var i = 0; i < dashArrayX[xId0].length; ++i) { + xSum += dashArrayX[xId0][i]; + } + if (xSum <= 0) { + // Skip empty line + break; + } + // E.g., [15, 5, 20, 5] draws only for 15 and 20 + if (xId1 % 2 === 0) { + var size = (1 - decalOpt.symbolSize) * 0.5; + var left = x + dashArrayX[xId0][xId1] * size; + var top_1 = y + dashArrayY[yId] * size; + var width = dashArrayX[xId0][xId1] * decalOpt.symbolSize; + var height = dashArrayY[yId] * decalOpt.symbolSize; + var symbolXId = xId1Total / 2 % symbolArray[symbolYId].length; + brushSymbol(left, top_1, width, height, symbolArray[symbolYId][symbolXId]); + } + x += dashArrayX[xId0][xId1]; + ++xId1Total; + ++xId1; + if (xId1 === dashArrayX[xId0].length) { + xId1 = 0; + } + } + ++xId0; + if (xId0 === dashArrayX.length) { + xId0 = 0; + } + } + y += dashArrayY[yId]; + ++yIdTotal; + ++yId; + if (yId === dashArrayY.length) { + yId = 0; + } + } + function brushSymbol(x, y, width, height, symbolType) { + var scale = isSVG ? 1 : dpr; + var symbol = createSymbol(symbolType, x * scale, y * scale, width * scale, height * scale, decalOpt.color, decalOpt.symbolKeepAspect); + if (isSVG) { + var symbolVNode = zr.painter.renderOneToVNode(symbol); + if (symbolVNode) { + svgRoot.children.push(symbolVNode); + } + } else { + // Paint to canvas for all other renderers. + brushSingle(ctx, symbol); + } + } + } + } + } + /** + * Convert symbol array into normalized array + * + * @param {string | (string | string[])[]} symbol symbol input + * @return {string[][]} normolized symbol array + */ + function normalizeSymbolArray(symbol) { + if (!symbol || symbol.length === 0) { + return [['rect']]; + } + if (isString(symbol)) { + return [[symbol]]; + } + var isAllString = true; + for (var i = 0; i < symbol.length; ++i) { + if (!isString(symbol[i])) { + isAllString = false; + break; + } + } + if (isAllString) { + return normalizeSymbolArray([symbol]); + } + var result = []; + for (var i = 0; i < symbol.length; ++i) { + if (isString(symbol[i])) { + result.push([symbol[i]]); + } else { + result.push(symbol[i]); + } + } + return result; + } + /** + * Convert dash input into dashArray + * + * @param {DecalDashArrayX} dash dash input + * @return {number[][]} normolized dash array + */ + function normalizeDashArrayX(dash) { + if (!dash || dash.length === 0) { + return [[0, 0]]; + } + if (isNumber(dash)) { + var dashValue = Math.ceil(dash); + return [[dashValue, dashValue]]; + } + /** + * [20, 5] should be normalized into [[20, 5]], + * while [20, [5, 10]] should be normalized into [[20, 20], [5, 10]] + */ + var isAllNumber = true; + for (var i = 0; i < dash.length; ++i) { + if (!isNumber(dash[i])) { + isAllNumber = false; + break; + } + } + if (isAllNumber) { + return normalizeDashArrayX([dash]); + } + var result = []; + for (var i = 0; i < dash.length; ++i) { + if (isNumber(dash[i])) { + var dashValue = Math.ceil(dash[i]); + result.push([dashValue, dashValue]); + } else { + var dashValue = map(dash[i], function (n) { + return Math.ceil(n); + }); + if (dashValue.length % 2 === 1) { + // [4, 2, 1] means |---- - -- |---- - -- | + // so normalize it to be [4, 2, 1, 4, 2, 1] + result.push(dashValue.concat(dashValue)); + } else { + result.push(dashValue); + } + } + } + return result; + } + /** + * Convert dash input into dashArray + * + * @param {DecalDashArrayY} dash dash input + * @return {number[]} normolized dash array + */ + function normalizeDashArrayY(dash) { + if (!dash || typeof dash === 'object' && dash.length === 0) { + return [0, 0]; + } + if (isNumber(dash)) { + var dashValue_1 = Math.ceil(dash); + return [dashValue_1, dashValue_1]; + } + var dashValue = map(dash, function (n) { + return Math.ceil(n); + }); + return dash.length % 2 ? dashValue.concat(dashValue) : dashValue; + } + /** + * Get block length of each line. A block is the length of dash line and space. + * For example, a line with [4, 1] has a dash line of 4 and a space of 1 after + * that, so the block length of this line is 5. + * + * @param {number[][]} dash dash array of X or Y + * @return {number[]} block length of each line + */ + function getLineBlockLengthX(dash) { + return map(dash, function (line) { + return getLineBlockLengthY(line); + }); + } + function getLineBlockLengthY(dash) { + var blockLength = 0; + for (var i = 0; i < dash.length; ++i) { + blockLength += dash[i]; + } + if (dash.length % 2 === 1) { + // [4, 2, 1] means |---- - -- |---- - -- | + // So total length is (4 + 2 + 1) * 2 + return blockLength * 2; + } + return blockLength; + } + + function decalVisual(ecModel, api) { + ecModel.eachRawSeries(function (seriesModel) { + if (ecModel.isSeriesFiltered(seriesModel)) { + return; + } + var data = seriesModel.getData(); + if (data.hasItemVisual()) { + data.each(function (idx) { + var decal = data.getItemVisual(idx, 'decal'); + if (decal) { + var itemStyle = data.ensureUniqueItemVisual(idx, 'style'); + itemStyle.decal = createOrUpdatePatternFromDecal(decal, api); + } + }); + } + var decal = data.getVisual('decal'); + if (decal) { + var style = data.getVisual('style'); + style.decal = createOrUpdatePatternFromDecal(decal, api); + } + }); + } + + var lifecycle = new Eventful(); + + // Implementation of exported APIs. For example registerMap, getMap. + // The implementations will be registered when installing the component. + // Avoid these code being bundled to the core module. + var implsStore = {}; + // TODO Type + function registerImpl(name, impl) { + if ("development" !== 'production') { + if (implsStore[name]) { + error("Already has an implementation of " + name + "."); + } + } + implsStore[name] = impl; + } + function getImpl(name) { + if ("development" !== 'production') { + if (!implsStore[name]) { + error("Implementation of " + name + " doesn't exists."); + } + } + return implsStore[name]; + } + + var version$1 = '5.5.0'; + var dependencies = { + zrender: '5.5.0' + }; + var TEST_FRAME_REMAIN_TIME = 1; + var PRIORITY_PROCESSOR_SERIES_FILTER = 800; + // Some data processors depends on the stack result dimension (to calculate data extent). + // So data stack stage should be in front of data processing stage. + var PRIORITY_PROCESSOR_DATASTACK = 900; + // "Data filter" will block the stream, so it should be + // put at the beginning of data processing. + var PRIORITY_PROCESSOR_FILTER = 1000; + var PRIORITY_PROCESSOR_DEFAULT = 2000; + var PRIORITY_PROCESSOR_STATISTIC = 5000; + var PRIORITY_VISUAL_LAYOUT = 1000; + var PRIORITY_VISUAL_PROGRESSIVE_LAYOUT = 1100; + var PRIORITY_VISUAL_GLOBAL = 2000; + var PRIORITY_VISUAL_CHART = 3000; + var PRIORITY_VISUAL_COMPONENT = 4000; + // Visual property in data. Greater than `PRIORITY_VISUAL_COMPONENT` to enable to + // overwrite the viusal result of component (like `visualMap`) + // using data item specific setting (like itemStyle.xxx on data item) + var PRIORITY_VISUAL_CHART_DATA_CUSTOM = 4500; + // Greater than `PRIORITY_VISUAL_CHART_DATA_CUSTOM` to enable to layout based on + // visual result like `symbolSize`. + var PRIORITY_VISUAL_POST_CHART_LAYOUT = 4600; + var PRIORITY_VISUAL_BRUSH = 5000; + var PRIORITY_VISUAL_ARIA = 6000; + var PRIORITY_VISUAL_DECAL = 7000; + var PRIORITY = { + PROCESSOR: { + FILTER: PRIORITY_PROCESSOR_FILTER, + SERIES_FILTER: PRIORITY_PROCESSOR_SERIES_FILTER, + STATISTIC: PRIORITY_PROCESSOR_STATISTIC + }, + VISUAL: { + LAYOUT: PRIORITY_VISUAL_LAYOUT, + PROGRESSIVE_LAYOUT: PRIORITY_VISUAL_PROGRESSIVE_LAYOUT, + GLOBAL: PRIORITY_VISUAL_GLOBAL, + CHART: PRIORITY_VISUAL_CHART, + POST_CHART_LAYOUT: PRIORITY_VISUAL_POST_CHART_LAYOUT, + COMPONENT: PRIORITY_VISUAL_COMPONENT, + BRUSH: PRIORITY_VISUAL_BRUSH, + CHART_ITEM: PRIORITY_VISUAL_CHART_DATA_CUSTOM, + ARIA: PRIORITY_VISUAL_ARIA, + DECAL: PRIORITY_VISUAL_DECAL + } + }; + // Main process have three entries: `setOption`, `dispatchAction` and `resize`, + // where they must not be invoked nestedly, except the only case: invoke + // dispatchAction with updateMethod "none" in main process. + // This flag is used to carry out this rule. + // All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]). + var IN_MAIN_PROCESS_KEY = '__flagInMainProcess'; + var PENDING_UPDATE = '__pendingUpdate'; + var STATUS_NEEDS_UPDATE_KEY = '__needsUpdateStatus'; + var ACTION_REG = /^[a-zA-Z0-9_]+$/; + var CONNECT_STATUS_KEY = '__connectUpdateStatus'; + var CONNECT_STATUS_PENDING = 0; + var CONNECT_STATUS_UPDATING = 1; + var CONNECT_STATUS_UPDATED = 2; + function createRegisterEventWithLowercaseECharts(method) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (this.isDisposed()) { + disposedWarning(this.id); + return; + } + return toLowercaseNameAndCallEventful(this, method, args); + }; + } + function createRegisterEventWithLowercaseMessageCenter(method) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return toLowercaseNameAndCallEventful(this, method, args); + }; + } + function toLowercaseNameAndCallEventful(host, method, args) { + // `args[0]` is event name. Event name is all lowercase. + args[0] = args[0] && args[0].toLowerCase(); + return Eventful.prototype[method].apply(host, args); + } + var MessageCenter = /** @class */function (_super) { + __extends(MessageCenter, _super); + function MessageCenter() { + return _super !== null && _super.apply(this, arguments) || this; + } + return MessageCenter; + }(Eventful); + var messageCenterProto = MessageCenter.prototype; + messageCenterProto.on = createRegisterEventWithLowercaseMessageCenter('on'); + messageCenterProto.off = createRegisterEventWithLowercaseMessageCenter('off'); + // --------------------------------------- + // Internal method names for class ECharts + // --------------------------------------- + var prepare; + var prepareView; + var updateDirectly; + var updateMethods; + var doConvertPixel; + var updateStreamModes; + var doDispatchAction; + var flushPendingActions; + var triggerUpdatedEvent; + var bindRenderedEvent; + var bindMouseEvent; + var render; + var renderComponents; + var renderSeries; + var createExtensionAPI; + var enableConnect; + var markStatusToUpdate; + var applyChangedStates; + var ECharts = /** @class */function (_super) { + __extends(ECharts, _super); + function ECharts(dom, + // Theme name or themeOption. + theme, opts) { + var _this = _super.call(this, new ECEventProcessor()) || this; + _this._chartsViews = []; + _this._chartsMap = {}; + _this._componentsViews = []; + _this._componentsMap = {}; + // Can't dispatch action during rendering procedure + _this._pendingActions = []; + opts = opts || {}; + // Get theme by name + if (isString(theme)) { + theme = themeStorage[theme]; + } + _this._dom = dom; + var defaultRenderer = 'canvas'; + var defaultCoarsePointer = 'auto'; + var defaultUseDirtyRect = false; + if ("development" !== 'production') { + var root = /* eslint-disable-next-line */ + env.hasGlobalWindow ? window : global; + if (root) { + defaultRenderer = retrieve2(root.__ECHARTS__DEFAULT__RENDERER__, defaultRenderer); + defaultCoarsePointer = retrieve2(root.__ECHARTS__DEFAULT__COARSE_POINTER, defaultCoarsePointer); + defaultUseDirtyRect = retrieve2(root.__ECHARTS__DEFAULT__USE_DIRTY_RECT__, defaultUseDirtyRect); + } + } + if (opts.ssr) { + registerSSRDataGetter(function (el) { + var ecData = getECData(el); + var dataIndex = ecData.dataIndex; + if (dataIndex == null) { + return; + } + var hashMap = createHashMap(); + hashMap.set('series_index', ecData.seriesIndex); + hashMap.set('data_index', dataIndex); + ecData.ssrType && hashMap.set('ssr_type', ecData.ssrType); + return hashMap; + }); + } + var zr = _this._zr = init(dom, { + renderer: opts.renderer || defaultRenderer, + devicePixelRatio: opts.devicePixelRatio, + width: opts.width, + height: opts.height, + ssr: opts.ssr, + useDirtyRect: retrieve2(opts.useDirtyRect, defaultUseDirtyRect), + useCoarsePointer: retrieve2(opts.useCoarsePointer, defaultCoarsePointer), + pointerSize: opts.pointerSize + }); + _this._ssr = opts.ssr; + // Expect 60 fps. + _this._throttledZrFlush = throttle(bind(zr.flush, zr), 17); + theme = clone(theme); + theme && globalBackwardCompat(theme, true); + _this._theme = theme; + _this._locale = createLocaleObject(opts.locale || SYSTEM_LANG); + _this._coordSysMgr = new CoordinateSystemManager(); + var api = _this._api = createExtensionAPI(_this); + // Sort on demand + function prioritySortFunc(a, b) { + return a.__prio - b.__prio; + } + sort(visualFuncs, prioritySortFunc); + sort(dataProcessorFuncs, prioritySortFunc); + _this._scheduler = new Scheduler(_this, api, dataProcessorFuncs, visualFuncs); + _this._messageCenter = new MessageCenter(); + // Init mouse events + _this._initEvents(); + // In case some people write `window.onresize = chart.resize` + _this.resize = bind(_this.resize, _this); + zr.animation.on('frame', _this._onframe, _this); + bindRenderedEvent(zr, _this); + bindMouseEvent(zr, _this); + // ECharts instance can be used as value. + setAsPrimitive(_this); + return _this; + } + ECharts.prototype._onframe = function () { + if (this._disposed) { + return; + } + applyChangedStates(this); + var scheduler = this._scheduler; + // Lazy update + if (this[PENDING_UPDATE]) { + var silent = this[PENDING_UPDATE].silent; + this[IN_MAIN_PROCESS_KEY] = true; + try { + prepare(this); + updateMethods.update.call(this, null, this[PENDING_UPDATE].updateParams); + } catch (e) { + this[IN_MAIN_PROCESS_KEY] = false; + this[PENDING_UPDATE] = null; + throw e; + } + // At present, in each frame, zrender performs: + // (1) animation step forward. + // (2) trigger('frame') (where this `_onframe` is called) + // (3) zrender flush (render). + // If we do nothing here, since we use `setToFinal: true`, the step (3) above + // will render the final state of the elements before the real animation started. + this._zr.flush(); + this[IN_MAIN_PROCESS_KEY] = false; + this[PENDING_UPDATE] = null; + flushPendingActions.call(this, silent); + triggerUpdatedEvent.call(this, silent); + } + // Avoid do both lazy update and progress in one frame. + else if (scheduler.unfinished) { + // Stream progress. + var remainTime = TEST_FRAME_REMAIN_TIME; + var ecModel = this._model; + var api = this._api; + scheduler.unfinished = false; + do { + var startTime = +new Date(); + scheduler.performSeriesTasks(ecModel); + // Currently dataProcessorFuncs do not check threshold. + scheduler.performDataProcessorTasks(ecModel); + updateStreamModes(this, ecModel); + // Do not update coordinate system here. Because that coord system update in + // each frame is not a good user experience. So we follow the rule that + // the extent of the coordinate system is determined in the first frame (the + // frame is executed immediately after task reset. + // this._coordSysMgr.update(ecModel, api); + // console.log('--- ec frame visual ---', remainTime); + scheduler.performVisualTasks(ecModel); + renderSeries(this, this._model, api, 'remain', {}); + remainTime -= +new Date() - startTime; + } while (remainTime > 0 && scheduler.unfinished); + // Call flush explicitly for trigger finished event. + if (!scheduler.unfinished) { + this._zr.flush(); + } + // Else, zr flushing be ensue within the same frame, + // because zr flushing is after onframe event. + } + }; + + ECharts.prototype.getDom = function () { + return this._dom; + }; + ECharts.prototype.getId = function () { + return this.id; + }; + ECharts.prototype.getZr = function () { + return this._zr; + }; + ECharts.prototype.isSSR = function () { + return this._ssr; + }; + /* eslint-disable-next-line */ + ECharts.prototype.setOption = function (option, notMerge, lazyUpdate) { + if (this[IN_MAIN_PROCESS_KEY]) { + if ("development" !== 'production') { + error('`setOption` should not be called during main process.'); + } + return; + } + if (this._disposed) { + disposedWarning(this.id); + return; + } + var silent; + var replaceMerge; + var transitionOpt; + if (isObject(notMerge)) { + lazyUpdate = notMerge.lazyUpdate; + silent = notMerge.silent; + replaceMerge = notMerge.replaceMerge; + transitionOpt = notMerge.transition; + notMerge = notMerge.notMerge; + } + this[IN_MAIN_PROCESS_KEY] = true; + if (!this._model || notMerge) { + var optionManager = new OptionManager(this._api); + var theme = this._theme; + var ecModel = this._model = new GlobalModel(); + ecModel.scheduler = this._scheduler; + ecModel.ssr = this._ssr; + ecModel.init(null, null, null, theme, this._locale, optionManager); + } + this._model.setOption(option, { + replaceMerge: replaceMerge + }, optionPreprocessorFuncs); + var updateParams = { + seriesTransition: transitionOpt, + optionChanged: true + }; + if (lazyUpdate) { + this[PENDING_UPDATE] = { + silent: silent, + updateParams: updateParams + }; + this[IN_MAIN_PROCESS_KEY] = false; + // `setOption(option, {lazyMode: true})` may be called when zrender has been slept. + // It should wake it up to make sure zrender start to render at the next frame. + this.getZr().wakeUp(); + } else { + try { + prepare(this); + updateMethods.update.call(this, null, updateParams); + } catch (e) { + this[PENDING_UPDATE] = null; + this[IN_MAIN_PROCESS_KEY] = false; + throw e; + } + // Ensure zr refresh sychronously, and then pixel in canvas can be + // fetched after `setOption`. + if (!this._ssr) { + // not use flush when using ssr mode. + this._zr.flush(); + } + this[PENDING_UPDATE] = null; + this[IN_MAIN_PROCESS_KEY] = false; + flushPendingActions.call(this, silent); + triggerUpdatedEvent.call(this, silent); + } + }; + /** + * @deprecated + */ + ECharts.prototype.setTheme = function () { + deprecateLog('ECharts#setTheme() is DEPRECATED in ECharts 3.0'); + }; + // We don't want developers to use getModel directly. + ECharts.prototype.getModel = function () { + return this._model; + }; + ECharts.prototype.getOption = function () { + return this._model && this._model.getOption(); + }; + ECharts.prototype.getWidth = function () { + return this._zr.getWidth(); + }; + ECharts.prototype.getHeight = function () { + return this._zr.getHeight(); + }; + ECharts.prototype.getDevicePixelRatio = function () { + return this._zr.painter.dpr + /* eslint-disable-next-line */ || env.hasGlobalWindow && window.devicePixelRatio || 1; + }; + /** + * Get canvas which has all thing rendered + * @deprecated Use renderToCanvas instead. + */ + ECharts.prototype.getRenderedCanvas = function (opts) { + if ("development" !== 'production') { + deprecateReplaceLog('getRenderedCanvas', 'renderToCanvas'); + } + return this.renderToCanvas(opts); + }; + ECharts.prototype.renderToCanvas = function (opts) { + opts = opts || {}; + var painter = this._zr.painter; + if ("development" !== 'production') { + if (painter.type !== 'canvas') { + throw new Error('renderToCanvas can only be used in the canvas renderer.'); + } + } + return painter.getRenderedCanvas({ + backgroundColor: opts.backgroundColor || this._model.get('backgroundColor'), + pixelRatio: opts.pixelRatio || this.getDevicePixelRatio() + }); + }; + ECharts.prototype.renderToSVGString = function (opts) { + opts = opts || {}; + var painter = this._zr.painter; + if ("development" !== 'production') { + if (painter.type !== 'svg') { + throw new Error('renderToSVGString can only be used in the svg renderer.'); + } + } + return painter.renderToString({ + useViewBox: opts.useViewBox + }); + }; + /** + * Get svg data url + */ + ECharts.prototype.getSvgDataURL = function () { + if (!env.svgSupported) { + return; + } + var zr = this._zr; + var list = zr.storage.getDisplayList(); + // Stop animations + each(list, function (el) { + el.stopAnimation(null, true); + }); + return zr.painter.toDataURL(); + }; + ECharts.prototype.getDataURL = function (opts) { + if (this._disposed) { + disposedWarning(this.id); + return; + } + opts = opts || {}; + var excludeComponents = opts.excludeComponents; + var ecModel = this._model; + var excludesComponentViews = []; + var self = this; + each(excludeComponents, function (componentType) { + ecModel.eachComponent({ + mainType: componentType + }, function (component) { + var view = self._componentsMap[component.__viewId]; + if (!view.group.ignore) { + excludesComponentViews.push(view); + view.group.ignore = true; + } + }); + }); + var url = this._zr.painter.getType() === 'svg' ? this.getSvgDataURL() : this.renderToCanvas(opts).toDataURL('image/' + (opts && opts.type || 'png')); + each(excludesComponentViews, function (view) { + view.group.ignore = false; + }); + return url; + }; + ECharts.prototype.getConnectedDataURL = function (opts) { + if (this._disposed) { + disposedWarning(this.id); + return; + } + var isSvg = opts.type === 'svg'; + var groupId = this.group; + var mathMin = Math.min; + var mathMax = Math.max; + var MAX_NUMBER = Infinity; + if (connectedGroups[groupId]) { + var left_1 = MAX_NUMBER; + var top_1 = MAX_NUMBER; + var right_1 = -MAX_NUMBER; + var bottom_1 = -MAX_NUMBER; + var canvasList_1 = []; + var dpr_1 = opts && opts.pixelRatio || this.getDevicePixelRatio(); + each(instances$1, function (chart, id) { + if (chart.group === groupId) { + var canvas = isSvg ? chart.getZr().painter.getSvgDom().innerHTML : chart.renderToCanvas(clone(opts)); + var boundingRect = chart.getDom().getBoundingClientRect(); + left_1 = mathMin(boundingRect.left, left_1); + top_1 = mathMin(boundingRect.top, top_1); + right_1 = mathMax(boundingRect.right, right_1); + bottom_1 = mathMax(boundingRect.bottom, bottom_1); + canvasList_1.push({ + dom: canvas, + left: boundingRect.left, + top: boundingRect.top + }); + } + }); + left_1 *= dpr_1; + top_1 *= dpr_1; + right_1 *= dpr_1; + bottom_1 *= dpr_1; + var width = right_1 - left_1; + var height = bottom_1 - top_1; + var targetCanvas = platformApi.createCanvas(); + var zr_1 = init(targetCanvas, { + renderer: isSvg ? 'svg' : 'canvas' + }); + zr_1.resize({ + width: width, + height: height + }); + if (isSvg) { + var content_1 = ''; + each(canvasList_1, function (item) { + var x = item.left - left_1; + var y = item.top - top_1; + content_1 += '' + item.dom + ''; + }); + zr_1.painter.getSvgRoot().innerHTML = content_1; + if (opts.connectedBackgroundColor) { + zr_1.painter.setBackgroundColor(opts.connectedBackgroundColor); + } + zr_1.refreshImmediately(); + return zr_1.painter.toDataURL(); + } else { + // Background between the charts + if (opts.connectedBackgroundColor) { + zr_1.add(new Rect({ + shape: { + x: 0, + y: 0, + width: width, + height: height + }, + style: { + fill: opts.connectedBackgroundColor + } + })); + } + each(canvasList_1, function (item) { + var img = new ZRImage({ + style: { + x: item.left * dpr_1 - left_1, + y: item.top * dpr_1 - top_1, + image: item.dom + } + }); + zr_1.add(img); + }); + zr_1.refreshImmediately(); + return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png')); + } + } else { + return this.getDataURL(opts); + } + }; + ECharts.prototype.convertToPixel = function (finder, value) { + return doConvertPixel(this, 'convertToPixel', finder, value); + }; + ECharts.prototype.convertFromPixel = function (finder, value) { + return doConvertPixel(this, 'convertFromPixel', finder, value); + }; + /** + * Is the specified coordinate systems or components contain the given pixel point. + * @param {Array|number} value + * @return {boolean} result + */ + ECharts.prototype.containPixel = function (finder, value) { + if (this._disposed) { + disposedWarning(this.id); + return; + } + var ecModel = this._model; + var result; + var findResult = parseFinder(ecModel, finder); + each(findResult, function (models, key) { + key.indexOf('Models') >= 0 && each(models, function (model) { + var coordSys = model.coordinateSystem; + if (coordSys && coordSys.containPoint) { + result = result || !!coordSys.containPoint(value); + } else if (key === 'seriesModels') { + var view = this._chartsMap[model.__viewId]; + if (view && view.containPoint) { + result = result || view.containPoint(value, model); + } else { + if ("development" !== 'production') { + warn(key + ': ' + (view ? 'The found component do not support containPoint.' : 'No view mapping to the found component.')); + } + } + } else { + if ("development" !== 'production') { + warn(key + ': containPoint is not supported'); + } + } + }, this); + }, this); + return !!result; + }; + /** + * Get visual from series or data. + * @param finder + * If string, e.g., 'series', means {seriesIndex: 0}. + * If Object, could contain some of these properties below: + * { + * seriesIndex / seriesId / seriesName, + * dataIndex / dataIndexInside + * } + * If dataIndex is not specified, series visual will be fetched, + * but not data item visual. + * If all of seriesIndex, seriesId, seriesName are not specified, + * visual will be fetched from first series. + * @param visualType 'color', 'symbol', 'symbolSize' + */ + ECharts.prototype.getVisual = function (finder, visualType) { + var ecModel = this._model; + var parsedFinder = parseFinder(ecModel, finder, { + defaultMainType: 'series' + }); + var seriesModel = parsedFinder.seriesModel; + if ("development" !== 'production') { + if (!seriesModel) { + warn('There is no specified series model'); + } + } + var data = seriesModel.getData(); + var dataIndexInside = parsedFinder.hasOwnProperty('dataIndexInside') ? parsedFinder.dataIndexInside : parsedFinder.hasOwnProperty('dataIndex') ? data.indexOfRawIndex(parsedFinder.dataIndex) : null; + return dataIndexInside != null ? getItemVisualFromData(data, dataIndexInside, visualType) : getVisualFromData(data, visualType); + }; + /** + * Get view of corresponding component model + */ + ECharts.prototype.getViewOfComponentModel = function (componentModel) { + return this._componentsMap[componentModel.__viewId]; + }; + /** + * Get view of corresponding series model + */ + ECharts.prototype.getViewOfSeriesModel = function (seriesModel) { + return this._chartsMap[seriesModel.__viewId]; + }; + ECharts.prototype._initEvents = function () { + var _this = this; + each(MOUSE_EVENT_NAMES, function (eveName) { + var handler = function (e) { + var ecModel = _this.getModel(); + var el = e.target; + var params; + var isGlobalOut = eveName === 'globalout'; + // no e.target when 'globalout'. + if (isGlobalOut) { + params = {}; + } else { + el && findEventDispatcher(el, function (parent) { + var ecData = getECData(parent); + if (ecData && ecData.dataIndex != null) { + var dataModel = ecData.dataModel || ecModel.getSeriesByIndex(ecData.seriesIndex); + params = dataModel && dataModel.getDataParams(ecData.dataIndex, ecData.dataType, el) || {}; + return true; + } + // If element has custom eventData of components + else if (ecData.eventData) { + params = extend({}, ecData.eventData); + return true; + } + }, true); + } + // Contract: if params prepared in mouse event, + // these properties must be specified: + // { + // componentType: string (component main type) + // componentIndex: number + // } + // Otherwise event query can not work. + if (params) { + var componentType = params.componentType; + var componentIndex = params.componentIndex; + // Special handling for historic reason: when trigger by + // markLine/markPoint/markArea, the componentType is + // 'markLine'/'markPoint'/'markArea', but we should better + // enable them to be queried by seriesIndex, since their + // option is set in each series. + if (componentType === 'markLine' || componentType === 'markPoint' || componentType === 'markArea') { + componentType = 'series'; + componentIndex = params.seriesIndex; + } + var model = componentType && componentIndex != null && ecModel.getComponent(componentType, componentIndex); + var view = model && _this[model.mainType === 'series' ? '_chartsMap' : '_componentsMap'][model.__viewId]; + if ("development" !== 'production') { + // `event.componentType` and `event[componentTpype + 'Index']` must not + // be missed, otherwise there is no way to distinguish source component. + // See `dataFormat.getDataParams`. + if (!isGlobalOut && !(model && view)) { + warn('model or view can not be found by params'); + } + } + params.event = e; + params.type = eveName; + _this._$eventProcessor.eventInfo = { + targetEl: el, + packedEvent: params, + model: model, + view: view + }; + _this.trigger(eveName, params); + } + }; + // Consider that some component (like tooltip, brush, ...) + // register zr event handler, but user event handler might + // do anything, such as call `setOption` or `dispatchAction`, + // which probably update any of the content and probably + // cause problem if it is called previous other inner handlers. + handler.zrEventfulCallAtLast = true; + _this._zr.on(eveName, handler, _this); + }); + each(eventActionMap, function (actionType, eventType) { + _this._messageCenter.on(eventType, function (event) { + this.trigger(eventType, event); + }, _this); + }); + // Extra events + // TODO register? + each(['selectchanged'], function (eventType) { + _this._messageCenter.on(eventType, function (event) { + this.trigger(eventType, event); + }, _this); + }); + handleLegacySelectEvents(this._messageCenter, this, this._api); + }; + ECharts.prototype.isDisposed = function () { + return this._disposed; + }; + ECharts.prototype.clear = function () { + if (this._disposed) { + disposedWarning(this.id); + return; + } + this.setOption({ + series: [] + }, true); + }; + ECharts.prototype.dispose = function () { + if (this._disposed) { + disposedWarning(this.id); + return; + } + this._disposed = true; + var dom = this.getDom(); + if (dom) { + setAttribute(this.getDom(), DOM_ATTRIBUTE_KEY, ''); + } + var chart = this; + var api = chart._api; + var ecModel = chart._model; + each(chart._componentsViews, function (component) { + component.dispose(ecModel, api); + }); + each(chart._chartsViews, function (chart) { + chart.dispose(ecModel, api); + }); + // Dispose after all views disposed + chart._zr.dispose(); + // Set properties to null. + // To reduce the memory cost in case the top code still holds this instance unexpectedly. + chart._dom = chart._model = chart._chartsMap = chart._componentsMap = chart._chartsViews = chart._componentsViews = chart._scheduler = chart._api = chart._zr = chart._throttledZrFlush = chart._theme = chart._coordSysMgr = chart._messageCenter = null; + delete instances$1[chart.id]; + }; + /** + * Resize the chart + */ + ECharts.prototype.resize = function (opts) { + if (this[IN_MAIN_PROCESS_KEY]) { + if ("development" !== 'production') { + error('`resize` should not be called during main process.'); + } + return; + } + if (this._disposed) { + disposedWarning(this.id); + return; + } + this._zr.resize(opts); + var ecModel = this._model; + // Resize loading effect + this._loadingFX && this._loadingFX.resize(); + if (!ecModel) { + return; + } + var needPrepare = ecModel.resetOption('media'); + var silent = opts && opts.silent; + // There is some real cases that: + // chart.setOption(option, { lazyUpdate: true }); + // chart.resize(); + if (this[PENDING_UPDATE]) { + if (silent == null) { + silent = this[PENDING_UPDATE].silent; + } + needPrepare = true; + this[PENDING_UPDATE] = null; + } + this[IN_MAIN_PROCESS_KEY] = true; + try { + needPrepare && prepare(this); + updateMethods.update.call(this, { + type: 'resize', + animation: extend({ + // Disable animation + duration: 0 + }, opts && opts.animation) + }); + } catch (e) { + this[IN_MAIN_PROCESS_KEY] = false; + throw e; + } + this[IN_MAIN_PROCESS_KEY] = false; + flushPendingActions.call(this, silent); + triggerUpdatedEvent.call(this, silent); + }; + ECharts.prototype.showLoading = function (name, cfg) { + if (this._disposed) { + disposedWarning(this.id); + return; + } + if (isObject(name)) { + cfg = name; + name = ''; + } + name = name || 'default'; + this.hideLoading(); + if (!loadingEffects[name]) { + if ("development" !== 'production') { + warn('Loading effects ' + name + ' not exists.'); + } + return; + } + var el = loadingEffects[name](this._api, cfg); + var zr = this._zr; + this._loadingFX = el; + zr.add(el); + }; + /** + * Hide loading effect + */ + ECharts.prototype.hideLoading = function () { + if (this._disposed) { + disposedWarning(this.id); + return; + } + this._loadingFX && this._zr.remove(this._loadingFX); + this._loadingFX = null; + }; + ECharts.prototype.makeActionFromEvent = function (eventObj) { + var payload = extend({}, eventObj); + payload.type = eventActionMap[eventObj.type]; + return payload; + }; + /** + * @param opt If pass boolean, means opt.silent + * @param opt.silent Default `false`. Whether trigger events. + * @param opt.flush Default `undefined`. + * true: Flush immediately, and then pixel in canvas can be fetched + * immediately. Caution: it might affect performance. + * false: Not flush. + * undefined: Auto decide whether perform flush. + */ + ECharts.prototype.dispatchAction = function (payload, opt) { + if (this._disposed) { + disposedWarning(this.id); + return; + } + if (!isObject(opt)) { + opt = { + silent: !!opt + }; + } + if (!actions[payload.type]) { + return; + } + // Avoid dispatch action before setOption. Especially in `connect`. + if (!this._model) { + return; + } + // May dispatchAction in rendering procedure + if (this[IN_MAIN_PROCESS_KEY]) { + this._pendingActions.push(payload); + return; + } + var silent = opt.silent; + doDispatchAction.call(this, payload, silent); + var flush = opt.flush; + if (flush) { + this._zr.flush(); + } else if (flush !== false && env.browser.weChat) { + // In WeChat embedded browser, `requestAnimationFrame` and `setInterval` + // hang when sliding page (on touch event), which cause that zr does not + // refresh until user interaction finished, which is not expected. + // But `dispatchAction` may be called too frequently when pan on touch + // screen, which impacts performance if do not throttle them. + this._throttledZrFlush(); + } + flushPendingActions.call(this, silent); + triggerUpdatedEvent.call(this, silent); + }; + ECharts.prototype.updateLabelLayout = function () { + lifecycle.trigger('series:layoutlabels', this._model, this._api, { + // Not adding series labels. + // TODO + updatedSeries: [] + }); + }; + ECharts.prototype.appendData = function (params) { + if (this._disposed) { + disposedWarning(this.id); + return; + } + var seriesIndex = params.seriesIndex; + var ecModel = this.getModel(); + var seriesModel = ecModel.getSeriesByIndex(seriesIndex); + if ("development" !== 'production') { + assert(params.data && seriesModel); + } + seriesModel.appendData(params); + // Note: `appendData` does not support that update extent of coordinate + // system, util some scenario require that. In the expected usage of + // `appendData`, the initial extent of coordinate system should better + // be fixed by axis `min`/`max` setting or initial data, otherwise if + // the extent changed while `appendData`, the location of the painted + // graphic elements have to be changed, which make the usage of + // `appendData` meaningless. + this._scheduler.unfinished = true; + this.getZr().wakeUp(); + }; + // A work around for no `internal` modifier in ts yet but + // need to strictly hide private methods to JS users. + ECharts.internalField = function () { + prepare = function (ecIns) { + var scheduler = ecIns._scheduler; + scheduler.restorePipelines(ecIns._model); + scheduler.prepareStageTasks(); + prepareView(ecIns, true); + prepareView(ecIns, false); + scheduler.plan(); + }; + /** + * Prepare view instances of charts and components + */ + prepareView = function (ecIns, isComponent) { + var ecModel = ecIns._model; + var scheduler = ecIns._scheduler; + var viewList = isComponent ? ecIns._componentsViews : ecIns._chartsViews; + var viewMap = isComponent ? ecIns._componentsMap : ecIns._chartsMap; + var zr = ecIns._zr; + var api = ecIns._api; + for (var i = 0; i < viewList.length; i++) { + viewList[i].__alive = false; + } + isComponent ? ecModel.eachComponent(function (componentType, model) { + componentType !== 'series' && doPrepare(model); + }) : ecModel.eachSeries(doPrepare); + function doPrepare(model) { + // By default view will be reused if possible for the case that `setOption` with "notMerge" + // mode and need to enable transition animation. (Usually, when they have the same id, or + // especially no id but have the same type & name & index. See the `model.id` generation + // rule in `makeIdAndName` and `viewId` generation rule here). + // But in `replaceMerge` mode, this feature should be able to disabled when it is clear that + // the new model has nothing to do with the old model. + var requireNewView = model.__requireNewView; + // This command should not work twice. + model.__requireNewView = false; + // Consider: id same and type changed. + var viewId = '_ec_' + model.id + '_' + model.type; + var view = !requireNewView && viewMap[viewId]; + if (!view) { + var classType = parseClassType(model.type); + var Clazz = isComponent ? ComponentView.getClass(classType.main, classType.sub) : + // FIXME:TS + // (ChartView as ChartViewConstructor).getClass('series', classType.sub) + // For backward compat, still support a chart type declared as only subType + // like "liquidfill", but recommend "series.liquidfill" + // But need a base class to make a type series. + ChartView.getClass(classType.sub); + if ("development" !== 'production') { + assert(Clazz, classType.sub + ' does not exist.'); + } + view = new Clazz(); + view.init(ecModel, api); + viewMap[viewId] = view; + viewList.push(view); + zr.add(view.group); + } + model.__viewId = view.__id = viewId; + view.__alive = true; + view.__model = model; + view.group.__ecComponentInfo = { + mainType: model.mainType, + index: model.componentIndex + }; + !isComponent && scheduler.prepareView(view, model, ecModel, api); + } + for (var i = 0; i < viewList.length;) { + var view = viewList[i]; + if (!view.__alive) { + !isComponent && view.renderTask.dispose(); + zr.remove(view.group); + view.dispose(ecModel, api); + viewList.splice(i, 1); + if (viewMap[view.__id] === view) { + delete viewMap[view.__id]; + } + view.__id = view.group.__ecComponentInfo = null; + } else { + i++; + } + } + }; + updateDirectly = function (ecIns, method, payload, mainType, subType) { + var ecModel = ecIns._model; + ecModel.setUpdatePayload(payload); + // broadcast + if (!mainType) { + // FIXME + // Chart will not be update directly here, except set dirty. + // But there is no such scenario now. + each([].concat(ecIns._componentsViews).concat(ecIns._chartsViews), callView); + return; + } + var query = {}; + query[mainType + 'Id'] = payload[mainType + 'Id']; + query[mainType + 'Index'] = payload[mainType + 'Index']; + query[mainType + 'Name'] = payload[mainType + 'Name']; + var condition = { + mainType: mainType, + query: query + }; + subType && (condition.subType = subType); // subType may be '' by parseClassType; + var excludeSeriesId = payload.excludeSeriesId; + var excludeSeriesIdMap; + if (excludeSeriesId != null) { + excludeSeriesIdMap = createHashMap(); + each(normalizeToArray(excludeSeriesId), function (id) { + var modelId = convertOptionIdName(id, null); + if (modelId != null) { + excludeSeriesIdMap.set(modelId, true); + } + }); + } + // If dispatchAction before setOption, do nothing. + ecModel && ecModel.eachComponent(condition, function (model) { + var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) != null; + if (isExcluded) { + return; + } + if (isHighDownPayload(payload)) { + if (model instanceof SeriesModel) { + if (payload.type === HIGHLIGHT_ACTION_TYPE && !payload.notBlur && !model.get(['emphasis', 'disabled'])) { + blurSeriesFromHighlightPayload(model, payload, ecIns._api); + } + } else { + var _a = findComponentHighDownDispatchers(model.mainType, model.componentIndex, payload.name, ecIns._api), + focusSelf = _a.focusSelf, + dispatchers = _a.dispatchers; + if (payload.type === HIGHLIGHT_ACTION_TYPE && focusSelf && !payload.notBlur) { + blurComponent(model.mainType, model.componentIndex, ecIns._api); + } + // PENDING: + // Whether to put this "enter emphasis" code in `ComponentView`, + // which will be the same as `ChartView` but might be not necessary + // and will be far from this logic. + if (dispatchers) { + each(dispatchers, function (dispatcher) { + payload.type === HIGHLIGHT_ACTION_TYPE ? enterEmphasis(dispatcher) : leaveEmphasis(dispatcher); + }); + } + } + } else if (isSelectChangePayload(payload)) { + // TODO geo + if (model instanceof SeriesModel) { + toggleSelectionFromPayload(model, payload, ecIns._api); + updateSeriesElementSelection(model); + markStatusToUpdate(ecIns); + } + } + }, ecIns); + ecModel && ecModel.eachComponent(condition, function (model) { + var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) != null; + if (isExcluded) { + return; + } + callView(ecIns[mainType === 'series' ? '_chartsMap' : '_componentsMap'][model.__viewId]); + }, ecIns); + function callView(view) { + view && view.__alive && view[method] && view[method](view.__model, ecModel, ecIns._api, payload); + } + }; + updateMethods = { + prepareAndUpdate: function (payload) { + prepare(this); + updateMethods.update.call(this, payload, { + // Needs to mark option changed if newOption is given. + // It's from MagicType. + // TODO If use a separate flag optionChanged in payload? + optionChanged: payload.newOption != null + }); + }, + update: function (payload, updateParams) { + var ecModel = this._model; + var api = this._api; + var zr = this._zr; + var coordSysMgr = this._coordSysMgr; + var scheduler = this._scheduler; + // update before setOption + if (!ecModel) { + return; + } + ecModel.setUpdatePayload(payload); + scheduler.restoreData(ecModel, payload); + scheduler.performSeriesTasks(ecModel); + // TODO + // Save total ecModel here for undo/redo (after restoring data and before processing data). + // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call. + // Create new coordinate system each update + // In LineView may save the old coordinate system and use it to get the original point. + coordSysMgr.create(ecModel, api); + scheduler.performDataProcessorTasks(ecModel, payload); + // Current stream render is not supported in data process. So we can update + // stream modes after data processing, where the filtered data is used to + // determine whether to use progressive rendering. + updateStreamModes(this, ecModel); + // We update stream modes before coordinate system updated, then the modes info + // can be fetched when coord sys updating (consider the barGrid extent fix). But + // the drawback is the full coord info can not be fetched. Fortunately this full + // coord is not required in stream mode updater currently. + coordSysMgr.update(ecModel, api); + clearColorPalette(ecModel); + scheduler.performVisualTasks(ecModel, payload); + render(this, ecModel, api, payload, updateParams); + // Set background + var backgroundColor = ecModel.get('backgroundColor') || 'transparent'; + var darkMode = ecModel.get('darkMode'); + zr.setBackgroundColor(backgroundColor); + // Force set dark mode. + if (darkMode != null && darkMode !== 'auto') { + zr.setDarkMode(darkMode); + } + lifecycle.trigger('afterupdate', ecModel, api); + }, + updateTransform: function (payload) { + var _this = this; + var ecModel = this._model; + var api = this._api; + // update before setOption + if (!ecModel) { + return; + } + ecModel.setUpdatePayload(payload); + // ChartView.markUpdateMethod(payload, 'updateTransform'); + var componentDirtyList = []; + ecModel.eachComponent(function (componentType, componentModel) { + if (componentType === 'series') { + return; + } + var componentView = _this.getViewOfComponentModel(componentModel); + if (componentView && componentView.__alive) { + if (componentView.updateTransform) { + var result = componentView.updateTransform(componentModel, ecModel, api, payload); + result && result.update && componentDirtyList.push(componentView); + } else { + componentDirtyList.push(componentView); + } + } + }); + var seriesDirtyMap = createHashMap(); + ecModel.eachSeries(function (seriesModel) { + var chartView = _this._chartsMap[seriesModel.__viewId]; + if (chartView.updateTransform) { + var result = chartView.updateTransform(seriesModel, ecModel, api, payload); + result && result.update && seriesDirtyMap.set(seriesModel.uid, 1); + } else { + seriesDirtyMap.set(seriesModel.uid, 1); + } + }); + clearColorPalette(ecModel); + // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline. + // this._scheduler.performVisualTasks(ecModel, payload, 'layout', true); + this._scheduler.performVisualTasks(ecModel, payload, { + setDirty: true, + dirtyMap: seriesDirtyMap + }); + // Currently, not call render of components. Geo render cost a lot. + // renderComponents(ecIns, ecModel, api, payload, componentDirtyList); + renderSeries(this, ecModel, api, payload, {}, seriesDirtyMap); + lifecycle.trigger('afterupdate', ecModel, api); + }, + updateView: function (payload) { + var ecModel = this._model; + // update before setOption + if (!ecModel) { + return; + } + ecModel.setUpdatePayload(payload); + ChartView.markUpdateMethod(payload, 'updateView'); + clearColorPalette(ecModel); + // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline. + this._scheduler.performVisualTasks(ecModel, payload, { + setDirty: true + }); + render(this, ecModel, this._api, payload, {}); + lifecycle.trigger('afterupdate', ecModel, this._api); + }, + updateVisual: function (payload) { + // updateMethods.update.call(this, payload); + var _this = this; + var ecModel = this._model; + // update before setOption + if (!ecModel) { + return; + } + ecModel.setUpdatePayload(payload); + // clear all visual + ecModel.eachSeries(function (seriesModel) { + seriesModel.getData().clearAllVisual(); + }); + // Perform visual + ChartView.markUpdateMethod(payload, 'updateVisual'); + clearColorPalette(ecModel); + // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline. + this._scheduler.performVisualTasks(ecModel, payload, { + visualType: 'visual', + setDirty: true + }); + ecModel.eachComponent(function (componentType, componentModel) { + if (componentType !== 'series') { + var componentView = _this.getViewOfComponentModel(componentModel); + componentView && componentView.__alive && componentView.updateVisual(componentModel, ecModel, _this._api, payload); + } + }); + ecModel.eachSeries(function (seriesModel) { + var chartView = _this._chartsMap[seriesModel.__viewId]; + chartView.updateVisual(seriesModel, ecModel, _this._api, payload); + }); + lifecycle.trigger('afterupdate', ecModel, this._api); + }, + updateLayout: function (payload) { + updateMethods.update.call(this, payload); + } + }; + doConvertPixel = function (ecIns, methodName, finder, value) { + if (ecIns._disposed) { + disposedWarning(ecIns.id); + return; + } + var ecModel = ecIns._model; + var coordSysList = ecIns._coordSysMgr.getCoordinateSystems(); + var result; + var parsedFinder = parseFinder(ecModel, finder); + for (var i = 0; i < coordSysList.length; i++) { + var coordSys = coordSysList[i]; + if (coordSys[methodName] && (result = coordSys[methodName](ecModel, parsedFinder, value)) != null) { + return result; + } + } + if ("development" !== 'production') { + warn('No coordinate system that supports ' + methodName + ' found by the given finder.'); + } + }; + updateStreamModes = function (ecIns, ecModel) { + var chartsMap = ecIns._chartsMap; + var scheduler = ecIns._scheduler; + ecModel.eachSeries(function (seriesModel) { + scheduler.updateStreamModes(seriesModel, chartsMap[seriesModel.__viewId]); + }); + }; + doDispatchAction = function (payload, silent) { + var _this = this; + var ecModel = this.getModel(); + var payloadType = payload.type; + var escapeConnect = payload.escapeConnect; + var actionWrap = actions[payloadType]; + var actionInfo = actionWrap.actionInfo; + var cptTypeTmp = (actionInfo.update || 'update').split(':'); + var updateMethod = cptTypeTmp.pop(); + var cptType = cptTypeTmp[0] != null && parseClassType(cptTypeTmp[0]); + this[IN_MAIN_PROCESS_KEY] = true; + var payloads = [payload]; + var batched = false; + // Batch action + if (payload.batch) { + batched = true; + payloads = map(payload.batch, function (item) { + item = defaults(extend({}, item), payload); + item.batch = null; + return item; + }); + } + var eventObjBatch = []; + var eventObj; + var isSelectChange = isSelectChangePayload(payload); + var isHighDown = isHighDownPayload(payload); + // Only leave blur once if there are multiple batches. + if (isHighDown) { + allLeaveBlur(this._api); + } + each(payloads, function (batchItem) { + // Action can specify the event by return it. + eventObj = actionWrap.action(batchItem, _this._model, _this._api); + // Emit event outside + eventObj = eventObj || extend({}, batchItem); + // Convert type to eventType + eventObj.type = actionInfo.event || eventObj.type; + eventObjBatch.push(eventObj); + // light update does not perform data process, layout and visual. + if (isHighDown) { + var _a = preParseFinder(payload), + queryOptionMap = _a.queryOptionMap, + mainTypeSpecified = _a.mainTypeSpecified; + var componentMainType = mainTypeSpecified ? queryOptionMap.keys()[0] : 'series'; + updateDirectly(_this, updateMethod, batchItem, componentMainType); + markStatusToUpdate(_this); + } else if (isSelectChange) { + // At present `dispatchAction({ type: 'select', ... })` is not supported on components. + // geo still use 'geoselect'. + updateDirectly(_this, updateMethod, batchItem, 'series'); + markStatusToUpdate(_this); + } else if (cptType) { + updateDirectly(_this, updateMethod, batchItem, cptType.main, cptType.sub); + } + }); + if (updateMethod !== 'none' && !isHighDown && !isSelectChange && !cptType) { + try { + // Still dirty + if (this[PENDING_UPDATE]) { + prepare(this); + updateMethods.update.call(this, payload); + this[PENDING_UPDATE] = null; + } else { + updateMethods[updateMethod].call(this, payload); + } + } catch (e) { + this[IN_MAIN_PROCESS_KEY] = false; + throw e; + } + } + // Follow the rule of action batch + if (batched) { + eventObj = { + type: actionInfo.event || payloadType, + escapeConnect: escapeConnect, + batch: eventObjBatch + }; + } else { + eventObj = eventObjBatch[0]; + } + this[IN_MAIN_PROCESS_KEY] = false; + if (!silent) { + var messageCenter = this._messageCenter; + messageCenter.trigger(eventObj.type, eventObj); + // Extra triggered 'selectchanged' event + if (isSelectChange) { + var newObj = { + type: 'selectchanged', + escapeConnect: escapeConnect, + selected: getAllSelectedIndices(ecModel), + isFromClick: payload.isFromClick || false, + fromAction: payload.type, + fromActionPayload: payload + }; + messageCenter.trigger(newObj.type, newObj); + } + } + }; + flushPendingActions = function (silent) { + var pendingActions = this._pendingActions; + while (pendingActions.length) { + var payload = pendingActions.shift(); + doDispatchAction.call(this, payload, silent); + } + }; + triggerUpdatedEvent = function (silent) { + !silent && this.trigger('updated'); + }; + /** + * Event `rendered` is triggered when zr + * rendered. It is useful for realtime + * snapshot (reflect animation). + * + * Event `finished` is triggered when: + * (1) zrender rendering finished. + * (2) initial animation finished. + * (3) progressive rendering finished. + * (4) no pending action. + * (5) no delayed setOption needs to be processed. + */ + bindRenderedEvent = function (zr, ecIns) { + zr.on('rendered', function (params) { + ecIns.trigger('rendered', params); + // The `finished` event should not be triggered repeatedly, + // so it should only be triggered when rendering indeed happens + // in zrender. (Consider the case that dipatchAction is keep + // triggering when mouse move). + if ( + // Although zr is dirty if initial animation is not finished + // and this checking is called on frame, we also check + // animation finished for robustness. + zr.animation.isFinished() && !ecIns[PENDING_UPDATE] && !ecIns._scheduler.unfinished && !ecIns._pendingActions.length) { + ecIns.trigger('finished'); + } + }); + }; + bindMouseEvent = function (zr, ecIns) { + zr.on('mouseover', function (e) { + var el = e.target; + var dispatcher = findEventDispatcher(el, isHighDownDispatcher); + if (dispatcher) { + handleGlobalMouseOverForHighDown(dispatcher, e, ecIns._api); + markStatusToUpdate(ecIns); + } + }).on('mouseout', function (e) { + var el = e.target; + var dispatcher = findEventDispatcher(el, isHighDownDispatcher); + if (dispatcher) { + handleGlobalMouseOutForHighDown(dispatcher, e, ecIns._api); + markStatusToUpdate(ecIns); + } + }).on('click', function (e) { + var el = e.target; + var dispatcher = findEventDispatcher(el, function (target) { + return getECData(target).dataIndex != null; + }, true); + if (dispatcher) { + var actionType = dispatcher.selected ? 'unselect' : 'select'; + var ecData = getECData(dispatcher); + ecIns._api.dispatchAction({ + type: actionType, + dataType: ecData.dataType, + dataIndexInside: ecData.dataIndex, + seriesIndex: ecData.seriesIndex, + isFromClick: true + }); + } + }); + }; + function clearColorPalette(ecModel) { + ecModel.clearColorPalette(); + ecModel.eachSeries(function (seriesModel) { + seriesModel.clearColorPalette(); + }); + } + // Allocate zlevels for series and components + function allocateZlevels(ecModel) { + var componentZLevels = []; + var seriesZLevels = []; + var hasSeparateZLevel = false; + ecModel.eachComponent(function (componentType, componentModel) { + var zlevel = componentModel.get('zlevel') || 0; + var z = componentModel.get('z') || 0; + var zlevelKey = componentModel.getZLevelKey(); + hasSeparateZLevel = hasSeparateZLevel || !!zlevelKey; + (componentType === 'series' ? seriesZLevels : componentZLevels).push({ + zlevel: zlevel, + z: z, + idx: componentModel.componentIndex, + type: componentType, + key: zlevelKey + }); + }); + if (hasSeparateZLevel) { + // Series after component + var zLevels = componentZLevels.concat(seriesZLevels); + var lastSeriesZLevel_1; + var lastSeriesKey_1; + sort(zLevels, function (a, b) { + if (a.zlevel === b.zlevel) { + return a.z - b.z; + } + return a.zlevel - b.zlevel; + }); + each(zLevels, function (item) { + var componentModel = ecModel.getComponent(item.type, item.idx); + var zlevel = item.zlevel; + var key = item.key; + if (lastSeriesZLevel_1 != null) { + zlevel = Math.max(lastSeriesZLevel_1, zlevel); + } + if (key) { + if (zlevel === lastSeriesZLevel_1 && key !== lastSeriesKey_1) { + zlevel++; + } + lastSeriesKey_1 = key; + } else if (lastSeriesKey_1) { + if (zlevel === lastSeriesZLevel_1) { + zlevel++; + } + lastSeriesKey_1 = ''; + } + lastSeriesZLevel_1 = zlevel; + componentModel.setZLevel(zlevel); + }); + } + } + render = function (ecIns, ecModel, api, payload, updateParams) { + allocateZlevels(ecModel); + renderComponents(ecIns, ecModel, api, payload, updateParams); + each(ecIns._chartsViews, function (chart) { + chart.__alive = false; + }); + renderSeries(ecIns, ecModel, api, payload, updateParams); + // Remove groups of unrendered charts + each(ecIns._chartsViews, function (chart) { + if (!chart.__alive) { + chart.remove(ecModel, api); + } + }); + }; + renderComponents = function (ecIns, ecModel, api, payload, updateParams, dirtyList) { + each(dirtyList || ecIns._componentsViews, function (componentView) { + var componentModel = componentView.__model; + clearStates(componentModel, componentView); + componentView.render(componentModel, ecModel, api, payload); + updateZ(componentModel, componentView); + updateStates(componentModel, componentView); + }); + }; + /** + * Render each chart and component + */ + renderSeries = function (ecIns, ecModel, api, payload, updateParams, dirtyMap) { + // Render all charts + var scheduler = ecIns._scheduler; + updateParams = extend(updateParams || {}, { + updatedSeries: ecModel.getSeries() + }); + // TODO progressive? + lifecycle.trigger('series:beforeupdate', ecModel, api, updateParams); + var unfinished = false; + ecModel.eachSeries(function (seriesModel) { + var chartView = ecIns._chartsMap[seriesModel.__viewId]; + chartView.__alive = true; + var renderTask = chartView.renderTask; + scheduler.updatePayload(renderTask, payload); + // TODO states on marker. + clearStates(seriesModel, chartView); + if (dirtyMap && dirtyMap.get(seriesModel.uid)) { + renderTask.dirty(); + } + if (renderTask.perform(scheduler.getPerformArgs(renderTask))) { + unfinished = true; + } + chartView.group.silent = !!seriesModel.get('silent'); + // Should not call markRedraw on group, because it will disable zrender + // incremental render (always render from the __startIndex each frame) + // chartView.group.markRedraw(); + updateBlend(seriesModel, chartView); + updateSeriesElementSelection(seriesModel); + }); + scheduler.unfinished = unfinished || scheduler.unfinished; + lifecycle.trigger('series:layoutlabels', ecModel, api, updateParams); + // transition after label is layouted. + lifecycle.trigger('series:transition', ecModel, api, updateParams); + ecModel.eachSeries(function (seriesModel) { + var chartView = ecIns._chartsMap[seriesModel.__viewId]; + // Update Z after labels updated. Before applying states. + updateZ(seriesModel, chartView); + // NOTE: Update states after label is updated. + // label should be in normal status when layouting. + updateStates(seriesModel, chartView); + }); + // If use hover layer + updateHoverLayerStatus(ecIns, ecModel); + lifecycle.trigger('series:afterupdate', ecModel, api, updateParams); + }; + markStatusToUpdate = function (ecIns) { + ecIns[STATUS_NEEDS_UPDATE_KEY] = true; + // Wake up zrender if it's sleep. Let it update states in the next frame. + ecIns.getZr().wakeUp(); + }; + applyChangedStates = function (ecIns) { + if (!ecIns[STATUS_NEEDS_UPDATE_KEY]) { + return; + } + ecIns.getZr().storage.traverse(function (el) { + // Not applied on removed elements, it may still in fading. + if (isElementRemoved(el)) { + return; + } + applyElementStates(el); + }); + ecIns[STATUS_NEEDS_UPDATE_KEY] = false; + }; + function applyElementStates(el) { + var newStates = []; + var oldStates = el.currentStates; + // Keep other states. + for (var i = 0; i < oldStates.length; i++) { + var stateName = oldStates[i]; + if (!(stateName === 'emphasis' || stateName === 'blur' || stateName === 'select')) { + newStates.push(stateName); + } + } + // Only use states when it's exists. + if (el.selected && el.states.select) { + newStates.push('select'); + } + if (el.hoverState === HOVER_STATE_EMPHASIS && el.states.emphasis) { + newStates.push('emphasis'); + } else if (el.hoverState === HOVER_STATE_BLUR && el.states.blur) { + newStates.push('blur'); + } + el.useStates(newStates); + } + function updateHoverLayerStatus(ecIns, ecModel) { + var zr = ecIns._zr; + var storage = zr.storage; + var elCount = 0; + storage.traverse(function (el) { + if (!el.isGroup) { + elCount++; + } + }); + if (elCount > ecModel.get('hoverLayerThreshold') && !env.node && !env.worker) { + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.preventUsingHoverLayer) { + return; + } + var chartView = ecIns._chartsMap[seriesModel.__viewId]; + if (chartView.__alive) { + chartView.eachRendered(function (el) { + if (el.states.emphasis) { + el.states.emphasis.hoverLayer = true; + } + }); + } + }); + } + } + /** + * Update chart and blend. + */ + function updateBlend(seriesModel, chartView) { + var blendMode = seriesModel.get('blendMode') || null; + chartView.eachRendered(function (el) { + // FIXME marker and other components + if (!el.isGroup) { + // DON'T mark the element dirty. In case element is incremental and don't want to rerender. + el.style.blend = blendMode; + } + }); + } + function updateZ(model, view) { + if (model.preventAutoZ) { + return; + } + var z = model.get('z') || 0; + var zlevel = model.get('zlevel') || 0; + // Set z and zlevel + view.eachRendered(function (el) { + doUpdateZ(el, z, zlevel, -Infinity); + // Don't traverse the children because it has been traversed in _updateZ. + return true; + }); + } + function doUpdateZ(el, z, zlevel, maxZ2) { + // Group may also have textContent + var label = el.getTextContent(); + var labelLine = el.getTextGuideLine(); + var isGroup = el.isGroup; + if (isGroup) { + // set z & zlevel of children elements of Group + var children = el.childrenRef(); + for (var i = 0; i < children.length; i++) { + maxZ2 = Math.max(doUpdateZ(children[i], z, zlevel, maxZ2), maxZ2); + } + } else { + // not Group + el.z = z; + el.zlevel = zlevel; + maxZ2 = Math.max(el.z2, maxZ2); + } + // always set z and zlevel if label/labelLine exists + if (label) { + label.z = z; + label.zlevel = zlevel; + // lift z2 of text content + // TODO if el.emphasis.z2 is spcefied, what about textContent. + isFinite(maxZ2) && (label.z2 = maxZ2 + 2); + } + if (labelLine) { + var textGuideLineConfig = el.textGuideLineConfig; + labelLine.z = z; + labelLine.zlevel = zlevel; + isFinite(maxZ2) && (labelLine.z2 = maxZ2 + (textGuideLineConfig && textGuideLineConfig.showAbove ? 1 : -1)); + } + return maxZ2; + } + // Clear states without animation. + // TODO States on component. + function clearStates(model, view) { + view.eachRendered(function (el) { + // Not applied on removed elements, it may still in fading. + if (isElementRemoved(el)) { + return; + } + var textContent = el.getTextContent(); + var textGuide = el.getTextGuideLine(); + if (el.stateTransition) { + el.stateTransition = null; + } + if (textContent && textContent.stateTransition) { + textContent.stateTransition = null; + } + if (textGuide && textGuide.stateTransition) { + textGuide.stateTransition = null; + } + // TODO If el is incremental. + if (el.hasState()) { + el.prevStates = el.currentStates; + el.clearStates(); + } else if (el.prevStates) { + el.prevStates = null; + } + }); + } + function updateStates(model, view) { + var stateAnimationModel = model.getModel('stateAnimation'); + var enableAnimation = model.isAnimationEnabled(); + var duration = stateAnimationModel.get('duration'); + var stateTransition = duration > 0 ? { + duration: duration, + delay: stateAnimationModel.get('delay'), + easing: stateAnimationModel.get('easing') + // additive: stateAnimationModel.get('additive') + } : null; + view.eachRendered(function (el) { + if (el.states && el.states.emphasis) { + // Not applied on removed elements, it may still in fading. + if (isElementRemoved(el)) { + return; + } + if (el instanceof Path) { + savePathStates(el); + } + // Only updated on changed element. In case element is incremental and don't want to rerender. + // TODO, a more proper way? + if (el.__dirty) { + var prevStates = el.prevStates; + // Restore states without animation + if (prevStates) { + el.useStates(prevStates); + } + } + // Update state transition and enable animation again. + if (enableAnimation) { + el.stateTransition = stateTransition; + var textContent = el.getTextContent(); + var textGuide = el.getTextGuideLine(); + // TODO Is it necessary to animate label? + if (textContent) { + textContent.stateTransition = stateTransition; + } + if (textGuide) { + textGuide.stateTransition = stateTransition; + } + } + // Use highlighted and selected flag to toggle states. + if (el.__dirty) { + applyElementStates(el); + } + } + }); + } + createExtensionAPI = function (ecIns) { + return new ( /** @class */function (_super) { + __extends(class_1, _super); + function class_1() { + return _super !== null && _super.apply(this, arguments) || this; + } + class_1.prototype.getCoordinateSystems = function () { + return ecIns._coordSysMgr.getCoordinateSystems(); + }; + class_1.prototype.getComponentByElement = function (el) { + while (el) { + var modelInfo = el.__ecComponentInfo; + if (modelInfo != null) { + return ecIns._model.getComponent(modelInfo.mainType, modelInfo.index); + } + el = el.parent; + } + }; + class_1.prototype.enterEmphasis = function (el, highlightDigit) { + enterEmphasis(el, highlightDigit); + markStatusToUpdate(ecIns); + }; + class_1.prototype.leaveEmphasis = function (el, highlightDigit) { + leaveEmphasis(el, highlightDigit); + markStatusToUpdate(ecIns); + }; + class_1.prototype.enterBlur = function (el) { + enterBlur(el); + markStatusToUpdate(ecIns); + }; + class_1.prototype.leaveBlur = function (el) { + leaveBlur(el); + markStatusToUpdate(ecIns); + }; + class_1.prototype.enterSelect = function (el) { + enterSelect(el); + markStatusToUpdate(ecIns); + }; + class_1.prototype.leaveSelect = function (el) { + leaveSelect(el); + markStatusToUpdate(ecIns); + }; + class_1.prototype.getModel = function () { + return ecIns.getModel(); + }; + class_1.prototype.getViewOfComponentModel = function (componentModel) { + return ecIns.getViewOfComponentModel(componentModel); + }; + class_1.prototype.getViewOfSeriesModel = function (seriesModel) { + return ecIns.getViewOfSeriesModel(seriesModel); + }; + return class_1; + }(ExtensionAPI))(ecIns); + }; + enableConnect = function (chart) { + function updateConnectedChartsStatus(charts, status) { + for (var i = 0; i < charts.length; i++) { + var otherChart = charts[i]; + otherChart[CONNECT_STATUS_KEY] = status; + } + } + each(eventActionMap, function (actionType, eventType) { + chart._messageCenter.on(eventType, function (event) { + if (connectedGroups[chart.group] && chart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_PENDING) { + if (event && event.escapeConnect) { + return; + } + var action_1 = chart.makeActionFromEvent(event); + var otherCharts_1 = []; + each(instances$1, function (otherChart) { + if (otherChart !== chart && otherChart.group === chart.group) { + otherCharts_1.push(otherChart); + } + }); + updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_PENDING); + each(otherCharts_1, function (otherChart) { + if (otherChart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_UPDATING) { + otherChart.dispatchAction(action_1); + } + }); + updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_UPDATED); + } + }); + }); + }; + }(); + return ECharts; + }(Eventful); + var echartsProto = ECharts.prototype; + echartsProto.on = createRegisterEventWithLowercaseECharts('on'); + echartsProto.off = createRegisterEventWithLowercaseECharts('off'); + /** + * @deprecated + */ + // @ts-ignore + echartsProto.one = function (eventName, cb, ctx) { + var self = this; + deprecateLog('ECharts#one is deprecated.'); + function wrapped() { + var args2 = []; + for (var _i = 0; _i < arguments.length; _i++) { + args2[_i] = arguments[_i]; + } + cb && cb.apply && cb.apply(this, args2); + // @ts-ignore + self.off(eventName, wrapped); + } + // @ts-ignore + this.on.call(this, eventName, wrapped, ctx); + }; + var MOUSE_EVENT_NAMES = ['click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'mouseup', 'globalout', 'contextmenu']; + function disposedWarning(id) { + if ("development" !== 'production') { + warn('Instance ' + id + ' has been disposed'); + } + } + var actions = {}; + /** + * Map eventType to actionType + */ + var eventActionMap = {}; + var dataProcessorFuncs = []; + var optionPreprocessorFuncs = []; + var visualFuncs = []; + var themeStorage = {}; + var loadingEffects = {}; + var instances$1 = {}; + var connectedGroups = {}; + var idBase = +new Date() - 0; + var groupIdBase = +new Date() - 0; + var DOM_ATTRIBUTE_KEY = '_echarts_instance_'; + /** + * @param opts.devicePixelRatio Use window.devicePixelRatio by default + * @param opts.renderer Can choose 'canvas' or 'svg' to render the chart. + * @param opts.width Use clientWidth of the input `dom` by default. + * Can be 'auto' (the same as null/undefined) + * @param opts.height Use clientHeight of the input `dom` by default. + * Can be 'auto' (the same as null/undefined) + * @param opts.locale Specify the locale. + * @param opts.useDirtyRect Enable dirty rectangle rendering or not. + */ + function init$1(dom, theme, opts) { + var isClient = !(opts && opts.ssr); + if (isClient) { + if ("development" !== 'production') { + if (!dom) { + throw new Error('Initialize failed: invalid dom.'); + } + } + var existInstance = getInstanceByDom(dom); + if (existInstance) { + if ("development" !== 'production') { + warn('There is a chart instance already initialized on the dom.'); + } + return existInstance; + } + if ("development" !== 'production') { + if (isDom(dom) && dom.nodeName.toUpperCase() !== 'CANVAS' && (!dom.clientWidth && (!opts || opts.width == null) || !dom.clientHeight && (!opts || opts.height == null))) { + warn('Can\'t get DOM width or height. Please check ' + 'dom.clientWidth and dom.clientHeight. They should not be 0.' + 'For example, you may need to call this in the callback ' + 'of window.onload.'); + } + } + } + var chart = new ECharts(dom, theme, opts); + chart.id = 'ec_' + idBase++; + instances$1[chart.id] = chart; + isClient && setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id); + enableConnect(chart); + lifecycle.trigger('afterinit', chart); + return chart; + } + /** + * @usage + * (A) + * ```js + * let chart1 = echarts.init(dom1); + * let chart2 = echarts.init(dom2); + * chart1.group = 'xxx'; + * chart2.group = 'xxx'; + * echarts.connect('xxx'); + * ``` + * (B) + * ```js + * let chart1 = echarts.init(dom1); + * let chart2 = echarts.init(dom2); + * echarts.connect('xxx', [chart1, chart2]); + * ``` + */ + function connect(groupId) { + // Is array of charts + if (isArray(groupId)) { + var charts = groupId; + groupId = null; + // If any chart has group + each(charts, function (chart) { + if (chart.group != null) { + groupId = chart.group; + } + }); + groupId = groupId || 'g_' + groupIdBase++; + each(charts, function (chart) { + chart.group = groupId; + }); + } + connectedGroups[groupId] = true; + return groupId; + } + function disconnect(groupId) { + connectedGroups[groupId] = false; + } + /** + * Alias and backward compatibility + * @deprecated + */ + var disConnect = disconnect; + /** + * Dispose a chart instance + */ + function dispose$1(chart) { + if (isString(chart)) { + chart = instances$1[chart]; + } else if (!(chart instanceof ECharts)) { + // Try to treat as dom + chart = getInstanceByDom(chart); + } + if (chart instanceof ECharts && !chart.isDisposed()) { + chart.dispose(); + } + } + function getInstanceByDom(dom) { + return instances$1[getAttribute(dom, DOM_ATTRIBUTE_KEY)]; + } + function getInstanceById(key) { + return instances$1[key]; + } + /** + * Register theme + */ + function registerTheme(name, theme) { + themeStorage[name] = theme; + } + /** + * Register option preprocessor + */ + function registerPreprocessor(preprocessorFunc) { + if (indexOf(optionPreprocessorFuncs, preprocessorFunc) < 0) { + optionPreprocessorFuncs.push(preprocessorFunc); + } + } + function registerProcessor(priority, processor) { + normalizeRegister(dataProcessorFuncs, priority, processor, PRIORITY_PROCESSOR_DEFAULT); + } + /** + * Register postIniter + * @param {Function} postInitFunc + */ + function registerPostInit(postInitFunc) { + registerUpdateLifecycle('afterinit', postInitFunc); + } + /** + * Register postUpdater + * @param {Function} postUpdateFunc + */ + function registerPostUpdate(postUpdateFunc) { + registerUpdateLifecycle('afterupdate', postUpdateFunc); + } + function registerUpdateLifecycle(name, cb) { + lifecycle.on(name, cb); + } + function registerAction(actionInfo, eventName, action) { + if (isFunction(eventName)) { + action = eventName; + eventName = ''; + } + var actionType = isObject(actionInfo) ? actionInfo.type : [actionInfo, actionInfo = { + event: eventName + }][0]; + // Event name is all lowercase + actionInfo.event = (actionInfo.event || actionType).toLowerCase(); + eventName = actionInfo.event; + if (eventActionMap[eventName]) { + // Already registered. + return; + } + // Validate action type and event name. + assert(ACTION_REG.test(actionType) && ACTION_REG.test(eventName)); + if (!actions[actionType]) { + actions[actionType] = { + action: action, + actionInfo: actionInfo + }; + } + eventActionMap[eventName] = actionType; + } + function registerCoordinateSystem(type, coordSysCreator) { + CoordinateSystemManager.register(type, coordSysCreator); + } + /** + * Get dimensions of specified coordinate system. + * @param {string} type + * @return {Array.} + */ + function getCoordinateSystemDimensions(type) { + var coordSysCreator = CoordinateSystemManager.get(type); + if (coordSysCreator) { + return coordSysCreator.getDimensionsInfo ? coordSysCreator.getDimensionsInfo() : coordSysCreator.dimensions.slice(); + } + } + function registerLayout(priority, layoutTask) { + normalizeRegister(visualFuncs, priority, layoutTask, PRIORITY_VISUAL_LAYOUT, 'layout'); + } + function registerVisual(priority, visualTask) { + normalizeRegister(visualFuncs, priority, visualTask, PRIORITY_VISUAL_CHART, 'visual'); + } + var registeredTasks = []; + function normalizeRegister(targetList, priority, fn, defaultPriority, visualType) { + if (isFunction(priority) || isObject(priority)) { + fn = priority; + priority = defaultPriority; + } + if ("development" !== 'production') { + if (isNaN(priority) || priority == null) { + throw new Error('Illegal priority'); + } + // Check duplicate + each(targetList, function (wrap) { + assert(wrap.__raw !== fn); + }); + } + // Already registered + if (indexOf(registeredTasks, fn) >= 0) { + return; + } + registeredTasks.push(fn); + var stageHandler = Scheduler.wrapStageHandler(fn, visualType); + stageHandler.__prio = priority; + stageHandler.__raw = fn; + targetList.push(stageHandler); + } + function registerLoading(name, loadingFx) { + loadingEffects[name] = loadingFx; + } + /** + * ZRender need a canvas context to do measureText. + * But in node environment canvas may be created by node-canvas. + * So we need to specify how to create a canvas instead of using document.createElement('canvas') + * + * + * @deprecated use setPlatformAPI({ createCanvas }) instead. + * + * @example + * let Canvas = require('canvas'); + * let echarts = require('echarts'); + * echarts.setCanvasCreator(function () { + * // Small size is enough. + * return new Canvas(32, 32); + * }); + */ + function setCanvasCreator(creator) { + if ("development" !== 'production') { + deprecateLog('setCanvasCreator is deprecated. Use setPlatformAPI({ createCanvas }) instead.'); + } + setPlatformAPI({ + createCanvas: creator + }); + } + /** + * The parameters and usage: see `geoSourceManager.registerMap`. + * Compatible with previous `echarts.registerMap`. + */ + function registerMap(mapName, geoJson, specialAreas) { + var registerMap = getImpl('registerMap'); + registerMap && registerMap(mapName, geoJson, specialAreas); + } + function getMap(mapName) { + var getMap = getImpl('getMap'); + return getMap && getMap(mapName); + } + var registerTransform = registerExternalTransform; + /** + * Globa dispatchAction to a specified chart instance. + */ + // export function dispatchAction(payload: { chartId: string } & Payload, opt?: Parameters[1]) { + // if (!payload || !payload.chartId) { + // // Must have chartId to find chart + // return; + // } + // const chart = instances[payload.chartId]; + // if (chart) { + // chart.dispatchAction(payload, opt); + // } + // } + // Builtin global visual + registerVisual(PRIORITY_VISUAL_GLOBAL, seriesStyleTask); + registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataStyleTask); + registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataColorPaletteTask); + registerVisual(PRIORITY_VISUAL_GLOBAL, seriesSymbolTask); + registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataSymbolTask); + registerVisual(PRIORITY_VISUAL_DECAL, decalVisual); + registerPreprocessor(globalBackwardCompat); + registerProcessor(PRIORITY_PROCESSOR_DATASTACK, dataStack); + registerLoading('default', defaultLoading); + // Default actions + registerAction({ + type: HIGHLIGHT_ACTION_TYPE, + event: HIGHLIGHT_ACTION_TYPE, + update: HIGHLIGHT_ACTION_TYPE + }, noop); + registerAction({ + type: DOWNPLAY_ACTION_TYPE, + event: DOWNPLAY_ACTION_TYPE, + update: DOWNPLAY_ACTION_TYPE + }, noop); + registerAction({ + type: SELECT_ACTION_TYPE, + event: SELECT_ACTION_TYPE, + update: SELECT_ACTION_TYPE + }, noop); + registerAction({ + type: UNSELECT_ACTION_TYPE, + event: UNSELECT_ACTION_TYPE, + update: UNSELECT_ACTION_TYPE + }, noop); + registerAction({ + type: TOGGLE_SELECT_ACTION_TYPE, + event: TOGGLE_SELECT_ACTION_TYPE, + update: TOGGLE_SELECT_ACTION_TYPE + }, noop); + // Default theme + registerTheme('light', lightTheme); + registerTheme('dark', theme); + // For backward compatibility, where the namespace `dataTool` will + // be mounted on `echarts` is the extension `dataTool` is imported. + var dataTool = {}; + + var extensions = []; + var extensionRegisters = { + registerPreprocessor: registerPreprocessor, + registerProcessor: registerProcessor, + registerPostInit: registerPostInit, + registerPostUpdate: registerPostUpdate, + registerUpdateLifecycle: registerUpdateLifecycle, + registerAction: registerAction, + registerCoordinateSystem: registerCoordinateSystem, + registerLayout: registerLayout, + registerVisual: registerVisual, + registerTransform: registerTransform, + registerLoading: registerLoading, + registerMap: registerMap, + registerImpl: registerImpl, + PRIORITY: PRIORITY, + ComponentModel: ComponentModel, + ComponentView: ComponentView, + SeriesModel: SeriesModel, + ChartView: ChartView, + // TODO Use ComponentModel and SeriesModel instead of Constructor + registerComponentModel: function (ComponentModelClass) { + ComponentModel.registerClass(ComponentModelClass); + }, + registerComponentView: function (ComponentViewClass) { + ComponentView.registerClass(ComponentViewClass); + }, + registerSeriesModel: function (SeriesModelClass) { + SeriesModel.registerClass(SeriesModelClass); + }, + registerChartView: function (ChartViewClass) { + ChartView.registerClass(ChartViewClass); + }, + registerSubTypeDefaulter: function (componentType, defaulter) { + ComponentModel.registerSubTypeDefaulter(componentType, defaulter); + }, + registerPainter: function (painterType, PainterCtor) { + registerPainter(painterType, PainterCtor); + } + }; + function use(ext) { + if (isArray(ext)) { + // use([ChartLine, ChartBar]); + each(ext, function (singleExt) { + use(singleExt); + }); + return; + } + if (indexOf(extensions, ext) >= 0) { + return; + } + extensions.push(ext); + if (isFunction(ext)) { + ext = { + install: ext + }; + } + ext.install(extensionRegisters); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function dataIndexMapValueLength(valNumOrArrLengthMoreThan2) { + return valNumOrArrLengthMoreThan2 == null ? 0 : valNumOrArrLengthMoreThan2.length || 1; + } + function defaultKeyGetter(item) { + return item; + } + var DataDiffer = /** @class */function () { + /** + * @param context Can be visited by this.context in callback. + */ + function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter, context, + // By default: 'oneToOne'. + diffMode) { + this._old = oldArr; + this._new = newArr; + this._oldKeyGetter = oldKeyGetter || defaultKeyGetter; + this._newKeyGetter = newKeyGetter || defaultKeyGetter; + // Visible in callback via `this.context`; + this.context = context; + this._diffModeMultiple = diffMode === 'multiple'; + } + /** + * Callback function when add a data + */ + DataDiffer.prototype.add = function (func) { + this._add = func; + return this; + }; + /** + * Callback function when update a data + */ + DataDiffer.prototype.update = function (func) { + this._update = func; + return this; + }; + /** + * Callback function when update a data and only work in `cbMode: 'byKey'`. + */ + DataDiffer.prototype.updateManyToOne = function (func) { + this._updateManyToOne = func; + return this; + }; + /** + * Callback function when update a data and only work in `cbMode: 'byKey'`. + */ + DataDiffer.prototype.updateOneToMany = function (func) { + this._updateOneToMany = func; + return this; + }; + /** + * Callback function when update a data and only work in `cbMode: 'byKey'`. + */ + DataDiffer.prototype.updateManyToMany = function (func) { + this._updateManyToMany = func; + return this; + }; + /** + * Callback function when remove a data + */ + DataDiffer.prototype.remove = function (func) { + this._remove = func; + return this; + }; + DataDiffer.prototype.execute = function () { + this[this._diffModeMultiple ? '_executeMultiple' : '_executeOneToOne'](); + }; + DataDiffer.prototype._executeOneToOne = function () { + var oldArr = this._old; + var newArr = this._new; + var newDataIndexMap = {}; + var oldDataKeyArr = new Array(oldArr.length); + var newDataKeyArr = new Array(newArr.length); + this._initIndexMap(oldArr, null, oldDataKeyArr, '_oldKeyGetter'); + this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter'); + for (var i = 0; i < oldArr.length; i++) { + var oldKey = oldDataKeyArr[i]; + var newIdxMapVal = newDataIndexMap[oldKey]; + var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal); + // idx can never be empty array here. see 'set null' logic below. + if (newIdxMapValLen > 1) { + // Consider there is duplicate key (for example, use dataItem.name as key). + // We should make sure every item in newArr and oldArr can be visited. + var newIdx = newIdxMapVal.shift(); + if (newIdxMapVal.length === 1) { + newDataIndexMap[oldKey] = newIdxMapVal[0]; + } + this._update && this._update(newIdx, i); + } else if (newIdxMapValLen === 1) { + newDataIndexMap[oldKey] = null; + this._update && this._update(newIdxMapVal, i); + } else { + this._remove && this._remove(i); + } + } + this._performRestAdd(newDataKeyArr, newDataIndexMap); + }; + /** + * For example, consider the case: + * oldData: [o0, o1, o2, o3, o4, o5, o6, o7], + * newData: [n0, n1, n2, n3, n4, n5, n6, n7, n8], + * Where: + * o0, o1, n0 has key 'a' (many to one) + * o5, n4, n5, n6 has key 'b' (one to many) + * o2, n1 has key 'c' (one to one) + * n2, n3 has key 'd' (add) + * o3, o4 has key 'e' (remove) + * o6, o7, n7, n8 has key 'f' (many to many, treated as add and remove) + * Then: + * (The order of the following directives are not ensured.) + * this._updateManyToOne(n0, [o0, o1]); + * this._updateOneToMany([n4, n5, n6], o5); + * this._update(n1, o2); + * this._remove(o3); + * this._remove(o4); + * this._remove(o6); + * this._remove(o7); + * this._add(n2); + * this._add(n3); + * this._add(n7); + * this._add(n8); + */ + DataDiffer.prototype._executeMultiple = function () { + var oldArr = this._old; + var newArr = this._new; + var oldDataIndexMap = {}; + var newDataIndexMap = {}; + var oldDataKeyArr = []; + var newDataKeyArr = []; + this._initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, '_oldKeyGetter'); + this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter'); + for (var i = 0; i < oldDataKeyArr.length; i++) { + var oldKey = oldDataKeyArr[i]; + var oldIdxMapVal = oldDataIndexMap[oldKey]; + var newIdxMapVal = newDataIndexMap[oldKey]; + var oldIdxMapValLen = dataIndexMapValueLength(oldIdxMapVal); + var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal); + if (oldIdxMapValLen > 1 && newIdxMapValLen === 1) { + this._updateManyToOne && this._updateManyToOne(newIdxMapVal, oldIdxMapVal); + newDataIndexMap[oldKey] = null; + } else if (oldIdxMapValLen === 1 && newIdxMapValLen > 1) { + this._updateOneToMany && this._updateOneToMany(newIdxMapVal, oldIdxMapVal); + newDataIndexMap[oldKey] = null; + } else if (oldIdxMapValLen === 1 && newIdxMapValLen === 1) { + this._update && this._update(newIdxMapVal, oldIdxMapVal); + newDataIndexMap[oldKey] = null; + } else if (oldIdxMapValLen > 1 && newIdxMapValLen > 1) { + this._updateManyToMany && this._updateManyToMany(newIdxMapVal, oldIdxMapVal); + newDataIndexMap[oldKey] = null; + } else if (oldIdxMapValLen > 1) { + for (var i_1 = 0; i_1 < oldIdxMapValLen; i_1++) { + this._remove && this._remove(oldIdxMapVal[i_1]); + } + } else { + this._remove && this._remove(oldIdxMapVal); + } + } + this._performRestAdd(newDataKeyArr, newDataIndexMap); + }; + DataDiffer.prototype._performRestAdd = function (newDataKeyArr, newDataIndexMap) { + for (var i = 0; i < newDataKeyArr.length; i++) { + var newKey = newDataKeyArr[i]; + var newIdxMapVal = newDataIndexMap[newKey]; + var idxMapValLen = dataIndexMapValueLength(newIdxMapVal); + if (idxMapValLen > 1) { + for (var j = 0; j < idxMapValLen; j++) { + this._add && this._add(newIdxMapVal[j]); + } + } else if (idxMapValLen === 1) { + this._add && this._add(newIdxMapVal); + } + // Support both `newDataKeyArr` are duplication removed or not removed. + newDataIndexMap[newKey] = null; + } + }; + DataDiffer.prototype._initIndexMap = function (arr, + // Can be null. + map, + // In 'byKey', the output `keyArr` is duplication removed. + // In 'byIndex', the output `keyArr` is not duplication removed and + // its indices are accurately corresponding to `arr`. + keyArr, keyGetterName) { + var cbModeMultiple = this._diffModeMultiple; + for (var i = 0; i < arr.length; i++) { + // Add prefix to avoid conflict with Object.prototype. + var key = '_ec_' + this[keyGetterName](arr[i], i); + if (!cbModeMultiple) { + keyArr[i] = key; + } + if (!map) { + continue; + } + var idxMapVal = map[key]; + var idxMapValLen = dataIndexMapValueLength(idxMapVal); + if (idxMapValLen === 0) { + // Simple optimize: in most cases, one index has one key, + // do not need array. + map[key] = i; + if (cbModeMultiple) { + keyArr.push(key); + } + } else if (idxMapValLen === 1) { + map[key] = [idxMapVal, i]; + } else { + idxMapVal.push(i); + } + } + }; + return DataDiffer; + }(); + + var DimensionUserOuput = /** @class */function () { + function DimensionUserOuput(encode, dimRequest) { + this._encode = encode; + this._schema = dimRequest; + } + DimensionUserOuput.prototype.get = function () { + return { + // Do not generate full dimension name until fist used. + fullDimensions: this._getFullDimensionNames(), + encode: this._encode + }; + }; + /** + * Get all data store dimension names. + * Theoretically a series data store is defined both by series and used dataset (if any). + * If some dimensions are omitted for performance reason in `this.dimensions`, + * the dimension name may not be auto-generated if user does not specify a dimension name. + * In this case, the dimension name is `null`/`undefined`. + */ + DimensionUserOuput.prototype._getFullDimensionNames = function () { + if (!this._cachedDimNames) { + this._cachedDimNames = this._schema ? this._schema.makeOutputDimensionNames() : []; + } + return this._cachedDimNames; + }; + return DimensionUserOuput; + }(); + function summarizeDimensions(data, schema) { + var summary = {}; + var encode = summary.encode = {}; + var notExtraCoordDimMap = createHashMap(); + var defaultedLabel = []; + var defaultedTooltip = []; + var userOutputEncode = {}; + each(data.dimensions, function (dimName) { + var dimItem = data.getDimensionInfo(dimName); + var coordDim = dimItem.coordDim; + if (coordDim) { + if ("development" !== 'production') { + assert(VISUAL_DIMENSIONS.get(coordDim) == null); + } + var coordDimIndex = dimItem.coordDimIndex; + getOrCreateEncodeArr(encode, coordDim)[coordDimIndex] = dimName; + if (!dimItem.isExtraCoord) { + notExtraCoordDimMap.set(coordDim, 1); + // Use the last coord dim (and label friendly) as default label, + // because when dataset is used, it is hard to guess which dimension + // can be value dimension. If both show x, y on label is not look good, + // and conventionally y axis is focused more. + if (mayLabelDimType(dimItem.type)) { + defaultedLabel[0] = dimName; + } + // User output encode do not contain generated coords. + // And it only has index. User can use index to retrieve value from the raw item array. + getOrCreateEncodeArr(userOutputEncode, coordDim)[coordDimIndex] = data.getDimensionIndex(dimItem.name); + } + if (dimItem.defaultTooltip) { + defaultedTooltip.push(dimName); + } + } + VISUAL_DIMENSIONS.each(function (v, otherDim) { + var encodeArr = getOrCreateEncodeArr(encode, otherDim); + var dimIndex = dimItem.otherDims[otherDim]; + if (dimIndex != null && dimIndex !== false) { + encodeArr[dimIndex] = dimItem.name; + } + }); + }); + var dataDimsOnCoord = []; + var encodeFirstDimNotExtra = {}; + notExtraCoordDimMap.each(function (v, coordDim) { + var dimArr = encode[coordDim]; + encodeFirstDimNotExtra[coordDim] = dimArr[0]; + // Not necessary to remove duplicate, because a data + // dim canot on more than one coordDim. + dataDimsOnCoord = dataDimsOnCoord.concat(dimArr); + }); + summary.dataDimsOnCoord = dataDimsOnCoord; + summary.dataDimIndicesOnCoord = map(dataDimsOnCoord, function (dimName) { + return data.getDimensionInfo(dimName).storeDimIndex; + }); + summary.encodeFirstDimNotExtra = encodeFirstDimNotExtra; + var encodeLabel = encode.label; + // FIXME `encode.label` is not recommended, because formatter cannot be set + // in this way. Use label.formatter instead. Maybe remove this approach someday. + if (encodeLabel && encodeLabel.length) { + defaultedLabel = encodeLabel.slice(); + } + var encodeTooltip = encode.tooltip; + if (encodeTooltip && encodeTooltip.length) { + defaultedTooltip = encodeTooltip.slice(); + } else if (!defaultedTooltip.length) { + defaultedTooltip = defaultedLabel.slice(); + } + encode.defaultedLabel = defaultedLabel; + encode.defaultedTooltip = defaultedTooltip; + summary.userOutput = new DimensionUserOuput(userOutputEncode, schema); + return summary; + } + function getOrCreateEncodeArr(encode, dim) { + if (!encode.hasOwnProperty(dim)) { + encode[dim] = []; + } + return encode[dim]; + } + // FIXME:TS should be type `AxisType` + function getDimensionTypeByAxis(axisType) { + return axisType === 'category' ? 'ordinal' : axisType === 'time' ? 'time' : 'float'; + } + function mayLabelDimType(dimType) { + // In most cases, ordinal and time do not suitable for label. + // Ordinal info can be displayed on axis. Time is too long. + return !(dimType === 'ordinal' || dimType === 'time'); + } + // function findTheLastDimMayLabel(data) { + // // Get last value dim + // let dimensions = data.dimensions.slice(); + // let valueType; + // let valueDim; + // while (dimensions.length && ( + // valueDim = dimensions.pop(), + // valueType = data.getDimensionInfo(valueDim).type, + // valueType === 'ordinal' || valueType === 'time' + // )) {} // jshint ignore:line + // return valueDim; + // } + + var SeriesDimensionDefine = /** @class */function () { + /** + * @param opt All of the fields will be shallow copied. + */ + function SeriesDimensionDefine(opt) { + /** + * The format of `otherDims` is: + * ```js + * { + * tooltip?: number + * label?: number + * itemName?: number + * seriesName?: number + * } + * ``` + * + * A `series.encode` can specified these fields: + * ```js + * encode: { + * // "3, 1, 5" is the index of data dimension. + * tooltip: [3, 1, 5], + * label: [0, 3], + * ... + * } + * ``` + * `otherDims` is the parse result of the `series.encode` above, like: + * ```js + * // Suppose the index of this data dimension is `3`. + * this.otherDims = { + * // `3` is at the index `0` of the `encode.tooltip` + * tooltip: 0, + * // `3` is at the index `1` of the `encode.label` + * label: 1 + * }; + * ``` + * + * This prop should never be `null`/`undefined` after initialized. + */ + this.otherDims = {}; + if (opt != null) { + extend(this, opt); + } + } + return SeriesDimensionDefine; + }(); + + var inner$4 = makeInner(); + var dimTypeShort = { + float: 'f', + int: 'i', + ordinal: 'o', + number: 'n', + time: 't' + }; + /** + * Represents the dimension requirement of a series. + * + * NOTICE: + * When there are too many dimensions in dataset and many series, only the used dimensions + * (i.e., used by coord sys and declared in `series.encode`) are add to `dimensionDefineList`. + * But users may query data by other unused dimension names. + * In this case, users can only query data if and only if they have defined dimension names + * via ec option, so we provide `getDimensionIndexFromSource`, which only query them from + * `source` dimensions. + */ + var SeriesDataSchema = /** @class */function () { + function SeriesDataSchema(opt) { + this.dimensions = opt.dimensions; + this._dimOmitted = opt.dimensionOmitted; + this.source = opt.source; + this._fullDimCount = opt.fullDimensionCount; + this._updateDimOmitted(opt.dimensionOmitted); + } + SeriesDataSchema.prototype.isDimensionOmitted = function () { + return this._dimOmitted; + }; + SeriesDataSchema.prototype._updateDimOmitted = function (dimensionOmitted) { + this._dimOmitted = dimensionOmitted; + if (!dimensionOmitted) { + return; + } + if (!this._dimNameMap) { + this._dimNameMap = ensureSourceDimNameMap(this.source); + } + }; + /** + * @caution Can only be used when `dimensionOmitted: true`. + * + * Get index by user defined dimension name (i.e., not internal generate name). + * That is, get index from `dimensionsDefine`. + * If no `dimensionsDefine`, or no name get, return -1. + */ + SeriesDataSchema.prototype.getSourceDimensionIndex = function (dimName) { + return retrieve2(this._dimNameMap.get(dimName), -1); + }; + /** + * @caution Can only be used when `dimensionOmitted: true`. + * + * Notice: may return `null`/`undefined` if user not specify dimension names. + */ + SeriesDataSchema.prototype.getSourceDimension = function (dimIndex) { + var dimensionsDefine = this.source.dimensionsDefine; + if (dimensionsDefine) { + return dimensionsDefine[dimIndex]; + } + }; + SeriesDataSchema.prototype.makeStoreSchema = function () { + var dimCount = this._fullDimCount; + var willRetrieveDataByName = shouldRetrieveDataByName(this.source); + var makeHashStrict = !shouldOmitUnusedDimensions(dimCount); + // If source don't have dimensions or series don't omit unsed dimensions. + // Generate from seriesDimList directly + var dimHash = ''; + var dims = []; + for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < dimCount; fullDimIdx++) { + var property = void 0; + var type = void 0; + var ordinalMeta = void 0; + var seriesDimDef = this.dimensions[seriesDimIdx]; + // The list has been sorted by `storeDimIndex` asc. + if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) { + property = willRetrieveDataByName ? seriesDimDef.name : null; + type = seriesDimDef.type; + ordinalMeta = seriesDimDef.ordinalMeta; + seriesDimIdx++; + } else { + var sourceDimDef = this.getSourceDimension(fullDimIdx); + if (sourceDimDef) { + property = willRetrieveDataByName ? sourceDimDef.name : null; + type = sourceDimDef.type; + } + } + dims.push({ + property: property, + type: type, + ordinalMeta: ordinalMeta + }); + // If retrieving data by index, + // use to determine whether data can be shared. + // (Because in this case there might be no dimension name defined in dataset, but indices always exists). + // (Indices are always 0, 1, 2, ..., so we can ignore them to shorten the hash). + // Otherwise if retrieving data by property name (like `data: [{aa: 123, bb: 765}, ...]`), + // use in hash. + if (willRetrieveDataByName && property != null + // For data stack, we have make sure each series has its own dim on this store. + // So we do not add property to hash to make sure they can share this store. + && (!seriesDimDef || !seriesDimDef.isCalculationCoord)) { + dimHash += makeHashStrict + // Use escape character '`' in case that property name contains '$'. + ? property.replace(/\`/g, '`1').replace(/\$/g, '`2') + // For better performance, when there are large dimensions, tolerant this defects that hardly meet. + : property; + } + dimHash += '$'; + dimHash += dimTypeShort[type] || 'f'; + if (ordinalMeta) { + dimHash += ordinalMeta.uid; + } + dimHash += '$'; + } + // Source from endpoint(usually series) will be read differently + // when seriesLayoutBy or startIndex(which is affected by sourceHeader) are different. + // So we use this three props as key. + var source = this.source; + var hash = [source.seriesLayoutBy, source.startIndex, dimHash].join('$$'); + return { + dimensions: dims, + hash: hash + }; + }; + SeriesDataSchema.prototype.makeOutputDimensionNames = function () { + var result = []; + for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < this._fullDimCount; fullDimIdx++) { + var name_1 = void 0; + var seriesDimDef = this.dimensions[seriesDimIdx]; + // The list has been sorted by `storeDimIndex` asc. + if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) { + if (!seriesDimDef.isCalculationCoord) { + name_1 = seriesDimDef.name; + } + seriesDimIdx++; + } else { + var sourceDimDef = this.getSourceDimension(fullDimIdx); + if (sourceDimDef) { + name_1 = sourceDimDef.name; + } + } + result.push(name_1); + } + return result; + }; + SeriesDataSchema.prototype.appendCalculationDimension = function (dimDef) { + this.dimensions.push(dimDef); + dimDef.isCalculationCoord = true; + this._fullDimCount++; + // If append dimension on a data store, consider the store + // might be shared by different series, series dimensions not + // really map to store dimensions. + this._updateDimOmitted(true); + }; + return SeriesDataSchema; + }(); + function isSeriesDataSchema(schema) { + return schema instanceof SeriesDataSchema; + } + function createDimNameMap(dimsDef) { + var dataDimNameMap = createHashMap(); + for (var i = 0; i < (dimsDef || []).length; i++) { + var dimDefItemRaw = dimsDef[i]; + var userDimName = isObject(dimDefItemRaw) ? dimDefItemRaw.name : dimDefItemRaw; + if (userDimName != null && dataDimNameMap.get(userDimName) == null) { + dataDimNameMap.set(userDimName, i); + } + } + return dataDimNameMap; + } + function ensureSourceDimNameMap(source) { + var innerSource = inner$4(source); + return innerSource.dimNameMap || (innerSource.dimNameMap = createDimNameMap(source.dimensionsDefine)); + } + function shouldOmitUnusedDimensions(dimCount) { + return dimCount > 30; + } + + var isObject$2 = isObject; + var map$1 = map; + var CtorInt32Array$1 = typeof Int32Array === 'undefined' ? Array : Int32Array; + // Use prefix to avoid index to be the same as otherIdList[idx], + // which will cause weird update animation. + var ID_PREFIX = 'e\0\0'; + var INDEX_NOT_FOUND = -1; + // type SeriesDimensionIndex = DimensionIndex; + var TRANSFERABLE_PROPERTIES = ['hasItemOption', '_nameList', '_idList', '_invertedIndicesMap', '_dimSummary', 'userOutput', '_rawData', '_dimValueGetter', '_nameDimIdx', '_idDimIdx', '_nameRepeatCount']; + var CLONE_PROPERTIES = ['_approximateExtent']; + // ----------------------------- + // Internal method declarations: + // ----------------------------- + var prepareInvertedIndex; + var getId; + var getIdNameFromStore; + var normalizeDimensions; + var transferProperties; + var cloneListForMapAndSample; + var makeIdFromName; + var SeriesData = /** @class */function () { + /** + * @param dimensionsInput.dimensions + * For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...]. + * Dimensions should be concrete names like x, y, z, lng, lat, angle, radius + */ + function SeriesData(dimensionsInput, hostModel) { + this.type = 'list'; + this._dimOmitted = false; + this._nameList = []; + this._idList = []; + // Models of data option is stored sparse for optimizing memory cost + // Never used yet (not used yet). + // private _optionModels: Model[] = []; + // Global visual properties after visual coding + this._visual = {}; + // Global layout properties. + this._layout = {}; + // Item visual properties after visual coding + this._itemVisuals = []; + // Item layout properties after layout + this._itemLayouts = []; + // Graphic elements + this._graphicEls = []; + // key: dim, value: extent + this._approximateExtent = {}; + this._calculationInfo = {}; + // Having detected that there is data item is non primitive type + // (in type `OptionDataItemObject`). + // Like `data: [ { value: xx, itemStyle: {...} }, ...]` + // At present it only happen in `SOURCE_FORMAT_ORIGINAL`. + this.hasItemOption = false; + // Methods that create a new list based on this list should be listed here. + // Notice that those method should `RETURN` the new list. + this.TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'lttbDownSample', 'map']; + // Methods that change indices of this list should be listed here. + this.CHANGABLE_METHODS = ['filterSelf', 'selectRange']; + this.DOWNSAMPLE_METHODS = ['downSample', 'lttbDownSample']; + var dimensions; + var assignStoreDimIdx = false; + if (isSeriesDataSchema(dimensionsInput)) { + dimensions = dimensionsInput.dimensions; + this._dimOmitted = dimensionsInput.isDimensionOmitted(); + this._schema = dimensionsInput; + } else { + assignStoreDimIdx = true; + dimensions = dimensionsInput; + } + dimensions = dimensions || ['x', 'y']; + var dimensionInfos = {}; + var dimensionNames = []; + var invertedIndicesMap = {}; + var needsHasOwn = false; + var emptyObj = {}; + for (var i = 0; i < dimensions.length; i++) { + // Use the original dimensions[i], where other flag props may exists. + var dimInfoInput = dimensions[i]; + var dimensionInfo = isString(dimInfoInput) ? new SeriesDimensionDefine({ + name: dimInfoInput + }) : !(dimInfoInput instanceof SeriesDimensionDefine) ? new SeriesDimensionDefine(dimInfoInput) : dimInfoInput; + var dimensionName = dimensionInfo.name; + dimensionInfo.type = dimensionInfo.type || 'float'; + if (!dimensionInfo.coordDim) { + dimensionInfo.coordDim = dimensionName; + dimensionInfo.coordDimIndex = 0; + } + var otherDims = dimensionInfo.otherDims = dimensionInfo.otherDims || {}; + dimensionNames.push(dimensionName); + dimensionInfos[dimensionName] = dimensionInfo; + if (emptyObj[dimensionName] != null) { + needsHasOwn = true; + } + if (dimensionInfo.createInvertedIndices) { + invertedIndicesMap[dimensionName] = []; + } + if (otherDims.itemName === 0) { + this._nameDimIdx = i; + } + if (otherDims.itemId === 0) { + this._idDimIdx = i; + } + if ("development" !== 'production') { + assert(assignStoreDimIdx || dimensionInfo.storeDimIndex >= 0); + } + if (assignStoreDimIdx) { + dimensionInfo.storeDimIndex = i; + } + } + this.dimensions = dimensionNames; + this._dimInfos = dimensionInfos; + this._initGetDimensionInfo(needsHasOwn); + this.hostModel = hostModel; + this._invertedIndicesMap = invertedIndicesMap; + if (this._dimOmitted) { + var dimIdxToName_1 = this._dimIdxToName = createHashMap(); + each(dimensionNames, function (dimName) { + dimIdxToName_1.set(dimensionInfos[dimName].storeDimIndex, dimName); + }); + } + } + /** + * + * Get concrete dimension name by dimension name or dimension index. + * If input a dimension name, do not validate whether the dimension name exits. + * + * @caution + * @param dim Must make sure the dimension is `SeriesDimensionLoose`. + * Because only those dimensions will have auto-generated dimension names if not + * have a user-specified name, and other dimensions will get a return of null/undefined. + * + * @notice Because of this reason, should better use `getDimensionIndex` instead, for examples: + * ```js + * const val = data.getStore().get(data.getDimensionIndex(dim), dataIdx); + * ``` + * + * @return Concrete dim name. + */ + SeriesData.prototype.getDimension = function (dim) { + var dimIdx = this._recognizeDimIndex(dim); + if (dimIdx == null) { + return dim; + } + dimIdx = dim; + if (!this._dimOmitted) { + return this.dimensions[dimIdx]; + } + // Retrieve from series dimension definition because it probably contains + // generated dimension name (like 'x', 'y'). + var dimName = this._dimIdxToName.get(dimIdx); + if (dimName != null) { + return dimName; + } + var sourceDimDef = this._schema.getSourceDimension(dimIdx); + if (sourceDimDef) { + return sourceDimDef.name; + } + }; + /** + * Get dimension index in data store. Return -1 if not found. + * Can be used to index value from getRawValue. + */ + SeriesData.prototype.getDimensionIndex = function (dim) { + var dimIdx = this._recognizeDimIndex(dim); + if (dimIdx != null) { + return dimIdx; + } + if (dim == null) { + return -1; + } + var dimInfo = this._getDimInfo(dim); + return dimInfo ? dimInfo.storeDimIndex : this._dimOmitted ? this._schema.getSourceDimensionIndex(dim) : -1; + }; + /** + * The meanings of the input parameter `dim`: + * + * + If dim is a number (e.g., `1`), it means the index of the dimension. + * For example, `getDimension(0)` will return 'x' or 'lng' or 'radius'. + * + If dim is a number-like string (e.g., `"1"`): + * + If there is the same concrete dim name defined in `series.dimensions` or `dataset.dimensions`, + * it means that concrete name. + * + If not, it will be converted to a number, which means the index of the dimension. + * (why? because of the backward compatibility. We have been tolerating number-like string in + * dimension setting, although now it seems that it is not a good idea.) + * For example, `visualMap[i].dimension: "1"` is the same meaning as `visualMap[i].dimension: 1`, + * if no dimension name is defined as `"1"`. + * + If dim is a not-number-like string, it means the concrete dim name. + * For example, it can be be default name `"x"`, `"y"`, `"z"`, `"lng"`, `"lat"`, `"angle"`, `"radius"`, + * or customized in `dimensions` property of option like `"age"`. + * + * @return recognized `DimensionIndex`. Otherwise return null/undefined (means that dim is `DimensionName`). + */ + SeriesData.prototype._recognizeDimIndex = function (dim) { + if (isNumber(dim) + // If being a number-like string but not being defined as a dimension name. + || dim != null && !isNaN(dim) && !this._getDimInfo(dim) && (!this._dimOmitted || this._schema.getSourceDimensionIndex(dim) < 0)) { + return +dim; + } + }; + SeriesData.prototype._getStoreDimIndex = function (dim) { + var dimIdx = this.getDimensionIndex(dim); + if ("development" !== 'production') { + if (dimIdx == null) { + throw new Error('Unknown dimension ' + dim); + } + } + return dimIdx; + }; + /** + * Get type and calculation info of particular dimension + * @param dim + * Dimension can be concrete names like x, y, z, lng, lat, angle, radius + * Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius' + */ + SeriesData.prototype.getDimensionInfo = function (dim) { + // Do not clone, because there may be categories in dimInfo. + return this._getDimInfo(this.getDimension(dim)); + }; + SeriesData.prototype._initGetDimensionInfo = function (needsHasOwn) { + var dimensionInfos = this._dimInfos; + this._getDimInfo = needsHasOwn ? function (dimName) { + return dimensionInfos.hasOwnProperty(dimName) ? dimensionInfos[dimName] : undefined; + } : function (dimName) { + return dimensionInfos[dimName]; + }; + }; + /** + * concrete dimension name list on coord. + */ + SeriesData.prototype.getDimensionsOnCoord = function () { + return this._dimSummary.dataDimsOnCoord.slice(); + }; + SeriesData.prototype.mapDimension = function (coordDim, idx) { + var dimensionsSummary = this._dimSummary; + if (idx == null) { + return dimensionsSummary.encodeFirstDimNotExtra[coordDim]; + } + var dims = dimensionsSummary.encode[coordDim]; + return dims ? dims[idx] : null; + }; + SeriesData.prototype.mapDimensionsAll = function (coordDim) { + var dimensionsSummary = this._dimSummary; + var dims = dimensionsSummary.encode[coordDim]; + return (dims || []).slice(); + }; + SeriesData.prototype.getStore = function () { + return this._store; + }; + /** + * Initialize from data + * @param data source or data or data store. + * @param nameList The name of a datum is used on data diff and + * default label/tooltip. + * A name can be specified in encode.itemName, + * or dataItem.name (only for series option data), + * or provided in nameList from outside. + */ + SeriesData.prototype.initData = function (data, nameList, dimValueGetter) { + var _this = this; + var store; + if (data instanceof DataStore) { + store = data; + } + if (!store) { + var dimensions = this.dimensions; + var provider = isSourceInstance(data) || isArrayLike(data) ? new DefaultDataProvider(data, dimensions.length) : data; + store = new DataStore(); + var dimensionInfos = map$1(dimensions, function (dimName) { + return { + type: _this._dimInfos[dimName].type, + property: dimName + }; + }); + store.initData(provider, dimensionInfos, dimValueGetter); + } + this._store = store; + // Reset + this._nameList = (nameList || []).slice(); + this._idList = []; + this._nameRepeatCount = {}; + this._doInit(0, store.count()); + // Cache summary info for fast visit. See "dimensionHelper". + // Needs to be initialized after store is prepared. + this._dimSummary = summarizeDimensions(this, this._schema); + this.userOutput = this._dimSummary.userOutput; + }; + /** + * Caution: Can be only called on raw data (before `this._indices` created). + */ + SeriesData.prototype.appendData = function (data) { + var range = this._store.appendData(data); + this._doInit(range[0], range[1]); + }; + /** + * Caution: Can be only called on raw data (before `this._indices` created). + * This method does not modify `rawData` (`dataProvider`), but only + * add values to store. + * + * The final count will be increased by `Math.max(values.length, names.length)`. + * + * @param values That is the SourceType: 'arrayRows', like + * [ + * [12, 33, 44], + * [NaN, 43, 1], + * ['-', 'asdf', 0] + * ] + * Each item is exactly corresponding to a dimension. + */ + SeriesData.prototype.appendValues = function (values, names) { + var _a = this._store.appendValues(values, names.length), + start = _a.start, + end = _a.end; + var shouldMakeIdFromName = this._shouldMakeIdFromName(); + this._updateOrdinalMeta(); + if (names) { + for (var idx = start; idx < end; idx++) { + var sourceIdx = idx - start; + this._nameList[idx] = names[sourceIdx]; + if (shouldMakeIdFromName) { + makeIdFromName(this, idx); + } + } + } + }; + SeriesData.prototype._updateOrdinalMeta = function () { + var store = this._store; + var dimensions = this.dimensions; + for (var i = 0; i < dimensions.length; i++) { + var dimInfo = this._dimInfos[dimensions[i]]; + if (dimInfo.ordinalMeta) { + store.collectOrdinalMeta(dimInfo.storeDimIndex, dimInfo.ordinalMeta); + } + } + }; + SeriesData.prototype._shouldMakeIdFromName = function () { + var provider = this._store.getProvider(); + return this._idDimIdx == null && provider.getSource().sourceFormat !== SOURCE_FORMAT_TYPED_ARRAY && !provider.fillStorage; + }; + SeriesData.prototype._doInit = function (start, end) { + if (start >= end) { + return; + } + var store = this._store; + var provider = store.getProvider(); + this._updateOrdinalMeta(); + var nameList = this._nameList; + var idList = this._idList; + var sourceFormat = provider.getSource().sourceFormat; + var isFormatOriginal = sourceFormat === SOURCE_FORMAT_ORIGINAL; + // Each data item is value + // [1, 2] + // 2 + // Bar chart, line chart which uses category axis + // only gives the 'y' value. 'x' value is the indices of category + // Use a tempValue to normalize the value to be a (x, y) value + // If dataItem is {name: ...} or {id: ...}, it has highest priority. + // This kind of ids and names are always stored `_nameList` and `_idList`. + if (isFormatOriginal && !provider.pure) { + var sharedDataItem = []; + for (var idx = start; idx < end; idx++) { + // NOTICE: Try not to write things into dataItem + var dataItem = provider.getItem(idx, sharedDataItem); + if (!this.hasItemOption && isDataItemOption(dataItem)) { + this.hasItemOption = true; + } + if (dataItem) { + var itemName = dataItem.name; + if (nameList[idx] == null && itemName != null) { + nameList[idx] = convertOptionIdName(itemName, null); + } + var itemId = dataItem.id; + if (idList[idx] == null && itemId != null) { + idList[idx] = convertOptionIdName(itemId, null); + } + } + } + } + if (this._shouldMakeIdFromName()) { + for (var idx = start; idx < end; idx++) { + makeIdFromName(this, idx); + } + } + prepareInvertedIndex(this); + }; + /** + * PENDING: In fact currently this function is only used to short-circuit + * the calling of `scale.unionExtentFromData` when data have been filtered by modules + * like "dataZoom". `scale.unionExtentFromData` is used to calculate data extent for series on + * an axis, but if a "axis related data filter module" is used, the extent of the axis have + * been fixed and no need to calling `scale.unionExtentFromData` actually. + * But if we add "custom data filter" in future, which is not "axis related", this method may + * be still needed. + * + * Optimize for the scenario that data is filtered by a given extent. + * Consider that if data amount is more than hundreds of thousand, + * extent calculation will cost more than 10ms and the cache will + * be erased because of the filtering. + */ + SeriesData.prototype.getApproximateExtent = function (dim) { + return this._approximateExtent[dim] || this._store.getDataExtent(this._getStoreDimIndex(dim)); + }; + /** + * Calculate extent on a filtered data might be time consuming. + * Approximate extent is only used for: calculate extent of filtered data outside. + */ + SeriesData.prototype.setApproximateExtent = function (extent, dim) { + dim = this.getDimension(dim); + this._approximateExtent[dim] = extent.slice(); + }; + SeriesData.prototype.getCalculationInfo = function (key) { + return this._calculationInfo[key]; + }; + SeriesData.prototype.setCalculationInfo = function (key, value) { + isObject$2(key) ? extend(this._calculationInfo, key) : this._calculationInfo[key] = value; + }; + /** + * @return Never be null/undefined. `number` will be converted to string. Because: + * In most cases, name is used in display, where returning a string is more convenient. + * In other cases, name is used in query (see `indexOfName`), where we can keep the + * rule that name `2` equals to name `'2'`. + */ + SeriesData.prototype.getName = function (idx) { + var rawIndex = this.getRawIndex(idx); + var name = this._nameList[rawIndex]; + if (name == null && this._nameDimIdx != null) { + name = getIdNameFromStore(this, this._nameDimIdx, rawIndex); + } + if (name == null) { + name = ''; + } + return name; + }; + SeriesData.prototype._getCategory = function (dimIdx, idx) { + var ordinal = this._store.get(dimIdx, idx); + var ordinalMeta = this._store.getOrdinalMeta(dimIdx); + if (ordinalMeta) { + return ordinalMeta.categories[ordinal]; + } + return ordinal; + }; + /** + * @return Never null/undefined. `number` will be converted to string. Because: + * In all cases having encountered at present, id is used in making diff comparison, which + * are usually based on hash map. We can keep the rule that the internal id are always string + * (treat `2` is the same as `'2'`) to make the related logic simple. + */ + SeriesData.prototype.getId = function (idx) { + return getId(this, this.getRawIndex(idx)); + }; + SeriesData.prototype.count = function () { + return this._store.count(); + }; + /** + * Get value. Return NaN if idx is out of range. + * + * @notice Should better to use `data.getStore().get(dimIndex, dataIdx)` instead. + */ + SeriesData.prototype.get = function (dim, idx) { + var store = this._store; + var dimInfo = this._dimInfos[dim]; + if (dimInfo) { + return store.get(dimInfo.storeDimIndex, idx); + } + }; + /** + * @notice Should better to use `data.getStore().getByRawIndex(dimIndex, dataIdx)` instead. + */ + SeriesData.prototype.getByRawIndex = function (dim, rawIdx) { + var store = this._store; + var dimInfo = this._dimInfos[dim]; + if (dimInfo) { + return store.getByRawIndex(dimInfo.storeDimIndex, rawIdx); + } + }; + SeriesData.prototype.getIndices = function () { + return this._store.getIndices(); + }; + SeriesData.prototype.getDataExtent = function (dim) { + return this._store.getDataExtent(this._getStoreDimIndex(dim)); + }; + SeriesData.prototype.getSum = function (dim) { + return this._store.getSum(this._getStoreDimIndex(dim)); + }; + SeriesData.prototype.getMedian = function (dim) { + return this._store.getMedian(this._getStoreDimIndex(dim)); + }; + SeriesData.prototype.getValues = function (dimensions, idx) { + var _this = this; + var store = this._store; + return isArray(dimensions) ? store.getValues(map$1(dimensions, function (dim) { + return _this._getStoreDimIndex(dim); + }), idx) : store.getValues(dimensions); + }; + /** + * If value is NaN. Including '-' + * Only check the coord dimensions. + */ + SeriesData.prototype.hasValue = function (idx) { + var dataDimIndicesOnCoord = this._dimSummary.dataDimIndicesOnCoord; + for (var i = 0, len = dataDimIndicesOnCoord.length; i < len; i++) { + // Ordinal type originally can be string or number. + // But when an ordinal type is used on coord, it can + // not be string but only number. So we can also use isNaN. + if (isNaN(this._store.get(dataDimIndicesOnCoord[i], idx))) { + return false; + } + } + return true; + }; + /** + * Retrieve the index with given name + */ + SeriesData.prototype.indexOfName = function (name) { + for (var i = 0, len = this._store.count(); i < len; i++) { + if (this.getName(i) === name) { + return i; + } + } + return -1; + }; + SeriesData.prototype.getRawIndex = function (idx) { + return this._store.getRawIndex(idx); + }; + SeriesData.prototype.indexOfRawIndex = function (rawIndex) { + return this._store.indexOfRawIndex(rawIndex); + }; + /** + * Only support the dimension which inverted index created. + * Do not support other cases until required. + * @param dim concrete dim + * @param value ordinal index + * @return rawIndex + */ + SeriesData.prototype.rawIndexOf = function (dim, value) { + var invertedIndices = dim && this._invertedIndicesMap[dim]; + if ("development" !== 'production') { + if (!invertedIndices) { + throw new Error('Do not supported yet'); + } + } + var rawIndex = invertedIndices[value]; + if (rawIndex == null || isNaN(rawIndex)) { + return INDEX_NOT_FOUND; + } + return rawIndex; + }; + /** + * Retrieve the index of nearest value + * @param dim + * @param value + * @param [maxDistance=Infinity] + * @return If and only if multiple indices has + * the same value, they are put to the result. + */ + SeriesData.prototype.indicesOfNearest = function (dim, value, maxDistance) { + return this._store.indicesOfNearest(this._getStoreDimIndex(dim), value, maxDistance); + }; + SeriesData.prototype.each = function (dims, cb, ctx) { + + if (isFunction(dims)) { + ctx = cb; + cb = dims; + dims = []; + } + // ctxCompat just for compat echarts3 + var fCtx = ctx || this; + var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this); + this._store.each(dimIndices, fCtx ? bind(cb, fCtx) : cb); + }; + SeriesData.prototype.filterSelf = function (dims, cb, ctx) { + + if (isFunction(dims)) { + ctx = cb; + cb = dims; + dims = []; + } + // ctxCompat just for compat echarts3 + var fCtx = ctx || this; + var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this); + this._store = this._store.filter(dimIndices, fCtx ? bind(cb, fCtx) : cb); + return this; + }; + /** + * Select data in range. (For optimization of filter) + * (Manually inline code, support 5 million data filtering in data zoom.) + */ + SeriesData.prototype.selectRange = function (range) { + + var _this = this; + var innerRange = {}; + var dims = keys(range); + each(dims, function (dim) { + var dimIdx = _this._getStoreDimIndex(dim); + innerRange[dimIdx] = range[dim]; + }); + this._store = this._store.selectRange(innerRange); + return this; + }; + /* eslint-enable max-len */ + SeriesData.prototype.mapArray = function (dims, cb, ctx) { + + if (isFunction(dims)) { + ctx = cb; + cb = dims; + dims = []; + } + // ctxCompat just for compat echarts3 + ctx = ctx || this; + var result = []; + this.each(dims, function () { + result.push(cb && cb.apply(this, arguments)); + }, ctx); + return result; + }; + SeriesData.prototype.map = function (dims, cb, ctx, ctxCompat) { + + // ctxCompat just for compat echarts3 + var fCtx = ctx || ctxCompat || this; + var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this); + var list = cloneListForMapAndSample(this); + list._store = this._store.map(dimIndices, fCtx ? bind(cb, fCtx) : cb); + return list; + }; + SeriesData.prototype.modify = function (dims, cb, ctx, ctxCompat) { + var _this = this; + // ctxCompat just for compat echarts3 + var fCtx = ctx || ctxCompat || this; + if ("development" !== 'production') { + each(normalizeDimensions(dims), function (dim) { + var dimInfo = _this.getDimensionInfo(dim); + if (!dimInfo.isCalculationCoord) { + console.error('Danger: only stack dimension can be modified'); + } + }); + } + var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this); + // If do shallow clone here, if there are too many stacked series, + // it still cost lots of memory, because `_store.dimensions` are not shared. + // We should consider there probably be shallow clone happen in each series + // in consequent filter/map. + this._store.modify(dimIndices, fCtx ? bind(cb, fCtx) : cb); + }; + /** + * Large data down sampling on given dimension + * @param sampleIndex Sample index for name and id + */ + SeriesData.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) { + var list = cloneListForMapAndSample(this); + list._store = this._store.downSample(this._getStoreDimIndex(dimension), rate, sampleValue, sampleIndex); + return list; + }; + /** + * Large data down sampling using largest-triangle-three-buckets + * @param {string} valueDimension + * @param {number} targetCount + */ + SeriesData.prototype.lttbDownSample = function (valueDimension, rate) { + var list = cloneListForMapAndSample(this); + list._store = this._store.lttbDownSample(this._getStoreDimIndex(valueDimension), rate); + return list; + }; + SeriesData.prototype.getRawDataItem = function (idx) { + return this._store.getRawDataItem(idx); + }; + /** + * Get model of one data item. + */ + // TODO: Type of data item + SeriesData.prototype.getItemModel = function (idx) { + var hostModel = this.hostModel; + var dataItem = this.getRawDataItem(idx); + return new Model(dataItem, hostModel, hostModel && hostModel.ecModel); + }; + /** + * Create a data differ + */ + SeriesData.prototype.diff = function (otherList) { + var thisList = this; + return new DataDiffer(otherList ? otherList.getStore().getIndices() : [], this.getStore().getIndices(), function (idx) { + return getId(otherList, idx); + }, function (idx) { + return getId(thisList, idx); + }); + }; + /** + * Get visual property. + */ + SeriesData.prototype.getVisual = function (key) { + var visual = this._visual; + return visual && visual[key]; + }; + SeriesData.prototype.setVisual = function (kvObj, val) { + this._visual = this._visual || {}; + if (isObject$2(kvObj)) { + extend(this._visual, kvObj); + } else { + this._visual[kvObj] = val; + } + }; + /** + * Get visual property of single data item + */ + // eslint-disable-next-line + SeriesData.prototype.getItemVisual = function (idx, key) { + var itemVisual = this._itemVisuals[idx]; + var val = itemVisual && itemVisual[key]; + if (val == null) { + // Use global visual property + return this.getVisual(key); + } + return val; + }; + /** + * If exists visual property of single data item + */ + SeriesData.prototype.hasItemVisual = function () { + return this._itemVisuals.length > 0; + }; + /** + * Make sure itemVisual property is unique + */ + // TODO: use key to save visual to reduce memory. + SeriesData.prototype.ensureUniqueItemVisual = function (idx, key) { + var itemVisuals = this._itemVisuals; + var itemVisual = itemVisuals[idx]; + if (!itemVisual) { + itemVisual = itemVisuals[idx] = {}; + } + var val = itemVisual[key]; + if (val == null) { + val = this.getVisual(key); + // TODO Performance? + if (isArray(val)) { + val = val.slice(); + } else if (isObject$2(val)) { + val = extend({}, val); + } + itemVisual[key] = val; + } + return val; + }; + // eslint-disable-next-line + SeriesData.prototype.setItemVisual = function (idx, key, value) { + var itemVisual = this._itemVisuals[idx] || {}; + this._itemVisuals[idx] = itemVisual; + if (isObject$2(key)) { + extend(itemVisual, key); + } else { + itemVisual[key] = value; + } + }; + /** + * Clear itemVisuals and list visual. + */ + SeriesData.prototype.clearAllVisual = function () { + this._visual = {}; + this._itemVisuals = []; + }; + SeriesData.prototype.setLayout = function (key, val) { + isObject$2(key) ? extend(this._layout, key) : this._layout[key] = val; + }; + /** + * Get layout property. + */ + SeriesData.prototype.getLayout = function (key) { + return this._layout[key]; + }; + /** + * Get layout of single data item + */ + SeriesData.prototype.getItemLayout = function (idx) { + return this._itemLayouts[idx]; + }; + /** + * Set layout of single data item + */ + SeriesData.prototype.setItemLayout = function (idx, layout, merge) { + this._itemLayouts[idx] = merge ? extend(this._itemLayouts[idx] || {}, layout) : layout; + }; + /** + * Clear all layout of single data item + */ + SeriesData.prototype.clearItemLayouts = function () { + this._itemLayouts.length = 0; + }; + /** + * Set graphic element relative to data. It can be set as null + */ + SeriesData.prototype.setItemGraphicEl = function (idx, el) { + var seriesIndex = this.hostModel && this.hostModel.seriesIndex; + setCommonECData(seriesIndex, this.dataType, idx, el); + this._graphicEls[idx] = el; + }; + SeriesData.prototype.getItemGraphicEl = function (idx) { + return this._graphicEls[idx]; + }; + SeriesData.prototype.eachItemGraphicEl = function (cb, context) { + each(this._graphicEls, function (el, idx) { + if (el) { + cb && cb.call(context, el, idx); + } + }); + }; + /** + * Shallow clone a new list except visual and layout properties, and graph elements. + * New list only change the indices. + */ + SeriesData.prototype.cloneShallow = function (list) { + if (!list) { + list = new SeriesData(this._schema ? this._schema : map$1(this.dimensions, this._getDimInfo, this), this.hostModel); + } + transferProperties(list, this); + list._store = this._store; + return list; + }; + /** + * Wrap some method to add more feature + */ + SeriesData.prototype.wrapMethod = function (methodName, injectFunction) { + var originalMethod = this[methodName]; + if (!isFunction(originalMethod)) { + return; + } + this.__wrappedMethods = this.__wrappedMethods || []; + this.__wrappedMethods.push(methodName); + this[methodName] = function () { + var res = originalMethod.apply(this, arguments); + return injectFunction.apply(this, [res].concat(slice(arguments))); + }; + }; + // ---------------------------------------------------------- + // A work around for internal method visiting private member. + // ---------------------------------------------------------- + SeriesData.internalField = function () { + prepareInvertedIndex = function (data) { + var invertedIndicesMap = data._invertedIndicesMap; + each(invertedIndicesMap, function (invertedIndices, dim) { + var dimInfo = data._dimInfos[dim]; + // Currently, only dimensions that has ordinalMeta can create inverted indices. + var ordinalMeta = dimInfo.ordinalMeta; + var store = data._store; + if (ordinalMeta) { + invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array$1(ordinalMeta.categories.length); + // The default value of TypedArray is 0. To avoid miss + // mapping to 0, we should set it as INDEX_NOT_FOUND. + for (var i = 0; i < invertedIndices.length; i++) { + invertedIndices[i] = INDEX_NOT_FOUND; + } + for (var i = 0; i < store.count(); i++) { + // Only support the case that all values are distinct. + invertedIndices[store.get(dimInfo.storeDimIndex, i)] = i; + } + } + }); + }; + getIdNameFromStore = function (data, dimIdx, idx) { + return convertOptionIdName(data._getCategory(dimIdx, idx), null); + }; + /** + * @see the comment of `List['getId']`. + */ + getId = function (data, rawIndex) { + var id = data._idList[rawIndex]; + if (id == null && data._idDimIdx != null) { + id = getIdNameFromStore(data, data._idDimIdx, rawIndex); + } + if (id == null) { + id = ID_PREFIX + rawIndex; + } + return id; + }; + normalizeDimensions = function (dimensions) { + if (!isArray(dimensions)) { + dimensions = dimensions != null ? [dimensions] : []; + } + return dimensions; + }; + /** + * Data in excludeDimensions is copied, otherwise transferred. + */ + cloneListForMapAndSample = function (original) { + var list = new SeriesData(original._schema ? original._schema : map$1(original.dimensions, original._getDimInfo, original), original.hostModel); + // FIXME If needs stackedOn, value may already been stacked + transferProperties(list, original); + return list; + }; + transferProperties = function (target, source) { + each(TRANSFERABLE_PROPERTIES.concat(source.__wrappedMethods || []), function (propName) { + if (source.hasOwnProperty(propName)) { + target[propName] = source[propName]; + } + }); + target.__wrappedMethods = source.__wrappedMethods; + each(CLONE_PROPERTIES, function (propName) { + target[propName] = clone(source[propName]); + }); + target._calculationInfo = extend({}, source._calculationInfo); + }; + makeIdFromName = function (data, idx) { + var nameList = data._nameList; + var idList = data._idList; + var nameDimIdx = data._nameDimIdx; + var idDimIdx = data._idDimIdx; + var name = nameList[idx]; + var id = idList[idx]; + if (name == null && nameDimIdx != null) { + nameList[idx] = name = getIdNameFromStore(data, nameDimIdx, idx); + } + if (id == null && idDimIdx != null) { + idList[idx] = id = getIdNameFromStore(data, idDimIdx, idx); + } + if (id == null && name != null) { + var nameRepeatCount = data._nameRepeatCount; + var nmCnt = nameRepeatCount[name] = (nameRepeatCount[name] || 0) + 1; + id = name; + if (nmCnt > 1) { + id += '__ec__' + nmCnt; + } + idList[idx] = id; + } + }; + }(); + return SeriesData; + }(); + + /** + * For outside usage compat (like echarts-gl are using it). + */ + function createDimensions(source, opt) { + return prepareSeriesDataSchema(source, opt).dimensions; + } + /** + * This method builds the relationship between: + * + "what the coord sys or series requires (see `coordDimensions`)", + * + "what the user defines (in `encode` and `dimensions`, see `opt.dimensionsDefine` and `opt.encodeDefine`)" + * + "what the data source provids (see `source`)". + * + * Some guess strategy will be adapted if user does not define something. + * If no 'value' dimension specified, the first no-named dimension will be + * named as 'value'. + * + * @return The results are always sorted by `storeDimIndex` asc. + */ + function prepareSeriesDataSchema( + // TODO: TYPE completeDimensions type + source, opt) { + if (!isSourceInstance(source)) { + source = createSourceFromSeriesDataOption(source); + } + opt = opt || {}; + var sysDims = opt.coordDimensions || []; + var dimsDef = opt.dimensionsDefine || source.dimensionsDefine || []; + var coordDimNameMap = createHashMap(); + var resultList = []; + var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimensionsCount); + // Try to ignore unused dimensions if sharing a high dimension datastore + // 30 is an experience value. + var omitUnusedDimensions = opt.canOmitUnusedDimensions && shouldOmitUnusedDimensions(dimCount); + var isUsingSourceDimensionsDef = dimsDef === source.dimensionsDefine; + var dataDimNameMap = isUsingSourceDimensionsDef ? ensureSourceDimNameMap(source) : createDimNameMap(dimsDef); + var encodeDef = opt.encodeDefine; + if (!encodeDef && opt.encodeDefaulter) { + encodeDef = opt.encodeDefaulter(source, dimCount); + } + var encodeDefMap = createHashMap(encodeDef); + var indicesMap = new CtorInt32Array(dimCount); + for (var i = 0; i < indicesMap.length; i++) { + indicesMap[i] = -1; + } + function getResultItem(dimIdx) { + var idx = indicesMap[dimIdx]; + if (idx < 0) { + var dimDefItemRaw = dimsDef[dimIdx]; + var dimDefItem = isObject(dimDefItemRaw) ? dimDefItemRaw : { + name: dimDefItemRaw + }; + var resultItem = new SeriesDimensionDefine(); + var userDimName = dimDefItem.name; + if (userDimName != null && dataDimNameMap.get(userDimName) != null) { + // Only if `series.dimensions` is defined in option + // displayName, will be set, and dimension will be displayed vertically in + // tooltip by default. + resultItem.name = resultItem.displayName = userDimName; + } + dimDefItem.type != null && (resultItem.type = dimDefItem.type); + dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName); + var newIdx = resultList.length; + indicesMap[dimIdx] = newIdx; + resultItem.storeDimIndex = dimIdx; + resultList.push(resultItem); + return resultItem; + } + return resultList[idx]; + } + if (!omitUnusedDimensions) { + for (var i = 0; i < dimCount; i++) { + getResultItem(i); + } + } + // Set `coordDim` and `coordDimIndex` by `encodeDefMap` and normalize `encodeDefMap`. + encodeDefMap.each(function (dataDimsRaw, coordDim) { + var dataDims = normalizeToArray(dataDimsRaw).slice(); + // Note: It is allowed that `dataDims.length` is `0`, e.g., options is + // `{encode: {x: -1, y: 1}}`. Should not filter anything in + // this case. + if (dataDims.length === 1 && !isString(dataDims[0]) && dataDims[0] < 0) { + encodeDefMap.set(coordDim, false); + return; + } + var validDataDims = encodeDefMap.set(coordDim, []); + each(dataDims, function (resultDimIdxOrName, idx) { + // The input resultDimIdx can be dim name or index. + var resultDimIdx = isString(resultDimIdxOrName) ? dataDimNameMap.get(resultDimIdxOrName) : resultDimIdxOrName; + if (resultDimIdx != null && resultDimIdx < dimCount) { + validDataDims[idx] = resultDimIdx; + applyDim(getResultItem(resultDimIdx), coordDim, idx); + } + }); + }); + // Apply templates and default order from `sysDims`. + var availDimIdx = 0; + each(sysDims, function (sysDimItemRaw) { + var coordDim; + var sysDimItemDimsDef; + var sysDimItemOtherDims; + var sysDimItem; + if (isString(sysDimItemRaw)) { + coordDim = sysDimItemRaw; + sysDimItem = {}; + } else { + sysDimItem = sysDimItemRaw; + coordDim = sysDimItem.name; + var ordinalMeta = sysDimItem.ordinalMeta; + sysDimItem.ordinalMeta = null; + sysDimItem = extend({}, sysDimItem); + sysDimItem.ordinalMeta = ordinalMeta; + // `coordDimIndex` should not be set directly. + sysDimItemDimsDef = sysDimItem.dimsDef; + sysDimItemOtherDims = sysDimItem.otherDims; + sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex = sysDimItem.dimsDef = sysDimItem.otherDims = null; + } + var dataDims = encodeDefMap.get(coordDim); + // negative resultDimIdx means no need to mapping. + if (dataDims === false) { + return; + } + dataDims = normalizeToArray(dataDims); + // dimensions provides default dim sequences. + if (!dataDims.length) { + for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) { + while (availDimIdx < dimCount && getResultItem(availDimIdx).coordDim != null) { + availDimIdx++; + } + availDimIdx < dimCount && dataDims.push(availDimIdx++); + } + } + // Apply templates. + each(dataDims, function (resultDimIdx, coordDimIndex) { + var resultItem = getResultItem(resultDimIdx); + // Coordinate system has a higher priority on dim type than source. + if (isUsingSourceDimensionsDef && sysDimItem.type != null) { + resultItem.type = sysDimItem.type; + } + applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex); + if (resultItem.name == null && sysDimItemDimsDef) { + var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex]; + !isObject(sysDimItemDimsDefItem) && (sysDimItemDimsDefItem = { + name: sysDimItemDimsDefItem + }); + resultItem.name = resultItem.displayName = sysDimItemDimsDefItem.name; + resultItem.defaultTooltip = sysDimItemDimsDefItem.defaultTooltip; + } + // FIXME refactor, currently only used in case: {otherDims: {tooltip: false}} + sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims); + }); + }); + function applyDim(resultItem, coordDim, coordDimIndex) { + if (VISUAL_DIMENSIONS.get(coordDim) != null) { + resultItem.otherDims[coordDim] = coordDimIndex; + } else { + resultItem.coordDim = coordDim; + resultItem.coordDimIndex = coordDimIndex; + coordDimNameMap.set(coordDim, true); + } + } + // Make sure the first extra dim is 'value'. + var generateCoord = opt.generateCoord; + var generateCoordCount = opt.generateCoordCount; + var fromZero = generateCoordCount != null; + generateCoordCount = generateCoord ? generateCoordCount || 1 : 0; + var extra = generateCoord || 'value'; + function ifNoNameFillWithCoordName(resultItem) { + if (resultItem.name == null) { + // Duplication will be removed in the next step. + resultItem.name = resultItem.coordDim; + } + } + // Set dim `name` and other `coordDim` and other props. + if (!omitUnusedDimensions) { + for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) { + var resultItem = getResultItem(resultDimIdx); + var coordDim = resultItem.coordDim; + if (coordDim == null) { + // TODO no need to generate coordDim for isExtraCoord? + resultItem.coordDim = genCoordDimName(extra, coordDimNameMap, fromZero); + resultItem.coordDimIndex = 0; + // Series specified generateCoord is using out. + if (!generateCoord || generateCoordCount <= 0) { + resultItem.isExtraCoord = true; + } + generateCoordCount--; + } + ifNoNameFillWithCoordName(resultItem); + if (resultItem.type == null && (guessOrdinal(source, resultDimIdx) === BE_ORDINAL.Must + // Consider the case: + // { + // dataset: {source: [ + // ['2001', 123], + // ['2002', 456], + // ... + // ['The others', 987], + // ]}, + // series: {type: 'pie'} + // } + // The first column should better be treated as a "ordinal" although it + // might not be detected as an "ordinal" by `guessOrdinal`. + || resultItem.isExtraCoord && (resultItem.otherDims.itemName != null || resultItem.otherDims.seriesName != null))) { + resultItem.type = 'ordinal'; + } + } + } else { + each(resultList, function (resultItem) { + // PENDING: guessOrdinal or let user specify type: 'ordinal' manually? + ifNoNameFillWithCoordName(resultItem); + }); + // Sort dimensions: there are some rule that use the last dim as label, + // and for some latter travel process easier. + resultList.sort(function (item0, item1) { + return item0.storeDimIndex - item1.storeDimIndex; + }); + } + removeDuplication(resultList); + return new SeriesDataSchema({ + source: source, + dimensions: resultList, + fullDimensionCount: dimCount, + dimensionOmitted: omitUnusedDimensions + }); + } + function removeDuplication(result) { + var duplicationMap = createHashMap(); + for (var i = 0; i < result.length; i++) { + var dim = result[i]; + var dimOriginalName = dim.name; + var count = duplicationMap.get(dimOriginalName) || 0; + if (count > 0) { + // Starts from 0. + dim.name = dimOriginalName + (count - 1); + } + count++; + duplicationMap.set(dimOriginalName, count); + } + } + // ??? TODO + // Originally detect dimCount by data[0]. Should we + // optimize it to only by sysDims and dimensions and encode. + // So only necessary dims will be initialized. + // But + // (1) custom series should be considered. where other dims + // may be visited. + // (2) sometimes user need to calculate bubble size or use visualMap + // on other dimensions besides coordSys needed. + // So, dims that is not used by system, should be shared in data store? + function getDimCount(source, sysDims, dimsDef, optDimCount) { + // Note that the result dimCount should not small than columns count + // of data, otherwise `dataDimNameMap` checking will be incorrect. + var dimCount = Math.max(source.dimensionsDetectedCount || 1, sysDims.length, dimsDef.length, optDimCount || 0); + each(sysDims, function (sysDimItem) { + var sysDimItemDimsDef; + if (isObject(sysDimItem) && (sysDimItemDimsDef = sysDimItem.dimsDef)) { + dimCount = Math.max(dimCount, sysDimItemDimsDef.length); + } + }); + return dimCount; + } + function genCoordDimName(name, map, fromZero) { + if (fromZero || map.hasKey(name)) { + var i = 0; + while (map.hasKey(name + i)) { + i++; + } + name += i; + } + map.set(name, true); + return name; + } + + /** + * @class + * For example: + * { + * coordSysName: 'cartesian2d', + * coordSysDims: ['x', 'y', ...], + * axisMap: HashMap({ + * x: xAxisModel, + * y: yAxisModel + * }), + * categoryAxisMap: HashMap({ + * x: xAxisModel, + * y: undefined + * }), + * // The index of the first category axis in `coordSysDims`. + * // `null/undefined` means no category axis exists. + * firstCategoryDimIndex: 1, + * // To replace user specified encode. + * } + */ + var CoordSysInfo = /** @class */function () { + function CoordSysInfo(coordSysName) { + this.coordSysDims = []; + this.axisMap = createHashMap(); + this.categoryAxisMap = createHashMap(); + this.coordSysName = coordSysName; + } + return CoordSysInfo; + }(); + function getCoordSysInfoBySeries(seriesModel) { + var coordSysName = seriesModel.get('coordinateSystem'); + var result = new CoordSysInfo(coordSysName); + var fetch = fetchers[coordSysName]; + if (fetch) { + fetch(seriesModel, result, result.axisMap, result.categoryAxisMap); + return result; + } + } + var fetchers = { + cartesian2d: function (seriesModel, result, axisMap, categoryAxisMap) { + var xAxisModel = seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0]; + var yAxisModel = seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0]; + if ("development" !== 'production') { + if (!xAxisModel) { + throw new Error('xAxis "' + retrieve(seriesModel.get('xAxisIndex'), seriesModel.get('xAxisId'), 0) + '" not found'); + } + if (!yAxisModel) { + throw new Error('yAxis "' + retrieve(seriesModel.get('xAxisIndex'), seriesModel.get('yAxisId'), 0) + '" not found'); + } + } + result.coordSysDims = ['x', 'y']; + axisMap.set('x', xAxisModel); + axisMap.set('y', yAxisModel); + if (isCategory(xAxisModel)) { + categoryAxisMap.set('x', xAxisModel); + result.firstCategoryDimIndex = 0; + } + if (isCategory(yAxisModel)) { + categoryAxisMap.set('y', yAxisModel); + result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1); + } + }, + singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) { + var singleAxisModel = seriesModel.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0]; + if ("development" !== 'production') { + if (!singleAxisModel) { + throw new Error('singleAxis should be specified.'); + } + } + result.coordSysDims = ['single']; + axisMap.set('single', singleAxisModel); + if (isCategory(singleAxisModel)) { + categoryAxisMap.set('single', singleAxisModel); + result.firstCategoryDimIndex = 0; + } + }, + polar: function (seriesModel, result, axisMap, categoryAxisMap) { + var polarModel = seriesModel.getReferringComponents('polar', SINGLE_REFERRING).models[0]; + var radiusAxisModel = polarModel.findAxisModel('radiusAxis'); + var angleAxisModel = polarModel.findAxisModel('angleAxis'); + if ("development" !== 'production') { + if (!angleAxisModel) { + throw new Error('angleAxis option not found'); + } + if (!radiusAxisModel) { + throw new Error('radiusAxis option not found'); + } + } + result.coordSysDims = ['radius', 'angle']; + axisMap.set('radius', radiusAxisModel); + axisMap.set('angle', angleAxisModel); + if (isCategory(radiusAxisModel)) { + categoryAxisMap.set('radius', radiusAxisModel); + result.firstCategoryDimIndex = 0; + } + if (isCategory(angleAxisModel)) { + categoryAxisMap.set('angle', angleAxisModel); + result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1); + } + }, + geo: function (seriesModel, result, axisMap, categoryAxisMap) { + result.coordSysDims = ['lng', 'lat']; + }, + parallel: function (seriesModel, result, axisMap, categoryAxisMap) { + var ecModel = seriesModel.ecModel; + var parallelModel = ecModel.getComponent('parallel', seriesModel.get('parallelIndex')); + var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice(); + each(parallelModel.parallelAxisIndex, function (axisIndex, index) { + var axisModel = ecModel.getComponent('parallelAxis', axisIndex); + var axisDim = coordSysDims[index]; + axisMap.set(axisDim, axisModel); + if (isCategory(axisModel)) { + categoryAxisMap.set(axisDim, axisModel); + if (result.firstCategoryDimIndex == null) { + result.firstCategoryDimIndex = index; + } + } + }); + } + }; + function isCategory(axisModel) { + return axisModel.get('type') === 'category'; + } + + /** + * Note that it is too complicated to support 3d stack by value + * (have to create two-dimension inverted index), so in 3d case + * we just support that stacked by index. + * + * @param seriesModel + * @param dimensionsInput The same as the input of . + * The input will be modified. + * @param opt + * @param opt.stackedCoordDimension Specify a coord dimension if needed. + * @param opt.byIndex=false + * @return calculationInfo + * { + * stackedDimension: string + * stackedByDimension: string + * isStackedByIndex: boolean + * stackedOverDimension: string + * stackResultDimension: string + * } + */ + function enableDataStack(seriesModel, dimensionsInput, opt) { + opt = opt || {}; + var byIndex = opt.byIndex; + var stackedCoordDimension = opt.stackedCoordDimension; + var dimensionDefineList; + var schema; + var store; + if (isLegacyDimensionsInput(dimensionsInput)) { + dimensionDefineList = dimensionsInput; + } else { + schema = dimensionsInput.schema; + dimensionDefineList = schema.dimensions; + store = dimensionsInput.store; + } + // Compatibal: when `stack` is set as '', do not stack. + var mayStack = !!(seriesModel && seriesModel.get('stack')); + var stackedByDimInfo; + var stackedDimInfo; + var stackResultDimension; + var stackedOverDimension; + each(dimensionDefineList, function (dimensionInfo, index) { + if (isString(dimensionInfo)) { + dimensionDefineList[index] = dimensionInfo = { + name: dimensionInfo + }; + } + if (mayStack && !dimensionInfo.isExtraCoord) { + // Find the first ordinal dimension as the stackedByDimInfo. + if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) { + stackedByDimInfo = dimensionInfo; + } + // Find the first stackable dimension as the stackedDimInfo. + if (!stackedDimInfo && dimensionInfo.type !== 'ordinal' && dimensionInfo.type !== 'time' && (!stackedCoordDimension || stackedCoordDimension === dimensionInfo.coordDim)) { + stackedDimInfo = dimensionInfo; + } + } + }); + if (stackedDimInfo && !byIndex && !stackedByDimInfo) { + // Compatible with previous design, value axis (time axis) only stack by index. + // It may make sense if the user provides elaborately constructed data. + byIndex = true; + } + // Add stack dimension, they can be both calculated by coordinate system in `unionExtent`. + // That put stack logic in List is for using conveniently in echarts extensions, but it + // might not be a good way. + if (stackedDimInfo) { + // Use a weird name that not duplicated with other names. + // Also need to use seriesModel.id as postfix because different + // series may share same data store. The stack dimension needs to be distinguished. + stackResultDimension = '__\0ecstackresult_' + seriesModel.id; + stackedOverDimension = '__\0ecstackedover_' + seriesModel.id; + // Create inverted index to fast query index by value. + if (stackedByDimInfo) { + stackedByDimInfo.createInvertedIndices = true; + } + var stackedDimCoordDim_1 = stackedDimInfo.coordDim; + var stackedDimType = stackedDimInfo.type; + var stackedDimCoordIndex_1 = 0; + each(dimensionDefineList, function (dimensionInfo) { + if (dimensionInfo.coordDim === stackedDimCoordDim_1) { + stackedDimCoordIndex_1++; + } + }); + var stackedOverDimensionDefine = { + name: stackResultDimension, + coordDim: stackedDimCoordDim_1, + coordDimIndex: stackedDimCoordIndex_1, + type: stackedDimType, + isExtraCoord: true, + isCalculationCoord: true, + storeDimIndex: dimensionDefineList.length + }; + var stackResultDimensionDefine = { + name: stackedOverDimension, + // This dimension contains stack base (generally, 0), so do not set it as + // `stackedDimCoordDim` to avoid extent calculation, consider log scale. + coordDim: stackedOverDimension, + coordDimIndex: stackedDimCoordIndex_1 + 1, + type: stackedDimType, + isExtraCoord: true, + isCalculationCoord: true, + storeDimIndex: dimensionDefineList.length + 1 + }; + if (schema) { + if (store) { + stackedOverDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackedOverDimension, stackedDimType); + stackResultDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackResultDimension, stackedDimType); + } + schema.appendCalculationDimension(stackedOverDimensionDefine); + schema.appendCalculationDimension(stackResultDimensionDefine); + } else { + dimensionDefineList.push(stackedOverDimensionDefine); + dimensionDefineList.push(stackResultDimensionDefine); + } + } + return { + stackedDimension: stackedDimInfo && stackedDimInfo.name, + stackedByDimension: stackedByDimInfo && stackedByDimInfo.name, + isStackedByIndex: byIndex, + stackedOverDimension: stackedOverDimension, + stackResultDimension: stackResultDimension + }; + } + function isLegacyDimensionsInput(dimensionsInput) { + return !isSeriesDataSchema(dimensionsInput.schema); + } + function isDimensionStacked(data, stackedDim) { + // Each single series only maps to one pair of axis. So we do not need to + // check stackByDim, whatever stacked by a dimension or stacked by index. + return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension'); + } + function getStackedDimension(data, targetDim) { + return isDimensionStacked(data, targetDim) ? data.getCalculationInfo('stackResultDimension') : targetDim; + } + + function getCoordSysDimDefs(seriesModel, coordSysInfo) { + var coordSysName = seriesModel.get('coordinateSystem'); + var registeredCoordSys = CoordinateSystemManager.get(coordSysName); + var coordSysDimDefs; + if (coordSysInfo && coordSysInfo.coordSysDims) { + coordSysDimDefs = map(coordSysInfo.coordSysDims, function (dim) { + var dimInfo = { + name: dim + }; + var axisModel = coordSysInfo.axisMap.get(dim); + if (axisModel) { + var axisType = axisModel.get('type'); + dimInfo.type = getDimensionTypeByAxis(axisType); + } + return dimInfo; + }); + } + if (!coordSysDimDefs) { + // Get dimensions from registered coordinate system + coordSysDimDefs = registeredCoordSys && (registeredCoordSys.getDimensionsInfo ? registeredCoordSys.getDimensionsInfo() : registeredCoordSys.dimensions.slice()) || ['x', 'y']; + } + return coordSysDimDefs; + } + function injectOrdinalMeta(dimInfoList, createInvertedIndices, coordSysInfo) { + var firstCategoryDimIndex; + var hasNameEncode; + coordSysInfo && each(dimInfoList, function (dimInfo, dimIndex) { + var coordDim = dimInfo.coordDim; + var categoryAxisModel = coordSysInfo.categoryAxisMap.get(coordDim); + if (categoryAxisModel) { + if (firstCategoryDimIndex == null) { + firstCategoryDimIndex = dimIndex; + } + dimInfo.ordinalMeta = categoryAxisModel.getOrdinalMeta(); + if (createInvertedIndices) { + dimInfo.createInvertedIndices = true; + } + } + if (dimInfo.otherDims.itemName != null) { + hasNameEncode = true; + } + }); + if (!hasNameEncode && firstCategoryDimIndex != null) { + dimInfoList[firstCategoryDimIndex].otherDims.itemName = 0; + } + return firstCategoryDimIndex; + } + /** + * Caution: there are side effects to `sourceManager` in this method. + * Should better only be called in `Series['getInitialData']`. + */ + function createSeriesData(sourceRaw, seriesModel, opt) { + opt = opt || {}; + var sourceManager = seriesModel.getSourceManager(); + var source; + var isOriginalSource = false; + if (sourceRaw) { + isOriginalSource = true; + source = createSourceFromSeriesDataOption(sourceRaw); + } else { + source = sourceManager.getSource(); + // Is series.data. not dataset. + isOriginalSource = source.sourceFormat === SOURCE_FORMAT_ORIGINAL; + } + var coordSysInfo = getCoordSysInfoBySeries(seriesModel); + var coordSysDimDefs = getCoordSysDimDefs(seriesModel, coordSysInfo); + var useEncodeDefaulter = opt.useEncodeDefaulter; + var encodeDefaulter = isFunction(useEncodeDefaulter) ? useEncodeDefaulter : useEncodeDefaulter ? curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel) : null; + var createDimensionOptions = { + coordDimensions: coordSysDimDefs, + generateCoord: opt.generateCoord, + encodeDefine: seriesModel.getEncode(), + encodeDefaulter: encodeDefaulter, + canOmitUnusedDimensions: !isOriginalSource + }; + var schema = prepareSeriesDataSchema(source, createDimensionOptions); + var firstCategoryDimIndex = injectOrdinalMeta(schema.dimensions, opt.createInvertedIndices, coordSysInfo); + var store = !isOriginalSource ? sourceManager.getSharedDataStore(schema) : null; + var stackCalculationInfo = enableDataStack(seriesModel, { + schema: schema, + store: store + }); + var data = new SeriesData(schema, seriesModel); + data.setCalculationInfo(stackCalculationInfo); + var dimValueGetter = firstCategoryDimIndex != null && isNeedCompleteOrdinalData(source) ? function (itemOpt, dimName, dataIndex, dimIndex) { + // Use dataIndex as ordinal value in categoryAxis + return dimIndex === firstCategoryDimIndex ? dataIndex : this.defaultDimValueGetter(itemOpt, dimName, dataIndex, dimIndex); + } : null; + data.hasItemOption = false; + data.initData( + // Try to reuse the data store in sourceManager if using dataset. + isOriginalSource ? source : store, null, dimValueGetter); + return data; + } + function isNeedCompleteOrdinalData(source) { + if (source.sourceFormat === SOURCE_FORMAT_ORIGINAL) { + var sampleItem = firstDataNotNull(source.data || []); + return !isArray(getDataItemValue(sampleItem)); + } + } + function firstDataNotNull(arr) { + var i = 0; + while (i < arr.length && arr[i] == null) { + i++; + } + return arr[i]; + } + + var Scale = /** @class */function () { + function Scale(setting) { + this._setting = setting || {}; + this._extent = [Infinity, -Infinity]; + } + Scale.prototype.getSetting = function (name) { + return this._setting[name]; + }; + /** + * Set extent from data + */ + Scale.prototype.unionExtent = function (other) { + var extent = this._extent; + other[0] < extent[0] && (extent[0] = other[0]); + other[1] > extent[1] && (extent[1] = other[1]); + // not setExtent because in log axis it may transformed to power + // this.setExtent(extent[0], extent[1]); + }; + /** + * Set extent from data + */ + Scale.prototype.unionExtentFromData = function (data, dim) { + this.unionExtent(data.getApproximateExtent(dim)); + }; + /** + * Get extent + * + * Extent is always in increase order. + */ + Scale.prototype.getExtent = function () { + return this._extent.slice(); + }; + /** + * Set extent + */ + Scale.prototype.setExtent = function (start, end) { + var thisExtent = this._extent; + if (!isNaN(start)) { + thisExtent[0] = start; + } + if (!isNaN(end)) { + thisExtent[1] = end; + } + }; + /** + * If value is in extent range + */ + Scale.prototype.isInExtentRange = function (value) { + return this._extent[0] <= value && this._extent[1] >= value; + }; + /** + * When axis extent depends on data and no data exists, + * axis ticks should not be drawn, which is named 'blank'. + */ + Scale.prototype.isBlank = function () { + return this._isBlank; + }; + /** + * When axis extent depends on data and no data exists, + * axis ticks should not be drawn, which is named 'blank'. + */ + Scale.prototype.setBlank = function (isBlank) { + this._isBlank = isBlank; + }; + return Scale; + }(); + enableClassManagement(Scale); + + var uidBase = 0; + var OrdinalMeta = /** @class */function () { + function OrdinalMeta(opt) { + this.categories = opt.categories || []; + this._needCollect = opt.needCollect; + this._deduplication = opt.deduplication; + this.uid = ++uidBase; + } + OrdinalMeta.createByAxisModel = function (axisModel) { + var option = axisModel.option; + var data = option.data; + var categories = data && map(data, getName); + return new OrdinalMeta({ + categories: categories, + needCollect: !categories, + // deduplication is default in axis. + deduplication: option.dedplication !== false + }); + }; + OrdinalMeta.prototype.getOrdinal = function (category) { + // @ts-ignore + return this._getOrCreateMap().get(category); + }; + /** + * @return The ordinal. If not found, return NaN. + */ + OrdinalMeta.prototype.parseAndCollect = function (category) { + var index; + var needCollect = this._needCollect; + // The value of category dim can be the index of the given category set. + // This feature is only supported when !needCollect, because we should + // consider a common case: a value is 2017, which is a number but is + // expected to be tread as a category. This case usually happen in dataset, + // where it happent to be no need of the index feature. + if (!isString(category) && !needCollect) { + return category; + } + // Optimize for the scenario: + // category is ['2012-01-01', '2012-01-02', ...], where the input + // data has been ensured not duplicate and is large data. + // Notice, if a dataset dimension provide categroies, usually echarts + // should remove duplication except user tell echarts dont do that + // (set axis.deduplication = false), because echarts do not know whether + // the values in the category dimension has duplication (consider the + // parallel-aqi example) + if (needCollect && !this._deduplication) { + index = this.categories.length; + this.categories[index] = category; + return index; + } + var map = this._getOrCreateMap(); + // @ts-ignore + index = map.get(category); + if (index == null) { + if (needCollect) { + index = this.categories.length; + this.categories[index] = category; + // @ts-ignore + map.set(category, index); + } else { + index = NaN; + } + } + return index; + }; + // Consider big data, do not create map until needed. + OrdinalMeta.prototype._getOrCreateMap = function () { + return this._map || (this._map = createHashMap(this.categories)); + }; + return OrdinalMeta; + }(); + function getName(obj) { + if (isObject(obj) && obj.value != null) { + return obj.value; + } else { + return obj + ''; + } + } + + function isValueNice(val) { + var exp10 = Math.pow(10, quantityExponent(Math.abs(val))); + var f = Math.abs(val / exp10); + return f === 0 || f === 1 || f === 2 || f === 3 || f === 5; + } + function isIntervalOrLogScale(scale) { + return scale.type === 'interval' || scale.type === 'log'; + } + /** + * @param extent Both extent[0] and extent[1] should be valid number. + * Should be extent[0] < extent[1]. + * @param splitNumber splitNumber should be >= 1. + */ + function intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval) { + var result = {}; + var span = extent[1] - extent[0]; + var interval = result.interval = nice(span / splitNumber, true); + if (minInterval != null && interval < minInterval) { + interval = result.interval = minInterval; + } + if (maxInterval != null && interval > maxInterval) { + interval = result.interval = maxInterval; + } + // Tow more digital for tick. + var precision = result.intervalPrecision = getIntervalPrecision(interval); + // Niced extent inside original extent + var niceTickExtent = result.niceTickExtent = [round(Math.ceil(extent[0] / interval) * interval, precision), round(Math.floor(extent[1] / interval) * interval, precision)]; + fixExtent(niceTickExtent, extent); + return result; + } + function increaseInterval(interval) { + var exp10 = Math.pow(10, quantityExponent(interval)); + // Increase interval + var f = interval / exp10; + if (!f) { + f = 1; + } else if (f === 2) { + f = 3; + } else if (f === 3) { + f = 5; + } else { + // f is 1 or 5 + f *= 2; + } + return round(f * exp10); + } + /** + * @return interval precision + */ + function getIntervalPrecision(interval) { + // Tow more digital for tick. + return getPrecision(interval) + 2; + } + function clamp(niceTickExtent, idx, extent) { + niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]); + } + // In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent. + function fixExtent(niceTickExtent, extent) { + !isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]); + !isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]); + clamp(niceTickExtent, 0, extent); + clamp(niceTickExtent, 1, extent); + if (niceTickExtent[0] > niceTickExtent[1]) { + niceTickExtent[0] = niceTickExtent[1]; + } + } + function contain$1(val, extent) { + return val >= extent[0] && val <= extent[1]; + } + function normalize$1(val, extent) { + if (extent[1] === extent[0]) { + return 0.5; + } + return (val - extent[0]) / (extent[1] - extent[0]); + } + function scale$2(val, extent) { + return val * (extent[1] - extent[0]) + extent[0]; + } + + var OrdinalScale = /** @class */function (_super) { + __extends(OrdinalScale, _super); + function OrdinalScale(setting) { + var _this = _super.call(this, setting) || this; + _this.type = 'ordinal'; + var ordinalMeta = _this.getSetting('ordinalMeta'); + // Caution: Should not use instanceof, consider ec-extensions using + // import approach to get OrdinalMeta class. + if (!ordinalMeta) { + ordinalMeta = new OrdinalMeta({}); + } + if (isArray(ordinalMeta)) { + ordinalMeta = new OrdinalMeta({ + categories: map(ordinalMeta, function (item) { + return isObject(item) ? item.value : item; + }) + }); + } + _this._ordinalMeta = ordinalMeta; + _this._extent = _this.getSetting('extent') || [0, ordinalMeta.categories.length - 1]; + return _this; + } + OrdinalScale.prototype.parse = function (val) { + // Caution: Math.round(null) will return `0` rather than `NaN` + if (val == null) { + return NaN; + } + return isString(val) ? this._ordinalMeta.getOrdinal(val) + // val might be float. + : Math.round(val); + }; + OrdinalScale.prototype.contain = function (rank) { + rank = this.parse(rank); + return contain$1(rank, this._extent) && this._ordinalMeta.categories[rank] != null; + }; + /** + * Normalize given rank or name to linear [0, 1] + * @param val raw ordinal number. + * @return normalized value in [0, 1]. + */ + OrdinalScale.prototype.normalize = function (val) { + val = this._getTickNumber(this.parse(val)); + return normalize$1(val, this._extent); + }; + /** + * @param val normalized value in [0, 1]. + * @return raw ordinal number. + */ + OrdinalScale.prototype.scale = function (val) { + val = Math.round(scale$2(val, this._extent)); + return this.getRawOrdinalNumber(val); + }; + OrdinalScale.prototype.getTicks = function () { + var ticks = []; + var extent = this._extent; + var rank = extent[0]; + while (rank <= extent[1]) { + ticks.push({ + value: rank + }); + rank++; + } + return ticks; + }; + OrdinalScale.prototype.getMinorTicks = function (splitNumber) { + // Not support. + return; + }; + /** + * @see `Ordinal['_ordinalNumbersByTick']` + */ + OrdinalScale.prototype.setSortInfo = function (info) { + if (info == null) { + this._ordinalNumbersByTick = this._ticksByOrdinalNumber = null; + return; + } + var infoOrdinalNumbers = info.ordinalNumbers; + var ordinalsByTick = this._ordinalNumbersByTick = []; + var ticksByOrdinal = this._ticksByOrdinalNumber = []; + // Unnecessary support negative tick in `realtimeSort`. + var tickNum = 0; + var allCategoryLen = this._ordinalMeta.categories.length; + for (var len = Math.min(allCategoryLen, infoOrdinalNumbers.length); tickNum < len; ++tickNum) { + var ordinalNumber = infoOrdinalNumbers[tickNum]; + ordinalsByTick[tickNum] = ordinalNumber; + ticksByOrdinal[ordinalNumber] = tickNum; + } + // Handle that `series.data` only covers part of the `axis.category.data`. + var unusedOrdinal = 0; + for (; tickNum < allCategoryLen; ++tickNum) { + while (ticksByOrdinal[unusedOrdinal] != null) { + unusedOrdinal++; + } + ordinalsByTick.push(unusedOrdinal); + ticksByOrdinal[unusedOrdinal] = tickNum; + } + }; + OrdinalScale.prototype._getTickNumber = function (ordinal) { + var ticksByOrdinalNumber = this._ticksByOrdinalNumber; + // also support ordinal out of range of `ordinalMeta.categories.length`, + // where ordinal numbers are used as tick value directly. + return ticksByOrdinalNumber && ordinal >= 0 && ordinal < ticksByOrdinalNumber.length ? ticksByOrdinalNumber[ordinal] : ordinal; + }; + /** + * @usage + * ```js + * const ordinalNumber = ordinalScale.getRawOrdinalNumber(tickVal); + * + * // case0 + * const rawOrdinalValue = axisModel.getCategories()[ordinalNumber]; + * // case1 + * const rawOrdinalValue = this._ordinalMeta.categories[ordinalNumber]; + * // case2 + * const coord = axis.dataToCoord(ordinalNumber); + * ``` + * + * @param {OrdinalNumber} tickNumber index of display + */ + OrdinalScale.prototype.getRawOrdinalNumber = function (tickNumber) { + var ordinalNumbersByTick = this._ordinalNumbersByTick; + // tickNumber may be out of range, e.g., when axis max is larger than `ordinalMeta.categories.length`., + // where ordinal numbers are used as tick value directly. + return ordinalNumbersByTick && tickNumber >= 0 && tickNumber < ordinalNumbersByTick.length ? ordinalNumbersByTick[tickNumber] : tickNumber; + }; + /** + * Get item on tick + */ + OrdinalScale.prototype.getLabel = function (tick) { + if (!this.isBlank()) { + var ordinalNumber = this.getRawOrdinalNumber(tick.value); + var cateogry = this._ordinalMeta.categories[ordinalNumber]; + // Note that if no data, ordinalMeta.categories is an empty array. + // Return empty if it's not exist. + return cateogry == null ? '' : cateogry + ''; + } + }; + OrdinalScale.prototype.count = function () { + return this._extent[1] - this._extent[0] + 1; + }; + OrdinalScale.prototype.unionExtentFromData = function (data, dim) { + this.unionExtent(data.getApproximateExtent(dim)); + }; + /** + * @override + * If value is in extent range + */ + OrdinalScale.prototype.isInExtentRange = function (value) { + value = this._getTickNumber(value); + return this._extent[0] <= value && this._extent[1] >= value; + }; + OrdinalScale.prototype.getOrdinalMeta = function () { + return this._ordinalMeta; + }; + OrdinalScale.prototype.calcNiceTicks = function () {}; + OrdinalScale.prototype.calcNiceExtent = function () {}; + OrdinalScale.type = 'ordinal'; + return OrdinalScale; + }(Scale); + Scale.registerClass(OrdinalScale); + + var roundNumber = round; + var IntervalScale = /** @class */function (_super) { + __extends(IntervalScale, _super); + function IntervalScale() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = 'interval'; + // Step is calculated in adjustExtent. + _this._interval = 0; + _this._intervalPrecision = 2; + return _this; + } + IntervalScale.prototype.parse = function (val) { + return val; + }; + IntervalScale.prototype.contain = function (val) { + return contain$1(val, this._extent); + }; + IntervalScale.prototype.normalize = function (val) { + return normalize$1(val, this._extent); + }; + IntervalScale.prototype.scale = function (val) { + return scale$2(val, this._extent); + }; + IntervalScale.prototype.setExtent = function (start, end) { + var thisExtent = this._extent; + // start,end may be a Number like '25',so... + if (!isNaN(start)) { + thisExtent[0] = parseFloat(start); + } + if (!isNaN(end)) { + thisExtent[1] = parseFloat(end); + } + }; + IntervalScale.prototype.unionExtent = function (other) { + var extent = this._extent; + other[0] < extent[0] && (extent[0] = other[0]); + other[1] > extent[1] && (extent[1] = other[1]); + // unionExtent may called by it's sub classes + this.setExtent(extent[0], extent[1]); + }; + IntervalScale.prototype.getInterval = function () { + return this._interval; + }; + IntervalScale.prototype.setInterval = function (interval) { + this._interval = interval; + // Dropped auto calculated niceExtent and use user-set extent. + // We assume user wants to set both interval, min, max to get a better result. + this._niceExtent = this._extent.slice(); + this._intervalPrecision = getIntervalPrecision(interval); + }; + /** + * @param expandToNicedExtent Whether expand the ticks to niced extent. + */ + IntervalScale.prototype.getTicks = function (expandToNicedExtent) { + var interval = this._interval; + var extent = this._extent; + var niceTickExtent = this._niceExtent; + var intervalPrecision = this._intervalPrecision; + var ticks = []; + // If interval is 0, return []; + if (!interval) { + return ticks; + } + // Consider this case: using dataZoom toolbox, zoom and zoom. + var safeLimit = 10000; + if (extent[0] < niceTickExtent[0]) { + if (expandToNicedExtent) { + ticks.push({ + value: roundNumber(niceTickExtent[0] - interval, intervalPrecision) + }); + } else { + ticks.push({ + value: extent[0] + }); + } + } + var tick = niceTickExtent[0]; + while (tick <= niceTickExtent[1]) { + ticks.push({ + value: tick + }); + // Avoid rounding error + tick = roundNumber(tick + interval, intervalPrecision); + if (tick === ticks[ticks.length - 1].value) { + // Consider out of safe float point, e.g., + // -3711126.9907707 + 2e-10 === -3711126.9907707 + break; + } + if (ticks.length > safeLimit) { + return []; + } + } + // Consider this case: the last item of ticks is smaller + // than niceTickExtent[1] and niceTickExtent[1] === extent[1]. + var lastNiceTick = ticks.length ? ticks[ticks.length - 1].value : niceTickExtent[1]; + if (extent[1] > lastNiceTick) { + if (expandToNicedExtent) { + ticks.push({ + value: roundNumber(lastNiceTick + interval, intervalPrecision) + }); + } else { + ticks.push({ + value: extent[1] + }); + } + } + return ticks; + }; + IntervalScale.prototype.getMinorTicks = function (splitNumber) { + var ticks = this.getTicks(true); + var minorTicks = []; + var extent = this.getExtent(); + for (var i = 1; i < ticks.length; i++) { + var nextTick = ticks[i]; + var prevTick = ticks[i - 1]; + var count = 0; + var minorTicksGroup = []; + var interval = nextTick.value - prevTick.value; + var minorInterval = interval / splitNumber; + while (count < splitNumber - 1) { + var minorTick = roundNumber(prevTick.value + (count + 1) * minorInterval); + // For the first and last interval. The count may be less than splitNumber. + if (minorTick > extent[0] && minorTick < extent[1]) { + minorTicksGroup.push(minorTick); + } + count++; + } + minorTicks.push(minorTicksGroup); + } + return minorTicks; + }; + /** + * @param opt.precision If 'auto', use nice presision. + * @param opt.pad returns 1.50 but not 1.5 if precision is 2. + */ + IntervalScale.prototype.getLabel = function (data, opt) { + if (data == null) { + return ''; + } + var precision = opt && opt.precision; + if (precision == null) { + precision = getPrecision(data.value) || 0; + } else if (precision === 'auto') { + // Should be more precise then tick. + precision = this._intervalPrecision; + } + // (1) If `precision` is set, 12.005 should be display as '12.00500'. + // (2) Use roundNumber (toFixed) to avoid scientific notation like '3.5e-7'. + var dataNum = roundNumber(data.value, precision, true); + return addCommas(dataNum); + }; + /** + * @param splitNumber By default `5`. + */ + IntervalScale.prototype.calcNiceTicks = function (splitNumber, minInterval, maxInterval) { + splitNumber = splitNumber || 5; + var extent = this._extent; + var span = extent[1] - extent[0]; + if (!isFinite(span)) { + return; + } + // User may set axis min 0 and data are all negative + // FIXME If it needs to reverse ? + if (span < 0) { + span = -span; + extent.reverse(); + } + var result = intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval); + this._intervalPrecision = result.intervalPrecision; + this._interval = result.interval; + this._niceExtent = result.niceTickExtent; + }; + IntervalScale.prototype.calcNiceExtent = function (opt) { + var extent = this._extent; + // If extent start and end are same, expand them + if (extent[0] === extent[1]) { + if (extent[0] !== 0) { + // Expand extent + // Note that extents can be both negative. See #13154 + var expandSize = Math.abs(extent[0]); + // In the fowllowing case + // Axis has been fixed max 100 + // Plus data are all 100 and axis extent are [100, 100]. + // Extend to the both side will cause expanded max is larger than fixed max. + // So only expand to the smaller side. + if (!opt.fixMax) { + extent[1] += expandSize / 2; + extent[0] -= expandSize / 2; + } else { + extent[0] -= expandSize / 2; + } + } else { + extent[1] = 1; + } + } + var span = extent[1] - extent[0]; + // If there are no data and extent are [Infinity, -Infinity] + if (!isFinite(span)) { + extent[0] = 0; + extent[1] = 1; + } + this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); + // let extent = this._extent; + var interval = this._interval; + if (!opt.fixMin) { + extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval); + } + if (!opt.fixMax) { + extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval); + } + }; + IntervalScale.prototype.setNiceExtent = function (min, max) { + this._niceExtent = [min, max]; + }; + IntervalScale.type = 'interval'; + return IntervalScale; + }(Scale); + Scale.registerClass(IntervalScale); + + /* global Float32Array */ + var supportFloat32Array = typeof Float32Array !== 'undefined'; + var Float32ArrayCtor = !supportFloat32Array ? Array : Float32Array; + function createFloat32Array(arg) { + if (isArray(arg)) { + // Return self directly if don't support TypedArray. + return supportFloat32Array ? new Float32Array(arg) : arg; + } + // Else is number + return new Float32ArrayCtor(arg); + } + + var STACK_PREFIX = '__ec_stack_'; + function getSeriesStackId(seriesModel) { + return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex; + } + function getAxisKey(axis) { + return axis.dim + axis.index; + } + /** + * @return {Object} {width, offset, offsetCenter} If axis.type is not 'category', return undefined. + */ + function getLayoutOnAxis(opt) { + var params = []; + var baseAxis = opt.axis; + var axisKey = 'axis0'; + if (baseAxis.type !== 'category') { + return; + } + var bandWidth = baseAxis.getBandWidth(); + for (var i = 0; i < opt.count || 0; i++) { + params.push(defaults({ + bandWidth: bandWidth, + axisKey: axisKey, + stackId: STACK_PREFIX + i + }, opt)); + } + var widthAndOffsets = doCalBarWidthAndOffset(params); + var result = []; + for (var i = 0; i < opt.count; i++) { + var item = widthAndOffsets[axisKey][STACK_PREFIX + i]; + item.offsetCenter = item.offset + item.width / 2; + result.push(item); + } + return result; + } + function prepareLayoutBarSeries(seriesType, ecModel) { + var seriesModels = []; + ecModel.eachSeriesByType(seriesType, function (seriesModel) { + // Check series coordinate, do layout for cartesian2d only + if (isOnCartesian(seriesModel)) { + seriesModels.push(seriesModel); + } + }); + return seriesModels; + } + /** + * Map from (baseAxis.dim + '_' + baseAxis.index) to min gap of two adjacent + * values. + * This works for time axes, value axes, and log axes. + * For a single time axis, return value is in the form like + * {'x_0': [1000000]}. + * The value of 1000000 is in milliseconds. + */ + function getValueAxesMinGaps(barSeries) { + /** + * Map from axis.index to values. + * For a single time axis, axisValues is in the form like + * {'x_0': [1495555200000, 1495641600000, 1495728000000]}. + * Items in axisValues[x], e.g. 1495555200000, are time values of all + * series. + */ + var axisValues = {}; + each(barSeries, function (seriesModel) { + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + if (baseAxis.type !== 'time' && baseAxis.type !== 'value') { + return; + } + var data = seriesModel.getData(); + var key = baseAxis.dim + '_' + baseAxis.index; + var dimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim)); + var store = data.getStore(); + for (var i = 0, cnt = store.count(); i < cnt; ++i) { + var value = store.get(dimIdx, i); + if (!axisValues[key]) { + // No previous data for the axis + axisValues[key] = [value]; + } else { + // No value in previous series + axisValues[key].push(value); + } + // Ignore duplicated time values in the same axis + } + }); + + var axisMinGaps = {}; + for (var key in axisValues) { + if (axisValues.hasOwnProperty(key)) { + var valuesInAxis = axisValues[key]; + if (valuesInAxis) { + // Sort axis values into ascending order to calculate gaps + valuesInAxis.sort(function (a, b) { + return a - b; + }); + var min = null; + for (var j = 1; j < valuesInAxis.length; ++j) { + var delta = valuesInAxis[j] - valuesInAxis[j - 1]; + if (delta > 0) { + // Ignore 0 delta because they are of the same axis value + min = min === null ? delta : Math.min(min, delta); + } + } + // Set to null if only have one data + axisMinGaps[key] = min; + } + } + } + return axisMinGaps; + } + function makeColumnLayout(barSeries) { + var axisMinGaps = getValueAxesMinGaps(barSeries); + var seriesInfoList = []; + each(barSeries, function (seriesModel) { + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + var axisExtent = baseAxis.getExtent(); + var bandWidth; + if (baseAxis.type === 'category') { + bandWidth = baseAxis.getBandWidth(); + } else if (baseAxis.type === 'value' || baseAxis.type === 'time') { + var key = baseAxis.dim + '_' + baseAxis.index; + var minGap = axisMinGaps[key]; + var extentSpan = Math.abs(axisExtent[1] - axisExtent[0]); + var scale = baseAxis.scale.getExtent(); + var scaleSpan = Math.abs(scale[1] - scale[0]); + bandWidth = minGap ? extentSpan / scaleSpan * minGap : extentSpan; // When there is only one data value + } else { + var data = seriesModel.getData(); + bandWidth = Math.abs(axisExtent[1] - axisExtent[0]) / data.count(); + } + var barWidth = parsePercent$1(seriesModel.get('barWidth'), bandWidth); + var barMaxWidth = parsePercent$1(seriesModel.get('barMaxWidth'), bandWidth); + var barMinWidth = parsePercent$1( + // barMinWidth by default is 0.5 / 1 in cartesian. Because in value axis, + // the auto-calculated bar width might be less than 0.5 / 1. + seriesModel.get('barMinWidth') || (isInLargeMode(seriesModel) ? 0.5 : 1), bandWidth); + var barGap = seriesModel.get('barGap'); + var barCategoryGap = seriesModel.get('barCategoryGap'); + seriesInfoList.push({ + bandWidth: bandWidth, + barWidth: barWidth, + barMaxWidth: barMaxWidth, + barMinWidth: barMinWidth, + barGap: barGap, + barCategoryGap: barCategoryGap, + axisKey: getAxisKey(baseAxis), + stackId: getSeriesStackId(seriesModel) + }); + }); + return doCalBarWidthAndOffset(seriesInfoList); + } + function doCalBarWidthAndOffset(seriesInfoList) { + // Columns info on each category axis. Key is cartesian name + var columnsMap = {}; + each(seriesInfoList, function (seriesInfo, idx) { + var axisKey = seriesInfo.axisKey; + var bandWidth = seriesInfo.bandWidth; + var columnsOnAxis = columnsMap[axisKey] || { + bandWidth: bandWidth, + remainedWidth: bandWidth, + autoWidthCount: 0, + categoryGap: null, + gap: '20%', + stacks: {} + }; + var stacks = columnsOnAxis.stacks; + columnsMap[axisKey] = columnsOnAxis; + var stackId = seriesInfo.stackId; + if (!stacks[stackId]) { + columnsOnAxis.autoWidthCount++; + } + stacks[stackId] = stacks[stackId] || { + width: 0, + maxWidth: 0 + }; + // Caution: In a single coordinate system, these barGrid attributes + // will be shared by series. Consider that they have default values, + // only the attributes set on the last series will work. + // Do not change this fact unless there will be a break change. + var barWidth = seriesInfo.barWidth; + if (barWidth && !stacks[stackId].width) { + // See #6312, do not restrict width. + stacks[stackId].width = barWidth; + barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth); + columnsOnAxis.remainedWidth -= barWidth; + } + var barMaxWidth = seriesInfo.barMaxWidth; + barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth); + var barMinWidth = seriesInfo.barMinWidth; + barMinWidth && (stacks[stackId].minWidth = barMinWidth); + var barGap = seriesInfo.barGap; + barGap != null && (columnsOnAxis.gap = barGap); + var barCategoryGap = seriesInfo.barCategoryGap; + barCategoryGap != null && (columnsOnAxis.categoryGap = barCategoryGap); + }); + var result = {}; + each(columnsMap, function (columnsOnAxis, coordSysName) { + result[coordSysName] = {}; + var stacks = columnsOnAxis.stacks; + var bandWidth = columnsOnAxis.bandWidth; + var categoryGapPercent = columnsOnAxis.categoryGap; + if (categoryGapPercent == null) { + var columnCount = keys(stacks).length; + // More columns in one group + // the spaces between group is smaller. Or the column will be too thin. + categoryGapPercent = Math.max(35 - columnCount * 4, 15) + '%'; + } + var categoryGap = parsePercent$1(categoryGapPercent, bandWidth); + var barGapPercent = parsePercent$1(columnsOnAxis.gap, 1); + var remainedWidth = columnsOnAxis.remainedWidth; + var autoWidthCount = columnsOnAxis.autoWidthCount; + var autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent); + autoWidth = Math.max(autoWidth, 0); + // Find if any auto calculated bar exceeded maxBarWidth + each(stacks, function (column) { + var maxWidth = column.maxWidth; + var minWidth = column.minWidth; + if (!column.width) { + var finalWidth = autoWidth; + if (maxWidth && maxWidth < finalWidth) { + finalWidth = Math.min(maxWidth, remainedWidth); + } + // `minWidth` has higher priority. `minWidth` decide that whether the + // bar is able to be visible. So `minWidth` should not be restricted + // by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In + // the extreme cases for `value` axis, bars are allowed to overlap + // with each other if `minWidth` specified. + if (minWidth && minWidth > finalWidth) { + finalWidth = minWidth; + } + if (finalWidth !== autoWidth) { + column.width = finalWidth; + remainedWidth -= finalWidth + barGapPercent * finalWidth; + autoWidthCount--; + } + } else { + // `barMinWidth/barMaxWidth` has higher priority than `barWidth`, as + // CSS does. Because barWidth can be a percent value, where + // `barMaxWidth` can be used to restrict the final width. + var finalWidth = column.width; + if (maxWidth) { + finalWidth = Math.min(finalWidth, maxWidth); + } + // `minWidth` has higher priority, as described above + if (minWidth) { + finalWidth = Math.max(finalWidth, minWidth); + } + column.width = finalWidth; + remainedWidth -= finalWidth + barGapPercent * finalWidth; + autoWidthCount--; + } + }); + // Recalculate width again + autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent); + autoWidth = Math.max(autoWidth, 0); + var widthSum = 0; + var lastColumn; + each(stacks, function (column, idx) { + if (!column.width) { + column.width = autoWidth; + } + lastColumn = column; + widthSum += column.width * (1 + barGapPercent); + }); + if (lastColumn) { + widthSum -= lastColumn.width * barGapPercent; + } + var offset = -widthSum / 2; + each(stacks, function (column, stackId) { + result[coordSysName][stackId] = result[coordSysName][stackId] || { + bandWidth: bandWidth, + offset: offset, + width: column.width + }; + offset += column.width * (1 + barGapPercent); + }); + }); + return result; + } + function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) { + if (barWidthAndOffset && axis) { + var result = barWidthAndOffset[getAxisKey(axis)]; + if (result != null && seriesModel != null) { + return result[getSeriesStackId(seriesModel)]; + } + return result; + } + } + function layout(seriesType, ecModel) { + var seriesModels = prepareLayoutBarSeries(seriesType, ecModel); + var barWidthAndOffset = makeColumnLayout(seriesModels); + each(seriesModels, function (seriesModel) { + var data = seriesModel.getData(); + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + var stackId = getSeriesStackId(seriesModel); + var columnLayoutInfo = barWidthAndOffset[getAxisKey(baseAxis)][stackId]; + var columnOffset = columnLayoutInfo.offset; + var columnWidth = columnLayoutInfo.width; + data.setLayout({ + bandWidth: columnLayoutInfo.bandWidth, + offset: columnOffset, + size: columnWidth + }); + }); + } + // TODO: Do not support stack in large mode yet. + function createProgressiveLayout(seriesType) { + return { + seriesType: seriesType, + plan: createRenderPlanner(), + reset: function (seriesModel) { + if (!isOnCartesian(seriesModel)) { + return; + } + var data = seriesModel.getData(); + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + var valueAxis = cartesian.getOtherAxis(baseAxis); + var valueDimIdx = data.getDimensionIndex(data.mapDimension(valueAxis.dim)); + var baseDimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim)); + var drawBackground = seriesModel.get('showBackground', true); + var valueDim = data.mapDimension(valueAxis.dim); + var stackResultDim = data.getCalculationInfo('stackResultDimension'); + var stacked = isDimensionStacked(data, valueDim) && !!data.getCalculationInfo('stackedOnSeries'); + var isValueAxisH = valueAxis.isHorizontal(); + var valueAxisStart = getValueAxisStart(baseAxis, valueAxis); + var isLarge = isInLargeMode(seriesModel); + var barMinHeight = seriesModel.get('barMinHeight') || 0; + var stackedDimIdx = stackResultDim && data.getDimensionIndex(stackResultDim); + // Layout info. + var columnWidth = data.getLayout('size'); + var columnOffset = data.getLayout('offset'); + return { + progress: function (params, data) { + var count = params.count; + var largePoints = isLarge && createFloat32Array(count * 3); + var largeBackgroundPoints = isLarge && drawBackground && createFloat32Array(count * 3); + var largeDataIndices = isLarge && createFloat32Array(count); + var coordLayout = cartesian.master.getRect(); + var bgSize = isValueAxisH ? coordLayout.width : coordLayout.height; + var dataIndex; + var store = data.getStore(); + var idxOffset = 0; + while ((dataIndex = params.next()) != null) { + var value = store.get(stacked ? stackedDimIdx : valueDimIdx, dataIndex); + var baseValue = store.get(baseDimIdx, dataIndex); + var baseCoord = valueAxisStart; + var startValue = void 0; + // Because of the barMinHeight, we can not use the value in + // stackResultDimension directly. + if (stacked) { + startValue = +value - store.get(valueDimIdx, dataIndex); + } + var x = void 0; + var y = void 0; + var width = void 0; + var height = void 0; + if (isValueAxisH) { + var coord = cartesian.dataToPoint([value, baseValue]); + if (stacked) { + var startCoord = cartesian.dataToPoint([startValue, baseValue]); + baseCoord = startCoord[0]; + } + x = baseCoord; + y = coord[1] + columnOffset; + width = coord[0] - baseCoord; + height = columnWidth; + if (Math.abs(width) < barMinHeight) { + width = (width < 0 ? -1 : 1) * barMinHeight; + } + } else { + var coord = cartesian.dataToPoint([baseValue, value]); + if (stacked) { + var startCoord = cartesian.dataToPoint([baseValue, startValue]); + baseCoord = startCoord[1]; + } + x = coord[0] + columnOffset; + y = baseCoord; + width = columnWidth; + height = coord[1] - baseCoord; + if (Math.abs(height) < barMinHeight) { + // Include zero to has a positive bar + height = (height <= 0 ? -1 : 1) * barMinHeight; + } + } + if (!isLarge) { + data.setItemLayout(dataIndex, { + x: x, + y: y, + width: width, + height: height + }); + } else { + largePoints[idxOffset] = x; + largePoints[idxOffset + 1] = y; + largePoints[idxOffset + 2] = isValueAxisH ? width : height; + if (largeBackgroundPoints) { + largeBackgroundPoints[idxOffset] = isValueAxisH ? coordLayout.x : x; + largeBackgroundPoints[idxOffset + 1] = isValueAxisH ? y : coordLayout.y; + largeBackgroundPoints[idxOffset + 2] = bgSize; + } + largeDataIndices[dataIndex] = dataIndex; + } + idxOffset += 3; + } + if (isLarge) { + data.setLayout({ + largePoints: largePoints, + largeDataIndices: largeDataIndices, + largeBackgroundPoints: largeBackgroundPoints, + valueAxisHorizontal: isValueAxisH + }); + } + } + }; + } + }; + } + function isOnCartesian(seriesModel) { + return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d'; + } + function isInLargeMode(seriesModel) { + return seriesModel.pipelineContext && seriesModel.pipelineContext.large; + } + // See cases in `test/bar-start.html` and `#7412`, `#8747`. + function getValueAxisStart(baseAxis, valueAxis) { + return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0)); + } + + // FIXME 公用? + var bisect = function (a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid][1] < x) { + lo = mid + 1; + } else { + hi = mid; + } + } + return lo; + }; + var TimeScale = /** @class */function (_super) { + __extends(TimeScale, _super); + function TimeScale(settings) { + var _this = _super.call(this, settings) || this; + _this.type = 'time'; + return _this; + } + /** + * Get label is mainly for other components like dataZoom, tooltip. + */ + TimeScale.prototype.getLabel = function (tick) { + var useUTC = this.getSetting('useUTC'); + return format(tick.value, fullLeveledFormatter[getDefaultFormatPrecisionOfInterval(getPrimaryTimeUnit(this._minLevelUnit))] || fullLeveledFormatter.second, useUTC, this.getSetting('locale')); + }; + TimeScale.prototype.getFormattedLabel = function (tick, idx, labelFormatter) { + var isUTC = this.getSetting('useUTC'); + var lang = this.getSetting('locale'); + return leveledFormat(tick, idx, labelFormatter, lang, isUTC); + }; + /** + * @override + */ + TimeScale.prototype.getTicks = function () { + var interval = this._interval; + var extent = this._extent; + var ticks = []; + // If interval is 0, return []; + if (!interval) { + return ticks; + } + ticks.push({ + value: extent[0], + level: 0 + }); + var useUTC = this.getSetting('useUTC'); + var innerTicks = getIntervalTicks(this._minLevelUnit, this._approxInterval, useUTC, extent); + ticks = ticks.concat(innerTicks); + ticks.push({ + value: extent[1], + level: 0 + }); + return ticks; + }; + TimeScale.prototype.calcNiceExtent = function (opt) { + var extent = this._extent; + // If extent start and end are same, expand them + if (extent[0] === extent[1]) { + // Expand extent + extent[0] -= ONE_DAY; + extent[1] += ONE_DAY; + } + // If there are no data and extent are [Infinity, -Infinity] + if (extent[1] === -Infinity && extent[0] === Infinity) { + var d = new Date(); + extent[1] = +new Date(d.getFullYear(), d.getMonth(), d.getDate()); + extent[0] = extent[1] - ONE_DAY; + } + this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); + }; + TimeScale.prototype.calcNiceTicks = function (approxTickNum, minInterval, maxInterval) { + approxTickNum = approxTickNum || 10; + var extent = this._extent; + var span = extent[1] - extent[0]; + this._approxInterval = span / approxTickNum; + if (minInterval != null && this._approxInterval < minInterval) { + this._approxInterval = minInterval; + } + if (maxInterval != null && this._approxInterval > maxInterval) { + this._approxInterval = maxInterval; + } + var scaleIntervalsLen = scaleIntervals.length; + var idx = Math.min(bisect(scaleIntervals, this._approxInterval, 0, scaleIntervalsLen), scaleIntervalsLen - 1); + // Interval that can be used to calculate ticks + this._interval = scaleIntervals[idx][1]; + // Min level used when picking ticks from top down. + // We check one more level to avoid the ticks are to sparse in some case. + this._minLevelUnit = scaleIntervals[Math.max(idx - 1, 0)][0]; + }; + TimeScale.prototype.parse = function (val) { + // val might be float. + return isNumber(val) ? val : +parseDate(val); + }; + TimeScale.prototype.contain = function (val) { + return contain$1(this.parse(val), this._extent); + }; + TimeScale.prototype.normalize = function (val) { + return normalize$1(this.parse(val), this._extent); + }; + TimeScale.prototype.scale = function (val) { + return scale$2(val, this._extent); + }; + TimeScale.type = 'time'; + return TimeScale; + }(IntervalScale); + /** + * This implementation was originally copied from "d3.js" + * + * with some modifications made for this program. + * See the license statement at the head of this file. + */ + var scaleIntervals = [ + // Format interval + ['second', ONE_SECOND], ['minute', ONE_MINUTE], ['hour', ONE_HOUR], ['quarter-day', ONE_HOUR * 6], ['half-day', ONE_HOUR * 12], ['day', ONE_DAY * 1.2], ['half-week', ONE_DAY * 3.5], ['week', ONE_DAY * 7], ['month', ONE_DAY * 31], ['quarter', ONE_DAY * 95], ['half-year', ONE_YEAR / 2], ['year', ONE_YEAR] // 1Y + ]; + + function isUnitValueSame(unit, valueA, valueB, isUTC) { + var dateA = parseDate(valueA); + var dateB = parseDate(valueB); + var isSame = function (unit) { + return getUnitValue(dateA, unit, isUTC) === getUnitValue(dateB, unit, isUTC); + }; + var isSameYear = function () { + return isSame('year'); + }; + // const isSameHalfYear = () => isSameYear() && isSame('half-year'); + // const isSameQuater = () => isSameYear() && isSame('quarter'); + var isSameMonth = function () { + return isSameYear() && isSame('month'); + }; + var isSameDay = function () { + return isSameMonth() && isSame('day'); + }; + // const isSameHalfDay = () => isSameDay() && isSame('half-day'); + var isSameHour = function () { + return isSameDay() && isSame('hour'); + }; + var isSameMinute = function () { + return isSameHour() && isSame('minute'); + }; + var isSameSecond = function () { + return isSameMinute() && isSame('second'); + }; + var isSameMilliSecond = function () { + return isSameSecond() && isSame('millisecond'); + }; + switch (unit) { + case 'year': + return isSameYear(); + case 'month': + return isSameMonth(); + case 'day': + return isSameDay(); + case 'hour': + return isSameHour(); + case 'minute': + return isSameMinute(); + case 'second': + return isSameSecond(); + case 'millisecond': + return isSameMilliSecond(); + } + } + // const primaryUnitGetters = { + // year: fullYearGetterName(), + // month: monthGetterName(), + // day: dateGetterName(), + // hour: hoursGetterName(), + // minute: minutesGetterName(), + // second: secondsGetterName(), + // millisecond: millisecondsGetterName() + // }; + // const primaryUnitUTCGetters = { + // year: fullYearGetterName(true), + // month: monthGetterName(true), + // day: dateGetterName(true), + // hour: hoursGetterName(true), + // minute: minutesGetterName(true), + // second: secondsGetterName(true), + // millisecond: millisecondsGetterName(true) + // }; + // function moveTick(date: Date, unitName: TimeUnit, step: number, isUTC: boolean) { + // step = step || 1; + // switch (getPrimaryTimeUnit(unitName)) { + // case 'year': + // date[fullYearSetterName(isUTC)](date[fullYearGetterName(isUTC)]() + step); + // break; + // case 'month': + // date[monthSetterName(isUTC)](date[monthGetterName(isUTC)]() + step); + // break; + // case 'day': + // date[dateSetterName(isUTC)](date[dateGetterName(isUTC)]() + step); + // break; + // case 'hour': + // date[hoursSetterName(isUTC)](date[hoursGetterName(isUTC)]() + step); + // break; + // case 'minute': + // date[minutesSetterName(isUTC)](date[minutesGetterName(isUTC)]() + step); + // break; + // case 'second': + // date[secondsSetterName(isUTC)](date[secondsGetterName(isUTC)]() + step); + // break; + // case 'millisecond': + // date[millisecondsSetterName(isUTC)](date[millisecondsGetterName(isUTC)]() + step); + // break; + // } + // return date.getTime(); + // } + // const DATE_INTERVALS = [[8, 7.5], [4, 3.5], [2, 1.5]]; + // const MONTH_INTERVALS = [[6, 5.5], [3, 2.5], [2, 1.5]]; + // const MINUTES_SECONDS_INTERVALS = [[30, 30], [20, 20], [15, 15], [10, 10], [5, 5], [2, 2]]; + function getDateInterval(approxInterval, daysInMonth) { + approxInterval /= ONE_DAY; + return approxInterval > 16 ? 16 + // Math.floor(daysInMonth / 2) + 1 // In this case we only want one tick between two months. + : approxInterval > 7.5 ? 7 // TODO week 7 or day 8? + : approxInterval > 3.5 ? 4 : approxInterval > 1.5 ? 2 : 1; + } + function getMonthInterval(approxInterval) { + var APPROX_ONE_MONTH = 30 * ONE_DAY; + approxInterval /= APPROX_ONE_MONTH; + return approxInterval > 6 ? 6 : approxInterval > 3 ? 3 : approxInterval > 2 ? 2 : 1; + } + function getHourInterval(approxInterval) { + approxInterval /= ONE_HOUR; + return approxInterval > 12 ? 12 : approxInterval > 6 ? 6 : approxInterval > 3.5 ? 4 : approxInterval > 2 ? 2 : 1; + } + function getMinutesAndSecondsInterval(approxInterval, isMinutes) { + approxInterval /= isMinutes ? ONE_MINUTE : ONE_SECOND; + return approxInterval > 30 ? 30 : approxInterval > 20 ? 20 : approxInterval > 15 ? 15 : approxInterval > 10 ? 10 : approxInterval > 5 ? 5 : approxInterval > 2 ? 2 : 1; + } + function getMillisecondsInterval(approxInterval) { + return nice(approxInterval, true); + } + function getFirstTimestampOfUnit(date, unitName, isUTC) { + var outDate = new Date(date); + switch (getPrimaryTimeUnit(unitName)) { + case 'year': + case 'month': + outDate[monthSetterName(isUTC)](0); + case 'day': + outDate[dateSetterName(isUTC)](1); + case 'hour': + outDate[hoursSetterName(isUTC)](0); + case 'minute': + outDate[minutesSetterName(isUTC)](0); + case 'second': + outDate[secondsSetterName(isUTC)](0); + outDate[millisecondsSetterName(isUTC)](0); + } + return outDate.getTime(); + } + function getIntervalTicks(bottomUnitName, approxInterval, isUTC, extent) { + var safeLimit = 10000; + var unitNames = timeUnits; + var iter = 0; + function addTicksInSpan(interval, minTimestamp, maxTimestamp, getMethodName, setMethodName, isDate, out) { + var date = new Date(minTimestamp); + var dateTime = minTimestamp; + var d = date[getMethodName](); + // if (isDate) { + // d -= 1; // Starts with 0; PENDING + // } + while (dateTime < maxTimestamp && dateTime <= extent[1]) { + out.push({ + value: dateTime + }); + d += interval; + date[setMethodName](d); + dateTime = date.getTime(); + } + // This extra tick is for calcuating ticks of next level. Will not been added to the final result + out.push({ + value: dateTime, + notAdd: true + }); + } + function addLevelTicks(unitName, lastLevelTicks, levelTicks) { + var newAddedTicks = []; + var isFirstLevel = !lastLevelTicks.length; + if (isUnitValueSame(getPrimaryTimeUnit(unitName), extent[0], extent[1], isUTC)) { + return; + } + if (isFirstLevel) { + lastLevelTicks = [{ + // TODO Optimize. Not include so may ticks. + value: getFirstTimestampOfUnit(new Date(extent[0]), unitName, isUTC) + }, { + value: extent[1] + }]; + } + for (var i = 0; i < lastLevelTicks.length - 1; i++) { + var startTick = lastLevelTicks[i].value; + var endTick = lastLevelTicks[i + 1].value; + if (startTick === endTick) { + continue; + } + var interval = void 0; + var getterName = void 0; + var setterName = void 0; + var isDate = false; + switch (unitName) { + case 'year': + interval = Math.max(1, Math.round(approxInterval / ONE_DAY / 365)); + getterName = fullYearGetterName(isUTC); + setterName = fullYearSetterName(isUTC); + break; + case 'half-year': + case 'quarter': + case 'month': + interval = getMonthInterval(approxInterval); + getterName = monthGetterName(isUTC); + setterName = monthSetterName(isUTC); + break; + case 'week': // PENDING If week is added. Ignore day. + case 'half-week': + case 'day': + interval = getDateInterval(approxInterval); // Use 32 days and let interval been 16 + getterName = dateGetterName(isUTC); + setterName = dateSetterName(isUTC); + isDate = true; + break; + case 'half-day': + case 'quarter-day': + case 'hour': + interval = getHourInterval(approxInterval); + getterName = hoursGetterName(isUTC); + setterName = hoursSetterName(isUTC); + break; + case 'minute': + interval = getMinutesAndSecondsInterval(approxInterval, true); + getterName = minutesGetterName(isUTC); + setterName = minutesSetterName(isUTC); + break; + case 'second': + interval = getMinutesAndSecondsInterval(approxInterval, false); + getterName = secondsGetterName(isUTC); + setterName = secondsSetterName(isUTC); + break; + case 'millisecond': + interval = getMillisecondsInterval(approxInterval); + getterName = millisecondsGetterName(isUTC); + setterName = millisecondsSetterName(isUTC); + break; + } + addTicksInSpan(interval, startTick, endTick, getterName, setterName, isDate, newAddedTicks); + if (unitName === 'year' && levelTicks.length > 1 && i === 0) { + // Add nearest years to the left extent. + levelTicks.unshift({ + value: levelTicks[0].value - interval + }); + } + } + for (var i = 0; i < newAddedTicks.length; i++) { + levelTicks.push(newAddedTicks[i]); + } + // newAddedTicks.length && console.log(unitName, newAddedTicks); + return newAddedTicks; + } + var levelsTicks = []; + var currentLevelTicks = []; + var tickCount = 0; + var lastLevelTickCount = 0; + for (var i = 0; i < unitNames.length && iter++ < safeLimit; ++i) { + var primaryTimeUnit = getPrimaryTimeUnit(unitNames[i]); + if (!isPrimaryTimeUnit(unitNames[i])) { + // TODO + continue; + } + addLevelTicks(unitNames[i], levelsTicks[levelsTicks.length - 1] || [], currentLevelTicks); + var nextPrimaryTimeUnit = unitNames[i + 1] ? getPrimaryTimeUnit(unitNames[i + 1]) : null; + if (primaryTimeUnit !== nextPrimaryTimeUnit) { + if (currentLevelTicks.length) { + lastLevelTickCount = tickCount; + // Remove the duplicate so the tick count can be precisely. + currentLevelTicks.sort(function (a, b) { + return a.value - b.value; + }); + var levelTicksRemoveDuplicated = []; + for (var i_1 = 0; i_1 < currentLevelTicks.length; ++i_1) { + var tickValue = currentLevelTicks[i_1].value; + if (i_1 === 0 || currentLevelTicks[i_1 - 1].value !== tickValue) { + levelTicksRemoveDuplicated.push(currentLevelTicks[i_1]); + if (tickValue >= extent[0] && tickValue <= extent[1]) { + tickCount++; + } + } + } + var targetTickNum = (extent[1] - extent[0]) / approxInterval; + // Added too much in this level and not too less in last level + if (tickCount > targetTickNum * 1.5 && lastLevelTickCount > targetTickNum / 1.5) { + break; + } + // Only treat primary time unit as one level. + levelsTicks.push(levelTicksRemoveDuplicated); + if (tickCount > targetTickNum || bottomUnitName === unitNames[i]) { + break; + } + } + // Reset if next unitName is primary + currentLevelTicks = []; + } + } + if ("development" !== 'production') { + if (iter >= safeLimit) { + warn('Exceed safe limit.'); + } + } + var levelsTicksInExtent = filter(map(levelsTicks, function (levelTicks) { + return filter(levelTicks, function (tick) { + return tick.value >= extent[0] && tick.value <= extent[1] && !tick.notAdd; + }); + }), function (levelTicks) { + return levelTicks.length > 0; + }); + var ticks = []; + var maxLevel = levelsTicksInExtent.length - 1; + for (var i = 0; i < levelsTicksInExtent.length; ++i) { + var levelTicks = levelsTicksInExtent[i]; + for (var k = 0; k < levelTicks.length; ++k) { + ticks.push({ + value: levelTicks[k].value, + level: maxLevel - i + }); + } + } + ticks.sort(function (a, b) { + return a.value - b.value; + }); + // Remove duplicates + var result = []; + for (var i = 0; i < ticks.length; ++i) { + if (i === 0 || ticks[i].value !== ticks[i - 1].value) { + result.push(ticks[i]); + } + } + return result; + } + Scale.registerClass(TimeScale); + + var scaleProto = Scale.prototype; + // FIXME:TS refactor: not good to call it directly with `this`? + var intervalScaleProto = IntervalScale.prototype; + var roundingErrorFix = round; + var mathFloor = Math.floor; + var mathCeil = Math.ceil; + var mathPow$1 = Math.pow; + var mathLog = Math.log; + var LogScale = /** @class */function (_super) { + __extends(LogScale, _super); + function LogScale() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = 'log'; + _this.base = 10; + _this._originalScale = new IntervalScale(); + // FIXME:TS actually used by `IntervalScale` + _this._interval = 0; + return _this; + } + /** + * @param Whether expand the ticks to niced extent. + */ + LogScale.prototype.getTicks = function (expandToNicedExtent) { + var originalScale = this._originalScale; + var extent = this._extent; + var originalExtent = originalScale.getExtent(); + var ticks = intervalScaleProto.getTicks.call(this, expandToNicedExtent); + return map(ticks, function (tick) { + var val = tick.value; + var powVal = round(mathPow$1(this.base, val)); + // Fix #4158 + powVal = val === extent[0] && this._fixMin ? fixRoundingError(powVal, originalExtent[0]) : powVal; + powVal = val === extent[1] && this._fixMax ? fixRoundingError(powVal, originalExtent[1]) : powVal; + return { + value: powVal + }; + }, this); + }; + LogScale.prototype.setExtent = function (start, end) { + var base = mathLog(this.base); + // log(-Infinity) is NaN, so safe guard here + start = mathLog(Math.max(0, start)) / base; + end = mathLog(Math.max(0, end)) / base; + intervalScaleProto.setExtent.call(this, start, end); + }; + /** + * @return {number} end + */ + LogScale.prototype.getExtent = function () { + var base = this.base; + var extent = scaleProto.getExtent.call(this); + extent[0] = mathPow$1(base, extent[0]); + extent[1] = mathPow$1(base, extent[1]); + // Fix #4158 + var originalScale = this._originalScale; + var originalExtent = originalScale.getExtent(); + this._fixMin && (extent[0] = fixRoundingError(extent[0], originalExtent[0])); + this._fixMax && (extent[1] = fixRoundingError(extent[1], originalExtent[1])); + return extent; + }; + LogScale.prototype.unionExtent = function (extent) { + this._originalScale.unionExtent(extent); + var base = this.base; + extent[0] = mathLog(extent[0]) / mathLog(base); + extent[1] = mathLog(extent[1]) / mathLog(base); + scaleProto.unionExtent.call(this, extent); + }; + LogScale.prototype.unionExtentFromData = function (data, dim) { + // TODO + // filter value that <= 0 + this.unionExtent(data.getApproximateExtent(dim)); + }; + /** + * Update interval and extent of intervals for nice ticks + * @param approxTickNum default 10 Given approx tick number + */ + LogScale.prototype.calcNiceTicks = function (approxTickNum) { + approxTickNum = approxTickNum || 10; + var extent = this._extent; + var span = extent[1] - extent[0]; + if (span === Infinity || span <= 0) { + return; + } + var interval = quantity(span); + var err = approxTickNum / span * interval; + // Filter ticks to get closer to the desired count. + if (err <= 0.5) { + interval *= 10; + } + // Interval should be integer + while (!isNaN(interval) && Math.abs(interval) < 1 && Math.abs(interval) > 0) { + interval *= 10; + } + var niceExtent = [round(mathCeil(extent[0] / interval) * interval), round(mathFloor(extent[1] / interval) * interval)]; + this._interval = interval; + this._niceExtent = niceExtent; + }; + LogScale.prototype.calcNiceExtent = function (opt) { + intervalScaleProto.calcNiceExtent.call(this, opt); + this._fixMin = opt.fixMin; + this._fixMax = opt.fixMax; + }; + LogScale.prototype.parse = function (val) { + return val; + }; + LogScale.prototype.contain = function (val) { + val = mathLog(val) / mathLog(this.base); + return contain$1(val, this._extent); + }; + LogScale.prototype.normalize = function (val) { + val = mathLog(val) / mathLog(this.base); + return normalize$1(val, this._extent); + }; + LogScale.prototype.scale = function (val) { + val = scale$2(val, this._extent); + return mathPow$1(this.base, val); + }; + LogScale.type = 'log'; + return LogScale; + }(Scale); + var proto = LogScale.prototype; + proto.getMinorTicks = intervalScaleProto.getMinorTicks; + proto.getLabel = intervalScaleProto.getLabel; + function fixRoundingError(val, originalVal) { + return roundingErrorFix(val, getPrecision(originalVal)); + } + Scale.registerClass(LogScale); + + var ScaleRawExtentInfo = /** @class */function () { + function ScaleRawExtentInfo(scale, model, + // Usually: data extent from all series on this axis. + originalExtent) { + this._prepareParams(scale, model, originalExtent); + } + /** + * Parameters depending on outside (like model, user callback) + * are prepared and fixed here. + */ + ScaleRawExtentInfo.prototype._prepareParams = function (scale, model, + // Usually: data extent from all series on this axis. + dataExtent) { + if (dataExtent[1] < dataExtent[0]) { + dataExtent = [NaN, NaN]; + } + this._dataMin = dataExtent[0]; + this._dataMax = dataExtent[1]; + var isOrdinal = this._isOrdinal = scale.type === 'ordinal'; + this._needCrossZero = scale.type === 'interval' && model.getNeedCrossZero && model.getNeedCrossZero(); + var modelMinRaw = this._modelMinRaw = model.get('min', true); + if (isFunction(modelMinRaw)) { + // This callback always provides users the full data extent (before data is filtered). + this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw({ + min: dataExtent[0], + max: dataExtent[1] + })); + } else if (modelMinRaw !== 'dataMin') { + this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw); + } + var modelMaxRaw = this._modelMaxRaw = model.get('max', true); + if (isFunction(modelMaxRaw)) { + // This callback always provides users the full data extent (before data is filtered). + this._modelMaxNum = parseAxisModelMinMax(scale, modelMaxRaw({ + min: dataExtent[0], + max: dataExtent[1] + })); + } else if (modelMaxRaw !== 'dataMax') { + this._modelMaxNum = parseAxisModelMinMax(scale, modelMaxRaw); + } + if (isOrdinal) { + // FIXME: there is a flaw here: if there is no "block" data processor like `dataZoom`, + // and progressive rendering is using, here the category result might just only contain + // the processed chunk rather than the entire result. + this._axisDataLen = model.getCategories().length; + } else { + var boundaryGap = model.get('boundaryGap'); + var boundaryGapArr = isArray(boundaryGap) ? boundaryGap : [boundaryGap || 0, boundaryGap || 0]; + if (typeof boundaryGapArr[0] === 'boolean' || typeof boundaryGapArr[1] === 'boolean') { + if ("development" !== 'production') { + console.warn('Boolean type for boundaryGap is only ' + 'allowed for ordinal axis. Please use string in ' + 'percentage instead, e.g., "20%". Currently, ' + 'boundaryGap is set to be 0.'); + } + this._boundaryGapInner = [0, 0]; + } else { + this._boundaryGapInner = [parsePercent(boundaryGapArr[0], 1), parsePercent(boundaryGapArr[1], 1)]; + } + } + }; + /** + * Calculate extent by prepared parameters. + * This method has no external dependency and can be called duplicatedly, + * getting the same result. + * If parameters changed, should call this method to recalcuate. + */ + ScaleRawExtentInfo.prototype.calculate = function () { + // Notice: When min/max is not set (that is, when there are null/undefined, + // which is the most common case), these cases should be ensured: + // (1) For 'ordinal', show all axis.data. + // (2) For others: + // + `boundaryGap` is applied (if min/max set, boundaryGap is + // disabled). + // + If `needCrossZero`, min/max should be zero, otherwise, min/max should + // be the result that originalExtent enlarged by boundaryGap. + // (3) If no data, it should be ensured that `scale.setBlank` is set. + var isOrdinal = this._isOrdinal; + var dataMin = this._dataMin; + var dataMax = this._dataMax; + var axisDataLen = this._axisDataLen; + var boundaryGapInner = this._boundaryGapInner; + var span = !isOrdinal ? dataMax - dataMin || Math.abs(dataMin) : null; + // Currently if a `'value'` axis model min is specified as 'dataMin'/'dataMax', + // `boundaryGap` will not be used. It's the different from specifying as `null`/`undefined`. + var min = this._modelMinRaw === 'dataMin' ? dataMin : this._modelMinNum; + var max = this._modelMaxRaw === 'dataMax' ? dataMax : this._modelMaxNum; + // If `_modelMinNum`/`_modelMaxNum` is `null`/`undefined`, should not be fixed. + var minFixed = min != null; + var maxFixed = max != null; + if (min == null) { + min = isOrdinal ? axisDataLen ? 0 : NaN : dataMin - boundaryGapInner[0] * span; + } + if (max == null) { + max = isOrdinal ? axisDataLen ? axisDataLen - 1 : NaN : dataMax + boundaryGapInner[1] * span; + } + (min == null || !isFinite(min)) && (min = NaN); + (max == null || !isFinite(max)) && (max = NaN); + var isBlank = eqNaN(min) || eqNaN(max) || isOrdinal && !axisDataLen; + // If data extent modified, need to recalculated to ensure cross zero. + if (this._needCrossZero) { + // Axis is over zero and min is not set + if (min > 0 && max > 0 && !minFixed) { + min = 0; + // minFixed = true; + } + // Axis is under zero and max is not set + if (min < 0 && max < 0 && !maxFixed) { + max = 0; + // maxFixed = true; + } + // PENDING: + // When `needCrossZero` and all data is positive/negative, should it be ensured + // that the results processed by boundaryGap are positive/negative? + // If so, here `minFixed`/`maxFixed` need to be set. + } + + var determinedMin = this._determinedMin; + var determinedMax = this._determinedMax; + if (determinedMin != null) { + min = determinedMin; + minFixed = true; + } + if (determinedMax != null) { + max = determinedMax; + maxFixed = true; + } + // Ensure min/max be finite number or NaN here. (not to be null/undefined) + // `NaN` means min/max axis is blank. + return { + min: min, + max: max, + minFixed: minFixed, + maxFixed: maxFixed, + isBlank: isBlank + }; + }; + ScaleRawExtentInfo.prototype.modifyDataMinMax = function (minMaxName, val) { + if ("development" !== 'production') { + assert(!this.frozen); + } + this[DATA_MIN_MAX_ATTR[minMaxName]] = val; + }; + ScaleRawExtentInfo.prototype.setDeterminedMinMax = function (minMaxName, val) { + var attr = DETERMINED_MIN_MAX_ATTR[minMaxName]; + if ("development" !== 'production') { + assert(!this.frozen + // Earse them usually means logic flaw. + && this[attr] == null); + } + this[attr] = val; + }; + ScaleRawExtentInfo.prototype.freeze = function () { + // @ts-ignore + this.frozen = true; + }; + return ScaleRawExtentInfo; + }(); + var DETERMINED_MIN_MAX_ATTR = { + min: '_determinedMin', + max: '_determinedMax' + }; + var DATA_MIN_MAX_ATTR = { + min: '_dataMin', + max: '_dataMax' + }; + /** + * Get scale min max and related info only depends on model settings. + * This method can be called after coordinate system created. + * For example, in data processing stage. + * + * Scale extent info probably be required multiple times during a workflow. + * For example: + * (1) `dataZoom` depends it to get the axis extent in "100%" state. + * (2) `processor/extentCalculator` depends it to make sure whether axis extent is specified. + * (3) `coordSys.update` use it to finally decide the scale extent. + * But the callback of `min`/`max` should not be called multiple times. + * The code below should not be implemented repeatedly either. + * So we cache the result in the scale instance, which will be recreated at the beginning + * of the workflow (because `scale` instance will be recreated each round of the workflow). + */ + function ensureScaleRawExtentInfo(scale, model, + // Usually: data extent from all series on this axis. + originalExtent) { + // Do not permit to recreate. + var rawExtentInfo = scale.rawExtentInfo; + if (rawExtentInfo) { + return rawExtentInfo; + } + rawExtentInfo = new ScaleRawExtentInfo(scale, model, originalExtent); + // @ts-ignore + scale.rawExtentInfo = rawExtentInfo; + return rawExtentInfo; + } + function parseAxisModelMinMax(scale, minMax) { + return minMax == null ? null : eqNaN(minMax) ? NaN : scale.parse(minMax); + } + + /** + * Get axis scale extent before niced. + * Item of returned array can only be number (including Infinity and NaN). + * + * Caution: + * Precondition of calling this method: + * The scale extent has been initialized using series data extent via + * `scale.setExtent` or `scale.unionExtentFromData`; + */ + function getScaleExtent(scale, model) { + var scaleType = scale.type; + var rawExtentResult = ensureScaleRawExtentInfo(scale, model, scale.getExtent()).calculate(); + scale.setBlank(rawExtentResult.isBlank); + var min = rawExtentResult.min; + var max = rawExtentResult.max; + // If bars are placed on a base axis of type time or interval account for axis boundary overflow and current axis + // is base axis + // FIXME + // (1) Consider support value axis, where below zero and axis `onZero` should be handled properly. + // (2) Refactor the logic with `barGrid`. Is it not need to `makeBarWidthAndOffsetInfo` twice with different extent? + // Should not depend on series type `bar`? + // (3) Fix that might overlap when using dataZoom. + // (4) Consider other chart types using `barGrid`? + // See #6728, #4862, `test/bar-overflow-time-plot.html` + var ecModel = model.ecModel; + if (ecModel && scaleType === 'time' /* || scaleType === 'interval' */) { + var barSeriesModels = prepareLayoutBarSeries('bar', ecModel); + var isBaseAxisAndHasBarSeries_1 = false; + each(barSeriesModels, function (seriesModel) { + isBaseAxisAndHasBarSeries_1 = isBaseAxisAndHasBarSeries_1 || seriesModel.getBaseAxis() === model.axis; + }); + if (isBaseAxisAndHasBarSeries_1) { + // Calculate placement of bars on axis. TODO should be decoupled + // with barLayout + var barWidthAndOffset = makeColumnLayout(barSeriesModels); + // Adjust axis min and max to account for overflow + var adjustedScale = adjustScaleForOverflow(min, max, model, barWidthAndOffset); + min = adjustedScale.min; + max = adjustedScale.max; + } + } + return { + extent: [min, max], + // "fix" means "fixed", the value should not be + // changed in the subsequent steps. + fixMin: rawExtentResult.minFixed, + fixMax: rawExtentResult.maxFixed + }; + } + function adjustScaleForOverflow(min, max, model, + // Only support cartesian coord yet. + barWidthAndOffset) { + // Get Axis Length + var axisExtent = model.axis.getExtent(); + var axisLength = axisExtent[1] - axisExtent[0]; + // Get bars on current base axis and calculate min and max overflow + var barsOnCurrentAxis = retrieveColumnLayout(barWidthAndOffset, model.axis); + if (barsOnCurrentAxis === undefined) { + return { + min: min, + max: max + }; + } + var minOverflow = Infinity; + each(barsOnCurrentAxis, function (item) { + minOverflow = Math.min(item.offset, minOverflow); + }); + var maxOverflow = -Infinity; + each(barsOnCurrentAxis, function (item) { + maxOverflow = Math.max(item.offset + item.width, maxOverflow); + }); + minOverflow = Math.abs(minOverflow); + maxOverflow = Math.abs(maxOverflow); + var totalOverFlow = minOverflow + maxOverflow; + // Calculate required buffer based on old range and overflow + var oldRange = max - min; + var oldRangePercentOfNew = 1 - (minOverflow + maxOverflow) / axisLength; + var overflowBuffer = oldRange / oldRangePercentOfNew - oldRange; + max += overflowBuffer * (maxOverflow / totalOverFlow); + min -= overflowBuffer * (minOverflow / totalOverFlow); + return { + min: min, + max: max + }; + } + // Precondition of calling this method: + // The scale extent has been initialized using series data extent via + // `scale.setExtent` or `scale.unionExtentFromData`; + function niceScaleExtent(scale, inModel) { + var model = inModel; + var extentInfo = getScaleExtent(scale, model); + var extent = extentInfo.extent; + var splitNumber = model.get('splitNumber'); + if (scale instanceof LogScale) { + scale.base = model.get('logBase'); + } + var scaleType = scale.type; + var interval = model.get('interval'); + var isIntervalOrTime = scaleType === 'interval' || scaleType === 'time'; + scale.setExtent(extent[0], extent[1]); + scale.calcNiceExtent({ + splitNumber: splitNumber, + fixMin: extentInfo.fixMin, + fixMax: extentInfo.fixMax, + minInterval: isIntervalOrTime ? model.get('minInterval') : null, + maxInterval: isIntervalOrTime ? model.get('maxInterval') : null + }); + // If some one specified the min, max. And the default calculated interval + // is not good enough. He can specify the interval. It is often appeared + // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard + // to be 60. + // FIXME + if (interval != null) { + scale.setInterval && scale.setInterval(interval); + } + } + /** + * @param axisType Default retrieve from model.type + */ + function createScaleByModel(model, axisType) { + axisType = axisType || model.get('type'); + if (axisType) { + switch (axisType) { + // Buildin scale + case 'category': + return new OrdinalScale({ + ordinalMeta: model.getOrdinalMeta ? model.getOrdinalMeta() : model.getCategories(), + extent: [Infinity, -Infinity] + }); + case 'time': + return new TimeScale({ + locale: model.ecModel.getLocaleModel(), + useUTC: model.ecModel.get('useUTC') + }); + default: + // case 'value'/'interval', 'log', or others. + return new (Scale.getClass(axisType) || IntervalScale)(); + } + } + } + /** + * Check if the axis cross 0 + */ + function ifAxisCrossZero(axis) { + var dataExtent = axis.scale.getExtent(); + var min = dataExtent[0]; + var max = dataExtent[1]; + return !(min > 0 && max > 0 || min < 0 && max < 0); + } + /** + * @param axis + * @return Label formatter function. + * param: {number} tickValue, + * param: {number} idx, the index in all ticks. + * If category axis, this param is not required. + * return: {string} label string. + */ + function makeLabelFormatter(axis) { + var labelFormatter = axis.getLabelModel().get('formatter'); + var categoryTickStart = axis.type === 'category' ? axis.scale.getExtent()[0] : null; + if (axis.scale.type === 'time') { + return function (tpl) { + return function (tick, idx) { + return axis.scale.getFormattedLabel(tick, idx, tpl); + }; + }(labelFormatter); + } else if (isString(labelFormatter)) { + return function (tpl) { + return function (tick) { + // For category axis, get raw value; for numeric axis, + // get formatted label like '1,333,444'. + var label = axis.scale.getLabel(tick); + var text = tpl.replace('{value}', label != null ? label : ''); + return text; + }; + }(labelFormatter); + } else if (isFunction(labelFormatter)) { + return function (cb) { + return function (tick, idx) { + // The original intention of `idx` is "the index of the tick in all ticks". + // But the previous implementation of category axis do not consider the + // `axisLabel.interval`, which cause that, for example, the `interval` is + // `1`, then the ticks "name5", "name7", "name9" are displayed, where the + // corresponding `idx` are `0`, `2`, `4`, but not `0`, `1`, `2`. So we keep + // the definition here for back compatibility. + if (categoryTickStart != null) { + idx = tick.value - categoryTickStart; + } + return cb(getAxisRawValue(axis, tick), idx, tick.level != null ? { + level: tick.level + } : null); + }; + }(labelFormatter); + } else { + return function (tick) { + return axis.scale.getLabel(tick); + }; + } + } + function getAxisRawValue(axis, tick) { + // In category axis with data zoom, tick is not the original + // index of axis.data. So tick should not be exposed to user + // in category axis. + return axis.type === 'category' ? axis.scale.getLabel(tick) : tick.value; + } + /** + * @param axis + * @return Be null/undefined if no labels. + */ + function estimateLabelUnionRect(axis) { + var axisModel = axis.model; + var scale = axis.scale; + if (!axisModel.get(['axisLabel', 'show']) || scale.isBlank()) { + return; + } + var realNumberScaleTicks; + var tickCount; + var categoryScaleExtent = scale.getExtent(); + // Optimize for large category data, avoid call `getTicks()`. + if (scale instanceof OrdinalScale) { + tickCount = scale.count(); + } else { + realNumberScaleTicks = scale.getTicks(); + tickCount = realNumberScaleTicks.length; + } + var axisLabelModel = axis.getLabelModel(); + var labelFormatter = makeLabelFormatter(axis); + var rect; + var step = 1; + // Simple optimization for large amount of labels + if (tickCount > 40) { + step = Math.ceil(tickCount / 40); + } + for (var i = 0; i < tickCount; i += step) { + var tick = realNumberScaleTicks ? realNumberScaleTicks[i] : { + value: categoryScaleExtent[0] + i + }; + var label = labelFormatter(tick, i); + var unrotatedSingleRect = axisLabelModel.getTextRect(label); + var singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0); + rect ? rect.union(singleRect) : rect = singleRect; + } + return rect; + } + function rotateTextRect(textRect, rotate) { + var rotateRadians = rotate * Math.PI / 180; + var beforeWidth = textRect.width; + var beforeHeight = textRect.height; + var afterWidth = beforeWidth * Math.abs(Math.cos(rotateRadians)) + Math.abs(beforeHeight * Math.sin(rotateRadians)); + var afterHeight = beforeWidth * Math.abs(Math.sin(rotateRadians)) + Math.abs(beforeHeight * Math.cos(rotateRadians)); + var rotatedRect = new BoundingRect(textRect.x, textRect.y, afterWidth, afterHeight); + return rotatedRect; + } + /** + * @param model axisLabelModel or axisTickModel + * @return {number|String} Can be null|'auto'|number|function + */ + function getOptionCategoryInterval(model) { + var interval = model.get('interval'); + return interval == null ? 'auto' : interval; + } + /** + * Set `categoryInterval` as 0 implicitly indicates that + * show all labels regardless of overlap. + * @param {Object} axis axisModel.axis + */ + function shouldShowAllLabels(axis) { + return axis.type === 'category' && getOptionCategoryInterval(axis.getLabelModel()) === 0; + } + function getDataDimensionsOnAxis(data, axisDim) { + // Remove duplicated dat dimensions caused by `getStackedDimension`. + var dataDimMap = {}; + // Currently `mapDimensionsAll` will contain stack result dimension ('__\0ecstackresult'). + // PENDING: is it reasonable? Do we need to remove the original dim from "coord dim" since + // there has been stacked result dim? + each(data.mapDimensionsAll(axisDim), function (dataDim) { + // For example, the extent of the original dimension + // is [0.1, 0.5], the extent of the `stackResultDimension` + // is [7, 9], the final extent should NOT include [0.1, 0.5], + // because there is no graphic corresponding to [0.1, 0.5]. + // See the case in `test/area-stack.html` `main1`, where area line + // stack needs `yAxis` not start from 0. + dataDimMap[getStackedDimension(data, dataDim)] = true; + }); + return keys(dataDimMap); + } + function unionAxisExtentFromData(dataExtent, data, axisDim) { + if (data) { + each(getDataDimensionsOnAxis(data, axisDim), function (dim) { + var seriesExtent = data.getApproximateExtent(dim); + seriesExtent[0] < dataExtent[0] && (dataExtent[0] = seriesExtent[0]); + seriesExtent[1] > dataExtent[1] && (dataExtent[1] = seriesExtent[1]); + }); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + var AxisModelCommonMixin = /** @class */function () { + function AxisModelCommonMixin() {} + AxisModelCommonMixin.prototype.getNeedCrossZero = function () { + var option = this.option; + return !option.scale; + }; + /** + * Should be implemented by each axis model if necessary. + * @return coordinate system model + */ + AxisModelCommonMixin.prototype.getCoordSysModel = function () { + return; + }; + return AxisModelCommonMixin; + }(); + + /** + * Create a multi dimension List structure from seriesModel. + */ + function createList(seriesModel) { + return createSeriesData(null, seriesModel); + } + var dataStack$1 = { + isDimensionStacked: isDimensionStacked, + enableDataStack: enableDataStack, + getStackedDimension: getStackedDimension + }; + /** + * Create scale + * @param {Array.} dataExtent + * @param {Object|module:echarts/Model} option If `optoin.type` + * is secified, it can only be `'value'` currently. + */ + function createScale(dataExtent, option) { + var axisModel = option; + if (!(option instanceof Model)) { + axisModel = new Model(option); + // FIXME + // Currently AxisModelCommonMixin has nothing to do with the + // the requirements of `axisHelper.createScaleByModel`. For + // example the methods `getCategories` and `getOrdinalMeta` + // are required for `'category'` axis, and ecModel is required + // for `'time'` axis. But occasionally echarts-gl happened + // to only use `'value'` axis. + // zrUtil.mixin(axisModel, AxisModelCommonMixin); + } + + var scale = createScaleByModel(axisModel); + scale.setExtent(dataExtent[0], dataExtent[1]); + niceScaleExtent(scale, axisModel); + return scale; + } + /** + * Mixin common methods to axis model, + * + * Include methods + * `getFormattedLabels() => Array.` + * `getCategories() => Array.` + * `getMin(origin: boolean) => number` + * `getMax(origin: boolean) => number` + * `getNeedCrossZero() => boolean` + */ + function mixinAxisModelCommonMethods(Model) { + mixin(Model, AxisModelCommonMixin); + } + function createTextStyle$1(textStyleModel, opts) { + opts = opts || {}; + return createTextStyle(textStyleModel, null, null, opts.state !== 'normal'); + } + + var helper = /*#__PURE__*/Object.freeze({ + __proto__: null, + createList: createList, + getLayoutRect: getLayoutRect, + dataStack: dataStack$1, + createScale: createScale, + mixinAxisModelCommonMethods: mixinAxisModelCommonMethods, + getECData: getECData, + createTextStyle: createTextStyle$1, + createDimensions: createDimensions, + createSymbol: createSymbol, + enableHoverEmphasis: enableHoverEmphasis + }); + + var EPSILON$4 = 1e-8; + function isAroundEqual$1(a, b) { + return Math.abs(a - b) < EPSILON$4; + } + function contain$2(points, x, y) { + var w = 0; + var p = points[0]; + if (!p) { + return false; + } + for (var i = 1; i < points.length; i++) { + var p2 = points[i]; + w += windingLine(p[0], p[1], p2[0], p2[1], x, y); + p = p2; + } + var p0 = points[0]; + if (!isAroundEqual$1(p[0], p0[0]) || !isAroundEqual$1(p[1], p0[1])) { + w += windingLine(p[0], p[1], p0[0], p0[1], x, y); + } + return w !== 0; + } + + var TMP_TRANSFORM = []; + function transformPoints(points, transform) { + for (var p = 0; p < points.length; p++) { + applyTransform(points[p], points[p], transform); + } + } + function updateBBoxFromPoints(points, min$1, max$1, projection) { + for (var i = 0; i < points.length; i++) { + var p = points[i]; + if (projection) { + // projection may return null point. + p = projection.project(p); + } + if (p && isFinite(p[0]) && isFinite(p[1])) { + min(min$1, min$1, p); + max(max$1, max$1, p); + } + } + } + function centroid(points) { + var signedArea = 0; + var cx = 0; + var cy = 0; + var len = points.length; + var x0 = points[len - 1][0]; + var y0 = points[len - 1][1]; + // Polygon should been closed. + for (var i = 0; i < len; i++) { + var x1 = points[i][0]; + var y1 = points[i][1]; + var a = x0 * y1 - x1 * y0; + signedArea += a; + cx += (x0 + x1) * a; + cy += (y0 + y1) * a; + x0 = x1; + y0 = y1; + } + return signedArea ? [cx / signedArea / 3, cy / signedArea / 3, signedArea] : [points[0][0] || 0, points[0][1] || 0]; + } + var Region = /** @class */function () { + function Region(name) { + this.name = name; + } + Region.prototype.setCenter = function (center) { + this._center = center; + }; + /** + * Get center point in data unit. That is, + * for GeoJSONRegion, the unit is lat/lng, + * for GeoSVGRegion, the unit is SVG local coord. + */ + Region.prototype.getCenter = function () { + var center = this._center; + if (!center) { + // In most cases there are no need to calculate this center. + // So calculate only when called. + center = this._center = this.calcCenter(); + } + return center; + }; + return Region; + }(); + var GeoJSONPolygonGeometry = /** @class */function () { + function GeoJSONPolygonGeometry(exterior, interiors) { + this.type = 'polygon'; + this.exterior = exterior; + this.interiors = interiors; + } + return GeoJSONPolygonGeometry; + }(); + var GeoJSONLineStringGeometry = /** @class */function () { + function GeoJSONLineStringGeometry(points) { + this.type = 'linestring'; + this.points = points; + } + return GeoJSONLineStringGeometry; + }(); + var GeoJSONRegion = /** @class */function (_super) { + __extends(GeoJSONRegion, _super); + function GeoJSONRegion(name, geometries, cp) { + var _this = _super.call(this, name) || this; + _this.type = 'geoJSON'; + _this.geometries = geometries; + _this._center = cp && [cp[0], cp[1]]; + return _this; + } + GeoJSONRegion.prototype.calcCenter = function () { + var geometries = this.geometries; + var largestGeo; + var largestGeoSize = 0; + for (var i = 0; i < geometries.length; i++) { + var geo = geometries[i]; + var exterior = geo.exterior; + // Simple trick to use points count instead of polygon area as region size. + // Ignore linestring + var size = exterior && exterior.length; + if (size > largestGeoSize) { + largestGeo = geo; + largestGeoSize = size; + } + } + if (largestGeo) { + return centroid(largestGeo.exterior); + } + // from bounding rect by default. + var rect = this.getBoundingRect(); + return [rect.x + rect.width / 2, rect.y + rect.height / 2]; + }; + GeoJSONRegion.prototype.getBoundingRect = function (projection) { + var rect = this._rect; + // Always recalculate if using projection. + if (rect && !projection) { + return rect; + } + var min = [Infinity, Infinity]; + var max = [-Infinity, -Infinity]; + var geometries = this.geometries; + each(geometries, function (geo) { + if (geo.type === 'polygon') { + // Doesn't consider hole + updateBBoxFromPoints(geo.exterior, min, max, projection); + } else { + each(geo.points, function (points) { + updateBBoxFromPoints(points, min, max, projection); + }); + } + }); + // Normalie invalid bounding. + if (!(isFinite(min[0]) && isFinite(min[1]) && isFinite(max[0]) && isFinite(max[1]))) { + min[0] = min[1] = max[0] = max[1] = 0; + } + rect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]); + if (!projection) { + this._rect = rect; + } + return rect; + }; + GeoJSONRegion.prototype.contain = function (coord) { + var rect = this.getBoundingRect(); + var geometries = this.geometries; + if (!rect.contain(coord[0], coord[1])) { + return false; + } + loopGeo: for (var i = 0, len = geometries.length; i < len; i++) { + var geo = geometries[i]; + // Only support polygon. + if (geo.type !== 'polygon') { + continue; + } + var exterior = geo.exterior; + var interiors = geo.interiors; + if (contain$2(exterior, coord[0], coord[1])) { + // Not in the region if point is in the hole. + for (var k = 0; k < (interiors ? interiors.length : 0); k++) { + if (contain$2(interiors[k], coord[0], coord[1])) { + continue loopGeo; + } + } + return true; + } + } + return false; + }; + /** + * Transform the raw coords to target bounding. + * @param x + * @param y + * @param width + * @param height + */ + GeoJSONRegion.prototype.transformTo = function (x, y, width, height) { + var rect = this.getBoundingRect(); + var aspect = rect.width / rect.height; + if (!width) { + width = aspect * height; + } else if (!height) { + height = width / aspect; + } + var target = new BoundingRect(x, y, width, height); + var transform = rect.calculateTransform(target); + var geometries = this.geometries; + for (var i = 0; i < geometries.length; i++) { + var geo = geometries[i]; + if (geo.type === 'polygon') { + transformPoints(geo.exterior, transform); + each(geo.interiors, function (interior) { + transformPoints(interior, transform); + }); + } else { + each(geo.points, function (points) { + transformPoints(points, transform); + }); + } + } + rect = this._rect; + rect.copy(target); + // Update center + this._center = [rect.x + rect.width / 2, rect.y + rect.height / 2]; + }; + GeoJSONRegion.prototype.cloneShallow = function (name) { + name == null && (name = this.name); + var newRegion = new GeoJSONRegion(name, this.geometries, this._center); + newRegion._rect = this._rect; + newRegion.transformTo = null; // Simply avoid to be called. + return newRegion; + }; + return GeoJSONRegion; + }(Region); + var GeoSVGRegion = /** @class */function (_super) { + __extends(GeoSVGRegion, _super); + function GeoSVGRegion(name, elOnlyForCalculate) { + var _this = _super.call(this, name) || this; + _this.type = 'geoSVG'; + _this._elOnlyForCalculate = elOnlyForCalculate; + return _this; + } + GeoSVGRegion.prototype.calcCenter = function () { + var el = this._elOnlyForCalculate; + var rect = el.getBoundingRect(); + var center = [rect.x + rect.width / 2, rect.y + rect.height / 2]; + var mat = identity(TMP_TRANSFORM); + var target = el; + while (target && !target.isGeoSVGGraphicRoot) { + mul$1(mat, target.getLocalTransform(), mat); + target = target.parent; + } + invert(mat, mat); + applyTransform(center, center, mat); + return center; + }; + return GeoSVGRegion; + }(Region); + + function decode(json) { + if (!json.UTF8Encoding) { + return json; + } + var jsonCompressed = json; + var encodeScale = jsonCompressed.UTF8Scale; + if (encodeScale == null) { + encodeScale = 1024; + } + var features = jsonCompressed.features; + each(features, function (feature) { + var geometry = feature.geometry; + var encodeOffsets = geometry.encodeOffsets; + var coordinates = geometry.coordinates; + // Geometry may be appeded manually in the script after json loaded. + // In this case this geometry is usually not encoded. + if (!encodeOffsets) { + return; + } + switch (geometry.type) { + case 'LineString': + geometry.coordinates = decodeRing(coordinates, encodeOffsets, encodeScale); + break; + case 'Polygon': + decodeRings(coordinates, encodeOffsets, encodeScale); + break; + case 'MultiLineString': + decodeRings(coordinates, encodeOffsets, encodeScale); + break; + case 'MultiPolygon': + each(coordinates, function (rings, idx) { + return decodeRings(rings, encodeOffsets[idx], encodeScale); + }); + } + }); + // Has been decoded + jsonCompressed.UTF8Encoding = false; + return jsonCompressed; + } + function decodeRings(rings, encodeOffsets, encodeScale) { + for (var c = 0; c < rings.length; c++) { + rings[c] = decodeRing(rings[c], encodeOffsets[c], encodeScale); + } + } + function decodeRing(coordinate, encodeOffsets, encodeScale) { + var result = []; + var prevX = encodeOffsets[0]; + var prevY = encodeOffsets[1]; + for (var i = 0; i < coordinate.length; i += 2) { + var x = coordinate.charCodeAt(i) - 64; + var y = coordinate.charCodeAt(i + 1) - 64; + // ZigZag decoding + x = x >> 1 ^ -(x & 1); + y = y >> 1 ^ -(y & 1); + // Delta deocding + x += prevX; + y += prevY; + prevX = x; + prevY = y; + // Dequantize + result.push([x / encodeScale, y / encodeScale]); + } + return result; + } + function parseGeoJSON(geoJson, nameProperty) { + geoJson = decode(geoJson); + return map(filter(geoJson.features, function (featureObj) { + // Output of mapshaper may have geometry null + return featureObj.geometry && featureObj.properties && featureObj.geometry.coordinates.length > 0; + }), function (featureObj) { + var properties = featureObj.properties; + var geo = featureObj.geometry; + var geometries = []; + switch (geo.type) { + case 'Polygon': + var coordinates = geo.coordinates; + // According to the GeoJSON specification. + // First must be exterior, and the rest are all interior(holes). + geometries.push(new GeoJSONPolygonGeometry(coordinates[0], coordinates.slice(1))); + break; + case 'MultiPolygon': + each(geo.coordinates, function (item) { + if (item[0]) { + geometries.push(new GeoJSONPolygonGeometry(item[0], item.slice(1))); + } + }); + break; + case 'LineString': + geometries.push(new GeoJSONLineStringGeometry([geo.coordinates])); + break; + case 'MultiLineString': + geometries.push(new GeoJSONLineStringGeometry(geo.coordinates)); + } + var region = new GeoJSONRegion(properties[nameProperty || 'name'], geometries, properties.cp); + region.properties = properties; + return region; + }); + } + + var number = /*#__PURE__*/Object.freeze({ + __proto__: null, + linearMap: linearMap, + round: round, + asc: asc, + getPrecision: getPrecision, + getPrecisionSafe: getPrecisionSafe, + getPixelPrecision: getPixelPrecision, + getPercentWithPrecision: getPercentWithPrecision, + MAX_SAFE_INTEGER: MAX_SAFE_INTEGER, + remRadian: remRadian, + isRadianAroundZero: isRadianAroundZero, + parseDate: parseDate, + quantity: quantity, + quantityExponent: quantityExponent, + nice: nice, + quantile: quantile, + reformIntervals: reformIntervals, + isNumeric: isNumeric, + numericToNumber: numericToNumber + }); + + var time = /*#__PURE__*/Object.freeze({ + __proto__: null, + parse: parseDate, + format: format + }); + + var graphic$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + extendShape: extendShape, + extendPath: extendPath, + makePath: makePath, + makeImage: makeImage, + mergePath: mergePath$1, + resizePath: resizePath, + createIcon: createIcon, + updateProps: updateProps, + initProps: initProps, + getTransform: getTransform, + clipPointsByRect: clipPointsByRect, + clipRectByRect: clipRectByRect, + registerShape: registerShape, + getShapeClass: getShapeClass, + Group: Group, + Image: ZRImage, + Text: ZRText, + Circle: Circle, + Ellipse: Ellipse, + Sector: Sector, + Ring: Ring, + Polygon: Polygon, + Polyline: Polyline, + Rect: Rect, + Line: Line, + BezierCurve: BezierCurve, + Arc: Arc, + IncrementalDisplayable: IncrementalDisplayable, + CompoundPath: CompoundPath, + LinearGradient: LinearGradient, + RadialGradient: RadialGradient, + BoundingRect: BoundingRect + }); + + var format$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + addCommas: addCommas, + toCamelCase: toCamelCase, + normalizeCssArray: normalizeCssArray$1, + encodeHTML: encodeHTML, + formatTpl: formatTpl, + getTooltipMarker: getTooltipMarker, + formatTime: formatTime, + capitalFirst: capitalFirst, + truncateText: truncateText, + getTextRect: getTextRect + }); + + var util$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + map: map, + each: each, + indexOf: indexOf, + inherits: inherits, + reduce: reduce, + filter: filter, + bind: bind, + curry: curry, + isArray: isArray, + isString: isString, + isObject: isObject, + isFunction: isFunction, + extend: extend, + defaults: defaults, + clone: clone, + merge: merge + }); + + var inner$5 = makeInner(); + function createAxisLabels(axis) { + // Only ordinal scale support tick interval + return axis.type === 'category' ? makeCategoryLabels(axis) : makeRealNumberLabels(axis); + } + /** + * @param {module:echats/coord/Axis} axis + * @param {module:echarts/model/Model} tickModel For example, can be axisTick, splitLine, splitArea. + * @return {Object} { + * ticks: Array. + * tickCategoryInterval: number + * } + */ + function createAxisTicks(axis, tickModel) { + // Only ordinal scale support tick interval + return axis.type === 'category' ? makeCategoryTicks(axis, tickModel) : { + ticks: map(axis.scale.getTicks(), function (tick) { + return tick.value; + }) + }; + } + function makeCategoryLabels(axis) { + var labelModel = axis.getLabelModel(); + var result = makeCategoryLabelsActually(axis, labelModel); + return !labelModel.get('show') || axis.scale.isBlank() ? { + labels: [], + labelCategoryInterval: result.labelCategoryInterval + } : result; + } + function makeCategoryLabelsActually(axis, labelModel) { + var labelsCache = getListCache(axis, 'labels'); + var optionLabelInterval = getOptionCategoryInterval(labelModel); + var result = listCacheGet(labelsCache, optionLabelInterval); + if (result) { + return result; + } + var labels; + var numericLabelInterval; + if (isFunction(optionLabelInterval)) { + labels = makeLabelsByCustomizedCategoryInterval(axis, optionLabelInterval); + } else { + numericLabelInterval = optionLabelInterval === 'auto' ? makeAutoCategoryInterval(axis) : optionLabelInterval; + labels = makeLabelsByNumericCategoryInterval(axis, numericLabelInterval); + } + // Cache to avoid calling interval function repeatedly. + return listCacheSet(labelsCache, optionLabelInterval, { + labels: labels, + labelCategoryInterval: numericLabelInterval + }); + } + function makeCategoryTicks(axis, tickModel) { + var ticksCache = getListCache(axis, 'ticks'); + var optionTickInterval = getOptionCategoryInterval(tickModel); + var result = listCacheGet(ticksCache, optionTickInterval); + if (result) { + return result; + } + var ticks; + var tickCategoryInterval; + // Optimize for the case that large category data and no label displayed, + // we should not return all ticks. + if (!tickModel.get('show') || axis.scale.isBlank()) { + ticks = []; + } + if (isFunction(optionTickInterval)) { + ticks = makeLabelsByCustomizedCategoryInterval(axis, optionTickInterval, true); + } + // Always use label interval by default despite label show. Consider this + // scenario, Use multiple grid with the xAxis sync, and only one xAxis shows + // labels. `splitLine` and `axisTick` should be consistent in this case. + else if (optionTickInterval === 'auto') { + var labelsResult = makeCategoryLabelsActually(axis, axis.getLabelModel()); + tickCategoryInterval = labelsResult.labelCategoryInterval; + ticks = map(labelsResult.labels, function (labelItem) { + return labelItem.tickValue; + }); + } else { + tickCategoryInterval = optionTickInterval; + ticks = makeLabelsByNumericCategoryInterval(axis, tickCategoryInterval, true); + } + // Cache to avoid calling interval function repeatedly. + return listCacheSet(ticksCache, optionTickInterval, { + ticks: ticks, + tickCategoryInterval: tickCategoryInterval + }); + } + function makeRealNumberLabels(axis) { + var ticks = axis.scale.getTicks(); + var labelFormatter = makeLabelFormatter(axis); + return { + labels: map(ticks, function (tick, idx) { + return { + level: tick.level, + formattedLabel: labelFormatter(tick, idx), + rawLabel: axis.scale.getLabel(tick), + tickValue: tick.value + }; + }) + }; + } + function getListCache(axis, prop) { + // Because key can be a function, and cache size always is small, we use array cache. + return inner$5(axis)[prop] || (inner$5(axis)[prop] = []); + } + function listCacheGet(cache, key) { + for (var i = 0; i < cache.length; i++) { + if (cache[i].key === key) { + return cache[i].value; + } + } + } + function listCacheSet(cache, key, value) { + cache.push({ + key: key, + value: value + }); + return value; + } + function makeAutoCategoryInterval(axis) { + var result = inner$5(axis).autoInterval; + return result != null ? result : inner$5(axis).autoInterval = axis.calculateCategoryInterval(); + } + /** + * Calculate interval for category axis ticks and labels. + * To get precise result, at least one of `getRotate` and `isHorizontal` + * should be implemented in axis. + */ + function calculateCategoryInterval(axis) { + var params = fetchAutoCategoryIntervalCalculationParams(axis); + var labelFormatter = makeLabelFormatter(axis); + var rotation = (params.axisRotate - params.labelRotate) / 180 * Math.PI; + var ordinalScale = axis.scale; + var ordinalExtent = ordinalScale.getExtent(); + // Providing this method is for optimization: + // avoid generating a long array by `getTicks` + // in large category data case. + var tickCount = ordinalScale.count(); + if (ordinalExtent[1] - ordinalExtent[0] < 1) { + return 0; + } + var step = 1; + // Simple optimization. Empirical value: tick count should less than 40. + if (tickCount > 40) { + step = Math.max(1, Math.floor(tickCount / 40)); + } + var tickValue = ordinalExtent[0]; + var unitSpan = axis.dataToCoord(tickValue + 1) - axis.dataToCoord(tickValue); + var unitW = Math.abs(unitSpan * Math.cos(rotation)); + var unitH = Math.abs(unitSpan * Math.sin(rotation)); + var maxW = 0; + var maxH = 0; + // Caution: Performance sensitive for large category data. + // Consider dataZoom, we should make appropriate step to avoid O(n) loop. + for (; tickValue <= ordinalExtent[1]; tickValue += step) { + var width = 0; + var height = 0; + // Not precise, do not consider align and vertical align + // and each distance from axis line yet. + var rect = getBoundingRect(labelFormatter({ + value: tickValue + }), params.font, 'center', 'top'); + // Magic number + width = rect.width * 1.3; + height = rect.height * 1.3; + // Min size, void long loop. + maxW = Math.max(maxW, width, 7); + maxH = Math.max(maxH, height, 7); + } + var dw = maxW / unitW; + var dh = maxH / unitH; + // 0/0 is NaN, 1/0 is Infinity. + isNaN(dw) && (dw = Infinity); + isNaN(dh) && (dh = Infinity); + var interval = Math.max(0, Math.floor(Math.min(dw, dh))); + var cache = inner$5(axis.model); + var axisExtent = axis.getExtent(); + var lastAutoInterval = cache.lastAutoInterval; + var lastTickCount = cache.lastTickCount; + // Use cache to keep interval stable while moving zoom window, + // otherwise the calculated interval might jitter when the zoom + // window size is close to the interval-changing size. + // For example, if all of the axis labels are `a, b, c, d, e, f, g`. + // The jitter will cause that sometimes the displayed labels are + // `a, d, g` (interval: 2) sometimes `a, c, e`(interval: 1). + if (lastAutoInterval != null && lastTickCount != null && Math.abs(lastAutoInterval - interval) <= 1 && Math.abs(lastTickCount - tickCount) <= 1 + // Always choose the bigger one, otherwise the critical + // point is not the same when zooming in or zooming out. + && lastAutoInterval > interval + // If the axis change is caused by chart resize, the cache should not + // be used. Otherwise some hidden labels might not be shown again. + && cache.axisExtent0 === axisExtent[0] && cache.axisExtent1 === axisExtent[1]) { + interval = lastAutoInterval; + } + // Only update cache if cache not used, otherwise the + // changing of interval is too insensitive. + else { + cache.lastTickCount = tickCount; + cache.lastAutoInterval = interval; + cache.axisExtent0 = axisExtent[0]; + cache.axisExtent1 = axisExtent[1]; + } + return interval; + } + function fetchAutoCategoryIntervalCalculationParams(axis) { + var labelModel = axis.getLabelModel(); + return { + axisRotate: axis.getRotate ? axis.getRotate() : axis.isHorizontal && !axis.isHorizontal() ? 90 : 0, + labelRotate: labelModel.get('rotate') || 0, + font: labelModel.getFont() + }; + } + function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) { + var labelFormatter = makeLabelFormatter(axis); + var ordinalScale = axis.scale; + var ordinalExtent = ordinalScale.getExtent(); + var labelModel = axis.getLabelModel(); + var result = []; + // TODO: axisType: ordinalTime, pick the tick from each month/day/year/... + var step = Math.max((categoryInterval || 0) + 1, 1); + var startTick = ordinalExtent[0]; + var tickCount = ordinalScale.count(); + // Calculate start tick based on zero if possible to keep label consistent + // while zooming and moving while interval > 0. Otherwise the selection + // of displayable ticks and symbols probably keep changing. + // 3 is empirical value. + if (startTick !== 0 && step > 1 && tickCount / step > 2) { + startTick = Math.round(Math.ceil(startTick / step) * step); + } + // (1) Only add min max label here but leave overlap checking + // to render stage, which also ensure the returned list + // suitable for splitLine and splitArea rendering. + // (2) Scales except category always contain min max label so + // do not need to perform this process. + var showAllLabel = shouldShowAllLabels(axis); + var includeMinLabel = labelModel.get('showMinLabel') || showAllLabel; + var includeMaxLabel = labelModel.get('showMaxLabel') || showAllLabel; + if (includeMinLabel && startTick !== ordinalExtent[0]) { + addItem(ordinalExtent[0]); + } + // Optimize: avoid generating large array by `ordinalScale.getTicks()`. + var tickValue = startTick; + for (; tickValue <= ordinalExtent[1]; tickValue += step) { + addItem(tickValue); + } + if (includeMaxLabel && tickValue - step !== ordinalExtent[1]) { + addItem(ordinalExtent[1]); + } + function addItem(tickValue) { + var tickObj = { + value: tickValue + }; + result.push(onlyTick ? tickValue : { + formattedLabel: labelFormatter(tickObj), + rawLabel: ordinalScale.getLabel(tickObj), + tickValue: tickValue + }); + } + return result; + } + function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick) { + var ordinalScale = axis.scale; + var labelFormatter = makeLabelFormatter(axis); + var result = []; + each(ordinalScale.getTicks(), function (tick) { + var rawLabel = ordinalScale.getLabel(tick); + var tickValue = tick.value; + if (categoryInterval(tick.value, rawLabel)) { + result.push(onlyTick ? tickValue : { + formattedLabel: labelFormatter(tick), + rawLabel: rawLabel, + tickValue: tickValue + }); + } + }); + return result; + } + + var NORMALIZED_EXTENT = [0, 1]; + /** + * Base class of Axis. + */ + var Axis = /** @class */function () { + function Axis(dim, scale, extent) { + this.onBand = false; + this.inverse = false; + this.dim = dim; + this.scale = scale; + this._extent = extent || [0, 0]; + } + /** + * If axis extent contain given coord + */ + Axis.prototype.contain = function (coord) { + var extent = this._extent; + var min = Math.min(extent[0], extent[1]); + var max = Math.max(extent[0], extent[1]); + return coord >= min && coord <= max; + }; + /** + * If axis extent contain given data + */ + Axis.prototype.containData = function (data) { + return this.scale.contain(data); + }; + /** + * Get coord extent. + */ + Axis.prototype.getExtent = function () { + return this._extent.slice(); + }; + /** + * Get precision used for formatting + */ + Axis.prototype.getPixelPrecision = function (dataExtent) { + return getPixelPrecision(dataExtent || this.scale.getExtent(), this._extent); + }; + /** + * Set coord extent + */ + Axis.prototype.setExtent = function (start, end) { + var extent = this._extent; + extent[0] = start; + extent[1] = end; + }; + /** + * Convert data to coord. Data is the rank if it has an ordinal scale + */ + Axis.prototype.dataToCoord = function (data, clamp) { + var extent = this._extent; + var scale = this.scale; + data = scale.normalize(data); + if (this.onBand && scale.type === 'ordinal') { + extent = extent.slice(); + fixExtentWithBands(extent, scale.count()); + } + return linearMap(data, NORMALIZED_EXTENT, extent, clamp); + }; + /** + * Convert coord to data. Data is the rank if it has an ordinal scale + */ + Axis.prototype.coordToData = function (coord, clamp) { + var extent = this._extent; + var scale = this.scale; + if (this.onBand && scale.type === 'ordinal') { + extent = extent.slice(); + fixExtentWithBands(extent, scale.count()); + } + var t = linearMap(coord, extent, NORMALIZED_EXTENT, clamp); + return this.scale.scale(t); + }; + /** + * Convert pixel point to data in axis + */ + Axis.prototype.pointToData = function (point, clamp) { + // Should be implemented in derived class if necessary. + return; + }; + /** + * Different from `zrUtil.map(axis.getTicks(), axis.dataToCoord, axis)`, + * `axis.getTicksCoords` considers `onBand`, which is used by + * `boundaryGap:true` of category axis and splitLine and splitArea. + * @param opt.tickModel default: axis.model.getModel('axisTick') + * @param opt.clamp If `true`, the first and the last + * tick must be at the axis end points. Otherwise, clip ticks + * that outside the axis extent. + */ + Axis.prototype.getTicksCoords = function (opt) { + opt = opt || {}; + var tickModel = opt.tickModel || this.getTickModel(); + var result = createAxisTicks(this, tickModel); + var ticks = result.ticks; + var ticksCoords = map(ticks, function (tickVal) { + return { + coord: this.dataToCoord(this.scale.type === 'ordinal' ? this.scale.getRawOrdinalNumber(tickVal) : tickVal), + tickValue: tickVal + }; + }, this); + var alignWithLabel = tickModel.get('alignWithLabel'); + fixOnBandTicksCoords(this, ticksCoords, alignWithLabel, opt.clamp); + return ticksCoords; + }; + Axis.prototype.getMinorTicksCoords = function () { + if (this.scale.type === 'ordinal') { + // Category axis doesn't support minor ticks + return []; + } + var minorTickModel = this.model.getModel('minorTick'); + var splitNumber = minorTickModel.get('splitNumber'); + // Protection. + if (!(splitNumber > 0 && splitNumber < 100)) { + splitNumber = 5; + } + var minorTicks = this.scale.getMinorTicks(splitNumber); + var minorTicksCoords = map(minorTicks, function (minorTicksGroup) { + return map(minorTicksGroup, function (minorTick) { + return { + coord: this.dataToCoord(minorTick), + tickValue: minorTick + }; + }, this); + }, this); + return minorTicksCoords; + }; + Axis.prototype.getViewLabels = function () { + return createAxisLabels(this).labels; + }; + Axis.prototype.getLabelModel = function () { + return this.model.getModel('axisLabel'); + }; + /** + * Notice here we only get the default tick model. For splitLine + * or splitArea, we should pass the splitLineModel or splitAreaModel + * manually when calling `getTicksCoords`. + * In GL, this method may be overridden to: + * `axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));` + */ + Axis.prototype.getTickModel = function () { + return this.model.getModel('axisTick'); + }; + /** + * Get width of band + */ + Axis.prototype.getBandWidth = function () { + var axisExtent = this._extent; + var dataExtent = this.scale.getExtent(); + var len = dataExtent[1] - dataExtent[0] + (this.onBand ? 1 : 0); + // Fix #2728, avoid NaN when only one data. + len === 0 && (len = 1); + var size = Math.abs(axisExtent[1] - axisExtent[0]); + return Math.abs(size) / len; + }; + /** + * Only be called in category axis. + * Can be overridden, consider other axes like in 3D. + * @return Auto interval for cateogry axis tick and label + */ + Axis.prototype.calculateCategoryInterval = function () { + return calculateCategoryInterval(this); + }; + return Axis; + }(); + function fixExtentWithBands(extent, nTick) { + var size = extent[1] - extent[0]; + var len = nTick; + var margin = size / len / 2; + extent[0] += margin; + extent[1] -= margin; + } + // If axis has labels [1, 2, 3, 4]. Bands on the axis are + // |---1---|---2---|---3---|---4---|. + // So the displayed ticks and splitLine/splitArea should between + // each data item, otherwise cause misleading (e.g., split tow bars + // of a single data item when there are two bar series). + // Also consider if tickCategoryInterval > 0 and onBand, ticks and + // splitLine/spliteArea should layout appropriately corresponding + // to displayed labels. (So we should not use `getBandWidth` in this + // case). + function fixOnBandTicksCoords(axis, ticksCoords, alignWithLabel, clamp) { + var ticksLen = ticksCoords.length; + if (!axis.onBand || alignWithLabel || !ticksLen) { + return; + } + var axisExtent = axis.getExtent(); + var last; + var diffSize; + if (ticksLen === 1) { + ticksCoords[0].coord = axisExtent[0]; + last = ticksCoords[1] = { + coord: axisExtent[1] + }; + } else { + var crossLen = ticksCoords[ticksLen - 1].tickValue - ticksCoords[0].tickValue; + var shift_1 = (ticksCoords[ticksLen - 1].coord - ticksCoords[0].coord) / crossLen; + each(ticksCoords, function (ticksItem) { + ticksItem.coord -= shift_1 / 2; + }); + var dataExtent = axis.scale.getExtent(); + diffSize = 1 + dataExtent[1] - ticksCoords[ticksLen - 1].tickValue; + last = { + coord: ticksCoords[ticksLen - 1].coord + shift_1 * diffSize + }; + ticksCoords.push(last); + } + var inverse = axisExtent[0] > axisExtent[1]; + // Handling clamp. + if (littleThan(ticksCoords[0].coord, axisExtent[0])) { + clamp ? ticksCoords[0].coord = axisExtent[0] : ticksCoords.shift(); + } + if (clamp && littleThan(axisExtent[0], ticksCoords[0].coord)) { + ticksCoords.unshift({ + coord: axisExtent[0] + }); + } + if (littleThan(axisExtent[1], last.coord)) { + clamp ? last.coord = axisExtent[1] : ticksCoords.pop(); + } + if (clamp && littleThan(last.coord, axisExtent[1])) { + ticksCoords.push({ + coord: axisExtent[1] + }); + } + function littleThan(a, b) { + // Avoid rounding error cause calculated tick coord different with extent. + // It may cause an extra unnecessary tick added. + a = round(a); + b = round(b); + return inverse ? a > b : a < b; + } + } + + // --------------------- Deprecated Extension Methods --------------------- + // Should use `ComponentModel.extend` or `class XXXX extend ComponentModel` to create class. + // Then use `registerComponentModel` in `install` parameter when `use` this extension. For example: + // class Bar3DModel extends ComponentModel {} + // export function install(registers) { registers.registerComponentModel(Bar3DModel); } + // echarts.use(install); + function extendComponentModel(proto) { + var Model = ComponentModel.extend(proto); + ComponentModel.registerClass(Model); + return Model; + } + function extendComponentView(proto) { + var View = ComponentView.extend(proto); + ComponentView.registerClass(View); + return View; + } + function extendSeriesModel(proto) { + var Model = SeriesModel.extend(proto); + SeriesModel.registerClass(Model); + return Model; + } + function extendChartView(proto) { + var View = ChartView.extend(proto); + ChartView.registerClass(View); + return View; + } + + var PI2$6 = Math.PI * 2; + var CMD$3 = PathProxy.CMD; + var DEFAULT_SEARCH_SPACE = ['top', 'right', 'bottom', 'left']; + function getCandidateAnchor(pos, distance, rect, outPt, outDir) { + var width = rect.width; + var height = rect.height; + switch (pos) { + case 'top': + outPt.set(rect.x + width / 2, rect.y - distance); + outDir.set(0, -1); + break; + case 'bottom': + outPt.set(rect.x + width / 2, rect.y + height + distance); + outDir.set(0, 1); + break; + case 'left': + outPt.set(rect.x - distance, rect.y + height / 2); + outDir.set(-1, 0); + break; + case 'right': + outPt.set(rect.x + width + distance, rect.y + height / 2); + outDir.set(1, 0); + break; + } + } + function projectPointToArc(cx, cy, r, startAngle, endAngle, anticlockwise, x, y, out) { + x -= cx; + y -= cy; + var d = Math.sqrt(x * x + y * y); + x /= d; + y /= d; + // Intersect point. + var ox = x * r + cx; + var oy = y * r + cy; + if (Math.abs(startAngle - endAngle) % PI2$6 < 1e-4) { + // Is a circle + out[0] = ox; + out[1] = oy; + return d - r; + } + if (anticlockwise) { + var tmp = startAngle; + startAngle = normalizeRadian(endAngle); + endAngle = normalizeRadian(tmp); + } else { + startAngle = normalizeRadian(startAngle); + endAngle = normalizeRadian(endAngle); + } + if (startAngle > endAngle) { + endAngle += PI2$6; + } + var angle = Math.atan2(y, x); + if (angle < 0) { + angle += PI2$6; + } + if (angle >= startAngle && angle <= endAngle || angle + PI2$6 >= startAngle && angle + PI2$6 <= endAngle) { + // Project point is on the arc. + out[0] = ox; + out[1] = oy; + return d - r; + } + var x1 = r * Math.cos(startAngle) + cx; + var y1 = r * Math.sin(startAngle) + cy; + var x2 = r * Math.cos(endAngle) + cx; + var y2 = r * Math.sin(endAngle) + cy; + var d1 = (x1 - x) * (x1 - x) + (y1 - y) * (y1 - y); + var d2 = (x2 - x) * (x2 - x) + (y2 - y) * (y2 - y); + if (d1 < d2) { + out[0] = x1; + out[1] = y1; + return Math.sqrt(d1); + } else { + out[0] = x2; + out[1] = y2; + return Math.sqrt(d2); + } + } + function projectPointToLine(x1, y1, x2, y2, x, y, out, limitToEnds) { + var dx = x - x1; + var dy = y - y1; + var dx1 = x2 - x1; + var dy1 = y2 - y1; + var lineLen = Math.sqrt(dx1 * dx1 + dy1 * dy1); + dx1 /= lineLen; + dy1 /= lineLen; + // dot product + var projectedLen = dx * dx1 + dy * dy1; + var t = projectedLen / lineLen; + if (limitToEnds) { + t = Math.min(Math.max(t, 0), 1); + } + t *= lineLen; + var ox = out[0] = x1 + t * dx1; + var oy = out[1] = y1 + t * dy1; + return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y)); + } + function projectPointToRect(x1, y1, width, height, x, y, out) { + if (width < 0) { + x1 = x1 + width; + width = -width; + } + if (height < 0) { + y1 = y1 + height; + height = -height; + } + var x2 = x1 + width; + var y2 = y1 + height; + var ox = out[0] = Math.min(Math.max(x, x1), x2); + var oy = out[1] = Math.min(Math.max(y, y1), y2); + return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y)); + } + var tmpPt = []; + function nearestPointOnRect(pt, rect, out) { + var dist = projectPointToRect(rect.x, rect.y, rect.width, rect.height, pt.x, pt.y, tmpPt); + out.set(tmpPt[0], tmpPt[1]); + return dist; + } + /** + * Calculate min distance corresponding point. + * This method won't evaluate if point is in the path. + */ + function nearestPointOnPath(pt, path, out) { + var xi = 0; + var yi = 0; + var x0 = 0; + var y0 = 0; + var x1; + var y1; + var minDist = Infinity; + var data = path.data; + var x = pt.x; + var y = pt.y; + for (var i = 0; i < data.length;) { + var cmd = data[i++]; + if (i === 1) { + xi = data[i]; + yi = data[i + 1]; + x0 = xi; + y0 = yi; + } + var d = minDist; + switch (cmd) { + case CMD$3.M: + // moveTo 命令重新创建一个新的 subpath, 并且更新新的起点 + // 在 closePath 的时候使用 + x0 = data[i++]; + y0 = data[i++]; + xi = x0; + yi = y0; + break; + case CMD$3.L: + d = projectPointToLine(xi, yi, data[i], data[i + 1], x, y, tmpPt, true); + xi = data[i++]; + yi = data[i++]; + break; + case CMD$3.C: + d = cubicProjectPoint(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], x, y, tmpPt); + xi = data[i++]; + yi = data[i++]; + break; + case CMD$3.Q: + d = quadraticProjectPoint(xi, yi, data[i++], data[i++], data[i], data[i + 1], x, y, tmpPt); + xi = data[i++]; + yi = data[i++]; + break; + case CMD$3.A: + // TODO Arc 判断的开销比较大 + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var theta = data[i++]; + var dTheta = data[i++]; + // TODO Arc 旋转 + i += 1; + var anticlockwise = !!(1 - data[i++]); + x1 = Math.cos(theta) * rx + cx; + y1 = Math.sin(theta) * ry + cy; + // 不是直接使用 arc 命令 + if (i <= 1) { + // 第一个命令起点还未定义 + x0 = x1; + y0 = y1; + } + // zr 使用scale来模拟椭圆, 这里也对x做一定的缩放 + var _x = (x - cx) * ry / rx + cx; + d = projectPointToArc(cx, cy, ry, theta, theta + dTheta, anticlockwise, _x, y, tmpPt); + xi = Math.cos(theta + dTheta) * rx + cx; + yi = Math.sin(theta + dTheta) * ry + cy; + break; + case CMD$3.R: + x0 = xi = data[i++]; + y0 = yi = data[i++]; + var width = data[i++]; + var height = data[i++]; + d = projectPointToRect(x0, y0, width, height, x, y, tmpPt); + break; + case CMD$3.Z: + d = projectPointToLine(xi, yi, x0, y0, x, y, tmpPt, true); + xi = x0; + yi = y0; + break; + } + if (d < minDist) { + minDist = d; + out.set(tmpPt[0], tmpPt[1]); + } + } + return minDist; + } + // Temporal variable for intermediate usage. + var pt0 = new Point(); + var pt1 = new Point(); + var pt2 = new Point(); + var dir = new Point(); + var dir2 = new Point(); + /** + * Calculate a proper guide line based on the label position and graphic element definition + * @param label + * @param labelRect + * @param target + * @param targetRect + */ + function updateLabelLinePoints(target, labelLineModel) { + if (!target) { + return; + } + var labelLine = target.getTextGuideLine(); + var label = target.getTextContent(); + // Needs to create text guide in each charts. + if (!(label && labelLine)) { + return; + } + var labelGuideConfig = target.textGuideLineConfig || {}; + var points = [[0, 0], [0, 0], [0, 0]]; + var searchSpace = labelGuideConfig.candidates || DEFAULT_SEARCH_SPACE; + var labelRect = label.getBoundingRect().clone(); + labelRect.applyTransform(label.getComputedTransform()); + var minDist = Infinity; + var anchorPoint = labelGuideConfig.anchor; + var targetTransform = target.getComputedTransform(); + var targetInversedTransform = targetTransform && invert([], targetTransform); + var len = labelLineModel.get('length2') || 0; + if (anchorPoint) { + pt2.copy(anchorPoint); + } + for (var i = 0; i < searchSpace.length; i++) { + var candidate = searchSpace[i]; + getCandidateAnchor(candidate, 0, labelRect, pt0, dir); + Point.scaleAndAdd(pt1, pt0, dir, len); + // Transform to target coord space. + pt1.transform(targetInversedTransform); + // Note: getBoundingRect will ensure the `path` being created. + var boundingRect = target.getBoundingRect(); + var dist = anchorPoint ? anchorPoint.distance(pt1) : target instanceof Path ? nearestPointOnPath(pt1, target.path, pt2) : nearestPointOnRect(pt1, boundingRect, pt2); + // TODO pt2 is in the path + if (dist < minDist) { + minDist = dist; + // Transform back to global space. + pt1.transform(targetTransform); + pt2.transform(targetTransform); + pt2.toArray(points[0]); + pt1.toArray(points[1]); + pt0.toArray(points[2]); + } + } + limitTurnAngle(points, labelLineModel.get('minTurnAngle')); + labelLine.setShape({ + points: points + }); + } + // Temporal variable for the limitTurnAngle function + var tmpArr = []; + var tmpProjPoint = new Point(); + /** + * Reduce the line segment attached to the label to limit the turn angle between two segments. + * @param linePoints + * @param minTurnAngle Radian of minimum turn angle. 0 - 180 + */ + function limitTurnAngle(linePoints, minTurnAngle) { + if (!(minTurnAngle <= 180 && minTurnAngle > 0)) { + return; + } + minTurnAngle = minTurnAngle / 180 * Math.PI; + // The line points can be + // /pt1----pt2 (label) + // / + // pt0/ + pt0.fromArray(linePoints[0]); + pt1.fromArray(linePoints[1]); + pt2.fromArray(linePoints[2]); + Point.sub(dir, pt0, pt1); + Point.sub(dir2, pt2, pt1); + var len1 = dir.len(); + var len2 = dir2.len(); + if (len1 < 1e-3 || len2 < 1e-3) { + return; + } + dir.scale(1 / len1); + dir2.scale(1 / len2); + var angleCos = dir.dot(dir2); + var minTurnAngleCos = Math.cos(minTurnAngle); + if (minTurnAngleCos < angleCos) { + // Smaller than minTurnAngle + // Calculate project point of pt0 on pt1-pt2 + var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false); + tmpProjPoint.fromArray(tmpArr); + // Calculate new projected length with limited minTurnAngle and get the new connect point + tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI - minTurnAngle)); + // Limit the new calculated connect point between pt1 and pt2. + var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y); + if (isNaN(t)) { + return; + } + if (t < 0) { + Point.copy(tmpProjPoint, pt1); + } else if (t > 1) { + Point.copy(tmpProjPoint, pt2); + } + tmpProjPoint.toArray(linePoints[1]); + } + } + /** + * Limit the angle of line and the surface + * @param maxSurfaceAngle Radian of minimum turn angle. 0 - 180. 0 is same direction to normal. 180 is opposite + */ + function limitSurfaceAngle(linePoints, surfaceNormal, maxSurfaceAngle) { + if (!(maxSurfaceAngle <= 180 && maxSurfaceAngle > 0)) { + return; + } + maxSurfaceAngle = maxSurfaceAngle / 180 * Math.PI; + pt0.fromArray(linePoints[0]); + pt1.fromArray(linePoints[1]); + pt2.fromArray(linePoints[2]); + Point.sub(dir, pt1, pt0); + Point.sub(dir2, pt2, pt1); + var len1 = dir.len(); + var len2 = dir2.len(); + if (len1 < 1e-3 || len2 < 1e-3) { + return; + } + dir.scale(1 / len1); + dir2.scale(1 / len2); + var angleCos = dir.dot(surfaceNormal); + var maxSurfaceAngleCos = Math.cos(maxSurfaceAngle); + if (angleCos < maxSurfaceAngleCos) { + // Calculate project point of pt0 on pt1-pt2 + var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false); + tmpProjPoint.fromArray(tmpArr); + var HALF_PI = Math.PI / 2; + var angle2 = Math.acos(dir2.dot(surfaceNormal)); + var newAngle = HALF_PI + angle2 - maxSurfaceAngle; + if (newAngle >= HALF_PI) { + // parallel + Point.copy(tmpProjPoint, pt2); + } else { + // Calculate new projected length with limited minTurnAngle and get the new connect point + tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI / 2 - newAngle)); + // Limit the new calculated connect point between pt1 and pt2. + var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y); + if (isNaN(t)) { + return; + } + if (t < 0) { + Point.copy(tmpProjPoint, pt1); + } else if (t > 1) { + Point.copy(tmpProjPoint, pt2); + } + } + tmpProjPoint.toArray(linePoints[1]); + } + } + function setLabelLineState(labelLine, ignore, stateName, stateModel) { + var isNormal = stateName === 'normal'; + var stateObj = isNormal ? labelLine : labelLine.ensureState(stateName); + // Make sure display. + stateObj.ignore = ignore; + // Set smooth + var smooth = stateModel.get('smooth'); + if (smooth && smooth === true) { + smooth = 0.3; + } + stateObj.shape = stateObj.shape || {}; + if (smooth > 0) { + stateObj.shape.smooth = smooth; + } + var styleObj = stateModel.getModel('lineStyle').getLineStyle(); + isNormal ? labelLine.useStyle(styleObj) : stateObj.style = styleObj; + } + function buildLabelLinePath(path, shape) { + var smooth = shape.smooth; + var points = shape.points; + if (!points) { + return; + } + path.moveTo(points[0][0], points[0][1]); + if (smooth > 0 && points.length >= 3) { + var len1 = dist(points[0], points[1]); + var len2 = dist(points[1], points[2]); + if (!len1 || !len2) { + path.lineTo(points[1][0], points[1][1]); + path.lineTo(points[2][0], points[2][1]); + return; + } + var moveLen = Math.min(len1, len2) * smooth; + var midPoint0 = lerp([], points[1], points[0], moveLen / len1); + var midPoint2 = lerp([], points[1], points[2], moveLen / len2); + var midPoint1 = lerp([], midPoint0, midPoint2, 0.5); + path.bezierCurveTo(midPoint0[0], midPoint0[1], midPoint0[0], midPoint0[1], midPoint1[0], midPoint1[1]); + path.bezierCurveTo(midPoint2[0], midPoint2[1], midPoint2[0], midPoint2[1], points[2][0], points[2][1]); + } else { + for (var i = 1; i < points.length; i++) { + path.lineTo(points[i][0], points[i][1]); + } + } + } + /** + * Create a label line if necessary and set it's style. + */ + function setLabelLineStyle(targetEl, statesModels, defaultStyle) { + var labelLine = targetEl.getTextGuideLine(); + var label = targetEl.getTextContent(); + if (!label) { + // Not show label line if there is no label. + if (labelLine) { + targetEl.removeTextGuideLine(); + } + return; + } + var normalModel = statesModels.normal; + var showNormal = normalModel.get('show'); + var labelIgnoreNormal = label.ignore; + for (var i = 0; i < DISPLAY_STATES.length; i++) { + var stateName = DISPLAY_STATES[i]; + var stateModel = statesModels[stateName]; + var isNormal = stateName === 'normal'; + if (stateModel) { + var stateShow = stateModel.get('show'); + var isLabelIgnored = isNormal ? labelIgnoreNormal : retrieve2(label.states[stateName] && label.states[stateName].ignore, labelIgnoreNormal); + if (isLabelIgnored // Not show when label is not shown in this state. + || !retrieve2(stateShow, showNormal) // Use normal state by default if not set. + ) { + var stateObj = isNormal ? labelLine : labelLine && labelLine.states[stateName]; + if (stateObj) { + stateObj.ignore = true; + } + if (!!labelLine) { + setLabelLineState(labelLine, true, stateName, stateModel); + } + continue; + } + // Create labelLine if not exists + if (!labelLine) { + labelLine = new Polyline(); + targetEl.setTextGuideLine(labelLine); + // Reset state of normal because it's new created. + // NOTE: NORMAL should always been the first! + if (!isNormal && (labelIgnoreNormal || !showNormal)) { + setLabelLineState(labelLine, true, 'normal', statesModels.normal); + } + // Use same state proxy. + if (targetEl.stateProxy) { + labelLine.stateProxy = targetEl.stateProxy; + } + } + setLabelLineState(labelLine, false, stateName, stateModel); + } + } + if (labelLine) { + defaults(labelLine.style, defaultStyle); + // Not fill. + labelLine.style.fill = null; + var showAbove = normalModel.get('showAbove'); + var labelLineConfig = targetEl.textGuideLineConfig = targetEl.textGuideLineConfig || {}; + labelLineConfig.showAbove = showAbove || false; + // Custom the buildPath. + labelLine.buildPath = buildLabelLinePath; + } + } + function getLabelLineStatesModels(itemModel, labelLineName) { + labelLineName = labelLineName || 'labelLine'; + var statesModels = { + normal: itemModel.getModel(labelLineName) + }; + for (var i = 0; i < SPECIAL_STATES.length; i++) { + var stateName = SPECIAL_STATES[i]; + statesModels[stateName] = itemModel.getModel([stateName, labelLineName]); + } + return statesModels; + } + + function prepareLayoutList(input) { + var list = []; + for (var i = 0; i < input.length; i++) { + var rawItem = input[i]; + if (rawItem.defaultAttr.ignore) { + continue; + } + var label = rawItem.label; + var transform = label.getComputedTransform(); + // NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el. + var localRect = label.getBoundingRect(); + var isAxisAligned = !transform || transform[1] < 1e-5 && transform[2] < 1e-5; + var minMargin = label.style.margin || 0; + var globalRect = localRect.clone(); + globalRect.applyTransform(transform); + globalRect.x -= minMargin / 2; + globalRect.y -= minMargin / 2; + globalRect.width += minMargin; + globalRect.height += minMargin; + var obb = isAxisAligned ? new OrientedBoundingRect(localRect, transform) : null; + list.push({ + label: label, + labelLine: rawItem.labelLine, + rect: globalRect, + localRect: localRect, + obb: obb, + priority: rawItem.priority, + defaultAttr: rawItem.defaultAttr, + layoutOption: rawItem.computedLayoutOption, + axisAligned: isAxisAligned, + transform: transform + }); + } + return list; + } + function shiftLayout(list, xyDim, sizeDim, minBound, maxBound, balanceShift) { + var len = list.length; + if (len < 2) { + return; + } + list.sort(function (a, b) { + return a.rect[xyDim] - b.rect[xyDim]; + }); + var lastPos = 0; + var delta; + var adjusted = false; + var totalShifts = 0; + for (var i = 0; i < len; i++) { + var item = list[i]; + var rect = item.rect; + delta = rect[xyDim] - lastPos; + if (delta < 0) { + // shiftForward(i, len, -delta); + rect[xyDim] -= delta; + item.label[xyDim] -= delta; + adjusted = true; + } + var shift = Math.max(-delta, 0); + totalShifts += shift; + lastPos = rect[xyDim] + rect[sizeDim]; + } + if (totalShifts > 0 && balanceShift) { + // Shift back to make the distribution more equally. + shiftList(-totalShifts / len, 0, len); + } + // TODO bleedMargin? + var first = list[0]; + var last = list[len - 1]; + var minGap; + var maxGap; + updateMinMaxGap(); + // If ends exceed two bounds, squeeze at most 80%, then take the gap of two bounds. + minGap < 0 && squeezeGaps(-minGap, 0.8); + maxGap < 0 && squeezeGaps(maxGap, 0.8); + updateMinMaxGap(); + takeBoundsGap(minGap, maxGap, 1); + takeBoundsGap(maxGap, minGap, -1); + // Handle bailout when there is not enough space. + updateMinMaxGap(); + if (minGap < 0) { + squeezeWhenBailout(-minGap); + } + if (maxGap < 0) { + squeezeWhenBailout(maxGap); + } + function updateMinMaxGap() { + minGap = first.rect[xyDim] - minBound; + maxGap = maxBound - last.rect[xyDim] - last.rect[sizeDim]; + } + function takeBoundsGap(gapThisBound, gapOtherBound, moveDir) { + if (gapThisBound < 0) { + // Move from other gap if can. + var moveFromMaxGap = Math.min(gapOtherBound, -gapThisBound); + if (moveFromMaxGap > 0) { + shiftList(moveFromMaxGap * moveDir, 0, len); + var remained = moveFromMaxGap + gapThisBound; + if (remained < 0) { + squeezeGaps(-remained * moveDir, 1); + } + } else { + squeezeGaps(-gapThisBound * moveDir, 1); + } + } + } + function shiftList(delta, start, end) { + if (delta !== 0) { + adjusted = true; + } + for (var i = start; i < end; i++) { + var item = list[i]; + var rect = item.rect; + rect[xyDim] += delta; + item.label[xyDim] += delta; + } + } + // Squeeze gaps if the labels exceed margin. + function squeezeGaps(delta, maxSqeezePercent) { + var gaps = []; + var totalGaps = 0; + for (var i = 1; i < len; i++) { + var prevItemRect = list[i - 1].rect; + var gap = Math.max(list[i].rect[xyDim] - prevItemRect[xyDim] - prevItemRect[sizeDim], 0); + gaps.push(gap); + totalGaps += gap; + } + if (!totalGaps) { + return; + } + var squeezePercent = Math.min(Math.abs(delta) / totalGaps, maxSqeezePercent); + if (delta > 0) { + for (var i = 0; i < len - 1; i++) { + // Distribute the shift delta to all gaps. + var movement = gaps[i] * squeezePercent; + // Forward + shiftList(movement, 0, i + 1); + } + } else { + // Backward + for (var i = len - 1; i > 0; i--) { + // Distribute the shift delta to all gaps. + var movement = gaps[i - 1] * squeezePercent; + shiftList(-movement, i, len); + } + } + } + /** + * Squeeze to allow overlap if there is no more space available. + * Let other overlapping strategy like hideOverlap do the job instead of keep exceeding the bounds. + */ + function squeezeWhenBailout(delta) { + var dir = delta < 0 ? -1 : 1; + delta = Math.abs(delta); + var moveForEachLabel = Math.ceil(delta / (len - 1)); + for (var i = 0; i < len - 1; i++) { + if (dir > 0) { + // Forward + shiftList(moveForEachLabel, 0, i + 1); + } else { + // Backward + shiftList(-moveForEachLabel, len - i - 1, len); + } + delta -= moveForEachLabel; + if (delta <= 0) { + return; + } + } + } + return adjusted; + } + /** + * Adjust labels on x direction to avoid overlap. + */ + function shiftLayoutOnX(list, leftBound, rightBound, + // If average the shifts on all labels and add them to 0 + // TODO: Not sure if should enable it. + // Pros: The angle of lines will distribute more equally + // Cons: In some layout. It may not what user wanted. like in pie. the label of last sector is usually changed unexpectedly. + balanceShift) { + return shiftLayout(list, 'x', 'width', leftBound, rightBound, balanceShift); + } + /** + * Adjust labels on y direction to avoid overlap. + */ + function shiftLayoutOnY(list, topBound, bottomBound, + // If average the shifts on all labels and add them to 0 + balanceShift) { + return shiftLayout(list, 'y', 'height', topBound, bottomBound, balanceShift); + } + function hideOverlap(labelList) { + var displayedLabels = []; + // TODO, render overflow visible first, put in the displayedLabels. + labelList.sort(function (a, b) { + return b.priority - a.priority; + }); + var globalRect = new BoundingRect(0, 0, 0, 0); + function hideEl(el) { + if (!el.ignore) { + // Show on emphasis. + var emphasisState = el.ensureState('emphasis'); + if (emphasisState.ignore == null) { + emphasisState.ignore = false; + } + } + el.ignore = true; + } + for (var i = 0; i < labelList.length; i++) { + var labelItem = labelList[i]; + var isAxisAligned = labelItem.axisAligned; + var localRect = labelItem.localRect; + var transform = labelItem.transform; + var label = labelItem.label; + var labelLine = labelItem.labelLine; + globalRect.copy(labelItem.rect); + // Add a threshold because layout may be aligned precisely. + globalRect.width -= 0.1; + globalRect.height -= 0.1; + globalRect.x += 0.05; + globalRect.y += 0.05; + var obb = labelItem.obb; + var overlapped = false; + for (var j = 0; j < displayedLabels.length; j++) { + var existsTextCfg = displayedLabels[j]; + // Fast rejection. + if (!globalRect.intersect(existsTextCfg.rect)) { + continue; + } + if (isAxisAligned && existsTextCfg.axisAligned) { + // Is overlapped + overlapped = true; + break; + } + if (!existsTextCfg.obb) { + // If self is not axis aligned. But other is. + existsTextCfg.obb = new OrientedBoundingRect(existsTextCfg.localRect, existsTextCfg.transform); + } + if (!obb) { + // If self is axis aligned. But other is not. + obb = new OrientedBoundingRect(localRect, transform); + } + if (obb.intersect(existsTextCfg.obb)) { + overlapped = true; + break; + } + } + // TODO Callback to determine if this overlap should be handled? + if (overlapped) { + hideEl(label); + labelLine && hideEl(labelLine); + } else { + label.attr('ignore', labelItem.defaultAttr.ignore); + labelLine && labelLine.attr('ignore', labelItem.defaultAttr.labelGuideIgnore); + displayedLabels.push(labelItem); + } + } + } + + function cloneArr(points) { + if (points) { + var newPoints = []; + for (var i = 0; i < points.length; i++) { + newPoints.push(points[i].slice()); + } + return newPoints; + } + } + function prepareLayoutCallbackParams(labelItem, hostEl) { + var label = labelItem.label; + var labelLine = hostEl && hostEl.getTextGuideLine(); + return { + dataIndex: labelItem.dataIndex, + dataType: labelItem.dataType, + seriesIndex: labelItem.seriesModel.seriesIndex, + text: labelItem.label.style.text, + rect: labelItem.hostRect, + labelRect: labelItem.rect, + // x: labelAttr.x, + // y: labelAttr.y, + align: label.style.align, + verticalAlign: label.style.verticalAlign, + labelLinePoints: cloneArr(labelLine && labelLine.shape.points) + }; + } + var LABEL_OPTION_TO_STYLE_KEYS = ['align', 'verticalAlign', 'width', 'height', 'fontSize']; + var dummyTransformable = new Transformable(); + var labelLayoutInnerStore = makeInner(); + var labelLineAnimationStore = makeInner(); + function extendWithKeys(target, source, keys) { + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (source[key] != null) { + target[key] = source[key]; + } + } + } + var LABEL_LAYOUT_PROPS = ['x', 'y', 'rotation']; + var LabelManager = /** @class */function () { + function LabelManager() { + this._labelList = []; + this._chartViewList = []; + } + LabelManager.prototype.clearLabels = function () { + this._labelList = []; + this._chartViewList = []; + }; + /** + * Add label to manager + */ + LabelManager.prototype._addLabel = function (dataIndex, dataType, seriesModel, label, layoutOption) { + var labelStyle = label.style; + var hostEl = label.__hostTarget; + var textConfig = hostEl.textConfig || {}; + // TODO: If label is in other state. + var labelTransform = label.getComputedTransform(); + var labelRect = label.getBoundingRect().plain(); + BoundingRect.applyTransform(labelRect, labelRect, labelTransform); + if (labelTransform) { + dummyTransformable.setLocalTransform(labelTransform); + } else { + // Identity transform. + dummyTransformable.x = dummyTransformable.y = dummyTransformable.rotation = dummyTransformable.originX = dummyTransformable.originY = 0; + dummyTransformable.scaleX = dummyTransformable.scaleY = 1; + } + dummyTransformable.rotation = normalizeRadian(dummyTransformable.rotation); + var host = label.__hostTarget; + var hostRect; + if (host) { + hostRect = host.getBoundingRect().plain(); + var transform = host.getComputedTransform(); + BoundingRect.applyTransform(hostRect, hostRect, transform); + } + var labelGuide = hostRect && host.getTextGuideLine(); + this._labelList.push({ + label: label, + labelLine: labelGuide, + seriesModel: seriesModel, + dataIndex: dataIndex, + dataType: dataType, + layoutOption: layoutOption, + computedLayoutOption: null, + rect: labelRect, + hostRect: hostRect, + // Label with lower priority will be hidden when overlapped + // Use rect size as default priority + priority: hostRect ? hostRect.width * hostRect.height : 0, + // Save default label attributes. + // For restore if developers want get back to default value in callback. + defaultAttr: { + ignore: label.ignore, + labelGuideIgnore: labelGuide && labelGuide.ignore, + x: dummyTransformable.x, + y: dummyTransformable.y, + scaleX: dummyTransformable.scaleX, + scaleY: dummyTransformable.scaleY, + rotation: dummyTransformable.rotation, + style: { + x: labelStyle.x, + y: labelStyle.y, + align: labelStyle.align, + verticalAlign: labelStyle.verticalAlign, + width: labelStyle.width, + height: labelStyle.height, + fontSize: labelStyle.fontSize + }, + cursor: label.cursor, + attachedPos: textConfig.position, + attachedRot: textConfig.rotation + } + }); + }; + LabelManager.prototype.addLabelsOfSeries = function (chartView) { + var _this = this; + this._chartViewList.push(chartView); + var seriesModel = chartView.__model; + var layoutOption = seriesModel.get('labelLayout'); + /** + * Ignore layouting if it's not specified anything. + */ + if (!(isFunction(layoutOption) || keys(layoutOption).length)) { + return; + } + chartView.group.traverse(function (child) { + if (child.ignore) { + return true; // Stop traverse descendants. + } + // Only support label being hosted on graphic elements. + var textEl = child.getTextContent(); + var ecData = getECData(child); + // Can only attach the text on the element with dataIndex + if (textEl && !textEl.disableLabelLayout) { + _this._addLabel(ecData.dataIndex, ecData.dataType, seriesModel, textEl, layoutOption); + } + }); + }; + LabelManager.prototype.updateLayoutConfig = function (api) { + var width = api.getWidth(); + var height = api.getHeight(); + function createDragHandler(el, labelLineModel) { + return function () { + updateLabelLinePoints(el, labelLineModel); + }; + } + for (var i = 0; i < this._labelList.length; i++) { + var labelItem = this._labelList[i]; + var label = labelItem.label; + var hostEl = label.__hostTarget; + var defaultLabelAttr = labelItem.defaultAttr; + var layoutOption = void 0; + // TODO A global layout option? + if (isFunction(labelItem.layoutOption)) { + layoutOption = labelItem.layoutOption(prepareLayoutCallbackParams(labelItem, hostEl)); + } else { + layoutOption = labelItem.layoutOption; + } + layoutOption = layoutOption || {}; + labelItem.computedLayoutOption = layoutOption; + var degreeToRadian = Math.PI / 180; + // TODO hostEl should always exists. + // Or label should not have parent because the x, y is all in global space. + if (hostEl) { + hostEl.setTextConfig({ + // Force to set local false. + local: false, + // Ignore position and rotation config on the host el if x or y is changed. + position: layoutOption.x != null || layoutOption.y != null ? null : defaultLabelAttr.attachedPos, + // Ignore rotation config on the host el if rotation is changed. + rotation: layoutOption.rotate != null ? layoutOption.rotate * degreeToRadian : defaultLabelAttr.attachedRot, + offset: [layoutOption.dx || 0, layoutOption.dy || 0] + }); + } + var needsUpdateLabelLine = false; + if (layoutOption.x != null) { + // TODO width of chart view. + label.x = parsePercent$1(layoutOption.x, width); + label.setStyle('x', 0); // Ignore movement in style. TODO: origin. + needsUpdateLabelLine = true; + } else { + label.x = defaultLabelAttr.x; + label.setStyle('x', defaultLabelAttr.style.x); + } + if (layoutOption.y != null) { + // TODO height of chart view. + label.y = parsePercent$1(layoutOption.y, height); + label.setStyle('y', 0); // Ignore movement in style. + needsUpdateLabelLine = true; + } else { + label.y = defaultLabelAttr.y; + label.setStyle('y', defaultLabelAttr.style.y); + } + if (layoutOption.labelLinePoints) { + var guideLine = hostEl.getTextGuideLine(); + if (guideLine) { + guideLine.setShape({ + points: layoutOption.labelLinePoints + }); + // Not update + needsUpdateLabelLine = false; + } + } + var labelLayoutStore = labelLayoutInnerStore(label); + labelLayoutStore.needsUpdateLabelLine = needsUpdateLabelLine; + label.rotation = layoutOption.rotate != null ? layoutOption.rotate * degreeToRadian : defaultLabelAttr.rotation; + label.scaleX = defaultLabelAttr.scaleX; + label.scaleY = defaultLabelAttr.scaleY; + for (var k = 0; k < LABEL_OPTION_TO_STYLE_KEYS.length; k++) { + var key = LABEL_OPTION_TO_STYLE_KEYS[k]; + label.setStyle(key, layoutOption[key] != null ? layoutOption[key] : defaultLabelAttr.style[key]); + } + if (layoutOption.draggable) { + label.draggable = true; + label.cursor = 'move'; + if (hostEl) { + var hostModel = labelItem.seriesModel; + if (labelItem.dataIndex != null) { + var data = labelItem.seriesModel.getData(labelItem.dataType); + hostModel = data.getItemModel(labelItem.dataIndex); + } + label.on('drag', createDragHandler(hostEl, hostModel.getModel('labelLine'))); + } + } else { + // TODO Other drag functions? + label.off('drag'); + label.cursor = defaultLabelAttr.cursor; + } + } + }; + LabelManager.prototype.layout = function (api) { + var width = api.getWidth(); + var height = api.getHeight(); + var labelList = prepareLayoutList(this._labelList); + var labelsNeedsAdjustOnX = filter(labelList, function (item) { + return item.layoutOption.moveOverlap === 'shiftX'; + }); + var labelsNeedsAdjustOnY = filter(labelList, function (item) { + return item.layoutOption.moveOverlap === 'shiftY'; + }); + shiftLayoutOnX(labelsNeedsAdjustOnX, 0, width); + shiftLayoutOnY(labelsNeedsAdjustOnY, 0, height); + var labelsNeedsHideOverlap = filter(labelList, function (item) { + return item.layoutOption.hideOverlap; + }); + hideOverlap(labelsNeedsHideOverlap); + }; + /** + * Process all labels. Not only labels with layoutOption. + */ + LabelManager.prototype.processLabelsOverall = function () { + var _this = this; + each(this._chartViewList, function (chartView) { + var seriesModel = chartView.__model; + var ignoreLabelLineUpdate = chartView.ignoreLabelLineUpdate; + var animationEnabled = seriesModel.isAnimationEnabled(); + chartView.group.traverse(function (child) { + if (child.ignore && !child.forceLabelAnimation) { + return true; // Stop traverse descendants. + } + + var needsUpdateLabelLine = !ignoreLabelLineUpdate; + var label = child.getTextContent(); + if (!needsUpdateLabelLine && label) { + needsUpdateLabelLine = labelLayoutInnerStore(label).needsUpdateLabelLine; + } + if (needsUpdateLabelLine) { + _this._updateLabelLine(child, seriesModel); + } + if (animationEnabled) { + _this._animateLabels(child, seriesModel); + } + }); + }); + }; + LabelManager.prototype._updateLabelLine = function (el, seriesModel) { + // Only support label being hosted on graphic elements. + var textEl = el.getTextContent(); + // Update label line style. + var ecData = getECData(el); + var dataIndex = ecData.dataIndex; + // Only support labelLine on the labels represent data. + if (textEl && dataIndex != null) { + var data = seriesModel.getData(ecData.dataType); + var itemModel = data.getItemModel(dataIndex); + var defaultStyle = {}; + var visualStyle = data.getItemVisual(dataIndex, 'style'); + if (visualStyle) { + var visualType = data.getVisual('drawType'); + // Default to be same with main color + defaultStyle.stroke = visualStyle[visualType]; + } + var labelLineModel = itemModel.getModel('labelLine'); + setLabelLineStyle(el, getLabelLineStatesModels(itemModel), defaultStyle); + updateLabelLinePoints(el, labelLineModel); + } + }; + LabelManager.prototype._animateLabels = function (el, seriesModel) { + var textEl = el.getTextContent(); + var guideLine = el.getTextGuideLine(); + // Animate + if (textEl + // `forceLabelAnimation` has the highest priority + && (el.forceLabelAnimation || !textEl.ignore && !textEl.invisible && !el.disableLabelAnimation && !isElementRemoved(el))) { + var layoutStore = labelLayoutInnerStore(textEl); + var oldLayout = layoutStore.oldLayout; + var ecData = getECData(el); + var dataIndex = ecData.dataIndex; + var newProps = { + x: textEl.x, + y: textEl.y, + rotation: textEl.rotation + }; + var data = seriesModel.getData(ecData.dataType); + if (!oldLayout) { + textEl.attr(newProps); + // Disable fade in animation if value animation is enabled. + if (!labelInner(textEl).valueAnimation) { + var oldOpacity = retrieve2(textEl.style.opacity, 1); + // Fade in animation + textEl.style.opacity = 0; + initProps(textEl, { + style: { + opacity: oldOpacity + } + }, seriesModel, dataIndex); + } + } else { + textEl.attr(oldLayout); + // Make sure the animation from is in the right status. + var prevStates = el.prevStates; + if (prevStates) { + if (indexOf(prevStates, 'select') >= 0) { + textEl.attr(layoutStore.oldLayoutSelect); + } + if (indexOf(prevStates, 'emphasis') >= 0) { + textEl.attr(layoutStore.oldLayoutEmphasis); + } + } + updateProps(textEl, newProps, seriesModel, dataIndex); + } + layoutStore.oldLayout = newProps; + if (textEl.states.select) { + var layoutSelect = layoutStore.oldLayoutSelect = {}; + extendWithKeys(layoutSelect, newProps, LABEL_LAYOUT_PROPS); + extendWithKeys(layoutSelect, textEl.states.select, LABEL_LAYOUT_PROPS); + } + if (textEl.states.emphasis) { + var layoutEmphasis = layoutStore.oldLayoutEmphasis = {}; + extendWithKeys(layoutEmphasis, newProps, LABEL_LAYOUT_PROPS); + extendWithKeys(layoutEmphasis, textEl.states.emphasis, LABEL_LAYOUT_PROPS); + } + animateLabelValue(textEl, dataIndex, data, seriesModel, seriesModel); + } + if (guideLine && !guideLine.ignore && !guideLine.invisible) { + var layoutStore = labelLineAnimationStore(guideLine); + var oldLayout = layoutStore.oldLayout; + var newLayout = { + points: guideLine.shape.points + }; + if (!oldLayout) { + guideLine.setShape(newLayout); + guideLine.style.strokePercent = 0; + initProps(guideLine, { + style: { + strokePercent: 1 + } + }, seriesModel); + } else { + guideLine.attr({ + shape: oldLayout + }); + updateProps(guideLine, { + shape: newLayout + }, seriesModel); + } + layoutStore.oldLayout = newLayout; + } + }; + return LabelManager; + }(); + + var getLabelManager = makeInner(); + function installLabelLayout(registers) { + registers.registerUpdateLifecycle('series:beforeupdate', function (ecModel, api, params) { + // TODO api provide an namespace that can save stuff per instance + var labelManager = getLabelManager(api).labelManager; + if (!labelManager) { + labelManager = getLabelManager(api).labelManager = new LabelManager(); + } + labelManager.clearLabels(); + }); + registers.registerUpdateLifecycle('series:layoutlabels', function (ecModel, api, params) { + var labelManager = getLabelManager(api).labelManager; + params.updatedSeries.forEach(function (series) { + labelManager.addLabelsOfSeries(api.getViewOfSeriesModel(series)); + }); + labelManager.updateLayoutConfig(api); + labelManager.layout(api); + labelManager.processLabelsOverall(); + }); + } + + var mathSin$4 = Math.sin; + var mathCos$4 = Math.cos; + var PI$4 = Math.PI; + var PI2$7 = Math.PI * 2; + var degree = 180 / PI$4; + var SVGPathRebuilder = (function () { + function SVGPathRebuilder() { + } + SVGPathRebuilder.prototype.reset = function (precision) { + this._start = true; + this._d = []; + this._str = ''; + this._p = Math.pow(10, precision || 4); + }; + SVGPathRebuilder.prototype.moveTo = function (x, y) { + this._add('M', x, y); + }; + SVGPathRebuilder.prototype.lineTo = function (x, y) { + this._add('L', x, y); + }; + SVGPathRebuilder.prototype.bezierCurveTo = function (x, y, x2, y2, x3, y3) { + this._add('C', x, y, x2, y2, x3, y3); + }; + SVGPathRebuilder.prototype.quadraticCurveTo = function (x, y, x2, y2) { + this._add('Q', x, y, x2, y2); + }; + SVGPathRebuilder.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) { + this.ellipse(cx, cy, r, r, 0, startAngle, endAngle, anticlockwise); + }; + SVGPathRebuilder.prototype.ellipse = function (cx, cy, rx, ry, psi, startAngle, endAngle, anticlockwise) { + var dTheta = endAngle - startAngle; + var clockwise = !anticlockwise; + var dThetaPositive = Math.abs(dTheta); + var isCircle = isAroundZero$1(dThetaPositive - PI2$7) + || (clockwise ? dTheta >= PI2$7 : -dTheta >= PI2$7); + var unifiedTheta = dTheta > 0 ? dTheta % PI2$7 : (dTheta % PI2$7 + PI2$7); + var large = false; + if (isCircle) { + large = true; + } + else if (isAroundZero$1(dThetaPositive)) { + large = false; + } + else { + large = (unifiedTheta >= PI$4) === !!clockwise; + } + var x0 = cx + rx * mathCos$4(startAngle); + var y0 = cy + ry * mathSin$4(startAngle); + if (this._start) { + this._add('M', x0, y0); + } + var xRot = Math.round(psi * degree); + if (isCircle) { + var p = 1 / this._p; + var dTheta_1 = (clockwise ? 1 : -1) * (PI2$7 - p); + this._add('A', rx, ry, xRot, 1, +clockwise, cx + rx * mathCos$4(startAngle + dTheta_1), cy + ry * mathSin$4(startAngle + dTheta_1)); + if (p > 1e-2) { + this._add('A', rx, ry, xRot, 0, +clockwise, x0, y0); + } + } + else { + var x = cx + rx * mathCos$4(endAngle); + var y = cy + ry * mathSin$4(endAngle); + this._add('A', rx, ry, xRot, +large, +clockwise, x, y); + } + }; + SVGPathRebuilder.prototype.rect = function (x, y, w, h) { + this._add('M', x, y); + this._add('l', w, 0); + this._add('l', 0, h); + this._add('l', -w, 0); + this._add('Z'); + }; + SVGPathRebuilder.prototype.closePath = function () { + if (this._d.length > 0) { + this._add('Z'); + } + }; + SVGPathRebuilder.prototype._add = function (cmd, a, b, c, d, e, f, g, h) { + var vals = []; + var p = this._p; + for (var i = 1; i < arguments.length; i++) { + var val = arguments[i]; + if (isNaN(val)) { + this._invalid = true; + return; + } + vals.push(Math.round(val * p) / p); + } + this._d.push(cmd + vals.join(' ')); + this._start = cmd === 'Z'; + }; + SVGPathRebuilder.prototype.generateStr = function () { + this._str = this._invalid ? '' : this._d.join(''); + this._d = []; + }; + SVGPathRebuilder.prototype.getStr = function () { + return this._str; + }; + return SVGPathRebuilder; + }()); + + var NONE = 'none'; + var mathRound$1 = Math.round; + function pathHasFill(style) { + var fill = style.fill; + return fill != null && fill !== NONE; + } + function pathHasStroke(style) { + var stroke = style.stroke; + return stroke != null && stroke !== NONE; + } + var strokeProps = ['lineCap', 'miterLimit', 'lineJoin']; + var svgStrokeProps = map(strokeProps, function (prop) { return "stroke-" + prop.toLowerCase(); }); + function mapStyleToAttrs(updateAttr, style, el, forceUpdate) { + var opacity = style.opacity == null ? 1 : style.opacity; + if (el instanceof ZRImage) { + updateAttr('opacity', opacity); + return; + } + if (pathHasFill(style)) { + var fill = normalizeColor(style.fill); + updateAttr('fill', fill.color); + var fillOpacity = style.fillOpacity != null + ? style.fillOpacity * fill.opacity * opacity + : fill.opacity * opacity; + if (forceUpdate || fillOpacity < 1) { + updateAttr('fill-opacity', fillOpacity); + } + } + else { + updateAttr('fill', NONE); + } + if (pathHasStroke(style)) { + var stroke = normalizeColor(style.stroke); + updateAttr('stroke', stroke.color); + var strokeScale = style.strokeNoScale + ? el.getLineScale() + : 1; + var strokeWidth = (strokeScale ? (style.lineWidth || 0) / strokeScale : 0); + var strokeOpacity = style.strokeOpacity != null + ? style.strokeOpacity * stroke.opacity * opacity + : stroke.opacity * opacity; + var strokeFirst = style.strokeFirst; + if (forceUpdate || strokeWidth !== 1) { + updateAttr('stroke-width', strokeWidth); + } + if (forceUpdate || strokeFirst) { + updateAttr('paint-order', strokeFirst ? 'stroke' : 'fill'); + } + if (forceUpdate || strokeOpacity < 1) { + updateAttr('stroke-opacity', strokeOpacity); + } + if (style.lineDash) { + var _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1]; + if (lineDash) { + lineDashOffset = mathRound$1(lineDashOffset || 0); + updateAttr('stroke-dasharray', lineDash.join(',')); + if (lineDashOffset || forceUpdate) { + updateAttr('stroke-dashoffset', lineDashOffset); + } + } + } + else if (forceUpdate) { + updateAttr('stroke-dasharray', NONE); + } + for (var i = 0; i < strokeProps.length; i++) { + var propName = strokeProps[i]; + if (forceUpdate || style[propName] !== DEFAULT_PATH_STYLE[propName]) { + var val = style[propName] || DEFAULT_PATH_STYLE[propName]; + val && updateAttr(svgStrokeProps[i], val); + } + } + } + else if (forceUpdate) { + updateAttr('stroke', NONE); + } + } + + var SVGNS = 'http://www.w3.org/2000/svg'; + var XLINKNS = 'http://www.w3.org/1999/xlink'; + var XMLNS = 'http://www.w3.org/2000/xmlns/'; + var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'; + var META_DATA_PREFIX = 'ecmeta_'; + function createElement(name) { + return document.createElementNS(SVGNS, name); + } + function createVNode(tag, key, attrs, children, text) { + return { + tag: tag, + attrs: attrs || {}, + children: children, + text: text, + key: key + }; + } + function createElementOpen(name, attrs) { + var attrsStr = []; + if (attrs) { + for (var key in attrs) { + var val = attrs[key]; + var part = key; + if (val === false) { + continue; + } + else if (val !== true && val != null) { + part += "=\"" + val + "\""; + } + attrsStr.push(part); + } + } + return "<" + name + " " + attrsStr.join(' ') + ">"; + } + function createElementClose(name) { + return ""; + } + function vNodeToString(el, opts) { + opts = opts || {}; + var S = opts.newline ? '\n' : ''; + function convertElToString(el) { + var children = el.children, tag = el.tag, attrs = el.attrs, text = el.text; + return createElementOpen(tag, attrs) + + (tag !== 'style' ? encodeHTML(text) : text || '') + + (children ? "" + S + map(children, function (child) { return convertElToString(child); }).join(S) + S : '') + + createElementClose(tag); + } + return convertElToString(el); + } + function getCssString(selectorNodes, animationNodes, opts) { + opts = opts || {}; + var S = opts.newline ? '\n' : ''; + var bracketBegin = " {" + S; + var bracketEnd = S + "}"; + var selectors = map(keys(selectorNodes), function (className) { + return className + bracketBegin + map(keys(selectorNodes[className]), function (attrName) { + return attrName + ":" + selectorNodes[className][attrName] + ";"; + }).join(S) + bracketEnd; + }).join(S); + var animations = map(keys(animationNodes), function (animationName) { + return "@keyframes " + animationName + bracketBegin + map(keys(animationNodes[animationName]), function (percent) { + return percent + bracketBegin + map(keys(animationNodes[animationName][percent]), function (attrName) { + var val = animationNodes[animationName][percent][attrName]; + if (attrName === 'd') { + val = "path(\"" + val + "\")"; + } + return attrName + ":" + val + ";"; + }).join(S) + bracketEnd; + }).join(S) + bracketEnd; + }).join(S); + if (!selectors && !animations) { + return ''; + } + return [''].join(S); + } + function createBrushScope(zrId) { + return { + zrId: zrId, + shadowCache: {}, + patternCache: {}, + gradientCache: {}, + clipPathCache: {}, + defs: {}, + cssNodes: {}, + cssAnims: {}, + cssStyleCache: {}, + cssAnimIdx: 0, + shadowIdx: 0, + gradientIdx: 0, + patternIdx: 0, + clipPathIdx: 0 + }; + } + function createSVGVNode(width, height, children, useViewBox) { + return createVNode('svg', 'root', { + 'width': width, + 'height': height, + 'xmlns': SVGNS, + 'xmlns:xlink': XLINKNS, + 'version': '1.1', + 'baseProfile': 'full', + 'viewBox': useViewBox ? "0 0 " + width + " " + height : false + }, children); + } + + var cssClassIdx = 0; + function getClassId() { + return cssClassIdx++; + } + + var EASING_MAP = { + cubicIn: '0.32,0,0.67,0', + cubicOut: '0.33,1,0.68,1', + cubicInOut: '0.65,0,0.35,1', + quadraticIn: '0.11,0,0.5,0', + quadraticOut: '0.5,1,0.89,1', + quadraticInOut: '0.45,0,0.55,1', + quarticIn: '0.5,0,0.75,0', + quarticOut: '0.25,1,0.5,1', + quarticInOut: '0.76,0,0.24,1', + quinticIn: '0.64,0,0.78,0', + quinticOut: '0.22,1,0.36,1', + quinticInOut: '0.83,0,0.17,1', + sinusoidalIn: '0.12,0,0.39,0', + sinusoidalOut: '0.61,1,0.88,1', + sinusoidalInOut: '0.37,0,0.63,1', + exponentialIn: '0.7,0,0.84,0', + exponentialOut: '0.16,1,0.3,1', + exponentialInOut: '0.87,0,0.13,1', + circularIn: '0.55,0,1,0.45', + circularOut: '0,0.55,0.45,1', + circularInOut: '0.85,0,0.15,1' + }; + var transformOriginKey = 'transform-origin'; + function buildPathString(el, kfShape, path) { + var shape = extend({}, el.shape); + extend(shape, kfShape); + el.buildPath(path, shape); + var svgPathBuilder = new SVGPathRebuilder(); + svgPathBuilder.reset(getPathPrecision(el)); + path.rebuildPath(svgPathBuilder, 1); + svgPathBuilder.generateStr(); + return svgPathBuilder.getStr(); + } + function setTransformOrigin(target, transform) { + var originX = transform.originX, originY = transform.originY; + if (originX || originY) { + target[transformOriginKey] = originX + "px " + originY + "px"; + } + } + var ANIMATE_STYLE_MAP = { + fill: 'fill', + opacity: 'opacity', + lineWidth: 'stroke-width', + lineDashOffset: 'stroke-dashoffset' + }; + function addAnimation(cssAnim, scope) { + var animationName = scope.zrId + '-ani-' + scope.cssAnimIdx++; + scope.cssAnims[animationName] = cssAnim; + return animationName; + } + function createCompoundPathCSSAnimation(el, attrs, scope) { + var paths = el.shape.paths; + var composedAnim = {}; + var cssAnimationCfg; + var cssAnimationName; + each(paths, function (path) { + var subScope = createBrushScope(scope.zrId); + subScope.animation = true; + createCSSAnimation(path, {}, subScope, true); + var cssAnims = subScope.cssAnims; + var cssNodes = subScope.cssNodes; + var animNames = keys(cssAnims); + var len = animNames.length; + if (!len) { + return; + } + cssAnimationName = animNames[len - 1]; + var lastAnim = cssAnims[cssAnimationName]; + for (var percent in lastAnim) { + var kf = lastAnim[percent]; + composedAnim[percent] = composedAnim[percent] || { d: '' }; + composedAnim[percent].d += kf.d || ''; + } + for (var className in cssNodes) { + var val = cssNodes[className].animation; + if (val.indexOf(cssAnimationName) >= 0) { + cssAnimationCfg = val; + } + } + }); + if (!cssAnimationCfg) { + return; + } + attrs.d = false; + var animationName = addAnimation(composedAnim, scope); + return cssAnimationCfg.replace(cssAnimationName, animationName); + } + function getEasingFunc(easing) { + return isString(easing) + ? EASING_MAP[easing] + ? "cubic-bezier(" + EASING_MAP[easing] + ")" + : createCubicEasingFunc(easing) ? easing : '' + : ''; + } + function createCSSAnimation(el, attrs, scope, onlyShape) { + var animators = el.animators; + var len = animators.length; + var cssAnimations = []; + if (el instanceof CompoundPath) { + var animationCfg = createCompoundPathCSSAnimation(el, attrs, scope); + if (animationCfg) { + cssAnimations.push(animationCfg); + } + else if (!len) { + return; + } + } + else if (!len) { + return; + } + var groupAnimators = {}; + for (var i = 0; i < len; i++) { + var animator = animators[i]; + var cfgArr = [animator.getMaxTime() / 1000 + 's']; + var easing = getEasingFunc(animator.getClip().easing); + var delay = animator.getDelay(); + if (easing) { + cfgArr.push(easing); + } + else { + cfgArr.push('linear'); + } + if (delay) { + cfgArr.push(delay / 1000 + 's'); + } + if (animator.getLoop()) { + cfgArr.push('infinite'); + } + var cfg = cfgArr.join(' '); + groupAnimators[cfg] = groupAnimators[cfg] || [cfg, []]; + groupAnimators[cfg][1].push(animator); + } + function createSingleCSSAnimation(groupAnimator) { + var animators = groupAnimator[1]; + var len = animators.length; + var transformKfs = {}; + var shapeKfs = {}; + var finalKfs = {}; + var animationTimingFunctionAttrName = 'animation-timing-function'; + function saveAnimatorTrackToCssKfs(animator, cssKfs, toCssAttrName) { + var tracks = animator.getTracks(); + var maxTime = animator.getMaxTime(); + for (var k = 0; k < tracks.length; k++) { + var track = tracks[k]; + if (track.needsAnimate()) { + var kfs = track.keyframes; + var attrName = track.propName; + toCssAttrName && (attrName = toCssAttrName(attrName)); + if (attrName) { + for (var i = 0; i < kfs.length; i++) { + var kf = kfs[i]; + var percent = Math.round(kf.time / maxTime * 100) + '%'; + var kfEasing = getEasingFunc(kf.easing); + var rawValue = kf.rawValue; + if (isString(rawValue) || isNumber(rawValue)) { + cssKfs[percent] = cssKfs[percent] || {}; + cssKfs[percent][attrName] = kf.rawValue; + if (kfEasing) { + cssKfs[percent][animationTimingFunctionAttrName] = kfEasing; + } + } + } + } + } + } + } + for (var i = 0; i < len; i++) { + var animator = animators[i]; + var targetProp = animator.targetName; + if (!targetProp) { + !onlyShape && saveAnimatorTrackToCssKfs(animator, transformKfs); + } + else if (targetProp === 'shape') { + saveAnimatorTrackToCssKfs(animator, shapeKfs); + } + } + for (var percent in transformKfs) { + var transform = {}; + copyTransform(transform, el); + extend(transform, transformKfs[percent]); + var str = getSRTTransformString(transform); + var timingFunction = transformKfs[percent][animationTimingFunctionAttrName]; + finalKfs[percent] = str ? { + transform: str + } : {}; + setTransformOrigin(finalKfs[percent], transform); + if (timingFunction) { + finalKfs[percent][animationTimingFunctionAttrName] = timingFunction; + } + } + var path; + var canAnimateShape = true; + for (var percent in shapeKfs) { + finalKfs[percent] = finalKfs[percent] || {}; + var isFirst = !path; + var timingFunction = shapeKfs[percent][animationTimingFunctionAttrName]; + if (isFirst) { + path = new PathProxy(); + } + var len_1 = path.len(); + path.reset(); + finalKfs[percent].d = buildPathString(el, shapeKfs[percent], path); + var newLen = path.len(); + if (!isFirst && len_1 !== newLen) { + canAnimateShape = false; + break; + } + if (timingFunction) { + finalKfs[percent][animationTimingFunctionAttrName] = timingFunction; + } + } + if (!canAnimateShape) { + for (var percent in finalKfs) { + delete finalKfs[percent].d; + } + } + if (!onlyShape) { + for (var i = 0; i < len; i++) { + var animator = animators[i]; + var targetProp = animator.targetName; + if (targetProp === 'style') { + saveAnimatorTrackToCssKfs(animator, finalKfs, function (propName) { return ANIMATE_STYLE_MAP[propName]; }); + } + } + } + var percents = keys(finalKfs); + var allTransformOriginSame = true; + var transformOrigin; + for (var i = 1; i < percents.length; i++) { + var p0 = percents[i - 1]; + var p1 = percents[i]; + if (finalKfs[p0][transformOriginKey] !== finalKfs[p1][transformOriginKey]) { + allTransformOriginSame = false; + break; + } + transformOrigin = finalKfs[p0][transformOriginKey]; + } + if (allTransformOriginSame && transformOrigin) { + for (var percent in finalKfs) { + if (finalKfs[percent][transformOriginKey]) { + delete finalKfs[percent][transformOriginKey]; + } + } + attrs[transformOriginKey] = transformOrigin; + } + if (filter(percents, function (percent) { return keys(finalKfs[percent]).length > 0; }).length) { + var animationName = addAnimation(finalKfs, scope); + return animationName + " " + groupAnimator[0] + " both"; + } + } + for (var key in groupAnimators) { + var animationCfg = createSingleCSSAnimation(groupAnimators[key]); + if (animationCfg) { + cssAnimations.push(animationCfg); + } + } + if (cssAnimations.length) { + var className = scope.zrId + '-cls-' + getClassId(); + scope.cssNodes['.' + className] = { + animation: cssAnimations.join(',') + }; + attrs["class"] = className; + } + } + + function createCSSEmphasis(el, attrs, scope) { + if (!el.ignore) { + if (el.isSilent()) { + var style = { + 'pointer-events': 'none' + }; + setClassAttribute(style, attrs, scope, true); + } + else { + var emphasisStyle = el.states.emphasis && el.states.emphasis.style + ? el.states.emphasis.style + : {}; + var fill = emphasisStyle.fill; + if (!fill) { + var normalFill = el.style && el.style.fill; + var selectFill = el.states.select + && el.states.select.style + && el.states.select.style.fill; + var fromFill = el.currentStates.indexOf('select') >= 0 + ? (selectFill || normalFill) + : normalFill; + if (fromFill) { + fill = liftColor(fromFill); + } + } + var lineWidth = emphasisStyle.lineWidth; + if (lineWidth) { + var scaleX = (!emphasisStyle.strokeNoScale && el.transform) + ? el.transform[0] + : 1; + lineWidth = lineWidth / scaleX; + } + var style = { + cursor: 'pointer' + }; + if (fill) { + style.fill = fill; + } + if (emphasisStyle.stroke) { + style.stroke = emphasisStyle.stroke; + } + if (lineWidth) { + style['stroke-width'] = lineWidth; + } + setClassAttribute(style, attrs, scope, true); + } + } + } + function setClassAttribute(style, attrs, scope, withHover) { + var styleKey = JSON.stringify(style); + var className = scope.cssStyleCache[styleKey]; + if (!className) { + className = scope.zrId + '-cls-' + getClassId(); + scope.cssStyleCache[styleKey] = className; + scope.cssNodes['.' + className + (withHover ? ':hover' : '')] = style; + } + attrs["class"] = attrs["class"] ? (attrs["class"] + ' ' + className) : className; + } + + var round$2 = Math.round; + function isImageLike$1(val) { + return val && isString(val.src); + } + function isCanvasLike(val) { + return val && isFunction(val.toDataURL); + } + function setStyleAttrs(attrs, style, el, scope) { + mapStyleToAttrs(function (key, val) { + var isFillStroke = key === 'fill' || key === 'stroke'; + if (isFillStroke && isGradient(val)) { + setGradient(style, attrs, key, scope); + } + else if (isFillStroke && isPattern(val)) { + setPattern(el, attrs, key, scope); + } + else if (isFillStroke && val === 'none') { + attrs[key] = 'transparent'; + } + else { + attrs[key] = val; + } + }, style, el, false); + setShadow(el, attrs, scope); + } + function setMetaData(attrs, el) { + var metaData = getElementSSRData(el); + if (metaData) { + metaData.each(function (val, key) { + val != null && (attrs[(META_DATA_PREFIX + key).toLowerCase()] = val + ''); + }); + if (el.isSilent()) { + attrs[META_DATA_PREFIX + 'silent'] = 'true'; + } + } + } + function noRotateScale(m) { + return isAroundZero$1(m[0] - 1) + && isAroundZero$1(m[1]) + && isAroundZero$1(m[2]) + && isAroundZero$1(m[3] - 1); + } + function noTranslate(m) { + return isAroundZero$1(m[4]) && isAroundZero$1(m[5]); + } + function setTransform(attrs, m, compress) { + if (m && !(noTranslate(m) && noRotateScale(m))) { + var mul = compress ? 10 : 1e4; + attrs.transform = noRotateScale(m) + ? "translate(" + round$2(m[4] * mul) / mul + " " + round$2(m[5] * mul) / mul + ")" : getMatrixStr(m); + } + } + function convertPolyShape(shape, attrs, mul) { + var points = shape.points; + var strArr = []; + for (var i = 0; i < points.length; i++) { + strArr.push(round$2(points[i][0] * mul) / mul); + strArr.push(round$2(points[i][1] * mul) / mul); + } + attrs.points = strArr.join(' '); + } + function validatePolyShape(shape) { + return !shape.smooth; + } + function createAttrsConvert(desc) { + var normalizedDesc = map(desc, function (item) { + return (typeof item === 'string' ? [item, item] : item); + }); + return function (shape, attrs, mul) { + for (var i = 0; i < normalizedDesc.length; i++) { + var item = normalizedDesc[i]; + var val = shape[item[0]]; + if (val != null) { + attrs[item[1]] = round$2(val * mul) / mul; + } + } + }; + } + var builtinShapesDef = { + circle: [createAttrsConvert(['cx', 'cy', 'r'])], + polyline: [convertPolyShape, validatePolyShape], + polygon: [convertPolyShape, validatePolyShape] + }; + function hasShapeAnimation(el) { + var animators = el.animators; + for (var i = 0; i < animators.length; i++) { + if (animators[i].targetName === 'shape') { + return true; + } + } + return false; + } + function brushSVGPath(el, scope) { + var style = el.style; + var shape = el.shape; + var builtinShpDef = builtinShapesDef[el.type]; + var attrs = {}; + var needsAnimate = scope.animation; + var svgElType = 'path'; + var strokePercent = el.style.strokePercent; + var precision = (scope.compress && getPathPrecision(el)) || 4; + if (builtinShpDef + && !scope.willUpdate + && !(builtinShpDef[1] && !builtinShpDef[1](shape)) + && !(needsAnimate && hasShapeAnimation(el)) + && !(strokePercent < 1)) { + svgElType = el.type; + var mul = Math.pow(10, precision); + builtinShpDef[0](shape, attrs, mul); + } + else { + var needBuildPath = !el.path || el.shapeChanged(); + if (!el.path) { + el.createPathProxy(); + } + var path = el.path; + if (needBuildPath) { + path.beginPath(); + el.buildPath(path, el.shape); + el.pathUpdated(); + } + var pathVersion = path.getVersion(); + var elExt = el; + var svgPathBuilder = elExt.__svgPathBuilder; + if (elExt.__svgPathVersion !== pathVersion + || !svgPathBuilder + || strokePercent !== elExt.__svgPathStrokePercent) { + if (!svgPathBuilder) { + svgPathBuilder = elExt.__svgPathBuilder = new SVGPathRebuilder(); + } + svgPathBuilder.reset(precision); + path.rebuildPath(svgPathBuilder, strokePercent); + svgPathBuilder.generateStr(); + elExt.__svgPathVersion = pathVersion; + elExt.__svgPathStrokePercent = strokePercent; + } + attrs.d = svgPathBuilder.getStr(); + } + setTransform(attrs, el.transform); + setStyleAttrs(attrs, style, el, scope); + setMetaData(attrs, el); + scope.animation && createCSSAnimation(el, attrs, scope); + scope.emphasis && createCSSEmphasis(el, attrs, scope); + return createVNode(svgElType, el.id + '', attrs); + } + function brushSVGImage(el, scope) { + var style = el.style; + var image = style.image; + if (image && !isString(image)) { + if (isImageLike$1(image)) { + image = image.src; + } + else if (isCanvasLike(image)) { + image = image.toDataURL(); + } + } + if (!image) { + return; + } + var x = style.x || 0; + var y = style.y || 0; + var dw = style.width; + var dh = style.height; + var attrs = { + href: image, + width: dw, + height: dh + }; + if (x) { + attrs.x = x; + } + if (y) { + attrs.y = y; + } + setTransform(attrs, el.transform); + setStyleAttrs(attrs, style, el, scope); + setMetaData(attrs, el); + scope.animation && createCSSAnimation(el, attrs, scope); + return createVNode('image', el.id + '', attrs); + } + function brushSVGTSpan(el, scope) { + var style = el.style; + var text = style.text; + text != null && (text += ''); + if (!text || isNaN(style.x) || isNaN(style.y)) { + return; + } + var font = style.font || DEFAULT_FONT; + var x = style.x || 0; + var y = adjustTextY(style.y || 0, getLineHeight(font), style.textBaseline); + var textAlign = TEXT_ALIGN_TO_ANCHOR[style.textAlign] + || style.textAlign; + var attrs = { + 'dominant-baseline': 'central', + 'text-anchor': textAlign + }; + if (hasSeparateFont(style)) { + var separatedFontStr = ''; + var fontStyle = style.fontStyle; + var fontSize = parseFontSize(style.fontSize); + if (!parseFloat(fontSize)) { + return; + } + var fontFamily = style.fontFamily || DEFAULT_FONT_FAMILY; + var fontWeight = style.fontWeight; + separatedFontStr += "font-size:" + fontSize + ";font-family:" + fontFamily + ";"; + if (fontStyle && fontStyle !== 'normal') { + separatedFontStr += "font-style:" + fontStyle + ";"; + } + if (fontWeight && fontWeight !== 'normal') { + separatedFontStr += "font-weight:" + fontWeight + ";"; + } + attrs.style = separatedFontStr; + } + else { + attrs.style = "font: " + font; + } + if (text.match(/\s/)) { + attrs['xml:space'] = 'preserve'; + } + if (x) { + attrs.x = x; + } + if (y) { + attrs.y = y; + } + setTransform(attrs, el.transform); + setStyleAttrs(attrs, style, el, scope); + setMetaData(attrs, el); + scope.animation && createCSSAnimation(el, attrs, scope); + return createVNode('text', el.id + '', attrs, undefined, text); + } + function brush$1(el, scope) { + if (el instanceof Path) { + return brushSVGPath(el, scope); + } + else if (el instanceof ZRImage) { + return brushSVGImage(el, scope); + } + else if (el instanceof TSpan) { + return brushSVGTSpan(el, scope); + } + } + function setShadow(el, attrs, scope) { + var style = el.style; + if (hasShadow(style)) { + var shadowKey = getShadowKey(el); + var shadowCache = scope.shadowCache; + var shadowId = shadowCache[shadowKey]; + if (!shadowId) { + var globalScale = el.getGlobalScale(); + var scaleX = globalScale[0]; + var scaleY = globalScale[1]; + if (!scaleX || !scaleY) { + return; + } + var offsetX = style.shadowOffsetX || 0; + var offsetY = style.shadowOffsetY || 0; + var blur_1 = style.shadowBlur; + var _a = normalizeColor(style.shadowColor), opacity = _a.opacity, color = _a.color; + var stdDx = blur_1 / 2 / scaleX; + var stdDy = blur_1 / 2 / scaleY; + var stdDeviation = stdDx + ' ' + stdDy; + shadowId = scope.zrId + '-s' + scope.shadowIdx++; + scope.defs[shadowId] = createVNode('filter', shadowId, { + 'id': shadowId, + 'x': '-100%', + 'y': '-100%', + 'width': '300%', + 'height': '300%' + }, [ + createVNode('feDropShadow', '', { + 'dx': offsetX / scaleX, + 'dy': offsetY / scaleY, + 'stdDeviation': stdDeviation, + 'flood-color': color, + 'flood-opacity': opacity + }) + ]); + shadowCache[shadowKey] = shadowId; + } + attrs.filter = getIdURL(shadowId); + } + } + function setGradient(style, attrs, target, scope) { + var val = style[target]; + var gradientTag; + var gradientAttrs = { + 'gradientUnits': val.global + ? 'userSpaceOnUse' + : 'objectBoundingBox' + }; + if (isLinearGradient(val)) { + gradientTag = 'linearGradient'; + gradientAttrs.x1 = val.x; + gradientAttrs.y1 = val.y; + gradientAttrs.x2 = val.x2; + gradientAttrs.y2 = val.y2; + } + else if (isRadialGradient(val)) { + gradientTag = 'radialGradient'; + gradientAttrs.cx = retrieve2(val.x, 0.5); + gradientAttrs.cy = retrieve2(val.y, 0.5); + gradientAttrs.r = retrieve2(val.r, 0.5); + } + else { + if ("development" !== 'production') { + logError('Illegal gradient type.'); + } + return; + } + var colors = val.colorStops; + var colorStops = []; + for (var i = 0, len = colors.length; i < len; ++i) { + var offset = round4(colors[i].offset) * 100 + '%'; + var stopColor = colors[i].color; + var _a = normalizeColor(stopColor), color = _a.color, opacity = _a.opacity; + var stopsAttrs = { + 'offset': offset + }; + stopsAttrs['stop-color'] = color; + if (opacity < 1) { + stopsAttrs['stop-opacity'] = opacity; + } + colorStops.push(createVNode('stop', i + '', stopsAttrs)); + } + var gradientVNode = createVNode(gradientTag, '', gradientAttrs, colorStops); + var gradientKey = vNodeToString(gradientVNode); + var gradientCache = scope.gradientCache; + var gradientId = gradientCache[gradientKey]; + if (!gradientId) { + gradientId = scope.zrId + '-g' + scope.gradientIdx++; + gradientCache[gradientKey] = gradientId; + gradientAttrs.id = gradientId; + scope.defs[gradientId] = createVNode(gradientTag, gradientId, gradientAttrs, colorStops); + } + attrs[target] = getIdURL(gradientId); + } + function setPattern(el, attrs, target, scope) { + var val = el.style[target]; + var boundingRect = el.getBoundingRect(); + var patternAttrs = {}; + var repeat = val.repeat; + var noRepeat = repeat === 'no-repeat'; + var repeatX = repeat === 'repeat-x'; + var repeatY = repeat === 'repeat-y'; + var child; + if (isImagePattern(val)) { + var imageWidth_1 = val.imageWidth; + var imageHeight_1 = val.imageHeight; + var imageSrc = void 0; + var patternImage = val.image; + if (isString(patternImage)) { + imageSrc = patternImage; + } + else if (isImageLike$1(patternImage)) { + imageSrc = patternImage.src; + } + else if (isCanvasLike(patternImage)) { + imageSrc = patternImage.toDataURL(); + } + if (typeof Image === 'undefined') { + var errMsg = 'Image width/height must been given explictly in svg-ssr renderer.'; + assert(imageWidth_1, errMsg); + assert(imageHeight_1, errMsg); + } + else if (imageWidth_1 == null || imageHeight_1 == null) { + var setSizeToVNode_1 = function (vNode, img) { + if (vNode) { + var svgEl = vNode.elm; + var width = imageWidth_1 || img.width; + var height = imageHeight_1 || img.height; + if (vNode.tag === 'pattern') { + if (repeatX) { + height = 1; + width /= boundingRect.width; + } + else if (repeatY) { + width = 1; + height /= boundingRect.height; + } + } + vNode.attrs.width = width; + vNode.attrs.height = height; + if (svgEl) { + svgEl.setAttribute('width', width); + svgEl.setAttribute('height', height); + } + } + }; + var createdImage = createOrUpdateImage(imageSrc, null, el, function (img) { + noRepeat || setSizeToVNode_1(patternVNode, img); + setSizeToVNode_1(child, img); + }); + if (createdImage && createdImage.width && createdImage.height) { + imageWidth_1 = imageWidth_1 || createdImage.width; + imageHeight_1 = imageHeight_1 || createdImage.height; + } + } + child = createVNode('image', 'img', { + href: imageSrc, + width: imageWidth_1, + height: imageHeight_1 + }); + patternAttrs.width = imageWidth_1; + patternAttrs.height = imageHeight_1; + } + else if (val.svgElement) { + child = clone(val.svgElement); + patternAttrs.width = val.svgWidth; + patternAttrs.height = val.svgHeight; + } + if (!child) { + return; + } + var patternWidth; + var patternHeight; + if (noRepeat) { + patternWidth = patternHeight = 1; + } + else if (repeatX) { + patternHeight = 1; + patternWidth = patternAttrs.width / boundingRect.width; + } + else if (repeatY) { + patternWidth = 1; + patternHeight = patternAttrs.height / boundingRect.height; + } + else { + patternAttrs.patternUnits = 'userSpaceOnUse'; + } + if (patternWidth != null && !isNaN(patternWidth)) { + patternAttrs.width = patternWidth; + } + if (patternHeight != null && !isNaN(patternHeight)) { + patternAttrs.height = patternHeight; + } + var patternTransform = getSRTTransformString(val); + patternTransform && (patternAttrs.patternTransform = patternTransform); + var patternVNode = createVNode('pattern', '', patternAttrs, [child]); + var patternKey = vNodeToString(patternVNode); + var patternCache = scope.patternCache; + var patternId = patternCache[patternKey]; + if (!patternId) { + patternId = scope.zrId + '-p' + scope.patternIdx++; + patternCache[patternKey] = patternId; + patternAttrs.id = patternId; + patternVNode = scope.defs[patternId] = createVNode('pattern', patternId, patternAttrs, [child]); + } + attrs[target] = getIdURL(patternId); + } + function setClipPath(clipPath, attrs, scope) { + var clipPathCache = scope.clipPathCache, defs = scope.defs; + var clipPathId = clipPathCache[clipPath.id]; + if (!clipPathId) { + clipPathId = scope.zrId + '-c' + scope.clipPathIdx++; + var clipPathAttrs = { + id: clipPathId + }; + clipPathCache[clipPath.id] = clipPathId; + defs[clipPathId] = createVNode('clipPath', clipPathId, clipPathAttrs, [brushSVGPath(clipPath, scope)]); + } + attrs['clip-path'] = getIdURL(clipPathId); + } + + function createTextNode(text) { + return document.createTextNode(text); + } + function insertBefore(parentNode, newNode, referenceNode) { + parentNode.insertBefore(newNode, referenceNode); + } + function removeChild(node, child) { + node.removeChild(child); + } + function appendChild(node, child) { + node.appendChild(child); + } + function parentNode(node) { + return node.parentNode; + } + function nextSibling(node) { + return node.nextSibling; + } + function setTextContent(node, text) { + node.textContent = text; + } + + var colonChar = 58; + var xChar = 120; + var emptyNode = createVNode('', ''); + function isUndef(s) { + return s === undefined; + } + function isDef(s) { + return s !== undefined; + } + function createKeyToOldIdx(children, beginIdx, endIdx) { + var map = {}; + for (var i = beginIdx; i <= endIdx; ++i) { + var key = children[i].key; + if (key !== undefined) { + if ("development" !== 'production') { + if (map[key] != null) { + console.error("Duplicate key " + key); + } + } + map[key] = i; + } + } + return map; + } + function sameVnode(vnode1, vnode2) { + var isSameKey = vnode1.key === vnode2.key; + var isSameTag = vnode1.tag === vnode2.tag; + return isSameTag && isSameKey; + } + function createElm(vnode) { + var i; + var children = vnode.children; + var tag = vnode.tag; + if (isDef(tag)) { + var elm = (vnode.elm = createElement(tag)); + updateAttrs(emptyNode, vnode); + if (isArray(children)) { + for (i = 0; i < children.length; ++i) { + var ch = children[i]; + if (ch != null) { + appendChild(elm, createElm(ch)); + } + } + } + else if (isDef(vnode.text) && !isObject(vnode.text)) { + appendChild(elm, createTextNode(vnode.text)); + } + } + else { + vnode.elm = createTextNode(vnode.text); + } + return vnode.elm; + } + function addVnodes(parentElm, before, vnodes, startIdx, endIdx) { + for (; startIdx <= endIdx; ++startIdx) { + var ch = vnodes[startIdx]; + if (ch != null) { + insertBefore(parentElm, createElm(ch), before); + } + } + } + function removeVnodes(parentElm, vnodes, startIdx, endIdx) { + for (; startIdx <= endIdx; ++startIdx) { + var ch = vnodes[startIdx]; + if (ch != null) { + if (isDef(ch.tag)) { + var parent_1 = parentNode(ch.elm); + removeChild(parent_1, ch.elm); + } + else { + removeChild(parentElm, ch.elm); + } + } + } + } + function updateAttrs(oldVnode, vnode) { + var key; + var elm = vnode.elm; + var oldAttrs = oldVnode && oldVnode.attrs || {}; + var attrs = vnode.attrs || {}; + if (oldAttrs === attrs) { + return; + } + for (key in attrs) { + var cur = attrs[key]; + var old = oldAttrs[key]; + if (old !== cur) { + if (cur === true) { + elm.setAttribute(key, ''); + } + else if (cur === false) { + elm.removeAttribute(key); + } + else { + if (key === 'style') { + elm.style.cssText = cur; + } + else if (key.charCodeAt(0) !== xChar) { + elm.setAttribute(key, cur); + } + else if (key === 'xmlns:xlink' || key === 'xmlns') { + elm.setAttributeNS(XMLNS, key, cur); + } + else if (key.charCodeAt(3) === colonChar) { + elm.setAttributeNS(XML_NAMESPACE, key, cur); + } + else if (key.charCodeAt(5) === colonChar) { + elm.setAttributeNS(XLINKNS, key, cur); + } + else { + elm.setAttribute(key, cur); + } + } + } + } + for (key in oldAttrs) { + if (!(key in attrs)) { + elm.removeAttribute(key); + } + } + } + function updateChildren(parentElm, oldCh, newCh) { + var oldStartIdx = 0; + var newStartIdx = 0; + var oldEndIdx = oldCh.length - 1; + var oldStartVnode = oldCh[0]; + var oldEndVnode = oldCh[oldEndIdx]; + var newEndIdx = newCh.length - 1; + var newStartVnode = newCh[0]; + var newEndVnode = newCh[newEndIdx]; + var oldKeyToIdx; + var idxInOld; + var elmToMove; + var before; + while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { + if (oldStartVnode == null) { + oldStartVnode = oldCh[++oldStartIdx]; + } + else if (oldEndVnode == null) { + oldEndVnode = oldCh[--oldEndIdx]; + } + else if (newStartVnode == null) { + newStartVnode = newCh[++newStartIdx]; + } + else if (newEndVnode == null) { + newEndVnode = newCh[--newEndIdx]; + } + else if (sameVnode(oldStartVnode, newStartVnode)) { + patchVnode(oldStartVnode, newStartVnode); + oldStartVnode = oldCh[++oldStartIdx]; + newStartVnode = newCh[++newStartIdx]; + } + else if (sameVnode(oldEndVnode, newEndVnode)) { + patchVnode(oldEndVnode, newEndVnode); + oldEndVnode = oldCh[--oldEndIdx]; + newEndVnode = newCh[--newEndIdx]; + } + else if (sameVnode(oldStartVnode, newEndVnode)) { + patchVnode(oldStartVnode, newEndVnode); + insertBefore(parentElm, oldStartVnode.elm, nextSibling(oldEndVnode.elm)); + oldStartVnode = oldCh[++oldStartIdx]; + newEndVnode = newCh[--newEndIdx]; + } + else if (sameVnode(oldEndVnode, newStartVnode)) { + patchVnode(oldEndVnode, newStartVnode); + insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); + oldEndVnode = oldCh[--oldEndIdx]; + newStartVnode = newCh[++newStartIdx]; + } + else { + if (isUndef(oldKeyToIdx)) { + oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); + } + idxInOld = oldKeyToIdx[newStartVnode.key]; + if (isUndef(idxInOld)) { + insertBefore(parentElm, createElm(newStartVnode), oldStartVnode.elm); + } + else { + elmToMove = oldCh[idxInOld]; + if (elmToMove.tag !== newStartVnode.tag) { + insertBefore(parentElm, createElm(newStartVnode), oldStartVnode.elm); + } + else { + patchVnode(elmToMove, newStartVnode); + oldCh[idxInOld] = undefined; + insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm); + } + } + newStartVnode = newCh[++newStartIdx]; + } + } + if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) { + if (oldStartIdx > oldEndIdx) { + before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm; + addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx); + } + else { + removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); + } + } + } + function patchVnode(oldVnode, vnode) { + var elm = (vnode.elm = oldVnode.elm); + var oldCh = oldVnode.children; + var ch = vnode.children; + if (oldVnode === vnode) { + return; + } + updateAttrs(oldVnode, vnode); + if (isUndef(vnode.text)) { + if (isDef(oldCh) && isDef(ch)) { + if (oldCh !== ch) { + updateChildren(elm, oldCh, ch); + } + } + else if (isDef(ch)) { + if (isDef(oldVnode.text)) { + setTextContent(elm, ''); + } + addVnodes(elm, null, ch, 0, ch.length - 1); + } + else if (isDef(oldCh)) { + removeVnodes(elm, oldCh, 0, oldCh.length - 1); + } + else if (isDef(oldVnode.text)) { + setTextContent(elm, ''); + } + } + else if (oldVnode.text !== vnode.text) { + if (isDef(oldCh)) { + removeVnodes(elm, oldCh, 0, oldCh.length - 1); + } + setTextContent(elm, vnode.text); + } + } + function patch(oldVnode, vnode) { + if (sameVnode(oldVnode, vnode)) { + patchVnode(oldVnode, vnode); + } + else { + var elm = oldVnode.elm; + var parent_2 = parentNode(elm); + createElm(vnode); + if (parent_2 !== null) { + insertBefore(parent_2, vnode.elm, nextSibling(elm)); + removeVnodes(parent_2, [oldVnode], 0, 0); + } + } + return vnode; + } + + var svgId = 0; + var SVGPainter = (function () { + function SVGPainter(root, storage, opts) { + this.type = 'svg'; + this.refreshHover = createMethodNotSupport('refreshHover'); + this.configLayer = createMethodNotSupport('configLayer'); + this.storage = storage; + this._opts = opts = extend({}, opts); + this.root = root; + this._id = 'zr' + svgId++; + this._oldVNode = createSVGVNode(opts.width, opts.height); + if (root && !opts.ssr) { + var viewport = this._viewport = document.createElement('div'); + viewport.style.cssText = 'position:relative;overflow:hidden'; + var svgDom = this._svgDom = this._oldVNode.elm = createElement('svg'); + updateAttrs(null, this._oldVNode); + viewport.appendChild(svgDom); + root.appendChild(viewport); + } + this.resize(opts.width, opts.height); + } + SVGPainter.prototype.getType = function () { + return this.type; + }; + SVGPainter.prototype.getViewportRoot = function () { + return this._viewport; + }; + SVGPainter.prototype.getViewportRootOffset = function () { + var viewportRoot = this.getViewportRoot(); + if (viewportRoot) { + return { + offsetLeft: viewportRoot.offsetLeft || 0, + offsetTop: viewportRoot.offsetTop || 0 + }; + } + }; + SVGPainter.prototype.getSvgDom = function () { + return this._svgDom; + }; + SVGPainter.prototype.refresh = function () { + if (this.root) { + var vnode = this.renderToVNode({ + willUpdate: true + }); + vnode.attrs.style = 'position:absolute;left:0;top:0;user-select:none'; + patch(this._oldVNode, vnode); + this._oldVNode = vnode; + } + }; + SVGPainter.prototype.renderOneToVNode = function (el) { + return brush$1(el, createBrushScope(this._id)); + }; + SVGPainter.prototype.renderToVNode = function (opts) { + opts = opts || {}; + var list = this.storage.getDisplayList(true); + var width = this._width; + var height = this._height; + var scope = createBrushScope(this._id); + scope.animation = opts.animation; + scope.willUpdate = opts.willUpdate; + scope.compress = opts.compress; + scope.emphasis = opts.emphasis; + var children = []; + var bgVNode = this._bgVNode = createBackgroundVNode(width, height, this._backgroundColor, scope); + bgVNode && children.push(bgVNode); + var mainVNode = !opts.compress + ? (this._mainVNode = createVNode('g', 'main', {}, [])) : null; + this._paintList(list, scope, mainVNode ? mainVNode.children : children); + mainVNode && children.push(mainVNode); + var defs = map(keys(scope.defs), function (id) { return scope.defs[id]; }); + if (defs.length) { + children.push(createVNode('defs', 'defs', {}, defs)); + } + if (opts.animation) { + var animationCssStr = getCssString(scope.cssNodes, scope.cssAnims, { newline: true }); + if (animationCssStr) { + var styleNode = createVNode('style', 'stl', {}, [], animationCssStr); + children.push(styleNode); + } + } + return createSVGVNode(width, height, children, opts.useViewBox); + }; + SVGPainter.prototype.renderToString = function (opts) { + opts = opts || {}; + return vNodeToString(this.renderToVNode({ + animation: retrieve2(opts.cssAnimation, true), + emphasis: retrieve2(opts.cssEmphasis, true), + willUpdate: false, + compress: true, + useViewBox: retrieve2(opts.useViewBox, true) + }), { newline: true }); + }; + SVGPainter.prototype.setBackgroundColor = function (backgroundColor) { + this._backgroundColor = backgroundColor; + }; + SVGPainter.prototype.getSvgRoot = function () { + return this._mainVNode && this._mainVNode.elm; + }; + SVGPainter.prototype._paintList = function (list, scope, out) { + var listLen = list.length; + var clipPathsGroupsStack = []; + var clipPathsGroupsStackDepth = 0; + var currentClipPathGroup; + var prevClipPaths; + var clipGroupNodeIdx = 0; + for (var i = 0; i < listLen; i++) { + var displayable = list[i]; + if (!displayable.invisible) { + var clipPaths = displayable.__clipPaths; + var len = clipPaths && clipPaths.length || 0; + var prevLen = prevClipPaths && prevClipPaths.length || 0; + var lca = void 0; + for (lca = Math.max(len - 1, prevLen - 1); lca >= 0; lca--) { + if (clipPaths && prevClipPaths + && clipPaths[lca] === prevClipPaths[lca]) { + break; + } + } + for (var i_1 = prevLen - 1; i_1 > lca; i_1--) { + clipPathsGroupsStackDepth--; + currentClipPathGroup = clipPathsGroupsStack[clipPathsGroupsStackDepth - 1]; + } + for (var i_2 = lca + 1; i_2 < len; i_2++) { + var groupAttrs = {}; + setClipPath(clipPaths[i_2], groupAttrs, scope); + var g = createVNode('g', 'clip-g-' + clipGroupNodeIdx++, groupAttrs, []); + (currentClipPathGroup ? currentClipPathGroup.children : out).push(g); + clipPathsGroupsStack[clipPathsGroupsStackDepth++] = g; + currentClipPathGroup = g; + } + prevClipPaths = clipPaths; + var ret = brush$1(displayable, scope); + if (ret) { + (currentClipPathGroup ? currentClipPathGroup.children : out).push(ret); + } + } + } + }; + SVGPainter.prototype.resize = function (width, height) { + var opts = this._opts; + var root = this.root; + var viewport = this._viewport; + width != null && (opts.width = width); + height != null && (opts.height = height); + if (root && viewport) { + viewport.style.display = 'none'; + width = getSize(root, 0, opts); + height = getSize(root, 1, opts); + viewport.style.display = ''; + } + if (this._width !== width || this._height !== height) { + this._width = width; + this._height = height; + if (viewport) { + var viewportStyle = viewport.style; + viewportStyle.width = width + 'px'; + viewportStyle.height = height + 'px'; + } + if (!isPattern(this._backgroundColor)) { + var svgDom = this._svgDom; + if (svgDom) { + svgDom.setAttribute('width', width); + svgDom.setAttribute('height', height); + } + var bgEl = this._bgVNode && this._bgVNode.elm; + if (bgEl) { + bgEl.setAttribute('width', width); + bgEl.setAttribute('height', height); + } + } + else { + this.refresh(); + } + } + }; + SVGPainter.prototype.getWidth = function () { + return this._width; + }; + SVGPainter.prototype.getHeight = function () { + return this._height; + }; + SVGPainter.prototype.dispose = function () { + if (this.root) { + this.root.innerHTML = ''; + } + this._svgDom = + this._viewport = + this.storage = + this._oldVNode = + this._bgVNode = + this._mainVNode = null; + }; + SVGPainter.prototype.clear = function () { + if (this._svgDom) { + this._svgDom.innerHTML = null; + } + this._oldVNode = null; + }; + SVGPainter.prototype.toDataURL = function (base64) { + var str = this.renderToString(); + var prefix = 'data:image/svg+xml;'; + if (base64) { + str = encodeBase64(str); + return str && prefix + 'base64,' + str; + } + return prefix + 'charset=UTF-8,' + encodeURIComponent(str); + }; + return SVGPainter; + }()); + function createMethodNotSupport(method) { + return function () { + if ("development" !== 'production') { + logError('In SVG mode painter not support method "' + method + '"'); + } + }; + } + function createBackgroundVNode(width, height, backgroundColor, scope) { + var bgVNode; + if (backgroundColor && backgroundColor !== 'none') { + bgVNode = createVNode('rect', 'bg', { + width: width, + height: height, + x: '0', + y: '0' + }); + if (isGradient(backgroundColor)) { + setGradient({ fill: backgroundColor }, bgVNode.attrs, 'fill', scope); + } + else if (isPattern(backgroundColor)) { + setPattern({ + style: { + fill: backgroundColor + }, + dirty: noop, + getBoundingRect: function () { return ({ width: width, height: height }); } + }, bgVNode.attrs, 'fill', scope); + } + else { + var _a = normalizeColor(backgroundColor), color = _a.color, opacity = _a.opacity; + bgVNode.attrs.fill = color; + opacity < 1 && (bgVNode.attrs['fill-opacity'] = opacity); + } + } + return bgVNode; + } + + function install(registers) { + registers.registerPainter('svg', SVGPainter); + } + + function createDom(id, painter, dpr) { + var newDom = platformApi.createCanvas(); + var width = painter.getWidth(); + var height = painter.getHeight(); + var newDomStyle = newDom.style; + if (newDomStyle) { + newDomStyle.position = 'absolute'; + newDomStyle.left = '0'; + newDomStyle.top = '0'; + newDomStyle.width = width + 'px'; + newDomStyle.height = height + 'px'; + newDom.setAttribute('data-zr-dom-id', id); + } + newDom.width = width * dpr; + newDom.height = height * dpr; + return newDom; + } + var Layer = (function (_super) { + __extends(Layer, _super); + function Layer(id, painter, dpr) { + var _this = _super.call(this) || this; + _this.motionBlur = false; + _this.lastFrameAlpha = 0.7; + _this.dpr = 1; + _this.virtual = false; + _this.config = {}; + _this.incremental = false; + _this.zlevel = 0; + _this.maxRepaintRectCount = 5; + _this.__dirty = true; + _this.__firstTimePaint = true; + _this.__used = false; + _this.__drawIndex = 0; + _this.__startIndex = 0; + _this.__endIndex = 0; + _this.__prevStartIndex = null; + _this.__prevEndIndex = null; + var dom; + dpr = dpr || devicePixelRatio; + if (typeof id === 'string') { + dom = createDom(id, painter, dpr); + } + else if (isObject(id)) { + dom = id; + id = dom.id; + } + _this.id = id; + _this.dom = dom; + var domStyle = dom.style; + if (domStyle) { + disableUserSelect(dom); + dom.onselectstart = function () { return false; }; + domStyle.padding = '0'; + domStyle.margin = '0'; + domStyle.borderWidth = '0'; + } + _this.painter = painter; + _this.dpr = dpr; + return _this; + } + Layer.prototype.getElementCount = function () { + return this.__endIndex - this.__startIndex; + }; + Layer.prototype.afterBrush = function () { + this.__prevStartIndex = this.__startIndex; + this.__prevEndIndex = this.__endIndex; + }; + Layer.prototype.initContext = function () { + this.ctx = this.dom.getContext('2d'); + this.ctx.dpr = this.dpr; + }; + Layer.prototype.setUnpainted = function () { + this.__firstTimePaint = true; + }; + Layer.prototype.createBackBuffer = function () { + var dpr = this.dpr; + this.domBack = createDom('back-' + this.id, this.painter, dpr); + this.ctxBack = this.domBack.getContext('2d'); + if (dpr !== 1) { + this.ctxBack.scale(dpr, dpr); + } + }; + Layer.prototype.createRepaintRects = function (displayList, prevList, viewWidth, viewHeight) { + if (this.__firstTimePaint) { + this.__firstTimePaint = false; + return null; + } + var mergedRepaintRects = []; + var maxRepaintRectCount = this.maxRepaintRectCount; + var full = false; + var pendingRect = new BoundingRect(0, 0, 0, 0); + function addRectToMergePool(rect) { + if (!rect.isFinite() || rect.isZero()) { + return; + } + if (mergedRepaintRects.length === 0) { + var boundingRect = new BoundingRect(0, 0, 0, 0); + boundingRect.copy(rect); + mergedRepaintRects.push(boundingRect); + } + else { + var isMerged = false; + var minDeltaArea = Infinity; + var bestRectToMergeIdx = 0; + for (var i = 0; i < mergedRepaintRects.length; ++i) { + var mergedRect = mergedRepaintRects[i]; + if (mergedRect.intersect(rect)) { + var pendingRect_1 = new BoundingRect(0, 0, 0, 0); + pendingRect_1.copy(mergedRect); + pendingRect_1.union(rect); + mergedRepaintRects[i] = pendingRect_1; + isMerged = true; + break; + } + else if (full) { + pendingRect.copy(rect); + pendingRect.union(mergedRect); + var aArea = rect.width * rect.height; + var bArea = mergedRect.width * mergedRect.height; + var pendingArea = pendingRect.width * pendingRect.height; + var deltaArea = pendingArea - aArea - bArea; + if (deltaArea < minDeltaArea) { + minDeltaArea = deltaArea; + bestRectToMergeIdx = i; + } + } + } + if (full) { + mergedRepaintRects[bestRectToMergeIdx].union(rect); + isMerged = true; + } + if (!isMerged) { + var boundingRect = new BoundingRect(0, 0, 0, 0); + boundingRect.copy(rect); + mergedRepaintRects.push(boundingRect); + } + if (!full) { + full = mergedRepaintRects.length >= maxRepaintRectCount; + } + } + } + for (var i = this.__startIndex; i < this.__endIndex; ++i) { + var el = displayList[i]; + if (el) { + var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true); + var prevRect = el.__isRendered && ((el.__dirty & REDRAW_BIT) || !shouldPaint) + ? el.getPrevPaintRect() + : null; + if (prevRect) { + addRectToMergePool(prevRect); + } + var curRect = shouldPaint && ((el.__dirty & REDRAW_BIT) || !el.__isRendered) + ? el.getPaintRect() + : null; + if (curRect) { + addRectToMergePool(curRect); + } + } + } + for (var i = this.__prevStartIndex; i < this.__prevEndIndex; ++i) { + var el = prevList[i]; + var shouldPaint = el && el.shouldBePainted(viewWidth, viewHeight, true, true); + if (el && (!shouldPaint || !el.__zr) && el.__isRendered) { + var prevRect = el.getPrevPaintRect(); + if (prevRect) { + addRectToMergePool(prevRect); + } + } + } + var hasIntersections; + do { + hasIntersections = false; + for (var i = 0; i < mergedRepaintRects.length;) { + if (mergedRepaintRects[i].isZero()) { + mergedRepaintRects.splice(i, 1); + continue; + } + for (var j = i + 1; j < mergedRepaintRects.length;) { + if (mergedRepaintRects[i].intersect(mergedRepaintRects[j])) { + hasIntersections = true; + mergedRepaintRects[i].union(mergedRepaintRects[j]); + mergedRepaintRects.splice(j, 1); + } + else { + j++; + } + } + i++; + } + } while (hasIntersections); + this._paintRects = mergedRepaintRects; + return mergedRepaintRects; + }; + Layer.prototype.debugGetPaintRects = function () { + return (this._paintRects || []).slice(); + }; + Layer.prototype.resize = function (width, height) { + var dpr = this.dpr; + var dom = this.dom; + var domStyle = dom.style; + var domBack = this.domBack; + if (domStyle) { + domStyle.width = width + 'px'; + domStyle.height = height + 'px'; + } + dom.width = width * dpr; + dom.height = height * dpr; + if (domBack) { + domBack.width = width * dpr; + domBack.height = height * dpr; + if (dpr !== 1) { + this.ctxBack.scale(dpr, dpr); + } + } + }; + Layer.prototype.clear = function (clearAll, clearColor, repaintRects) { + var dom = this.dom; + var ctx = this.ctx; + var width = dom.width; + var height = dom.height; + clearColor = clearColor || this.clearColor; + var haveMotionBLur = this.motionBlur && !clearAll; + var lastFrameAlpha = this.lastFrameAlpha; + var dpr = this.dpr; + var self = this; + if (haveMotionBLur) { + if (!this.domBack) { + this.createBackBuffer(); + } + this.ctxBack.globalCompositeOperation = 'copy'; + this.ctxBack.drawImage(dom, 0, 0, width / dpr, height / dpr); + } + var domBack = this.domBack; + function doClear(x, y, width, height) { + ctx.clearRect(x, y, width, height); + if (clearColor && clearColor !== 'transparent') { + var clearColorGradientOrPattern = void 0; + if (isGradientObject(clearColor)) { + var shouldCache = clearColor.global || (clearColor.__width === width + && clearColor.__height === height); + clearColorGradientOrPattern = shouldCache + && clearColor.__canvasGradient + || getCanvasGradient(ctx, clearColor, { + x: 0, + y: 0, + width: width, + height: height + }); + clearColor.__canvasGradient = clearColorGradientOrPattern; + clearColor.__width = width; + clearColor.__height = height; + } + else if (isImagePatternObject(clearColor)) { + clearColor.scaleX = clearColor.scaleX || dpr; + clearColor.scaleY = clearColor.scaleY || dpr; + clearColorGradientOrPattern = createCanvasPattern(ctx, clearColor, { + dirty: function () { + self.setUnpainted(); + self.painter.refresh(); + } + }); + } + ctx.save(); + ctx.fillStyle = clearColorGradientOrPattern || clearColor; + ctx.fillRect(x, y, width, height); + ctx.restore(); + } + if (haveMotionBLur) { + ctx.save(); + ctx.globalAlpha = lastFrameAlpha; + ctx.drawImage(domBack, x, y, width, height); + ctx.restore(); + } + } + if (!repaintRects || haveMotionBLur) { + doClear(0, 0, width, height); + } + else if (repaintRects.length) { + each(repaintRects, function (rect) { + doClear(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr); + }); + } + }; + return Layer; + }(Eventful)); + + var HOVER_LAYER_ZLEVEL = 1e5; + var CANVAS_ZLEVEL = 314159; + var EL_AFTER_INCREMENTAL_INC = 0.01; + var INCREMENTAL_INC = 0.001; + function isLayerValid(layer) { + if (!layer) { + return false; + } + if (layer.__builtin__) { + return true; + } + if (typeof (layer.resize) !== 'function' + || typeof (layer.refresh) !== 'function') { + return false; + } + return true; + } + function createRoot(width, height) { + var domRoot = document.createElement('div'); + domRoot.style.cssText = [ + 'position:relative', + 'width:' + width + 'px', + 'height:' + height + 'px', + 'padding:0', + 'margin:0', + 'border-width:0' + ].join(';') + ';'; + return domRoot; + } + var CanvasPainter = (function () { + function CanvasPainter(root, storage, opts, id) { + this.type = 'canvas'; + this._zlevelList = []; + this._prevDisplayList = []; + this._layers = {}; + this._layerConfig = {}; + this._needsManuallyCompositing = false; + this.type = 'canvas'; + var singleCanvas = !root.nodeName + || root.nodeName.toUpperCase() === 'CANVAS'; + this._opts = opts = extend({}, opts || {}); + this.dpr = opts.devicePixelRatio || devicePixelRatio; + this._singleCanvas = singleCanvas; + this.root = root; + var rootStyle = root.style; + if (rootStyle) { + disableUserSelect(root); + root.innerHTML = ''; + } + this.storage = storage; + var zlevelList = this._zlevelList; + this._prevDisplayList = []; + var layers = this._layers; + if (!singleCanvas) { + this._width = getSize(root, 0, opts); + this._height = getSize(root, 1, opts); + var domRoot = this._domRoot = createRoot(this._width, this._height); + root.appendChild(domRoot); + } + else { + var rootCanvas = root; + var width = rootCanvas.width; + var height = rootCanvas.height; + if (opts.width != null) { + width = opts.width; + } + if (opts.height != null) { + height = opts.height; + } + this.dpr = opts.devicePixelRatio || 1; + rootCanvas.width = width * this.dpr; + rootCanvas.height = height * this.dpr; + this._width = width; + this._height = height; + var mainLayer = new Layer(rootCanvas, this, this.dpr); + mainLayer.__builtin__ = true; + mainLayer.initContext(); + layers[CANVAS_ZLEVEL] = mainLayer; + mainLayer.zlevel = CANVAS_ZLEVEL; + zlevelList.push(CANVAS_ZLEVEL); + this._domRoot = root; + } + } + CanvasPainter.prototype.getType = function () { + return 'canvas'; + }; + CanvasPainter.prototype.isSingleCanvas = function () { + return this._singleCanvas; + }; + CanvasPainter.prototype.getViewportRoot = function () { + return this._domRoot; + }; + CanvasPainter.prototype.getViewportRootOffset = function () { + var viewportRoot = this.getViewportRoot(); + if (viewportRoot) { + return { + offsetLeft: viewportRoot.offsetLeft || 0, + offsetTop: viewportRoot.offsetTop || 0 + }; + } + }; + CanvasPainter.prototype.refresh = function (paintAll) { + var list = this.storage.getDisplayList(true); + var prevList = this._prevDisplayList; + var zlevelList = this._zlevelList; + this._redrawId = Math.random(); + this._paintList(list, prevList, paintAll, this._redrawId); + for (var i = 0; i < zlevelList.length; i++) { + var z = zlevelList[i]; + var layer = this._layers[z]; + if (!layer.__builtin__ && layer.refresh) { + var clearColor = i === 0 ? this._backgroundColor : null; + layer.refresh(clearColor); + } + } + if (this._opts.useDirtyRect) { + this._prevDisplayList = list.slice(); + } + return this; + }; + CanvasPainter.prototype.refreshHover = function () { + this._paintHoverList(this.storage.getDisplayList(false)); + }; + CanvasPainter.prototype._paintHoverList = function (list) { + var len = list.length; + var hoverLayer = this._hoverlayer; + hoverLayer && hoverLayer.clear(); + if (!len) { + return; + } + var scope = { + inHover: true, + viewWidth: this._width, + viewHeight: this._height + }; + var ctx; + for (var i = 0; i < len; i++) { + var el = list[i]; + if (el.__inHover) { + if (!hoverLayer) { + hoverLayer = this._hoverlayer = this.getLayer(HOVER_LAYER_ZLEVEL); + } + if (!ctx) { + ctx = hoverLayer.ctx; + ctx.save(); + } + brush(ctx, el, scope, i === len - 1); + } + } + if (ctx) { + ctx.restore(); + } + }; + CanvasPainter.prototype.getHoverLayer = function () { + return this.getLayer(HOVER_LAYER_ZLEVEL); + }; + CanvasPainter.prototype.paintOne = function (ctx, el) { + brushSingle(ctx, el); + }; + CanvasPainter.prototype._paintList = function (list, prevList, paintAll, redrawId) { + if (this._redrawId !== redrawId) { + return; + } + paintAll = paintAll || false; + this._updateLayerStatus(list); + var _a = this._doPaintList(list, prevList, paintAll), finished = _a.finished, needsRefreshHover = _a.needsRefreshHover; + if (this._needsManuallyCompositing) { + this._compositeManually(); + } + if (needsRefreshHover) { + this._paintHoverList(list); + } + if (!finished) { + var self_1 = this; + requestAnimationFrame$1(function () { + self_1._paintList(list, prevList, paintAll, redrawId); + }); + } + else { + this.eachLayer(function (layer) { + layer.afterBrush && layer.afterBrush(); + }); + } + }; + CanvasPainter.prototype._compositeManually = function () { + var ctx = this.getLayer(CANVAS_ZLEVEL).ctx; + var width = this._domRoot.width; + var height = this._domRoot.height; + ctx.clearRect(0, 0, width, height); + this.eachBuiltinLayer(function (layer) { + if (layer.virtual) { + ctx.drawImage(layer.dom, 0, 0, width, height); + } + }); + }; + CanvasPainter.prototype._doPaintList = function (list, prevList, paintAll) { + var _this = this; + var layerList = []; + var useDirtyRect = this._opts.useDirtyRect; + for (var zi = 0; zi < this._zlevelList.length; zi++) { + var zlevel = this._zlevelList[zi]; + var layer = this._layers[zlevel]; + if (layer.__builtin__ + && layer !== this._hoverlayer + && (layer.__dirty || paintAll)) { + layerList.push(layer); + } + } + var finished = true; + var needsRefreshHover = false; + var _loop_1 = function (k) { + var layer = layerList[k]; + var ctx = layer.ctx; + var repaintRects = useDirtyRect + && layer.createRepaintRects(list, prevList, this_1._width, this_1._height); + var start = paintAll ? layer.__startIndex : layer.__drawIndex; + var useTimer = !paintAll && layer.incremental && Date.now; + var startTime = useTimer && Date.now(); + var clearColor = layer.zlevel === this_1._zlevelList[0] + ? this_1._backgroundColor : null; + if (layer.__startIndex === layer.__endIndex) { + layer.clear(false, clearColor, repaintRects); + } + else if (start === layer.__startIndex) { + var firstEl = list[start]; + if (!firstEl.incremental || !firstEl.notClear || paintAll) { + layer.clear(false, clearColor, repaintRects); + } + } + if (start === -1) { + console.error('For some unknown reason. drawIndex is -1'); + start = layer.__startIndex; + } + var i; + var repaint = function (repaintRect) { + var scope = { + inHover: false, + allClipped: false, + prevEl: null, + viewWidth: _this._width, + viewHeight: _this._height + }; + for (i = start; i < layer.__endIndex; i++) { + var el = list[i]; + if (el.__inHover) { + needsRefreshHover = true; + } + _this._doPaintEl(el, layer, useDirtyRect, repaintRect, scope, i === layer.__endIndex - 1); + if (useTimer) { + var dTime = Date.now() - startTime; + if (dTime > 15) { + break; + } + } + } + if (scope.prevElClipPaths) { + ctx.restore(); + } + }; + if (repaintRects) { + if (repaintRects.length === 0) { + i = layer.__endIndex; + } + else { + var dpr = this_1.dpr; + for (var r = 0; r < repaintRects.length; ++r) { + var rect = repaintRects[r]; + ctx.save(); + ctx.beginPath(); + ctx.rect(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr); + ctx.clip(); + repaint(rect); + ctx.restore(); + } + } + } + else { + ctx.save(); + repaint(); + ctx.restore(); + } + layer.__drawIndex = i; + if (layer.__drawIndex < layer.__endIndex) { + finished = false; + } + }; + var this_1 = this; + for (var k = 0; k < layerList.length; k++) { + _loop_1(k); + } + if (env.wxa) { + each(this._layers, function (layer) { + if (layer && layer.ctx && layer.ctx.draw) { + layer.ctx.draw(); + } + }); + } + return { + finished: finished, + needsRefreshHover: needsRefreshHover + }; + }; + CanvasPainter.prototype._doPaintEl = function (el, currentLayer, useDirtyRect, repaintRect, scope, isLast) { + var ctx = currentLayer.ctx; + if (useDirtyRect) { + var paintRect = el.getPaintRect(); + if (!repaintRect || paintRect && paintRect.intersect(repaintRect)) { + brush(ctx, el, scope, isLast); + el.setPrevPaintRect(paintRect); + } + } + else { + brush(ctx, el, scope, isLast); + } + }; + CanvasPainter.prototype.getLayer = function (zlevel, virtual) { + if (this._singleCanvas && !this._needsManuallyCompositing) { + zlevel = CANVAS_ZLEVEL; + } + var layer = this._layers[zlevel]; + if (!layer) { + layer = new Layer('zr_' + zlevel, this, this.dpr); + layer.zlevel = zlevel; + layer.__builtin__ = true; + if (this._layerConfig[zlevel]) { + merge(layer, this._layerConfig[zlevel], true); + } + else if (this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC]) { + merge(layer, this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC], true); + } + if (virtual) { + layer.virtual = virtual; + } + this.insertLayer(zlevel, layer); + layer.initContext(); + } + return layer; + }; + CanvasPainter.prototype.insertLayer = function (zlevel, layer) { + var layersMap = this._layers; + var zlevelList = this._zlevelList; + var len = zlevelList.length; + var domRoot = this._domRoot; + var prevLayer = null; + var i = -1; + if (layersMap[zlevel]) { + if ("development" !== 'production') { + logError('ZLevel ' + zlevel + ' has been used already'); + } + return; + } + if (!isLayerValid(layer)) { + if ("development" !== 'production') { + logError('Layer of zlevel ' + zlevel + ' is not valid'); + } + return; + } + if (len > 0 && zlevel > zlevelList[0]) { + for (i = 0; i < len - 1; i++) { + if (zlevelList[i] < zlevel + && zlevelList[i + 1] > zlevel) { + break; + } + } + prevLayer = layersMap[zlevelList[i]]; + } + zlevelList.splice(i + 1, 0, zlevel); + layersMap[zlevel] = layer; + if (!layer.virtual) { + if (prevLayer) { + var prevDom = prevLayer.dom; + if (prevDom.nextSibling) { + domRoot.insertBefore(layer.dom, prevDom.nextSibling); + } + else { + domRoot.appendChild(layer.dom); + } + } + else { + if (domRoot.firstChild) { + domRoot.insertBefore(layer.dom, domRoot.firstChild); + } + else { + domRoot.appendChild(layer.dom); + } + } + } + layer.painter || (layer.painter = this); + }; + CanvasPainter.prototype.eachLayer = function (cb, context) { + var zlevelList = this._zlevelList; + for (var i = 0; i < zlevelList.length; i++) { + var z = zlevelList[i]; + cb.call(context, this._layers[z], z); + } + }; + CanvasPainter.prototype.eachBuiltinLayer = function (cb, context) { + var zlevelList = this._zlevelList; + for (var i = 0; i < zlevelList.length; i++) { + var z = zlevelList[i]; + var layer = this._layers[z]; + if (layer.__builtin__) { + cb.call(context, layer, z); + } + } + }; + CanvasPainter.prototype.eachOtherLayer = function (cb, context) { + var zlevelList = this._zlevelList; + for (var i = 0; i < zlevelList.length; i++) { + var z = zlevelList[i]; + var layer = this._layers[z]; + if (!layer.__builtin__) { + cb.call(context, layer, z); + } + } + }; + CanvasPainter.prototype.getLayers = function () { + return this._layers; + }; + CanvasPainter.prototype._updateLayerStatus = function (list) { + this.eachBuiltinLayer(function (layer, z) { + layer.__dirty = layer.__used = false; + }); + function updatePrevLayer(idx) { + if (prevLayer) { + if (prevLayer.__endIndex !== idx) { + prevLayer.__dirty = true; + } + prevLayer.__endIndex = idx; + } + } + if (this._singleCanvas) { + for (var i_1 = 1; i_1 < list.length; i_1++) { + var el = list[i_1]; + if (el.zlevel !== list[i_1 - 1].zlevel || el.incremental) { + this._needsManuallyCompositing = true; + break; + } + } + } + var prevLayer = null; + var incrementalLayerCount = 0; + var prevZlevel; + var i; + for (i = 0; i < list.length; i++) { + var el = list[i]; + var zlevel = el.zlevel; + var layer = void 0; + if (prevZlevel !== zlevel) { + prevZlevel = zlevel; + incrementalLayerCount = 0; + } + if (el.incremental) { + layer = this.getLayer(zlevel + INCREMENTAL_INC, this._needsManuallyCompositing); + layer.incremental = true; + incrementalLayerCount = 1; + } + else { + layer = this.getLayer(zlevel + (incrementalLayerCount > 0 ? EL_AFTER_INCREMENTAL_INC : 0), this._needsManuallyCompositing); + } + if (!layer.__builtin__) { + logError('ZLevel ' + zlevel + ' has been used by unkown layer ' + layer.id); + } + if (layer !== prevLayer) { + layer.__used = true; + if (layer.__startIndex !== i) { + layer.__dirty = true; + } + layer.__startIndex = i; + if (!layer.incremental) { + layer.__drawIndex = i; + } + else { + layer.__drawIndex = -1; + } + updatePrevLayer(i); + prevLayer = layer; + } + if ((el.__dirty & REDRAW_BIT) && !el.__inHover) { + layer.__dirty = true; + if (layer.incremental && layer.__drawIndex < 0) { + layer.__drawIndex = i; + } + } + } + updatePrevLayer(i); + this.eachBuiltinLayer(function (layer, z) { + if (!layer.__used && layer.getElementCount() > 0) { + layer.__dirty = true; + layer.__startIndex = layer.__endIndex = layer.__drawIndex = 0; + } + if (layer.__dirty && layer.__drawIndex < 0) { + layer.__drawIndex = layer.__startIndex; + } + }); + }; + CanvasPainter.prototype.clear = function () { + this.eachBuiltinLayer(this._clearLayer); + return this; + }; + CanvasPainter.prototype._clearLayer = function (layer) { + layer.clear(); + }; + CanvasPainter.prototype.setBackgroundColor = function (backgroundColor) { + this._backgroundColor = backgroundColor; + each(this._layers, function (layer) { + layer.setUnpainted(); + }); + }; + CanvasPainter.prototype.configLayer = function (zlevel, config) { + if (config) { + var layerConfig = this._layerConfig; + if (!layerConfig[zlevel]) { + layerConfig[zlevel] = config; + } + else { + merge(layerConfig[zlevel], config, true); + } + for (var i = 0; i < this._zlevelList.length; i++) { + var _zlevel = this._zlevelList[i]; + if (_zlevel === zlevel || _zlevel === zlevel + EL_AFTER_INCREMENTAL_INC) { + var layer = this._layers[_zlevel]; + merge(layer, layerConfig[zlevel], true); + } + } + } + }; + CanvasPainter.prototype.delLayer = function (zlevel) { + var layers = this._layers; + var zlevelList = this._zlevelList; + var layer = layers[zlevel]; + if (!layer) { + return; + } + layer.dom.parentNode.removeChild(layer.dom); + delete layers[zlevel]; + zlevelList.splice(indexOf(zlevelList, zlevel), 1); + }; + CanvasPainter.prototype.resize = function (width, height) { + if (!this._domRoot.style) { + if (width == null || height == null) { + return; + } + this._width = width; + this._height = height; + this.getLayer(CANVAS_ZLEVEL).resize(width, height); + } + else { + var domRoot = this._domRoot; + domRoot.style.display = 'none'; + var opts = this._opts; + var root = this.root; + width != null && (opts.width = width); + height != null && (opts.height = height); + width = getSize(root, 0, opts); + height = getSize(root, 1, opts); + domRoot.style.display = ''; + if (this._width !== width || height !== this._height) { + domRoot.style.width = width + 'px'; + domRoot.style.height = height + 'px'; + for (var id in this._layers) { + if (this._layers.hasOwnProperty(id)) { + this._layers[id].resize(width, height); + } + } + this.refresh(true); + } + this._width = width; + this._height = height; + } + return this; + }; + CanvasPainter.prototype.clearLayer = function (zlevel) { + var layer = this._layers[zlevel]; + if (layer) { + layer.clear(); + } + }; + CanvasPainter.prototype.dispose = function () { + this.root.innerHTML = ''; + this.root = + this.storage = + this._domRoot = + this._layers = null; + }; + CanvasPainter.prototype.getRenderedCanvas = function (opts) { + opts = opts || {}; + if (this._singleCanvas && !this._compositeManually) { + return this._layers[CANVAS_ZLEVEL].dom; + } + var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr); + imageLayer.initContext(); + imageLayer.clear(false, opts.backgroundColor || this._backgroundColor); + var ctx = imageLayer.ctx; + if (opts.pixelRatio <= this.dpr) { + this.refresh(); + var width_1 = imageLayer.dom.width; + var height_1 = imageLayer.dom.height; + this.eachLayer(function (layer) { + if (layer.__builtin__) { + ctx.drawImage(layer.dom, 0, 0, width_1, height_1); + } + else if (layer.renderToCanvas) { + ctx.save(); + layer.renderToCanvas(ctx); + ctx.restore(); + } + }); + } + else { + var scope = { + inHover: false, + viewWidth: this._width, + viewHeight: this._height + }; + var displayList = this.storage.getDisplayList(true); + for (var i = 0, len = displayList.length; i < len; i++) { + var el = displayList[i]; + brush(ctx, el, scope, i === len - 1); + } + } + return imageLayer.dom; + }; + CanvasPainter.prototype.getWidth = function () { + return this._width; + }; + CanvasPainter.prototype.getHeight = function () { + return this._height; + }; + return CanvasPainter; + }()); + + function install$1(registers) { + registers.registerPainter('canvas', CanvasPainter); + } + + var LineSeriesModel = /** @class */function (_super) { + __extends(LineSeriesModel, _super); + function LineSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = LineSeriesModel.type; + _this.hasSymbolVisual = true; + return _this; + } + LineSeriesModel.prototype.getInitialData = function (option) { + if ("development" !== 'production') { + var coordSys = option.coordinateSystem; + if (coordSys !== 'polar' && coordSys !== 'cartesian2d') { + throw new Error('Line not support coordinateSystem besides cartesian and polar'); + } + } + return createSeriesData(null, this, { + useEncodeDefaulter: true + }); + }; + LineSeriesModel.prototype.getLegendIcon = function (opt) { + var group = new Group(); + var line = createSymbol('line', 0, opt.itemHeight / 2, opt.itemWidth, 0, opt.lineStyle.stroke, false); + group.add(line); + line.setStyle(opt.lineStyle); + var visualType = this.getData().getVisual('symbol'); + var visualRotate = this.getData().getVisual('symbolRotate'); + var symbolType = visualType === 'none' ? 'circle' : visualType; + // Symbol size is 80% when there is a line + var size = opt.itemHeight * 0.8; + var symbol = createSymbol(symbolType, (opt.itemWidth - size) / 2, (opt.itemHeight - size) / 2, size, size, opt.itemStyle.fill); + group.add(symbol); + symbol.setStyle(opt.itemStyle); + var symbolRotate = opt.iconRotate === 'inherit' ? visualRotate : opt.iconRotate || 0; + symbol.rotation = symbolRotate * Math.PI / 180; + symbol.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]); + if (symbolType.indexOf('empty') > -1) { + symbol.style.stroke = symbol.style.fill; + symbol.style.fill = '#fff'; + symbol.style.lineWidth = 2; + } + return group; + }; + LineSeriesModel.type = 'series.line'; + LineSeriesModel.dependencies = ['grid', 'polar']; + LineSeriesModel.defaultOption = { + // zlevel: 0, + z: 3, + coordinateSystem: 'cartesian2d', + legendHoverLink: true, + clip: true, + label: { + position: 'top' + }, + // itemStyle: { + // }, + endLabel: { + show: false, + valueAnimation: true, + distance: 8 + }, + lineStyle: { + width: 2, + type: 'solid' + }, + emphasis: { + scale: true + }, + // areaStyle: { + // origin of areaStyle. Valid values: + // `'auto'/null/undefined`: from axisLine to data + // `'start'`: from min to data + // `'end'`: from data to max + // origin: 'auto' + // }, + // false, 'start', 'end', 'middle' + step: false, + // Disabled if step is true + smooth: false, + smoothMonotone: null, + symbol: 'emptyCircle', + symbolSize: 4, + symbolRotate: null, + showSymbol: true, + // `false`: follow the label interval strategy. + // `true`: show all symbols. + // `'auto'`: If possible, show all symbols, otherwise + // follow the label interval strategy. + showAllSymbol: 'auto', + // Whether to connect break point. + connectNulls: false, + // Sampling for large data. Can be: 'average', 'max', 'min', 'sum', 'lttb'. + sampling: 'none', + animationEasing: 'linear', + // Disable progressive + progressive: 0, + hoverLayerThreshold: Infinity, + universalTransition: { + divideShape: 'clone' + }, + triggerLineEvent: false + }; + return LineSeriesModel; + }(SeriesModel); + + /** + * @return label string. Not null/undefined + */ + function getDefaultLabel(data, dataIndex) { + var labelDims = data.mapDimensionsAll('defaultedLabel'); + var len = labelDims.length; + // Simple optimization (in lots of cases, label dims length is 1) + if (len === 1) { + var rawVal = retrieveRawValue(data, dataIndex, labelDims[0]); + return rawVal != null ? rawVal + '' : null; + } else if (len) { + var vals = []; + for (var i = 0; i < labelDims.length; i++) { + vals.push(retrieveRawValue(data, dataIndex, labelDims[i])); + } + return vals.join(' '); + } + } + function getDefaultInterpolatedLabel(data, interpolatedValue) { + var labelDims = data.mapDimensionsAll('defaultedLabel'); + if (!isArray(interpolatedValue)) { + return interpolatedValue + ''; + } + var vals = []; + for (var i = 0; i < labelDims.length; i++) { + var dimIndex = data.getDimensionIndex(labelDims[i]); + if (dimIndex >= 0) { + vals.push(interpolatedValue[dimIndex]); + } + } + return vals.join(' '); + } + + var Symbol = /** @class */function (_super) { + __extends(Symbol, _super); + function Symbol(data, idx, seriesScope, opts) { + var _this = _super.call(this) || this; + _this.updateData(data, idx, seriesScope, opts); + return _this; + } + Symbol.prototype._createSymbol = function (symbolType, data, idx, symbolSize, keepAspect) { + // Remove paths created before + this.removeAll(); + // let symbolPath = createSymbol( + // symbolType, -0.5, -0.5, 1, 1, color + // ); + // If width/height are set too small (e.g., set to 1) on ios10 + // and macOS Sierra, a circle stroke become a rect, no matter what + // the scale is set. So we set width/height as 2. See #4150. + var symbolPath = createSymbol(symbolType, -1, -1, 2, 2, null, keepAspect); + symbolPath.attr({ + z2: 100, + culling: true, + scaleX: symbolSize[0] / 2, + scaleY: symbolSize[1] / 2 + }); + // Rewrite drift method + symbolPath.drift = driftSymbol; + this._symbolType = symbolType; + this.add(symbolPath); + }; + /** + * Stop animation + * @param {boolean} toLastFrame + */ + Symbol.prototype.stopSymbolAnimation = function (toLastFrame) { + this.childAt(0).stopAnimation(null, toLastFrame); + }; + Symbol.prototype.getSymbolType = function () { + return this._symbolType; + }; + /** + * FIXME: + * Caution: This method breaks the encapsulation of this module, + * but it indeed brings convenience. So do not use the method + * unless you detailedly know all the implements of `Symbol`, + * especially animation. + * + * Get symbol path element. + */ + Symbol.prototype.getSymbolPath = function () { + return this.childAt(0); + }; + /** + * Highlight symbol + */ + Symbol.prototype.highlight = function () { + enterEmphasis(this.childAt(0)); + }; + /** + * Downplay symbol + */ + Symbol.prototype.downplay = function () { + leaveEmphasis(this.childAt(0)); + }; + /** + * @param {number} zlevel + * @param {number} z + */ + Symbol.prototype.setZ = function (zlevel, z) { + var symbolPath = this.childAt(0); + symbolPath.zlevel = zlevel; + symbolPath.z = z; + }; + Symbol.prototype.setDraggable = function (draggable, hasCursorOption) { + var symbolPath = this.childAt(0); + symbolPath.draggable = draggable; + symbolPath.cursor = !hasCursorOption && draggable ? 'move' : symbolPath.cursor; + }; + /** + * Update symbol properties + */ + Symbol.prototype.updateData = function (data, idx, seriesScope, opts) { + this.silent = false; + var symbolType = data.getItemVisual(idx, 'symbol') || 'circle'; + var seriesModel = data.hostModel; + var symbolSize = Symbol.getSymbolSize(data, idx); + var isInit = symbolType !== this._symbolType; + var disableAnimation = opts && opts.disableAnimation; + if (isInit) { + var keepAspect = data.getItemVisual(idx, 'symbolKeepAspect'); + this._createSymbol(symbolType, data, idx, symbolSize, keepAspect); + } else { + var symbolPath = this.childAt(0); + symbolPath.silent = false; + var target = { + scaleX: symbolSize[0] / 2, + scaleY: symbolSize[1] / 2 + }; + disableAnimation ? symbolPath.attr(target) : updateProps(symbolPath, target, seriesModel, idx); + saveOldStyle(symbolPath); + } + this._updateCommon(data, idx, symbolSize, seriesScope, opts); + if (isInit) { + var symbolPath = this.childAt(0); + if (!disableAnimation) { + var target = { + scaleX: this._sizeX, + scaleY: this._sizeY, + style: { + // Always fadeIn. Because it has fadeOut animation when symbol is removed.. + opacity: symbolPath.style.opacity + } + }; + symbolPath.scaleX = symbolPath.scaleY = 0; + symbolPath.style.opacity = 0; + initProps(symbolPath, target, seriesModel, idx); + } + } + if (disableAnimation) { + // Must stop leave transition manually if don't call initProps or updateProps. + this.childAt(0).stopAnimation('leave'); + } + }; + Symbol.prototype._updateCommon = function (data, idx, symbolSize, seriesScope, opts) { + var symbolPath = this.childAt(0); + var seriesModel = data.hostModel; + var emphasisItemStyle; + var blurItemStyle; + var selectItemStyle; + var focus; + var blurScope; + var emphasisDisabled; + var labelStatesModels; + var hoverScale; + var cursorStyle; + if (seriesScope) { + emphasisItemStyle = seriesScope.emphasisItemStyle; + blurItemStyle = seriesScope.blurItemStyle; + selectItemStyle = seriesScope.selectItemStyle; + focus = seriesScope.focus; + blurScope = seriesScope.blurScope; + labelStatesModels = seriesScope.labelStatesModels; + hoverScale = seriesScope.hoverScale; + cursorStyle = seriesScope.cursorStyle; + emphasisDisabled = seriesScope.emphasisDisabled; + } + if (!seriesScope || data.hasItemOption) { + var itemModel = seriesScope && seriesScope.itemModel ? seriesScope.itemModel : data.getItemModel(idx); + var emphasisModel = itemModel.getModel('emphasis'); + emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle(); + selectItemStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle(); + blurItemStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle(); + focus = emphasisModel.get('focus'); + blurScope = emphasisModel.get('blurScope'); + emphasisDisabled = emphasisModel.get('disabled'); + labelStatesModels = getLabelStatesModels(itemModel); + hoverScale = emphasisModel.getShallow('scale'); + cursorStyle = itemModel.getShallow('cursor'); + } + var symbolRotate = data.getItemVisual(idx, 'symbolRotate'); + symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0); + var symbolOffset = normalizeSymbolOffset(data.getItemVisual(idx, 'symbolOffset'), symbolSize); + if (symbolOffset) { + symbolPath.x = symbolOffset[0]; + symbolPath.y = symbolOffset[1]; + } + cursorStyle && symbolPath.attr('cursor', cursorStyle); + var symbolStyle = data.getItemVisual(idx, 'style'); + var visualColor = symbolStyle.fill; + if (symbolPath instanceof ZRImage) { + var pathStyle = symbolPath.style; + symbolPath.useStyle(extend({ + // TODO other properties like x, y ? + image: pathStyle.image, + x: pathStyle.x, + y: pathStyle.y, + width: pathStyle.width, + height: pathStyle.height + }, symbolStyle)); + } else { + if (symbolPath.__isEmptyBrush) { + // fill and stroke will be swapped if it's empty. + // So we cloned a new style to avoid it affecting the original style in visual storage. + // TODO Better implementation. No empty logic! + symbolPath.useStyle(extend({}, symbolStyle)); + } else { + symbolPath.useStyle(symbolStyle); + } + // Disable decal because symbol scale will been applied on the decal. + symbolPath.style.decal = null; + symbolPath.setColor(visualColor, opts && opts.symbolInnerColor); + symbolPath.style.strokeNoScale = true; + } + var liftZ = data.getItemVisual(idx, 'liftZ'); + var z2Origin = this._z2; + if (liftZ != null) { + if (z2Origin == null) { + this._z2 = symbolPath.z2; + symbolPath.z2 += liftZ; + } + } else if (z2Origin != null) { + symbolPath.z2 = z2Origin; + this._z2 = null; + } + var useNameLabel = opts && opts.useNameLabel; + setLabelStyle(symbolPath, labelStatesModels, { + labelFetcher: seriesModel, + labelDataIndex: idx, + defaultText: getLabelDefaultText, + inheritColor: visualColor, + defaultOpacity: symbolStyle.opacity + }); + // Do not execute util needed. + function getLabelDefaultText(idx) { + return useNameLabel ? data.getName(idx) : getDefaultLabel(data, idx); + } + this._sizeX = symbolSize[0] / 2; + this._sizeY = symbolSize[1] / 2; + var emphasisState = symbolPath.ensureState('emphasis'); + emphasisState.style = emphasisItemStyle; + symbolPath.ensureState('select').style = selectItemStyle; + symbolPath.ensureState('blur').style = blurItemStyle; + // null / undefined / true means to use default strategy. + // 0 / false / negative number / NaN / Infinity means no scale. + var scaleRatio = hoverScale == null || hoverScale === true ? Math.max(1.1, 3 / this._sizeY) + // PENDING: restrict hoverScale > 1? It seems unreasonable to scale down + : isFinite(hoverScale) && hoverScale > 0 ? +hoverScale : 1; + // always set scale to allow resetting + emphasisState.scaleX = this._sizeX * scaleRatio; + emphasisState.scaleY = this._sizeY * scaleRatio; + this.setSymbolScale(1); + toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled); + }; + Symbol.prototype.setSymbolScale = function (scale) { + this.scaleX = this.scaleY = scale; + }; + Symbol.prototype.fadeOut = function (cb, seriesModel, opt) { + var symbolPath = this.childAt(0); + var dataIndex = getECData(this).dataIndex; + var animationOpt = opt && opt.animation; + // Avoid mistaken hover when fading out + this.silent = symbolPath.silent = true; + // Not show text when animating + if (opt && opt.fadeLabel) { + var textContent = symbolPath.getTextContent(); + if (textContent) { + removeElement(textContent, { + style: { + opacity: 0 + } + }, seriesModel, { + dataIndex: dataIndex, + removeOpt: animationOpt, + cb: function () { + symbolPath.removeTextContent(); + } + }); + } + } else { + symbolPath.removeTextContent(); + } + removeElement(symbolPath, { + style: { + opacity: 0 + }, + scaleX: 0, + scaleY: 0 + }, seriesModel, { + dataIndex: dataIndex, + cb: cb, + removeOpt: animationOpt + }); + }; + Symbol.getSymbolSize = function (data, idx) { + return normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize')); + }; + return Symbol; + }(Group); + function driftSymbol(dx, dy) { + this.parent.drift(dx, dy); + } + + function symbolNeedsDraw(data, point, idx, opt) { + return point && !isNaN(point[0]) && !isNaN(point[1]) && !(opt.isIgnore && opt.isIgnore(idx)) + // We do not set clipShape on group, because it will cut part of + // the symbol element shape. We use the same clip shape here as + // the line clip. + && !(opt.clipShape && !opt.clipShape.contain(point[0], point[1])) && data.getItemVisual(idx, 'symbol') !== 'none'; + } + function normalizeUpdateOpt(opt) { + if (opt != null && !isObject(opt)) { + opt = { + isIgnore: opt + }; + } + return opt || {}; + } + function makeSeriesScope(data) { + var seriesModel = data.hostModel; + var emphasisModel = seriesModel.getModel('emphasis'); + return { + emphasisItemStyle: emphasisModel.getModel('itemStyle').getItemStyle(), + blurItemStyle: seriesModel.getModel(['blur', 'itemStyle']).getItemStyle(), + selectItemStyle: seriesModel.getModel(['select', 'itemStyle']).getItemStyle(), + focus: emphasisModel.get('focus'), + blurScope: emphasisModel.get('blurScope'), + emphasisDisabled: emphasisModel.get('disabled'), + hoverScale: emphasisModel.get('scale'), + labelStatesModels: getLabelStatesModels(seriesModel), + cursorStyle: seriesModel.get('cursor') + }; + } + var SymbolDraw = /** @class */function () { + function SymbolDraw(SymbolCtor) { + this.group = new Group(); + this._SymbolCtor = SymbolCtor || Symbol; + } + /** + * Update symbols draw by new data + */ + SymbolDraw.prototype.updateData = function (data, opt) { + // Remove progressive els. + this._progressiveEls = null; + opt = normalizeUpdateOpt(opt); + var group = this.group; + var seriesModel = data.hostModel; + var oldData = this._data; + var SymbolCtor = this._SymbolCtor; + var disableAnimation = opt.disableAnimation; + var seriesScope = makeSeriesScope(data); + var symbolUpdateOpt = { + disableAnimation: disableAnimation + }; + var getSymbolPoint = opt.getSymbolPoint || function (idx) { + return data.getItemLayout(idx); + }; + // There is no oldLineData only when first rendering or switching from + // stream mode to normal mode, where previous elements should be removed. + if (!oldData) { + group.removeAll(); + } + data.diff(oldData).add(function (newIdx) { + var point = getSymbolPoint(newIdx); + if (symbolNeedsDraw(data, point, newIdx, opt)) { + var symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt); + symbolEl.setPosition(point); + data.setItemGraphicEl(newIdx, symbolEl); + group.add(symbolEl); + } + }).update(function (newIdx, oldIdx) { + var symbolEl = oldData.getItemGraphicEl(oldIdx); + var point = getSymbolPoint(newIdx); + if (!symbolNeedsDraw(data, point, newIdx, opt)) { + group.remove(symbolEl); + return; + } + var newSymbolType = data.getItemVisual(newIdx, 'symbol') || 'circle'; + var oldSymbolType = symbolEl && symbolEl.getSymbolType && symbolEl.getSymbolType(); + if (!symbolEl + // Create a new if symbol type changed. + || oldSymbolType && oldSymbolType !== newSymbolType) { + group.remove(symbolEl); + symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt); + symbolEl.setPosition(point); + } else { + symbolEl.updateData(data, newIdx, seriesScope, symbolUpdateOpt); + var target = { + x: point[0], + y: point[1] + }; + disableAnimation ? symbolEl.attr(target) : updateProps(symbolEl, target, seriesModel); + } + // Add back + group.add(symbolEl); + data.setItemGraphicEl(newIdx, symbolEl); + }).remove(function (oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + el && el.fadeOut(function () { + group.remove(el); + }, seriesModel); + }).execute(); + this._getSymbolPoint = getSymbolPoint; + this._data = data; + }; + SymbolDraw.prototype.updateLayout = function () { + var _this = this; + var data = this._data; + if (data) { + // Not use animation + data.eachItemGraphicEl(function (el, idx) { + var point = _this._getSymbolPoint(idx); + el.setPosition(point); + el.markRedraw(); + }); + } + }; + SymbolDraw.prototype.incrementalPrepareUpdate = function (data) { + this._seriesScope = makeSeriesScope(data); + this._data = null; + this.group.removeAll(); + }; + /** + * Update symbols draw by new data + */ + SymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) { + // Clear + this._progressiveEls = []; + opt = normalizeUpdateOpt(opt); + function updateIncrementalAndHover(el) { + if (!el.isGroup) { + el.incremental = true; + el.ensureState('emphasis').hoverLayer = true; + } + } + for (var idx = taskParams.start; idx < taskParams.end; idx++) { + var point = data.getItemLayout(idx); + if (symbolNeedsDraw(data, point, idx, opt)) { + var el = new this._SymbolCtor(data, idx, this._seriesScope); + el.traverse(updateIncrementalAndHover); + el.setPosition(point); + this.group.add(el); + data.setItemGraphicEl(idx, el); + this._progressiveEls.push(el); + } + } + }; + SymbolDraw.prototype.eachRendered = function (cb) { + traverseElements(this._progressiveEls || this.group, cb); + }; + SymbolDraw.prototype.remove = function (enableAnimation) { + var group = this.group; + var data = this._data; + // Incremental model do not have this._data. + if (data && enableAnimation) { + data.eachItemGraphicEl(function (el) { + el.fadeOut(function () { + group.remove(el); + }, data.hostModel); + }); + } else { + group.removeAll(); + } + }; + return SymbolDraw; + }(); + + function prepareDataCoordInfo(coordSys, data, valueOrigin) { + var baseAxis = coordSys.getBaseAxis(); + var valueAxis = coordSys.getOtherAxis(baseAxis); + var valueStart = getValueStart(valueAxis, valueOrigin); + var baseAxisDim = baseAxis.dim; + var valueAxisDim = valueAxis.dim; + var valueDim = data.mapDimension(valueAxisDim); + var baseDim = data.mapDimension(baseAxisDim); + var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0; + var dims = map(coordSys.dimensions, function (coordDim) { + return data.mapDimension(coordDim); + }); + var stacked = false; + var stackResultDim = data.getCalculationInfo('stackResultDimension'); + if (isDimensionStacked(data, dims[0] /* , dims[1] */)) { + // jshint ignore:line + stacked = true; + dims[0] = stackResultDim; + } + if (isDimensionStacked(data, dims[1] /* , dims[0] */)) { + // jshint ignore:line + stacked = true; + dims[1] = stackResultDim; + } + return { + dataDimsForPoint: dims, + valueStart: valueStart, + valueAxisDim: valueAxisDim, + baseAxisDim: baseAxisDim, + stacked: !!stacked, + valueDim: valueDim, + baseDim: baseDim, + baseDataOffset: baseDataOffset, + stackedOverDimension: data.getCalculationInfo('stackedOverDimension') + }; + } + function getValueStart(valueAxis, valueOrigin) { + var valueStart = 0; + var extent = valueAxis.scale.getExtent(); + if (valueOrigin === 'start') { + valueStart = extent[0]; + } else if (valueOrigin === 'end') { + valueStart = extent[1]; + } + // If origin is specified as a number, use it as + // valueStart directly + else if (isNumber(valueOrigin) && !isNaN(valueOrigin)) { + valueStart = valueOrigin; + } + // auto + else { + // Both positive + if (extent[0] > 0) { + valueStart = extent[0]; + } + // Both negative + else if (extent[1] < 0) { + valueStart = extent[1]; + } + // If is one positive, and one negative, onZero shall be true + } + + return valueStart; + } + function getStackedOnPoint(dataCoordInfo, coordSys, data, idx) { + var value = NaN; + if (dataCoordInfo.stacked) { + value = data.get(data.getCalculationInfo('stackedOverDimension'), idx); + } + if (isNaN(value)) { + value = dataCoordInfo.valueStart; + } + var baseDataOffset = dataCoordInfo.baseDataOffset; + var stackedData = []; + stackedData[baseDataOffset] = data.get(dataCoordInfo.baseDim, idx); + stackedData[1 - baseDataOffset] = value; + return coordSys.dataToPoint(stackedData); + } + + function diffData(oldData, newData) { + var diffResult = []; + newData.diff(oldData).add(function (idx) { + diffResult.push({ + cmd: '+', + idx: idx + }); + }).update(function (newIdx, oldIdx) { + diffResult.push({ + cmd: '=', + idx: oldIdx, + idx1: newIdx + }); + }).remove(function (idx) { + diffResult.push({ + cmd: '-', + idx: idx + }); + }).execute(); + return diffResult; + } + function lineAnimationDiff(oldData, newData, oldStackedOnPoints, newStackedOnPoints, oldCoordSys, newCoordSys, oldValueOrigin, newValueOrigin) { + var diff = diffData(oldData, newData); + // let newIdList = newData.mapArray(newData.getId); + // let oldIdList = oldData.mapArray(oldData.getId); + // convertToIntId(newIdList, oldIdList); + // // FIXME One data ? + // diff = arrayDiff(oldIdList, newIdList); + var currPoints = []; + var nextPoints = []; + // Points for stacking base line + var currStackedPoints = []; + var nextStackedPoints = []; + var status = []; + var sortedIndices = []; + var rawIndices = []; + var newDataOldCoordInfo = prepareDataCoordInfo(oldCoordSys, newData, oldValueOrigin); + // const oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin); + var oldPoints = oldData.getLayout('points') || []; + var newPoints = newData.getLayout('points') || []; + for (var i = 0; i < diff.length; i++) { + var diffItem = diff[i]; + var pointAdded = true; + var oldIdx2 = void 0; + var newIdx2 = void 0; + // FIXME, animation is not so perfect when dataZoom window moves fast + // Which is in case remvoing or add more than one data in the tail or head + switch (diffItem.cmd) { + case '=': + oldIdx2 = diffItem.idx * 2; + newIdx2 = diffItem.idx1 * 2; + var currentX = oldPoints[oldIdx2]; + var currentY = oldPoints[oldIdx2 + 1]; + var nextX = newPoints[newIdx2]; + var nextY = newPoints[newIdx2 + 1]; + // If previous data is NaN, use next point directly + if (isNaN(currentX) || isNaN(currentY)) { + currentX = nextX; + currentY = nextY; + } + currPoints.push(currentX, currentY); + nextPoints.push(nextX, nextY); + currStackedPoints.push(oldStackedOnPoints[oldIdx2], oldStackedOnPoints[oldIdx2 + 1]); + nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]); + rawIndices.push(newData.getRawIndex(diffItem.idx1)); + break; + case '+': + var newIdx = diffItem.idx; + var newDataDimsForPoint = newDataOldCoordInfo.dataDimsForPoint; + var oldPt = oldCoordSys.dataToPoint([newData.get(newDataDimsForPoint[0], newIdx), newData.get(newDataDimsForPoint[1], newIdx)]); + newIdx2 = newIdx * 2; + currPoints.push(oldPt[0], oldPt[1]); + nextPoints.push(newPoints[newIdx2], newPoints[newIdx2 + 1]); + var stackedOnPoint = getStackedOnPoint(newDataOldCoordInfo, oldCoordSys, newData, newIdx); + currStackedPoints.push(stackedOnPoint[0], stackedOnPoint[1]); + nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]); + rawIndices.push(newData.getRawIndex(newIdx)); + break; + case '-': + pointAdded = false; + } + // Original indices + if (pointAdded) { + status.push(diffItem); + sortedIndices.push(sortedIndices.length); + } + } + // Diff result may be crossed if all items are changed + // Sort by data index + sortedIndices.sort(function (a, b) { + return rawIndices[a] - rawIndices[b]; + }); + var len = currPoints.length; + var sortedCurrPoints = createFloat32Array(len); + var sortedNextPoints = createFloat32Array(len); + var sortedCurrStackedPoints = createFloat32Array(len); + var sortedNextStackedPoints = createFloat32Array(len); + var sortedStatus = []; + for (var i = 0; i < sortedIndices.length; i++) { + var idx = sortedIndices[i]; + var i2 = i * 2; + var idx2 = idx * 2; + sortedCurrPoints[i2] = currPoints[idx2]; + sortedCurrPoints[i2 + 1] = currPoints[idx2 + 1]; + sortedNextPoints[i2] = nextPoints[idx2]; + sortedNextPoints[i2 + 1] = nextPoints[idx2 + 1]; + sortedCurrStackedPoints[i2] = currStackedPoints[idx2]; + sortedCurrStackedPoints[i2 + 1] = currStackedPoints[idx2 + 1]; + sortedNextStackedPoints[i2] = nextStackedPoints[idx2]; + sortedNextStackedPoints[i2 + 1] = nextStackedPoints[idx2 + 1]; + sortedStatus[i] = status[idx]; + } + return { + current: sortedCurrPoints, + next: sortedNextPoints, + stackedOnCurrent: sortedCurrStackedPoints, + stackedOnNext: sortedNextStackedPoints, + status: sortedStatus + }; + } + + var mathMin$5 = Math.min; + var mathMax$5 = Math.max; + function isPointNull(x, y) { + return isNaN(x) || isNaN(y); + } + /** + * Draw smoothed line in non-monotone, in may cause undesired curve in extreme + * situations. This should be used when points are non-monotone neither in x or + * y dimension. + */ + function drawSegment(ctx, points, start, segLen, allLen, dir, smooth, smoothMonotone, connectNulls) { + var prevX; + var prevY; + var cpx0; + var cpy0; + var cpx1; + var cpy1; + var idx = start; + var k = 0; + for (; k < segLen; k++) { + var x = points[idx * 2]; + var y = points[idx * 2 + 1]; + if (idx >= allLen || idx < 0) { + break; + } + if (isPointNull(x, y)) { + if (connectNulls) { + idx += dir; + continue; + } + break; + } + if (idx === start) { + ctx[dir > 0 ? 'moveTo' : 'lineTo'](x, y); + cpx0 = x; + cpy0 = y; + } else { + var dx = x - prevX; + var dy = y - prevY; + // Ignore tiny segment. + if (dx * dx + dy * dy < 0.5) { + idx += dir; + continue; + } + if (smooth > 0) { + var nextIdx = idx + dir; + var nextX = points[nextIdx * 2]; + var nextY = points[nextIdx * 2 + 1]; + // Ignore duplicate point + while (nextX === x && nextY === y && k < segLen) { + k++; + nextIdx += dir; + idx += dir; + nextX = points[nextIdx * 2]; + nextY = points[nextIdx * 2 + 1]; + x = points[idx * 2]; + y = points[idx * 2 + 1]; + dx = x - prevX; + dy = y - prevY; + } + var tmpK = k + 1; + if (connectNulls) { + // Find next point not null + while (isPointNull(nextX, nextY) && tmpK < segLen) { + tmpK++; + nextIdx += dir; + nextX = points[nextIdx * 2]; + nextY = points[nextIdx * 2 + 1]; + } + } + var ratioNextSeg = 0.5; + var vx = 0; + var vy = 0; + var nextCpx0 = void 0; + var nextCpy0 = void 0; + // Is last point + if (tmpK >= segLen || isPointNull(nextX, nextY)) { + cpx1 = x; + cpy1 = y; + } else { + vx = nextX - prevX; + vy = nextY - prevY; + var dx0 = x - prevX; + var dx1 = nextX - x; + var dy0 = y - prevY; + var dy1 = nextY - y; + var lenPrevSeg = void 0; + var lenNextSeg = void 0; + if (smoothMonotone === 'x') { + lenPrevSeg = Math.abs(dx0); + lenNextSeg = Math.abs(dx1); + var dir_1 = vx > 0 ? 1 : -1; + cpx1 = x - dir_1 * lenPrevSeg * smooth; + cpy1 = y; + nextCpx0 = x + dir_1 * lenNextSeg * smooth; + nextCpy0 = y; + } else if (smoothMonotone === 'y') { + lenPrevSeg = Math.abs(dy0); + lenNextSeg = Math.abs(dy1); + var dir_2 = vy > 0 ? 1 : -1; + cpx1 = x; + cpy1 = y - dir_2 * lenPrevSeg * smooth; + nextCpx0 = x; + nextCpy0 = y + dir_2 * lenNextSeg * smooth; + } else { + lenPrevSeg = Math.sqrt(dx0 * dx0 + dy0 * dy0); + lenNextSeg = Math.sqrt(dx1 * dx1 + dy1 * dy1); + // Use ratio of seg length + ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg); + cpx1 = x - vx * smooth * (1 - ratioNextSeg); + cpy1 = y - vy * smooth * (1 - ratioNextSeg); + // cp0 of next segment + nextCpx0 = x + vx * smooth * ratioNextSeg; + nextCpy0 = y + vy * smooth * ratioNextSeg; + // Smooth constraint between point and next point. + // Avoid exceeding extreme after smoothing. + nextCpx0 = mathMin$5(nextCpx0, mathMax$5(nextX, x)); + nextCpy0 = mathMin$5(nextCpy0, mathMax$5(nextY, y)); + nextCpx0 = mathMax$5(nextCpx0, mathMin$5(nextX, x)); + nextCpy0 = mathMax$5(nextCpy0, mathMin$5(nextY, y)); + // Reclaculate cp1 based on the adjusted cp0 of next seg. + vx = nextCpx0 - x; + vy = nextCpy0 - y; + cpx1 = x - vx * lenPrevSeg / lenNextSeg; + cpy1 = y - vy * lenPrevSeg / lenNextSeg; + // Smooth constraint between point and prev point. + // Avoid exceeding extreme after smoothing. + cpx1 = mathMin$5(cpx1, mathMax$5(prevX, x)); + cpy1 = mathMin$5(cpy1, mathMax$5(prevY, y)); + cpx1 = mathMax$5(cpx1, mathMin$5(prevX, x)); + cpy1 = mathMax$5(cpy1, mathMin$5(prevY, y)); + // Adjust next cp0 again. + vx = x - cpx1; + vy = y - cpy1; + nextCpx0 = x + vx * lenNextSeg / lenPrevSeg; + nextCpy0 = y + vy * lenNextSeg / lenPrevSeg; + } + } + ctx.bezierCurveTo(cpx0, cpy0, cpx1, cpy1, x, y); + cpx0 = nextCpx0; + cpy0 = nextCpy0; + } else { + ctx.lineTo(x, y); + } + } + prevX = x; + prevY = y; + idx += dir; + } + return k; + } + var ECPolylineShape = /** @class */function () { + function ECPolylineShape() { + this.smooth = 0; + this.smoothConstraint = true; + } + return ECPolylineShape; + }(); + var ECPolyline = /** @class */function (_super) { + __extends(ECPolyline, _super); + function ECPolyline(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'ec-polyline'; + return _this; + } + ECPolyline.prototype.getDefaultStyle = function () { + return { + stroke: '#000', + fill: null + }; + }; + ECPolyline.prototype.getDefaultShape = function () { + return new ECPolylineShape(); + }; + ECPolyline.prototype.buildPath = function (ctx, shape) { + var points = shape.points; + var i = 0; + var len = points.length / 2; + // const result = getBoundingBox(points, shape.smoothConstraint); + if (shape.connectNulls) { + // Must remove first and last null values avoid draw error in polygon + for (; len > 0; len--) { + if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) { + break; + } + } + for (; i < len; i++) { + if (!isPointNull(points[i * 2], points[i * 2 + 1])) { + break; + } + } + } + while (i < len) { + i += drawSegment(ctx, points, i, len, len, 1, shape.smooth, shape.smoothMonotone, shape.connectNulls) + 1; + } + }; + ECPolyline.prototype.getPointOn = function (xOrY, dim) { + if (!this.path) { + this.createPathProxy(); + this.buildPath(this.path, this.shape); + } + var path = this.path; + var data = path.data; + var CMD = PathProxy.CMD; + var x0; + var y0; + var isDimX = dim === 'x'; + var roots = []; + for (var i = 0; i < data.length;) { + var cmd = data[i++]; + var x = void 0; + var y = void 0; + var x2 = void 0; + var y2 = void 0; + var x3 = void 0; + var y3 = void 0; + var t = void 0; + switch (cmd) { + case CMD.M: + x0 = data[i++]; + y0 = data[i++]; + break; + case CMD.L: + x = data[i++]; + y = data[i++]; + t = isDimX ? (xOrY - x0) / (x - x0) : (xOrY - y0) / (y - y0); + if (t <= 1 && t >= 0) { + var val = isDimX ? (y - y0) * t + y0 : (x - x0) * t + x0; + return isDimX ? [xOrY, val] : [val, xOrY]; + } + x0 = x; + y0 = y; + break; + case CMD.C: + x = data[i++]; + y = data[i++]; + x2 = data[i++]; + y2 = data[i++]; + x3 = data[i++]; + y3 = data[i++]; + var nRoot = isDimX ? cubicRootAt(x0, x, x2, x3, xOrY, roots) : cubicRootAt(y0, y, y2, y3, xOrY, roots); + if (nRoot > 0) { + for (var i_1 = 0; i_1 < nRoot; i_1++) { + var t_1 = roots[i_1]; + if (t_1 <= 1 && t_1 >= 0) { + var val = isDimX ? cubicAt(y0, y, y2, y3, t_1) : cubicAt(x0, x, x2, x3, t_1); + return isDimX ? [xOrY, val] : [val, xOrY]; + } + } + } + x0 = x3; + y0 = y3; + break; + } + } + }; + return ECPolyline; + }(Path); + var ECPolygonShape = /** @class */function (_super) { + __extends(ECPolygonShape, _super); + function ECPolygonShape() { + return _super !== null && _super.apply(this, arguments) || this; + } + return ECPolygonShape; + }(ECPolylineShape); + var ECPolygon = /** @class */function (_super) { + __extends(ECPolygon, _super); + function ECPolygon(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'ec-polygon'; + return _this; + } + ECPolygon.prototype.getDefaultShape = function () { + return new ECPolygonShape(); + }; + ECPolygon.prototype.buildPath = function (ctx, shape) { + var points = shape.points; + var stackedOnPoints = shape.stackedOnPoints; + var i = 0; + var len = points.length / 2; + var smoothMonotone = shape.smoothMonotone; + if (shape.connectNulls) { + // Must remove first and last null values avoid draw error in polygon + for (; len > 0; len--) { + if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) { + break; + } + } + for (; i < len; i++) { + if (!isPointNull(points[i * 2], points[i * 2 + 1])) { + break; + } + } + } + while (i < len) { + var k = drawSegment(ctx, points, i, len, len, 1, shape.smooth, smoothMonotone, shape.connectNulls); + drawSegment(ctx, stackedOnPoints, i + k - 1, k, len, -1, shape.stackedOnSmooth, smoothMonotone, shape.connectNulls); + i += k + 1; + ctx.closePath(); + } + }; + return ECPolygon; + }(Path); + + function createGridClipPath(cartesian, hasAnimation, seriesModel, done, during) { + var rect = cartesian.getArea(); + var x = rect.x; + var y = rect.y; + var width = rect.width; + var height = rect.height; + var lineWidth = seriesModel.get(['lineStyle', 'width']) || 2; + // Expand the clip path a bit to avoid the border is clipped and looks thinner + x -= lineWidth / 2; + y -= lineWidth / 2; + width += lineWidth; + height += lineWidth; + // fix: https://github.com/apache/incubator-echarts/issues/11369 + width = Math.ceil(width); + if (x !== Math.floor(x)) { + x = Math.floor(x); + // if no extra 1px on `width`, it will still be clipped since `x` is floored + width++; + } + var clipPath = new Rect({ + shape: { + x: x, + y: y, + width: width, + height: height + } + }); + if (hasAnimation) { + var baseAxis = cartesian.getBaseAxis(); + var isHorizontal = baseAxis.isHorizontal(); + var isAxisInversed = baseAxis.inverse; + if (isHorizontal) { + if (isAxisInversed) { + clipPath.shape.x += width; + } + clipPath.shape.width = 0; + } else { + if (!isAxisInversed) { + clipPath.shape.y += height; + } + clipPath.shape.height = 0; + } + var duringCb = isFunction(during) ? function (percent) { + during(percent, clipPath); + } : null; + initProps(clipPath, { + shape: { + width: width, + height: height, + x: x, + y: y + } + }, seriesModel, null, done, duringCb); + } + return clipPath; + } + function createPolarClipPath(polar, hasAnimation, seriesModel) { + var sectorArea = polar.getArea(); + // Avoid float number rounding error for symbol on the edge of axis extent. + var r0 = round(sectorArea.r0, 1); + var r = round(sectorArea.r, 1); + var clipPath = new Sector({ + shape: { + cx: round(polar.cx, 1), + cy: round(polar.cy, 1), + r0: r0, + r: r, + startAngle: sectorArea.startAngle, + endAngle: sectorArea.endAngle, + clockwise: sectorArea.clockwise + } + }); + if (hasAnimation) { + var isRadial = polar.getBaseAxis().dim === 'angle'; + if (isRadial) { + clipPath.shape.endAngle = sectorArea.startAngle; + } else { + clipPath.shape.r = r0; + } + initProps(clipPath, { + shape: { + endAngle: sectorArea.endAngle, + r: r + } + }, seriesModel); + } + return clipPath; + } + function createClipPath(coordSys, hasAnimation, seriesModel, done, during) { + if (!coordSys) { + return null; + } else if (coordSys.type === 'polar') { + return createPolarClipPath(coordSys, hasAnimation, seriesModel); + } else if (coordSys.type === 'cartesian2d') { + return createGridClipPath(coordSys, hasAnimation, seriesModel, done, during); + } + return null; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function isCoordinateSystemType(coordSys, type) { + return coordSys.type === type; + } + + function isPointsSame(points1, points2) { + if (points1.length !== points2.length) { + return; + } + for (var i = 0; i < points1.length; i++) { + if (points1[i] !== points2[i]) { + return; + } + } + return true; + } + function bboxFromPoints(points) { + var minX = Infinity; + var minY = Infinity; + var maxX = -Infinity; + var maxY = -Infinity; + for (var i = 0; i < points.length;) { + var x = points[i++]; + var y = points[i++]; + if (!isNaN(x)) { + minX = Math.min(x, minX); + maxX = Math.max(x, maxX); + } + if (!isNaN(y)) { + minY = Math.min(y, minY); + maxY = Math.max(y, maxY); + } + } + return [[minX, minY], [maxX, maxY]]; + } + function getBoundingDiff(points1, points2) { + var _a = bboxFromPoints(points1), + min1 = _a[0], + max1 = _a[1]; + var _b = bboxFromPoints(points2), + min2 = _b[0], + max2 = _b[1]; + // Get a max value from each corner of two boundings. + return Math.max(Math.abs(min1[0] - min2[0]), Math.abs(min1[1] - min2[1]), Math.abs(max1[0] - max2[0]), Math.abs(max1[1] - max2[1])); + } + function getSmooth(smooth) { + return isNumber(smooth) ? smooth : smooth ? 0.5 : 0; + } + function getStackedOnPoints(coordSys, data, dataCoordInfo) { + if (!dataCoordInfo.valueDim) { + return []; + } + var len = data.count(); + var points = createFloat32Array(len * 2); + for (var idx = 0; idx < len; idx++) { + var pt = getStackedOnPoint(dataCoordInfo, coordSys, data, idx); + points[idx * 2] = pt[0]; + points[idx * 2 + 1] = pt[1]; + } + return points; + } + function turnPointsIntoStep(points, coordSys, stepTurnAt, connectNulls) { + var baseAxis = coordSys.getBaseAxis(); + var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1; + var stepPoints = []; + var i = 0; + var stepPt = []; + var pt = []; + var nextPt = []; + var filteredPoints = []; + if (connectNulls) { + for (i = 0; i < points.length; i += 2) { + if (!isNaN(points[i]) && !isNaN(points[i + 1])) { + filteredPoints.push(points[i], points[i + 1]); + } + } + points = filteredPoints; + } + for (i = 0; i < points.length - 2; i += 2) { + nextPt[0] = points[i + 2]; + nextPt[1] = points[i + 3]; + pt[0] = points[i]; + pt[1] = points[i + 1]; + stepPoints.push(pt[0], pt[1]); + switch (stepTurnAt) { + case 'end': + stepPt[baseIndex] = nextPt[baseIndex]; + stepPt[1 - baseIndex] = pt[1 - baseIndex]; + stepPoints.push(stepPt[0], stepPt[1]); + break; + case 'middle': + var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2; + var stepPt2 = []; + stepPt[baseIndex] = stepPt2[baseIndex] = middle; + stepPt[1 - baseIndex] = pt[1 - baseIndex]; + stepPt2[1 - baseIndex] = nextPt[1 - baseIndex]; + stepPoints.push(stepPt[0], stepPt[1]); + stepPoints.push(stepPt2[0], stepPt2[1]); + break; + default: + // default is start + stepPt[baseIndex] = pt[baseIndex]; + stepPt[1 - baseIndex] = nextPt[1 - baseIndex]; + stepPoints.push(stepPt[0], stepPt[1]); + } + } + // Last points + stepPoints.push(points[i++], points[i++]); + return stepPoints; + } + /** + * Clip color stops to edge. Avoid creating too large gradients. + * Which may lead to blurry when GPU acceleration is enabled. See #15680 + * + * The stops has been sorted from small to large. + */ + function clipColorStops(colorStops, maxSize) { + var newColorStops = []; + var len = colorStops.length; + // coord will always < 0 in prevOutOfRangeColorStop. + var prevOutOfRangeColorStop; + var prevInRangeColorStop; + function lerpStop(stop0, stop1, clippedCoord) { + var coord0 = stop0.coord; + var p = (clippedCoord - coord0) / (stop1.coord - coord0); + var color = lerp$1(p, [stop0.color, stop1.color]); + return { + coord: clippedCoord, + color: color + }; + } + for (var i = 0; i < len; i++) { + var stop_1 = colorStops[i]; + var coord = stop_1.coord; + if (coord < 0) { + prevOutOfRangeColorStop = stop_1; + } else if (coord > maxSize) { + if (prevInRangeColorStop) { + newColorStops.push(lerpStop(prevInRangeColorStop, stop_1, maxSize)); + } else if (prevOutOfRangeColorStop) { + // If there are two stops and coord range is between these two stops + newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0), lerpStop(prevOutOfRangeColorStop, stop_1, maxSize)); + } + // All following stop will be out of range. So just ignore them. + break; + } else { + if (prevOutOfRangeColorStop) { + newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0)); + // Reset + prevOutOfRangeColorStop = null; + } + newColorStops.push(stop_1); + prevInRangeColorStop = stop_1; + } + } + return newColorStops; + } + function getVisualGradient(data, coordSys, api) { + var visualMetaList = data.getVisual('visualMeta'); + if (!visualMetaList || !visualMetaList.length || !data.count()) { + // When data.count() is 0, gradient range can not be calculated. + return; + } + if (coordSys.type !== 'cartesian2d') { + if ("development" !== 'production') { + console.warn('Visual map on line style is only supported on cartesian2d.'); + } + return; + } + var coordDim; + var visualMeta; + for (var i = visualMetaList.length - 1; i >= 0; i--) { + var dimInfo = data.getDimensionInfo(visualMetaList[i].dimension); + coordDim = dimInfo && dimInfo.coordDim; + // Can only be x or y + if (coordDim === 'x' || coordDim === 'y') { + visualMeta = visualMetaList[i]; + break; + } + } + if (!visualMeta) { + if ("development" !== 'production') { + console.warn('Visual map on line style only support x or y dimension.'); + } + return; + } + // If the area to be rendered is bigger than area defined by LinearGradient, + // the canvas spec prescribes that the color of the first stop and the last + // stop should be used. But if two stops are added at offset 0, in effect + // browsers use the color of the second stop to render area outside + // LinearGradient. So we can only infinitesimally extend area defined in + // LinearGradient to render `outerColors`. + var axis = coordSys.getAxis(coordDim); + // dataToCoord mapping may not be linear, but must be monotonic. + var colorStops = map(visualMeta.stops, function (stop) { + // offset will be calculated later. + return { + coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)), + color: stop.color + }; + }); + var stopLen = colorStops.length; + var outerColors = visualMeta.outerColors.slice(); + if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) { + colorStops.reverse(); + outerColors.reverse(); + } + var colorStopsInRange = clipColorStops(colorStops, coordDim === 'x' ? api.getWidth() : api.getHeight()); + var inRangeStopLen = colorStopsInRange.length; + if (!inRangeStopLen && stopLen) { + // All stops are out of range. All will be the same color. + return colorStops[0].coord < 0 ? outerColors[1] ? outerColors[1] : colorStops[stopLen - 1].color : outerColors[0] ? outerColors[0] : colorStops[0].color; + } + var tinyExtent = 10; // Arbitrary value: 10px + var minCoord = colorStopsInRange[0].coord - tinyExtent; + var maxCoord = colorStopsInRange[inRangeStopLen - 1].coord + tinyExtent; + var coordSpan = maxCoord - minCoord; + if (coordSpan < 1e-3) { + return 'transparent'; + } + each(colorStopsInRange, function (stop) { + stop.offset = (stop.coord - minCoord) / coordSpan; + }); + colorStopsInRange.push({ + // NOTE: inRangeStopLen may still be 0 if stoplen is zero. + offset: inRangeStopLen ? colorStopsInRange[inRangeStopLen - 1].offset : 0.5, + color: outerColors[1] || 'transparent' + }); + colorStopsInRange.unshift({ + offset: inRangeStopLen ? colorStopsInRange[0].offset : 0.5, + color: outerColors[0] || 'transparent' + }); + var gradient = new LinearGradient(0, 0, 0, 0, colorStopsInRange, true); + gradient[coordDim] = minCoord; + gradient[coordDim + '2'] = maxCoord; + return gradient; + } + function getIsIgnoreFunc(seriesModel, data, coordSys) { + var showAllSymbol = seriesModel.get('showAllSymbol'); + var isAuto = showAllSymbol === 'auto'; + if (showAllSymbol && !isAuto) { + return; + } + var categoryAxis = coordSys.getAxesByScale('ordinal')[0]; + if (!categoryAxis) { + return; + } + // Note that category label interval strategy might bring some weird effect + // in some scenario: users may wonder why some of the symbols are not + // displayed. So we show all symbols as possible as we can. + if (isAuto + // Simplify the logic, do not determine label overlap here. + && canShowAllSymbolForCategory(categoryAxis, data)) { + return; + } + // Otherwise follow the label interval strategy on category axis. + var categoryDataDim = data.mapDimension(categoryAxis.dim); + var labelMap = {}; + each(categoryAxis.getViewLabels(), function (labelItem) { + var ordinalNumber = categoryAxis.scale.getRawOrdinalNumber(labelItem.tickValue); + labelMap[ordinalNumber] = 1; + }); + return function (dataIndex) { + return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex)); + }; + } + function canShowAllSymbolForCategory(categoryAxis, data) { + // In most cases, line is monotonous on category axis, and the label size + // is close with each other. So we check the symbol size and some of the + // label size alone with the category axis to estimate whether all symbol + // can be shown without overlap. + var axisExtent = categoryAxis.getExtent(); + var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count(); + isNaN(availSize) && (availSize = 0); // 0/0 is NaN. + // Sampling some points, max 5. + var dataLen = data.count(); + var step = Math.max(1, Math.round(dataLen / 5)); + for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) { + if (Symbol.getSymbolSize(data, dataIndex + // Only for cartesian, where `isHorizontal` exists. + )[categoryAxis.isHorizontal() ? 1 : 0] + // Empirical number + * 1.5 > availSize) { + return false; + } + } + return true; + } + function isPointNull$1(x, y) { + return isNaN(x) || isNaN(y); + } + function getLastIndexNotNull(points) { + var len = points.length / 2; + for (; len > 0; len--) { + if (!isPointNull$1(points[len * 2 - 2], points[len * 2 - 1])) { + break; + } + } + return len - 1; + } + function getPointAtIndex(points, idx) { + return [points[idx * 2], points[idx * 2 + 1]]; + } + function getIndexRange(points, xOrY, dim) { + var len = points.length / 2; + var dimIdx = dim === 'x' ? 0 : 1; + var a; + var b; + var prevIndex = 0; + var nextIndex = -1; + for (var i = 0; i < len; i++) { + b = points[i * 2 + dimIdx]; + if (isNaN(b) || isNaN(points[i * 2 + 1 - dimIdx])) { + continue; + } + if (i === 0) { + a = b; + continue; + } + if (a <= xOrY && b >= xOrY || a >= xOrY && b <= xOrY) { + nextIndex = i; + break; + } + prevIndex = i; + a = b; + } + return { + range: [prevIndex, nextIndex], + t: (xOrY - a) / (b - a) + }; + } + function anyStateShowEndLabel(seriesModel) { + if (seriesModel.get(['endLabel', 'show'])) { + return true; + } + for (var i = 0; i < SPECIAL_STATES.length; i++) { + if (seriesModel.get([SPECIAL_STATES[i], 'endLabel', 'show'])) { + return true; + } + } + return false; + } + function createLineClipPath(lineView, coordSys, hasAnimation, seriesModel) { + if (isCoordinateSystemType(coordSys, 'cartesian2d')) { + var endLabelModel_1 = seriesModel.getModel('endLabel'); + var valueAnimation_1 = endLabelModel_1.get('valueAnimation'); + var data_1 = seriesModel.getData(); + var labelAnimationRecord_1 = { + lastFrameIndex: 0 + }; + var during = anyStateShowEndLabel(seriesModel) ? function (percent, clipRect) { + lineView._endLabelOnDuring(percent, clipRect, data_1, labelAnimationRecord_1, valueAnimation_1, endLabelModel_1, coordSys); + } : null; + var isHorizontal = coordSys.getBaseAxis().isHorizontal(); + var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, function () { + var endLabel = lineView._endLabel; + if (endLabel && hasAnimation) { + if (labelAnimationRecord_1.originalX != null) { + endLabel.attr({ + x: labelAnimationRecord_1.originalX, + y: labelAnimationRecord_1.originalY + }); + } + } + }, during); + // Expand clip shape to avoid clipping when line value exceeds axis + if (!seriesModel.get('clip', true)) { + var rectShape = clipPath.shape; + var expandSize = Math.max(rectShape.width, rectShape.height); + if (isHorizontal) { + rectShape.y -= expandSize; + rectShape.height += expandSize * 2; + } else { + rectShape.x -= expandSize; + rectShape.width += expandSize * 2; + } + } + // Set to the final frame. To make sure label layout is right. + if (during) { + during(1, clipPath); + } + return clipPath; + } else { + if ("development" !== 'production') { + if (seriesModel.get(['endLabel', 'show'])) { + console.warn('endLabel is not supported for lines in polar systems.'); + } + } + return createPolarClipPath(coordSys, hasAnimation, seriesModel); + } + } + function getEndLabelStateSpecified(endLabelModel, coordSys) { + var baseAxis = coordSys.getBaseAxis(); + var isHorizontal = baseAxis.isHorizontal(); + var isBaseInversed = baseAxis.inverse; + var align = isHorizontal ? isBaseInversed ? 'right' : 'left' : 'center'; + var verticalAlign = isHorizontal ? 'middle' : isBaseInversed ? 'top' : 'bottom'; + return { + normal: { + align: endLabelModel.get('align') || align, + verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign + } + }; + } + var LineView = /** @class */function (_super) { + __extends(LineView, _super); + function LineView() { + return _super !== null && _super.apply(this, arguments) || this; + } + LineView.prototype.init = function () { + var lineGroup = new Group(); + var symbolDraw = new SymbolDraw(); + this.group.add(symbolDraw.group); + this._symbolDraw = symbolDraw; + this._lineGroup = lineGroup; + }; + LineView.prototype.render = function (seriesModel, ecModel, api) { + var _this = this; + var coordSys = seriesModel.coordinateSystem; + var group = this.group; + var data = seriesModel.getData(); + var lineStyleModel = seriesModel.getModel('lineStyle'); + var areaStyleModel = seriesModel.getModel('areaStyle'); + var points = data.getLayout('points') || []; + var isCoordSysPolar = coordSys.type === 'polar'; + var prevCoordSys = this._coordSys; + var symbolDraw = this._symbolDraw; + var polyline = this._polyline; + var polygon = this._polygon; + var lineGroup = this._lineGroup; + var hasAnimation = !ecModel.ssr && seriesModel.get('animation'); + var isAreaChart = !areaStyleModel.isEmpty(); + var valueOrigin = areaStyleModel.get('origin'); + var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin); + var stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo); + var showSymbol = seriesModel.get('showSymbol'); + var connectNulls = seriesModel.get('connectNulls'); + var isIgnoreFunc = showSymbol && !isCoordSysPolar && getIsIgnoreFunc(seriesModel, data, coordSys); + // Remove temporary symbols + var oldData = this._data; + oldData && oldData.eachItemGraphicEl(function (el, idx) { + if (el.__temp) { + group.remove(el); + oldData.setItemGraphicEl(idx, null); + } + }); + // Remove previous created symbols if showSymbol changed to false + if (!showSymbol) { + symbolDraw.remove(); + } + group.add(lineGroup); + // FIXME step not support polar + var step = !isCoordSysPolar ? seriesModel.get('step') : false; + var clipShapeForSymbol; + if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) { + clipShapeForSymbol = coordSys.getArea(); + // Avoid float number rounding error for symbol on the edge of axis extent. + // See #7913 and `test/dataZoom-clip.html`. + if (clipShapeForSymbol.width != null) { + clipShapeForSymbol.x -= 0.1; + clipShapeForSymbol.y -= 0.1; + clipShapeForSymbol.width += 0.2; + clipShapeForSymbol.height += 0.2; + } else if (clipShapeForSymbol.r0) { + clipShapeForSymbol.r0 -= 0.5; + clipShapeForSymbol.r += 0.5; + } + } + this._clipShapeForSymbol = clipShapeForSymbol; + var visualColor = getVisualGradient(data, coordSys, api) || data.getVisual('style')[data.getVisual('drawType')]; + // Initialization animation or coordinate system changed + if (!(polyline && prevCoordSys.type === coordSys.type && step === this._step)) { + showSymbol && symbolDraw.updateData(data, { + isIgnore: isIgnoreFunc, + clipShape: clipShapeForSymbol, + disableAnimation: true, + getSymbolPoint: function (idx) { + return [points[idx * 2], points[idx * 2 + 1]]; + } + }); + hasAnimation && this._initSymbolLabelAnimation(data, coordSys, clipShapeForSymbol); + if (step) { + // TODO If stacked series is not step + points = turnPointsIntoStep(points, coordSys, step, connectNulls); + if (stackedOnPoints) { + stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls); + } + } + polyline = this._newPolyline(points); + if (isAreaChart) { + polygon = this._newPolygon(points, stackedOnPoints); + } // If areaStyle is removed + else if (polygon) { + lineGroup.remove(polygon); + polygon = this._polygon = null; + } + // NOTE: Must update _endLabel before setClipPath. + if (!isCoordSysPolar) { + this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor)); + } + lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel)); + } else { + if (isAreaChart && !polygon) { + // If areaStyle is added + polygon = this._newPolygon(points, stackedOnPoints); + } else if (polygon && !isAreaChart) { + // If areaStyle is removed + lineGroup.remove(polygon); + polygon = this._polygon = null; + } + // NOTE: Must update _endLabel before setClipPath. + if (!isCoordSysPolar) { + this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor)); + } + // Update clipPath + var oldClipPath = lineGroup.getClipPath(); + if (oldClipPath) { + var newClipPath = createLineClipPath(this, coordSys, false, seriesModel); + initProps(oldClipPath, { + shape: newClipPath.shape + }, seriesModel); + } else { + lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel)); + } + // Always update, or it is wrong in the case turning on legend + // because points are not changed. + showSymbol && symbolDraw.updateData(data, { + isIgnore: isIgnoreFunc, + clipShape: clipShapeForSymbol, + disableAnimation: true, + getSymbolPoint: function (idx) { + return [points[idx * 2], points[idx * 2 + 1]]; + } + }); + // In the case data zoom triggered refreshing frequently + // Data may not change if line has a category axis. So it should animate nothing. + if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || !isPointsSame(this._points, points)) { + if (hasAnimation) { + this._doUpdateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls); + } else { + // Not do it in update with animation + if (step) { + // TODO If stacked series is not step + points = turnPointsIntoStep(points, coordSys, step, connectNulls); + if (stackedOnPoints) { + stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls); + } + } + polyline.setShape({ + points: points + }); + polygon && polygon.setShape({ + points: points, + stackedOnPoints: stackedOnPoints + }); + } + } + } + var emphasisModel = seriesModel.getModel('emphasis'); + var focus = emphasisModel.get('focus'); + var blurScope = emphasisModel.get('blurScope'); + var emphasisDisabled = emphasisModel.get('disabled'); + polyline.useStyle(defaults( + // Use color in lineStyle first + lineStyleModel.getLineStyle(), { + fill: 'none', + stroke: visualColor, + lineJoin: 'bevel' + })); + setStatesStylesFromModel(polyline, seriesModel, 'lineStyle'); + if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') { + var emphasisLineStyle = polyline.getState('emphasis').style; + emphasisLineStyle.lineWidth = +polyline.style.lineWidth + 1; + } + // Needs seriesIndex for focus + getECData(polyline).seriesIndex = seriesModel.seriesIndex; + toggleHoverEmphasis(polyline, focus, blurScope, emphasisDisabled); + var smooth = getSmooth(seriesModel.get('smooth')); + var smoothMonotone = seriesModel.get('smoothMonotone'); + polyline.setShape({ + smooth: smooth, + smoothMonotone: smoothMonotone, + connectNulls: connectNulls + }); + if (polygon) { + var stackedOnSeries = data.getCalculationInfo('stackedOnSeries'); + var stackedOnSmooth = 0; + polygon.useStyle(defaults(areaStyleModel.getAreaStyle(), { + fill: visualColor, + opacity: 0.7, + lineJoin: 'bevel', + decal: data.getVisual('style').decal + })); + if (stackedOnSeries) { + stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth')); + } + polygon.setShape({ + smooth: smooth, + stackedOnSmooth: stackedOnSmooth, + smoothMonotone: smoothMonotone, + connectNulls: connectNulls + }); + setStatesStylesFromModel(polygon, seriesModel, 'areaStyle'); + // Needs seriesIndex for focus + getECData(polygon).seriesIndex = seriesModel.seriesIndex; + toggleHoverEmphasis(polygon, focus, blurScope, emphasisDisabled); + } + var changePolyState = function (toState) { + _this._changePolyState(toState); + }; + data.eachItemGraphicEl(function (el) { + // Switch polyline / polygon state if element changed its state. + el && (el.onHoverStateChange = changePolyState); + }); + this._polyline.onHoverStateChange = changePolyState; + this._data = data; + // Save the coordinate system for transition animation when data changed + this._coordSys = coordSys; + this._stackedOnPoints = stackedOnPoints; + this._points = points; + this._step = step; + this._valueOrigin = valueOrigin; + if (seriesModel.get('triggerLineEvent')) { + this.packEventData(seriesModel, polyline); + polygon && this.packEventData(seriesModel, polygon); + } + }; + LineView.prototype.packEventData = function (seriesModel, el) { + getECData(el).eventData = { + componentType: 'series', + componentSubType: 'line', + componentIndex: seriesModel.componentIndex, + seriesIndex: seriesModel.seriesIndex, + seriesName: seriesModel.name, + seriesType: 'line' + }; + }; + LineView.prototype.highlight = function (seriesModel, ecModel, api, payload) { + var data = seriesModel.getData(); + var dataIndex = queryDataIndex(data, payload); + this._changePolyState('emphasis'); + if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) { + var points = data.getLayout('points'); + var symbol = data.getItemGraphicEl(dataIndex); + if (!symbol) { + // Create a temporary symbol if it is not exists + var x = points[dataIndex * 2]; + var y = points[dataIndex * 2 + 1]; + if (isNaN(x) || isNaN(y)) { + // Null data + return; + } + // fix #11360: shouldn't draw symbol outside clipShapeForSymbol + if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) { + return; + } + var zlevel = seriesModel.get('zlevel') || 0; + var z = seriesModel.get('z') || 0; + symbol = new Symbol(data, dataIndex); + symbol.x = x; + symbol.y = y; + symbol.setZ(zlevel, z); + // ensure label text of the temporary symbol is in front of line and area polygon + var symbolLabel = symbol.getSymbolPath().getTextContent(); + if (symbolLabel) { + symbolLabel.zlevel = zlevel; + symbolLabel.z = z; + symbolLabel.z2 = this._polyline.z2 + 1; + } + symbol.__temp = true; + data.setItemGraphicEl(dataIndex, symbol); + // Stop scale animation + symbol.stopSymbolAnimation(true); + this.group.add(symbol); + } + symbol.highlight(); + } else { + // Highlight whole series + ChartView.prototype.highlight.call(this, seriesModel, ecModel, api, payload); + } + }; + LineView.prototype.downplay = function (seriesModel, ecModel, api, payload) { + var data = seriesModel.getData(); + var dataIndex = queryDataIndex(data, payload); + this._changePolyState('normal'); + if (dataIndex != null && dataIndex >= 0) { + var symbol = data.getItemGraphicEl(dataIndex); + if (symbol) { + if (symbol.__temp) { + data.setItemGraphicEl(dataIndex, null); + this.group.remove(symbol); + } else { + symbol.downplay(); + } + } + } else { + // FIXME + // can not downplay completely. + // Downplay whole series + ChartView.prototype.downplay.call(this, seriesModel, ecModel, api, payload); + } + }; + LineView.prototype._changePolyState = function (toState) { + var polygon = this._polygon; + setStatesFlag(this._polyline, toState); + polygon && setStatesFlag(polygon, toState); + }; + LineView.prototype._newPolyline = function (points) { + var polyline = this._polyline; + // Remove previous created polyline + if (polyline) { + this._lineGroup.remove(polyline); + } + polyline = new ECPolyline({ + shape: { + points: points + }, + segmentIgnoreThreshold: 2, + z2: 10 + }); + this._lineGroup.add(polyline); + this._polyline = polyline; + return polyline; + }; + LineView.prototype._newPolygon = function (points, stackedOnPoints) { + var polygon = this._polygon; + // Remove previous created polygon + if (polygon) { + this._lineGroup.remove(polygon); + } + polygon = new ECPolygon({ + shape: { + points: points, + stackedOnPoints: stackedOnPoints + }, + segmentIgnoreThreshold: 2 + }); + this._lineGroup.add(polygon); + this._polygon = polygon; + return polygon; + }; + LineView.prototype._initSymbolLabelAnimation = function (data, coordSys, clipShape) { + var isHorizontalOrRadial; + var isCoordSysPolar; + var baseAxis = coordSys.getBaseAxis(); + var isAxisInverse = baseAxis.inverse; + if (coordSys.type === 'cartesian2d') { + isHorizontalOrRadial = baseAxis.isHorizontal(); + isCoordSysPolar = false; + } else if (coordSys.type === 'polar') { + isHorizontalOrRadial = baseAxis.dim === 'angle'; + isCoordSysPolar = true; + } + var seriesModel = data.hostModel; + var seriesDuration = seriesModel.get('animationDuration'); + if (isFunction(seriesDuration)) { + seriesDuration = seriesDuration(null); + } + var seriesDelay = seriesModel.get('animationDelay') || 0; + var seriesDelayValue = isFunction(seriesDelay) ? seriesDelay(null) : seriesDelay; + data.eachItemGraphicEl(function (symbol, idx) { + var el = symbol; + if (el) { + var point = [symbol.x, symbol.y]; + var start = void 0; + var end = void 0; + var current = void 0; + if (clipShape) { + if (isCoordSysPolar) { + var polarClip = clipShape; + var coord = coordSys.pointToCoord(point); + if (isHorizontalOrRadial) { + start = polarClip.startAngle; + end = polarClip.endAngle; + current = -coord[1] / 180 * Math.PI; + } else { + start = polarClip.r0; + end = polarClip.r; + current = coord[0]; + } + } else { + var gridClip = clipShape; + if (isHorizontalOrRadial) { + start = gridClip.x; + end = gridClip.x + gridClip.width; + current = symbol.x; + } else { + start = gridClip.y + gridClip.height; + end = gridClip.y; + current = symbol.y; + } + } + } + var ratio = end === start ? 0 : (current - start) / (end - start); + if (isAxisInverse) { + ratio = 1 - ratio; + } + var delay = isFunction(seriesDelay) ? seriesDelay(idx) : seriesDuration * ratio + seriesDelayValue; + var symbolPath = el.getSymbolPath(); + var text = symbolPath.getTextContent(); + el.attr({ + scaleX: 0, + scaleY: 0 + }); + el.animateTo({ + scaleX: 1, + scaleY: 1 + }, { + duration: 200, + setToFinal: true, + delay: delay + }); + if (text) { + text.animateFrom({ + style: { + opacity: 0 + } + }, { + duration: 300, + delay: delay + }); + } + symbolPath.disableLabelAnimation = true; + } + }); + }; + LineView.prototype._initOrUpdateEndLabel = function (seriesModel, coordSys, inheritColor) { + var endLabelModel = seriesModel.getModel('endLabel'); + if (anyStateShowEndLabel(seriesModel)) { + var data_2 = seriesModel.getData(); + var polyline = this._polyline; + // series may be filtered. + var points = data_2.getLayout('points'); + if (!points) { + polyline.removeTextContent(); + this._endLabel = null; + return; + } + var endLabel = this._endLabel; + if (!endLabel) { + endLabel = this._endLabel = new ZRText({ + z2: 200 // should be higher than item symbol + }); + + endLabel.ignoreClip = true; + polyline.setTextContent(this._endLabel); + polyline.disableLabelAnimation = true; + } + // Find last non-NaN data to display data + var dataIndex = getLastIndexNotNull(points); + if (dataIndex >= 0) { + setLabelStyle(polyline, getLabelStatesModels(seriesModel, 'endLabel'), { + inheritColor: inheritColor, + labelFetcher: seriesModel, + labelDataIndex: dataIndex, + defaultText: function (dataIndex, opt, interpolatedValue) { + return interpolatedValue != null ? getDefaultInterpolatedLabel(data_2, interpolatedValue) : getDefaultLabel(data_2, dataIndex); + }, + enableTextSetter: true + }, getEndLabelStateSpecified(endLabelModel, coordSys)); + polyline.textConfig.position = null; + } + } else if (this._endLabel) { + this._polyline.removeTextContent(); + this._endLabel = null; + } + }; + LineView.prototype._endLabelOnDuring = function (percent, clipRect, data, animationRecord, valueAnimation, endLabelModel, coordSys) { + var endLabel = this._endLabel; + var polyline = this._polyline; + if (endLabel) { + // NOTE: Don't remove percent < 1. percent === 1 means the first frame during render. + // The label is not prepared at this time. + if (percent < 1 && animationRecord.originalX == null) { + animationRecord.originalX = endLabel.x; + animationRecord.originalY = endLabel.y; + } + var points = data.getLayout('points'); + var seriesModel = data.hostModel; + var connectNulls = seriesModel.get('connectNulls'); + var precision = endLabelModel.get('precision'); + var distance = endLabelModel.get('distance') || 0; + var baseAxis = coordSys.getBaseAxis(); + var isHorizontal = baseAxis.isHorizontal(); + var isBaseInversed = baseAxis.inverse; + var clipShape = clipRect.shape; + var xOrY = isBaseInversed ? isHorizontal ? clipShape.x : clipShape.y + clipShape.height : isHorizontal ? clipShape.x + clipShape.width : clipShape.y; + var distanceX = (isHorizontal ? distance : 0) * (isBaseInversed ? -1 : 1); + var distanceY = (isHorizontal ? 0 : -distance) * (isBaseInversed ? -1 : 1); + var dim = isHorizontal ? 'x' : 'y'; + var dataIndexRange = getIndexRange(points, xOrY, dim); + var indices = dataIndexRange.range; + var diff = indices[1] - indices[0]; + var value = void 0; + if (diff >= 1) { + // diff > 1 && connectNulls, which is on the null data. + if (diff > 1 && !connectNulls) { + var pt = getPointAtIndex(points, indices[0]); + endLabel.attr({ + x: pt[0] + distanceX, + y: pt[1] + distanceY + }); + valueAnimation && (value = seriesModel.getRawValue(indices[0])); + } else { + var pt = polyline.getPointOn(xOrY, dim); + pt && endLabel.attr({ + x: pt[0] + distanceX, + y: pt[1] + distanceY + }); + var startValue = seriesModel.getRawValue(indices[0]); + var endValue = seriesModel.getRawValue(indices[1]); + valueAnimation && (value = interpolateRawValues(data, precision, startValue, endValue, dataIndexRange.t)); + } + animationRecord.lastFrameIndex = indices[0]; + } else { + // If diff <= 0, which is the range is not found(Include NaN) + // Choose the first point or last point. + var idx = percent === 1 || animationRecord.lastFrameIndex > 0 ? indices[0] : 0; + var pt = getPointAtIndex(points, idx); + valueAnimation && (value = seriesModel.getRawValue(idx)); + endLabel.attr({ + x: pt[0] + distanceX, + y: pt[1] + distanceY + }); + } + if (valueAnimation) { + var inner = labelInner(endLabel); + if (typeof inner.setLabelText === 'function') { + inner.setLabelText(value); + } + } + } + }; + /** + * @private + */ + // FIXME Two value axis + LineView.prototype._doUpdateAnimation = function (data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls) { + var polyline = this._polyline; + var polygon = this._polygon; + var seriesModel = data.hostModel; + var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin); + var current = diff.current; + var stackedOnCurrent = diff.stackedOnCurrent; + var next = diff.next; + var stackedOnNext = diff.stackedOnNext; + if (step) { + // TODO If stacked series is not step + current = turnPointsIntoStep(diff.current, coordSys, step, connectNulls); + stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step, connectNulls); + next = turnPointsIntoStep(diff.next, coordSys, step, connectNulls); + stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step, connectNulls); + } + // Don't apply animation if diff is large. + // For better result and avoid memory explosion problems like + // https://github.com/apache/incubator-echarts/issues/12229 + if (getBoundingDiff(current, next) > 3000 || polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000) { + polyline.stopAnimation(); + polyline.setShape({ + points: next + }); + if (polygon) { + polygon.stopAnimation(); + polygon.setShape({ + points: next, + stackedOnPoints: stackedOnNext + }); + } + return; + } + polyline.shape.__points = diff.current; + polyline.shape.points = current; + var target = { + shape: { + points: next + } + }; + // Also animate the original points. + // If points reference is changed when turning into step line. + if (diff.current !== current) { + target.shape.__points = diff.next; + } + // Stop previous animation. + polyline.stopAnimation(); + updateProps(polyline, target, seriesModel); + if (polygon) { + polygon.setShape({ + // Reuse the points with polyline. + points: current, + stackedOnPoints: stackedOnCurrent + }); + polygon.stopAnimation(); + updateProps(polygon, { + shape: { + stackedOnPoints: stackedOnNext + } + }, seriesModel); + // If use attr directly in updateProps. + if (polyline.shape.points !== polygon.shape.points) { + polygon.shape.points = polyline.shape.points; + } + } + var updatedDataInfo = []; + var diffStatus = diff.status; + for (var i = 0; i < diffStatus.length; i++) { + var cmd = diffStatus[i].cmd; + if (cmd === '=') { + var el = data.getItemGraphicEl(diffStatus[i].idx1); + if (el) { + updatedDataInfo.push({ + el: el, + ptIdx: i // Index of points + }); + } + } + } + + if (polyline.animators && polyline.animators.length) { + polyline.animators[0].during(function () { + polygon && polygon.dirtyShape(); + var points = polyline.shape.__points; + for (var i = 0; i < updatedDataInfo.length; i++) { + var el = updatedDataInfo[i].el; + var offset = updatedDataInfo[i].ptIdx * 2; + el.x = points[offset]; + el.y = points[offset + 1]; + el.markRedraw(); + } + }); + } + }; + LineView.prototype.remove = function (ecModel) { + var group = this.group; + var oldData = this._data; + this._lineGroup.removeAll(); + this._symbolDraw.remove(true); + // Remove temporary created elements when highlighting + oldData && oldData.eachItemGraphicEl(function (el, idx) { + if (el.__temp) { + group.remove(el); + oldData.setItemGraphicEl(idx, null); + } + }); + this._polyline = this._polygon = this._coordSys = this._points = this._stackedOnPoints = this._endLabel = this._data = null; + }; + LineView.type = 'line'; + return LineView; + }(ChartView); + + function pointsLayout(seriesType, forceStoreInTypedArray) { + return { + seriesType: seriesType, + plan: createRenderPlanner(), + reset: function (seriesModel) { + var data = seriesModel.getData(); + var coordSys = seriesModel.coordinateSystem; + var pipelineContext = seriesModel.pipelineContext; + var useTypedArray = forceStoreInTypedArray || pipelineContext.large; + if (!coordSys) { + return; + } + var dims = map(coordSys.dimensions, function (dim) { + return data.mapDimension(dim); + }).slice(0, 2); + var dimLen = dims.length; + var stackResultDim = data.getCalculationInfo('stackResultDimension'); + if (isDimensionStacked(data, dims[0])) { + dims[0] = stackResultDim; + } + if (isDimensionStacked(data, dims[1])) { + dims[1] = stackResultDim; + } + var store = data.getStore(); + var dimIdx0 = data.getDimensionIndex(dims[0]); + var dimIdx1 = data.getDimensionIndex(dims[1]); + return dimLen && { + progress: function (params, data) { + var segCount = params.end - params.start; + var points = useTypedArray && createFloat32Array(segCount * dimLen); + var tmpIn = []; + var tmpOut = []; + for (var i = params.start, offset = 0; i < params.end; i++) { + var point = void 0; + if (dimLen === 1) { + var x = store.get(dimIdx0, i); + // NOTE: Make sure the second parameter is null to use default strategy. + point = coordSys.dataToPoint(x, null, tmpOut); + } else { + tmpIn[0] = store.get(dimIdx0, i); + tmpIn[1] = store.get(dimIdx1, i); + // Let coordinate system to handle the NaN data. + point = coordSys.dataToPoint(tmpIn, null, tmpOut); + } + if (useTypedArray) { + points[offset++] = point[0]; + points[offset++] = point[1]; + } else { + data.setItemLayout(i, point.slice()); + } + } + useTypedArray && data.setLayout('points', points); + } + }; + } + }; + } + + var samplers = { + average: function (frame) { + var sum = 0; + var count = 0; + for (var i = 0; i < frame.length; i++) { + if (!isNaN(frame[i])) { + sum += frame[i]; + count++; + } + } + // Return NaN if count is 0 + return count === 0 ? NaN : sum / count; + }, + sum: function (frame) { + var sum = 0; + for (var i = 0; i < frame.length; i++) { + // Ignore NaN + sum += frame[i] || 0; + } + return sum; + }, + max: function (frame) { + var max = -Infinity; + for (var i = 0; i < frame.length; i++) { + frame[i] > max && (max = frame[i]); + } + // NaN will cause illegal axis extent. + return isFinite(max) ? max : NaN; + }, + min: function (frame) { + var min = Infinity; + for (var i = 0; i < frame.length; i++) { + frame[i] < min && (min = frame[i]); + } + // NaN will cause illegal axis extent. + return isFinite(min) ? min : NaN; + }, + minmax: function (frame) { + var turningPointAbsoluteValue = -Infinity; + var turningPointOriginalValue = -Infinity; + for (var i = 0; i < frame.length; i++) { + var originalValue = frame[i]; + var absoluteValue = Math.abs(originalValue); + if (absoluteValue > turningPointAbsoluteValue) { + turningPointAbsoluteValue = absoluteValue; + turningPointOriginalValue = originalValue; + } + } + return isFinite(turningPointOriginalValue) ? turningPointOriginalValue : NaN; + }, + // TODO + // Median + nearest: function (frame) { + return frame[0]; + } + }; + var indexSampler = function (frame) { + return Math.round(frame.length / 2); + }; + function dataSample(seriesType) { + return { + seriesType: seriesType, + // FIXME:TS never used, so comment it + // modifyOutputEnd: true, + reset: function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var sampling = seriesModel.get('sampling'); + var coordSys = seriesModel.coordinateSystem; + var count = data.count(); + // Only cartesian2d support down sampling. Disable it when there is few data. + if (count > 10 && coordSys.type === 'cartesian2d' && sampling) { + var baseAxis = coordSys.getBaseAxis(); + var valueAxis = coordSys.getOtherAxis(baseAxis); + var extent = baseAxis.getExtent(); + var dpr = api.getDevicePixelRatio(); + // Coordinste system has been resized + var size = Math.abs(extent[1] - extent[0]) * (dpr || 1); + var rate = Math.round(count / size); + if (isFinite(rate) && rate > 1) { + if (sampling === 'lttb') { + seriesModel.setData(data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate)); + } + var sampler = void 0; + if (isString(sampling)) { + sampler = samplers[sampling]; + } else if (isFunction(sampling)) { + sampler = sampling; + } + if (sampler) { + // Only support sample the first dim mapped from value axis. + seriesModel.setData(data.downSample(data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler)); + } + } + } + } + }; + } + + function install$2(registers) { + registers.registerChartView(LineView); + registers.registerSeriesModel(LineSeriesModel); + registers.registerLayout(pointsLayout('line', true)); + registers.registerVisual({ + seriesType: 'line', + reset: function (seriesModel) { + var data = seriesModel.getData(); + // Visual coding for legend + var lineStyle = seriesModel.getModel('lineStyle').getLineStyle(); + if (lineStyle && !lineStyle.stroke) { + // Fill in visual should be palette color if + // has color callback + lineStyle.stroke = data.getVisual('style').fill; + } + data.setVisual('legendLineStyle', lineStyle); + } + }); + // Down sample after filter + registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('line')); + } + + var BaseBarSeriesModel = /** @class */function (_super) { + __extends(BaseBarSeriesModel, _super); + function BaseBarSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = BaseBarSeriesModel.type; + return _this; + } + BaseBarSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesData(null, this, { + useEncodeDefaulter: true + }); + }; + BaseBarSeriesModel.prototype.getMarkerPosition = function (value, dims, startingAtTick) { + var coordSys = this.coordinateSystem; + if (coordSys && coordSys.clampData) { + // PENDING if clamp ? + var clampData_1 = coordSys.clampData(value); + var pt_1 = coordSys.dataToPoint(clampData_1); + if (startingAtTick) { + each(coordSys.getAxes(), function (axis, idx) { + // If axis type is category, use tick coords instead + if (axis.type === 'category' && dims != null) { + var tickCoords = axis.getTicksCoords(); + var alignTicksWithLabel = axis.getTickModel().get('alignWithLabel'); + var targetTickId = clampData_1[idx]; + // The index of rightmost tick of markArea is 1 larger than x1/y1 index + var isEnd = dims[idx] === 'x1' || dims[idx] === 'y1'; + if (isEnd && !alignTicksWithLabel) { + targetTickId += 1; + } + // The only contains one tick, tickCoords is + // like [{coord: 0, tickValue: 0}, {coord: 0}] + // to the length should always be larger than 1 + if (tickCoords.length < 2) { + return; + } else if (tickCoords.length === 2) { + // The left value and right value of the axis are + // the same. coord is 0 in both items. Use the max + // value of the axis as the coord + pt_1[idx] = axis.toGlobalCoord(axis.getExtent()[isEnd ? 1 : 0]); + return; + } + var leftCoord = void 0; + var coord = void 0; + var stepTickValue = 1; + for (var i = 0; i < tickCoords.length; i++) { + var tickCoord = tickCoords[i].coord; + // The last item of tickCoords doesn't contain + // tickValue + var tickValue = i === tickCoords.length - 1 ? tickCoords[i - 1].tickValue + stepTickValue : tickCoords[i].tickValue; + if (tickValue === targetTickId) { + coord = tickCoord; + break; + } else if (tickValue < targetTickId) { + leftCoord = tickCoord; + } else if (leftCoord != null && tickValue > targetTickId) { + coord = (tickCoord + leftCoord) / 2; + break; + } + if (i === 1) { + // Here we assume the step of category axes is + // the same + stepTickValue = tickValue - tickCoords[0].tickValue; + } + } + if (coord == null) { + if (!leftCoord) { + // targetTickId is smaller than all tick ids in the + // visible area, use the leftmost tick coord + coord = tickCoords[0].coord; + } else if (leftCoord) { + // targetTickId is larger than all tick ids in the + // visible area, use the rightmost tick coord + coord = tickCoords[tickCoords.length - 1].coord; + } + } + pt_1[idx] = axis.toGlobalCoord(coord); + } + }); + } else { + var data = this.getData(); + var offset = data.getLayout('offset'); + var size = data.getLayout('size'); + var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1; + pt_1[offsetIndex] += offset + size / 2; + } + return pt_1; + } + return [NaN, NaN]; + }; + BaseBarSeriesModel.type = 'series.__base_bar__'; + BaseBarSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + coordinateSystem: 'cartesian2d', + legendHoverLink: true, + // stack: null + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + barMinHeight: 0, + barMinAngle: 0, + // cursor: null, + large: false, + largeThreshold: 400, + progressive: 3e3, + progressiveChunkMode: 'mod' + }; + return BaseBarSeriesModel; + }(SeriesModel); + SeriesModel.registerClass(BaseBarSeriesModel); + + var BarSeriesModel = /** @class */function (_super) { + __extends(BarSeriesModel, _super); + function BarSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = BarSeriesModel.type; + return _this; + } + BarSeriesModel.prototype.getInitialData = function () { + return createSeriesData(null, this, { + useEncodeDefaulter: true, + createInvertedIndices: !!this.get('realtimeSort', true) || null + }); + }; + /** + * @override + */ + BarSeriesModel.prototype.getProgressive = function () { + // Do not support progressive in normal mode. + return this.get('large') ? this.get('progressive') : false; + }; + /** + * @override + */ + BarSeriesModel.prototype.getProgressiveThreshold = function () { + // Do not support progressive in normal mode. + var progressiveThreshold = this.get('progressiveThreshold'); + var largeThreshold = this.get('largeThreshold'); + if (largeThreshold > progressiveThreshold) { + progressiveThreshold = largeThreshold; + } + return progressiveThreshold; + }; + BarSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) { + return selectors.rect(data.getItemLayout(dataIndex)); + }; + BarSeriesModel.type = 'series.bar'; + BarSeriesModel.dependencies = ['grid', 'polar']; + BarSeriesModel.defaultOption = inheritDefaultOption(BaseBarSeriesModel.defaultOption, { + // If clipped + // Only available on cartesian2d + clip: true, + roundCap: false, + showBackground: false, + backgroundStyle: { + color: 'rgba(180, 180, 180, 0.2)', + borderColor: null, + borderWidth: 0, + borderType: 'solid', + borderRadius: 0, + shadowBlur: 0, + shadowColor: null, + shadowOffsetX: 0, + shadowOffsetY: 0, + opacity: 1 + }, + select: { + itemStyle: { + borderColor: '#212121' + } + }, + realtimeSort: false + }); + return BarSeriesModel; + }(BaseBarSeriesModel); + + /** + * Sausage: similar to sector, but have half circle on both sides + */ + var SausageShape = /** @class */function () { + function SausageShape() { + this.cx = 0; + this.cy = 0; + this.r0 = 0; + this.r = 0; + this.startAngle = 0; + this.endAngle = Math.PI * 2; + this.clockwise = true; + } + return SausageShape; + }(); + var SausagePath = /** @class */function (_super) { + __extends(SausagePath, _super); + function SausagePath(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'sausage'; + return _this; + } + SausagePath.prototype.getDefaultShape = function () { + return new SausageShape(); + }; + SausagePath.prototype.buildPath = function (ctx, shape) { + var cx = shape.cx; + var cy = shape.cy; + var r0 = Math.max(shape.r0 || 0, 0); + var r = Math.max(shape.r, 0); + var dr = (r - r0) * 0.5; + var rCenter = r0 + dr; + var startAngle = shape.startAngle; + var endAngle = shape.endAngle; + var clockwise = shape.clockwise; + var PI2 = Math.PI * 2; + var lessThanCircle = clockwise ? endAngle - startAngle < PI2 : startAngle - endAngle < PI2; + if (!lessThanCircle) { + // Normalize angles + startAngle = endAngle - (clockwise ? PI2 : -PI2); + } + var unitStartX = Math.cos(startAngle); + var unitStartY = Math.sin(startAngle); + var unitEndX = Math.cos(endAngle); + var unitEndY = Math.sin(endAngle); + if (lessThanCircle) { + ctx.moveTo(unitStartX * r0 + cx, unitStartY * r0 + cy); + ctx.arc(unitStartX * rCenter + cx, unitStartY * rCenter + cy, dr, -Math.PI + startAngle, startAngle, !clockwise); + } else { + ctx.moveTo(unitStartX * r + cx, unitStartY * r + cy); + } + ctx.arc(cx, cy, r, startAngle, endAngle, !clockwise); + ctx.arc(unitEndX * rCenter + cx, unitEndY * rCenter + cy, dr, endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise); + if (r0 !== 0) { + ctx.arc(cx, cy, r0, endAngle, startAngle, clockwise); + } + // ctx.closePath(); + }; + + return SausagePath; + }(Path); + + function createSectorCalculateTextPosition(positionMapping, opts) { + opts = opts || {}; + var isRoundCap = opts.isRoundCap; + return function (out, opts, boundingRect) { + var textPosition = opts.position; + if (!textPosition || textPosition instanceof Array) { + return calculateTextPosition(out, opts, boundingRect); + } + var mappedSectorPosition = positionMapping(textPosition); + var distance = opts.distance != null ? opts.distance : 5; + var sector = this.shape; + var cx = sector.cx; + var cy = sector.cy; + var r = sector.r; + var r0 = sector.r0; + var middleR = (r + r0) / 2; + var startAngle = sector.startAngle; + var endAngle = sector.endAngle; + var middleAngle = (startAngle + endAngle) / 2; + var extraDist = isRoundCap ? Math.abs(r - r0) / 2 : 0; + var mathCos = Math.cos; + var mathSin = Math.sin; + // base position: top-left + var x = cx + r * mathCos(startAngle); + var y = cy + r * mathSin(startAngle); + var textAlign = 'left'; + var textVerticalAlign = 'top'; + switch (mappedSectorPosition) { + case 'startArc': + x = cx + (r0 - distance) * mathCos(middleAngle); + y = cy + (r0 - distance) * mathSin(middleAngle); + textAlign = 'center'; + textVerticalAlign = 'top'; + break; + case 'insideStartArc': + x = cx + (r0 + distance) * mathCos(middleAngle); + y = cy + (r0 + distance) * mathSin(middleAngle); + textAlign = 'center'; + textVerticalAlign = 'bottom'; + break; + case 'startAngle': + x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, distance + extraDist, false); + y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, distance + extraDist, false); + textAlign = 'right'; + textVerticalAlign = 'middle'; + break; + case 'insideStartAngle': + x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, -distance + extraDist, false); + y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, -distance + extraDist, false); + textAlign = 'left'; + textVerticalAlign = 'middle'; + break; + case 'middle': + x = cx + middleR * mathCos(middleAngle); + y = cy + middleR * mathSin(middleAngle); + textAlign = 'center'; + textVerticalAlign = 'middle'; + break; + case 'endArc': + x = cx + (r + distance) * mathCos(middleAngle); + y = cy + (r + distance) * mathSin(middleAngle); + textAlign = 'center'; + textVerticalAlign = 'bottom'; + break; + case 'insideEndArc': + x = cx + (r - distance) * mathCos(middleAngle); + y = cy + (r - distance) * mathSin(middleAngle); + textAlign = 'center'; + textVerticalAlign = 'top'; + break; + case 'endAngle': + x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, distance + extraDist, true); + y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, distance + extraDist, true); + textAlign = 'left'; + textVerticalAlign = 'middle'; + break; + case 'insideEndAngle': + x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, -distance + extraDist, true); + y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, -distance + extraDist, true); + textAlign = 'right'; + textVerticalAlign = 'middle'; + break; + default: + return calculateTextPosition(out, opts, boundingRect); + } + out = out || {}; + out.x = x; + out.y = y; + out.align = textAlign; + out.verticalAlign = textVerticalAlign; + return out; + }; + } + function setSectorTextRotation(sector, textPosition, positionMapping, rotateType) { + if (isNumber(rotateType)) { + // user-set rotation + sector.setTextConfig({ + rotation: rotateType + }); + return; + } else if (isArray(textPosition)) { + // user-set position, use 0 as auto rotation + sector.setTextConfig({ + rotation: 0 + }); + return; + } + var shape = sector.shape; + var startAngle = shape.clockwise ? shape.startAngle : shape.endAngle; + var endAngle = shape.clockwise ? shape.endAngle : shape.startAngle; + var middleAngle = (startAngle + endAngle) / 2; + var anchorAngle; + var mappedSectorPosition = positionMapping(textPosition); + switch (mappedSectorPosition) { + case 'startArc': + case 'insideStartArc': + case 'middle': + case 'insideEndArc': + case 'endArc': + anchorAngle = middleAngle; + break; + case 'startAngle': + case 'insideStartAngle': + anchorAngle = startAngle; + break; + case 'endAngle': + case 'insideEndAngle': + anchorAngle = endAngle; + break; + default: + sector.setTextConfig({ + rotation: 0 + }); + return; + } + var rotate = Math.PI * 1.5 - anchorAngle; + /** + * TODO: labels with rotate > Math.PI / 2 should be rotate another + * half round flipped to increase readability. However, only middle + * position supports this for now, because in other positions, the + * anchor point is not at the center of the text, so the positions + * after rotating is not as expected. + */ + if (mappedSectorPosition === 'middle' && rotate > Math.PI / 2 && rotate < Math.PI * 1.5) { + rotate -= Math.PI; + } + sector.setTextConfig({ + rotation: rotate + }); + } + function adjustAngleDistanceX(angle, distance, isEnd) { + return distance * Math.sin(angle) * (isEnd ? -1 : 1); + } + function adjustAngleDistanceY(angle, distance, isEnd) { + return distance * Math.cos(angle) * (isEnd ? 1 : -1); + } + + function getSectorCornerRadius(model, shape, zeroIfNull) { + var cornerRadius = model.get('borderRadius'); + if (cornerRadius == null) { + return zeroIfNull ? { + cornerRadius: 0 + } : null; + } + if (!isArray(cornerRadius)) { + cornerRadius = [cornerRadius, cornerRadius, cornerRadius, cornerRadius]; + } + var dr = Math.abs(shape.r || 0 - shape.r0 || 0); + return { + cornerRadius: map(cornerRadius, function (cr) { + return parsePercent(cr, dr); + }) + }; + } + + var mathMax$6 = Math.max; + var mathMin$6 = Math.min; + function getClipArea(coord, data) { + var coordSysClipArea = coord.getArea && coord.getArea(); + if (isCoordinateSystemType(coord, 'cartesian2d')) { + var baseAxis = coord.getBaseAxis(); + // When boundaryGap is false or using time axis. bar may exceed the grid. + // We should not clip this part. + // See test/bar2.html + if (baseAxis.type !== 'category' || !baseAxis.onBand) { + var expandWidth = data.getLayout('bandWidth'); + if (baseAxis.isHorizontal()) { + coordSysClipArea.x -= expandWidth; + coordSysClipArea.width += expandWidth * 2; + } else { + coordSysClipArea.y -= expandWidth; + coordSysClipArea.height += expandWidth * 2; + } + } + } + return coordSysClipArea; + } + var BarView = /** @class */function (_super) { + __extends(BarView, _super); + function BarView() { + var _this = _super.call(this) || this; + _this.type = BarView.type; + _this._isFirstFrame = true; + return _this; + } + BarView.prototype.render = function (seriesModel, ecModel, api, payload) { + this._model = seriesModel; + this._removeOnRenderedListener(api); + this._updateDrawMode(seriesModel); + var coordinateSystemType = seriesModel.get('coordinateSystem'); + if (coordinateSystemType === 'cartesian2d' || coordinateSystemType === 'polar') { + // Clear previously rendered progressive elements. + this._progressiveEls = null; + this._isLargeDraw ? this._renderLarge(seriesModel, ecModel, api) : this._renderNormal(seriesModel, ecModel, api, payload); + } else if ("development" !== 'production') { + warn('Only cartesian2d and polar supported for bar.'); + } + }; + BarView.prototype.incrementalPrepareRender = function (seriesModel) { + this._clear(); + this._updateDrawMode(seriesModel); + // incremental also need to clip, otherwise might be overlow. + // But must not set clip in each frame, otherwise all of the children will be marked redraw. + this._updateLargeClip(seriesModel); + }; + BarView.prototype.incrementalRender = function (params, seriesModel) { + // Reset + this._progressiveEls = []; + // Do not support progressive in normal mode. + this._incrementalRenderLarge(params, seriesModel); + }; + BarView.prototype.eachRendered = function (cb) { + traverseElements(this._progressiveEls || this.group, cb); + }; + BarView.prototype._updateDrawMode = function (seriesModel) { + var isLargeDraw = seriesModel.pipelineContext.large; + if (this._isLargeDraw == null || isLargeDraw !== this._isLargeDraw) { + this._isLargeDraw = isLargeDraw; + this._clear(); + } + }; + BarView.prototype._renderNormal = function (seriesModel, ecModel, api, payload) { + var group = this.group; + var data = seriesModel.getData(); + var oldData = this._data; + var coord = seriesModel.coordinateSystem; + var baseAxis = coord.getBaseAxis(); + var isHorizontalOrRadial; + if (coord.type === 'cartesian2d') { + isHorizontalOrRadial = baseAxis.isHorizontal(); + } else if (coord.type === 'polar') { + isHorizontalOrRadial = baseAxis.dim === 'angle'; + } + var animationModel = seriesModel.isAnimationEnabled() ? seriesModel : null; + var realtimeSortCfg = shouldRealtimeSort(seriesModel, coord); + if (realtimeSortCfg) { + this._enableRealtimeSort(realtimeSortCfg, data, api); + } + var needsClip = seriesModel.get('clip', true) || realtimeSortCfg; + var coordSysClipArea = getClipArea(coord, data); + // If there is clipPath created in large mode. Remove it. + group.removeClipPath(); + // We don't use clipPath in normal mode because we needs a perfect animation + // And don't want the label are clipped. + var roundCap = seriesModel.get('roundCap', true); + var drawBackground = seriesModel.get('showBackground', true); + var backgroundModel = seriesModel.getModel('backgroundStyle'); + var barBorderRadius = backgroundModel.get('borderRadius') || 0; + var bgEls = []; + var oldBgEls = this._backgroundEls; + var isInitSort = payload && payload.isInitSort; + var isChangeOrder = payload && payload.type === 'changeAxisOrder'; + function createBackground(dataIndex) { + var bgLayout = getLayout[coord.type](data, dataIndex); + var bgEl = createBackgroundEl(coord, isHorizontalOrRadial, bgLayout); + bgEl.useStyle(backgroundModel.getItemStyle()); + // Only cartesian2d support borderRadius. + if (coord.type === 'cartesian2d') { + bgEl.setShape('r', barBorderRadius); + } else { + bgEl.setShape('cornerRadius', barBorderRadius); + } + bgEls[dataIndex] = bgEl; + return bgEl; + } + data.diff(oldData).add(function (dataIndex) { + var itemModel = data.getItemModel(dataIndex); + var layout = getLayout[coord.type](data, dataIndex, itemModel); + if (drawBackground) { + createBackground(dataIndex); + } + // If dataZoom in filteMode: 'empty', the baseValue can be set as NaN in "axisProxy". + if (!data.hasValue(dataIndex) || !isValidLayout[coord.type](layout)) { + return; + } + var isClipped = false; + if (needsClip) { + // Clip will modify the layout params. + // And return a boolean to determine if the shape are fully clipped. + isClipped = clip[coord.type](coordSysClipArea, layout); + } + var el = elementCreator[coord.type](seriesModel, data, dataIndex, layout, isHorizontalOrRadial, animationModel, baseAxis.model, false, roundCap); + if (realtimeSortCfg) { + /** + * Force label animation because even if the element is + * ignored because it's clipped, it may not be clipped after + * changing order. Then, if not using forceLabelAnimation, + * the label animation was never started, in which case, + * the label will be the final value and doesn't have label + * animation. + */ + el.forceLabelAnimation = true; + } + updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar'); + if (isInitSort) { + el.attr({ + shape: layout + }); + } else if (realtimeSortCfg) { + updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, dataIndex, isHorizontalOrRadial, false, false); + } else { + initProps(el, { + shape: layout + }, seriesModel, dataIndex); + } + data.setItemGraphicEl(dataIndex, el); + group.add(el); + el.ignore = isClipped; + }).update(function (newIndex, oldIndex) { + var itemModel = data.getItemModel(newIndex); + var layout = getLayout[coord.type](data, newIndex, itemModel); + if (drawBackground) { + var bgEl = void 0; + if (oldBgEls.length === 0) { + bgEl = createBackground(oldIndex); + } else { + bgEl = oldBgEls[oldIndex]; + bgEl.useStyle(backgroundModel.getItemStyle()); + // Only cartesian2d support borderRadius. + if (coord.type === 'cartesian2d') { + bgEl.setShape('r', barBorderRadius); + } else { + bgEl.setShape('cornerRadius', barBorderRadius); + } + bgEls[newIndex] = bgEl; + } + var bgLayout = getLayout[coord.type](data, newIndex); + var shape = createBackgroundShape(isHorizontalOrRadial, bgLayout, coord); + updateProps(bgEl, { + shape: shape + }, animationModel, newIndex); + } + var el = oldData.getItemGraphicEl(oldIndex); + if (!data.hasValue(newIndex) || !isValidLayout[coord.type](layout)) { + group.remove(el); + return; + } + var isClipped = false; + if (needsClip) { + isClipped = clip[coord.type](coordSysClipArea, layout); + if (isClipped) { + group.remove(el); + } + } + if (!el) { + el = elementCreator[coord.type](seriesModel, data, newIndex, layout, isHorizontalOrRadial, animationModel, baseAxis.model, !!el, roundCap); + } else { + saveOldStyle(el); + } + if (realtimeSortCfg) { + el.forceLabelAnimation = true; + } + if (isChangeOrder) { + var textEl = el.getTextContent(); + if (textEl) { + var labelInnerStore = labelInner(textEl); + if (labelInnerStore.prevValue != null) { + /** + * Set preValue to be value so that no new label + * should be started, otherwise, it will take a full + * `animationDurationUpdate` time to finish the + * animation, which is not expected. + */ + labelInnerStore.prevValue = labelInnerStore.value; + } + } + } + // Not change anything if only order changed. + // Especially not change label. + else { + updateStyle(el, data, newIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar'); + } + if (isInitSort) { + el.attr({ + shape: layout + }); + } else if (realtimeSortCfg) { + updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, newIndex, isHorizontalOrRadial, true, isChangeOrder); + } else { + updateProps(el, { + shape: layout + }, seriesModel, newIndex, null); + } + data.setItemGraphicEl(newIndex, el); + el.ignore = isClipped; + group.add(el); + }).remove(function (dataIndex) { + var el = oldData.getItemGraphicEl(dataIndex); + el && removeElementWithFadeOut(el, seriesModel, dataIndex); + }).execute(); + var bgGroup = this._backgroundGroup || (this._backgroundGroup = new Group()); + bgGroup.removeAll(); + for (var i = 0; i < bgEls.length; ++i) { + bgGroup.add(bgEls[i]); + } + group.add(bgGroup); + this._backgroundEls = bgEls; + this._data = data; + }; + BarView.prototype._renderLarge = function (seriesModel, ecModel, api) { + this._clear(); + createLarge(seriesModel, this.group); + this._updateLargeClip(seriesModel); + }; + BarView.prototype._incrementalRenderLarge = function (params, seriesModel) { + this._removeBackground(); + createLarge(seriesModel, this.group, this._progressiveEls, true); + }; + BarView.prototype._updateLargeClip = function (seriesModel) { + // Use clipPath in large mode. + var clipPath = seriesModel.get('clip', true) && createClipPath(seriesModel.coordinateSystem, false, seriesModel); + var group = this.group; + if (clipPath) { + group.setClipPath(clipPath); + } else { + group.removeClipPath(); + } + }; + BarView.prototype._enableRealtimeSort = function (realtimeSortCfg, data, api) { + var _this = this; + // If no data in the first frame, wait for data to initSort + if (!data.count()) { + return; + } + var baseAxis = realtimeSortCfg.baseAxis; + if (this._isFirstFrame) { + this._dispatchInitSort(data, realtimeSortCfg, api); + this._isFirstFrame = false; + } else { + var orderMapping_1 = function (idx) { + var el = data.getItemGraphicEl(idx); + var shape = el && el.shape; + return shape && + // The result should be consistent with the initial sort by data value. + // Do not support the case that both positive and negative exist. + Math.abs(baseAxis.isHorizontal() ? shape.height : shape.width) + // If data is NaN, shape.xxx may be NaN, so use || 0 here in case + || 0; + }; + this._onRendered = function () { + _this._updateSortWithinSameData(data, orderMapping_1, baseAxis, api); + }; + api.getZr().on('rendered', this._onRendered); + } + }; + BarView.prototype._dataSort = function (data, baseAxis, orderMapping) { + var info = []; + data.each(data.mapDimension(baseAxis.dim), function (ordinalNumber, dataIdx) { + var mappedValue = orderMapping(dataIdx); + mappedValue = mappedValue == null ? NaN : mappedValue; + info.push({ + dataIndex: dataIdx, + mappedValue: mappedValue, + ordinalNumber: ordinalNumber + }); + }); + info.sort(function (a, b) { + // If NaN, it will be treated as min val. + return b.mappedValue - a.mappedValue; + }); + return { + ordinalNumbers: map(info, function (item) { + return item.ordinalNumber; + }) + }; + }; + BarView.prototype._isOrderChangedWithinSameData = function (data, orderMapping, baseAxis) { + var scale = baseAxis.scale; + var ordinalDataDim = data.mapDimension(baseAxis.dim); + var lastValue = Number.MAX_VALUE; + for (var tickNum = 0, len = scale.getOrdinalMeta().categories.length; tickNum < len; ++tickNum) { + var rawIdx = data.rawIndexOf(ordinalDataDim, scale.getRawOrdinalNumber(tickNum)); + var value = rawIdx < 0 + // If some tick have no bar, the tick will be treated as min. + ? Number.MIN_VALUE + // PENDING: if dataZoom on baseAxis exits, is it a performance issue? + : orderMapping(data.indexOfRawIndex(rawIdx)); + if (value > lastValue) { + return true; + } + lastValue = value; + } + return false; + }; + /* + * Consider the case when A and B changed order, whose representing + * bars are both out of sight, we don't wish to trigger reorder action + * as long as the order in the view doesn't change. + */ + BarView.prototype._isOrderDifferentInView = function (orderInfo, baseAxis) { + var scale = baseAxis.scale; + var extent = scale.getExtent(); + var tickNum = Math.max(0, extent[0]); + var tickMax = Math.min(extent[1], scale.getOrdinalMeta().categories.length - 1); + for (; tickNum <= tickMax; ++tickNum) { + if (orderInfo.ordinalNumbers[tickNum] !== scale.getRawOrdinalNumber(tickNum)) { + return true; + } + } + }; + BarView.prototype._updateSortWithinSameData = function (data, orderMapping, baseAxis, api) { + if (!this._isOrderChangedWithinSameData(data, orderMapping, baseAxis)) { + return; + } + var sortInfo = this._dataSort(data, baseAxis, orderMapping); + if (this._isOrderDifferentInView(sortInfo, baseAxis)) { + this._removeOnRenderedListener(api); + api.dispatchAction({ + type: 'changeAxisOrder', + componentType: baseAxis.dim + 'Axis', + axisId: baseAxis.index, + sortInfo: sortInfo + }); + } + }; + BarView.prototype._dispatchInitSort = function (data, realtimeSortCfg, api) { + var baseAxis = realtimeSortCfg.baseAxis; + var sortResult = this._dataSort(data, baseAxis, function (dataIdx) { + return data.get(data.mapDimension(realtimeSortCfg.otherAxis.dim), dataIdx); + }); + api.dispatchAction({ + type: 'changeAxisOrder', + componentType: baseAxis.dim + 'Axis', + isInitSort: true, + axisId: baseAxis.index, + sortInfo: sortResult + }); + }; + BarView.prototype.remove = function (ecModel, api) { + this._clear(this._model); + this._removeOnRenderedListener(api); + }; + BarView.prototype.dispose = function (ecModel, api) { + this._removeOnRenderedListener(api); + }; + BarView.prototype._removeOnRenderedListener = function (api) { + if (this._onRendered) { + api.getZr().off('rendered', this._onRendered); + this._onRendered = null; + } + }; + BarView.prototype._clear = function (model) { + var group = this.group; + var data = this._data; + if (model && model.isAnimationEnabled() && data && !this._isLargeDraw) { + this._removeBackground(); + this._backgroundEls = []; + data.eachItemGraphicEl(function (el) { + removeElementWithFadeOut(el, model, getECData(el).dataIndex); + }); + } else { + group.removeAll(); + } + this._data = null; + this._isFirstFrame = true; + }; + BarView.prototype._removeBackground = function () { + this.group.remove(this._backgroundGroup); + this._backgroundGroup = null; + }; + BarView.type = 'bar'; + return BarView; + }(ChartView); + var clip = { + cartesian2d: function (coordSysBoundingRect, layout) { + var signWidth = layout.width < 0 ? -1 : 1; + var signHeight = layout.height < 0 ? -1 : 1; + // Needs positive width and height + if (signWidth < 0) { + layout.x += layout.width; + layout.width = -layout.width; + } + if (signHeight < 0) { + layout.y += layout.height; + layout.height = -layout.height; + } + var coordSysX2 = coordSysBoundingRect.x + coordSysBoundingRect.width; + var coordSysY2 = coordSysBoundingRect.y + coordSysBoundingRect.height; + var x = mathMax$6(layout.x, coordSysBoundingRect.x); + var x2 = mathMin$6(layout.x + layout.width, coordSysX2); + var y = mathMax$6(layout.y, coordSysBoundingRect.y); + var y2 = mathMin$6(layout.y + layout.height, coordSysY2); + var xClipped = x2 < x; + var yClipped = y2 < y; + // When xClipped or yClipped, the element will be marked as `ignore`. + // But we should also place the element at the edge of the coord sys bounding rect. + // Because if data changed and the bar shows again, its transition animation + // will begin at this place. + layout.x = xClipped && x > coordSysX2 ? x2 : x; + layout.y = yClipped && y > coordSysY2 ? y2 : y; + layout.width = xClipped ? 0 : x2 - x; + layout.height = yClipped ? 0 : y2 - y; + // Reverse back + if (signWidth < 0) { + layout.x += layout.width; + layout.width = -layout.width; + } + if (signHeight < 0) { + layout.y += layout.height; + layout.height = -layout.height; + } + return xClipped || yClipped; + }, + polar: function (coordSysClipArea, layout) { + var signR = layout.r0 <= layout.r ? 1 : -1; + // Make sure r is larger than r0 + if (signR < 0) { + var tmp = layout.r; + layout.r = layout.r0; + layout.r0 = tmp; + } + var r = mathMin$6(layout.r, coordSysClipArea.r); + var r0 = mathMax$6(layout.r0, coordSysClipArea.r0); + layout.r = r; + layout.r0 = r0; + var clipped = r - r0 < 0; + // Reverse back + if (signR < 0) { + var tmp = layout.r; + layout.r = layout.r0; + layout.r0 = tmp; + } + return clipped; + } + }; + var elementCreator = { + cartesian2d: function (seriesModel, data, newIndex, layout, isHorizontal, animationModel, axisModel, isUpdate, roundCap) { + var rect = new Rect({ + shape: extend({}, layout), + z2: 1 + }); + rect.__dataIndex = newIndex; + rect.name = 'item'; + if (animationModel) { + var rectShape = rect.shape; + var animateProperty = isHorizontal ? 'height' : 'width'; + rectShape[animateProperty] = 0; + } + return rect; + }, + polar: function (seriesModel, data, newIndex, layout, isRadial, animationModel, axisModel, isUpdate, roundCap) { + var ShapeClass = !isRadial && roundCap ? SausagePath : Sector; + var sector = new ShapeClass({ + shape: layout, + z2: 1 + }); + sector.name = 'item'; + var positionMap = createPolarPositionMapping(isRadial); + sector.calculateTextPosition = createSectorCalculateTextPosition(positionMap, { + isRoundCap: ShapeClass === SausagePath + }); + // Animation + if (animationModel) { + var sectorShape = sector.shape; + var animateProperty = isRadial ? 'r' : 'endAngle'; + var animateTarget = {}; + sectorShape[animateProperty] = isRadial ? layout.r0 : layout.startAngle; + animateTarget[animateProperty] = layout[animateProperty]; + (isUpdate ? updateProps : initProps)(sector, { + shape: animateTarget + // __value: typeof dataValue === 'string' ? parseInt(dataValue, 10) : dataValue + }, animationModel); + } + return sector; + } + }; + function shouldRealtimeSort(seriesModel, coordSys) { + var realtimeSortOption = seriesModel.get('realtimeSort', true); + var baseAxis = coordSys.getBaseAxis(); + if ("development" !== 'production') { + if (realtimeSortOption) { + if (baseAxis.type !== 'category') { + warn('`realtimeSort` will not work because this bar series is not based on a category axis.'); + } + if (coordSys.type !== 'cartesian2d') { + warn('`realtimeSort` will not work because this bar series is not on cartesian2d.'); + } + } + } + if (realtimeSortOption && baseAxis.type === 'category' && coordSys.type === 'cartesian2d') { + return { + baseAxis: baseAxis, + otherAxis: coordSys.getOtherAxis(baseAxis) + }; + } + } + function updateRealtimeAnimation(realtimeSortCfg, seriesAnimationModel, el, layout, newIndex, isHorizontal, isUpdate, isChangeOrder) { + var seriesTarget; + var axisTarget; + if (isHorizontal) { + axisTarget = { + x: layout.x, + width: layout.width + }; + seriesTarget = { + y: layout.y, + height: layout.height + }; + } else { + axisTarget = { + y: layout.y, + height: layout.height + }; + seriesTarget = { + x: layout.x, + width: layout.width + }; + } + if (!isChangeOrder) { + // Keep the original growth animation if only axis order changed. + // Not start a new animation. + (isUpdate ? updateProps : initProps)(el, { + shape: seriesTarget + }, seriesAnimationModel, newIndex, null); + } + var axisAnimationModel = seriesAnimationModel ? realtimeSortCfg.baseAxis.model : null; + (isUpdate ? updateProps : initProps)(el, { + shape: axisTarget + }, axisAnimationModel, newIndex); + } + function checkPropertiesNotValid(obj, props) { + for (var i = 0; i < props.length; i++) { + if (!isFinite(obj[props[i]])) { + return true; + } + } + return false; + } + var rectPropties = ['x', 'y', 'width', 'height']; + var polarPropties = ['cx', 'cy', 'r', 'startAngle', 'endAngle']; + var isValidLayout = { + cartesian2d: function (layout) { + return !checkPropertiesNotValid(layout, rectPropties); + }, + polar: function (layout) { + return !checkPropertiesNotValid(layout, polarPropties); + } + }; + var getLayout = { + // itemModel is only used to get borderWidth, which is not needed + // when calculating bar background layout. + cartesian2d: function (data, dataIndex, itemModel) { + var layout = data.getItemLayout(dataIndex); + var fixedLineWidth = itemModel ? getLineWidth(itemModel, layout) : 0; + // fix layout with lineWidth + var signX = layout.width > 0 ? 1 : -1; + var signY = layout.height > 0 ? 1 : -1; + return { + x: layout.x + signX * fixedLineWidth / 2, + y: layout.y + signY * fixedLineWidth / 2, + width: layout.width - signX * fixedLineWidth, + height: layout.height - signY * fixedLineWidth + }; + }, + polar: function (data, dataIndex, itemModel) { + var layout = data.getItemLayout(dataIndex); + return { + cx: layout.cx, + cy: layout.cy, + r0: layout.r0, + r: layout.r, + startAngle: layout.startAngle, + endAngle: layout.endAngle, + clockwise: layout.clockwise + }; + } + }; + function isZeroOnPolar(layout) { + return layout.startAngle != null && layout.endAngle != null && layout.startAngle === layout.endAngle; + } + function createPolarPositionMapping(isRadial) { + return function (isRadial) { + var arcOrAngle = isRadial ? 'Arc' : 'Angle'; + return function (position) { + switch (position) { + case 'start': + case 'insideStart': + case 'end': + case 'insideEnd': + return position + arcOrAngle; + default: + return position; + } + }; + }(isRadial); + } + function updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, isPolar) { + var style = data.getItemVisual(dataIndex, 'style'); + if (!isPolar) { + var borderRadius = itemModel.get(['itemStyle', 'borderRadius']) || 0; + el.setShape('r', borderRadius); + } else if (!seriesModel.get('roundCap')) { + var sectorShape = el.shape; + var cornerRadius = getSectorCornerRadius(itemModel.getModel('itemStyle'), sectorShape, true); + extend(sectorShape, cornerRadius); + el.setShape(sectorShape); + } + el.useStyle(style); + var cursorStyle = itemModel.getShallow('cursor'); + cursorStyle && el.attr('cursor', cursorStyle); + var labelPositionOutside = isPolar ? isHorizontalOrRadial ? layout.r >= layout.r0 ? 'endArc' : 'startArc' : layout.endAngle >= layout.startAngle ? 'endAngle' : 'startAngle' : isHorizontalOrRadial ? layout.height >= 0 ? 'bottom' : 'top' : layout.width >= 0 ? 'right' : 'left'; + var labelStatesModels = getLabelStatesModels(itemModel); + setLabelStyle(el, labelStatesModels, { + labelFetcher: seriesModel, + labelDataIndex: dataIndex, + defaultText: getDefaultLabel(seriesModel.getData(), dataIndex), + inheritColor: style.fill, + defaultOpacity: style.opacity, + defaultOutsidePosition: labelPositionOutside + }); + var label = el.getTextContent(); + if (isPolar && label) { + var position = itemModel.get(['label', 'position']); + el.textConfig.inside = position === 'middle' ? true : null; + setSectorTextRotation(el, position === 'outside' ? labelPositionOutside : position, createPolarPositionMapping(isHorizontalOrRadial), itemModel.get(['label', 'rotate'])); + } + setLabelValueAnimation(label, labelStatesModels, seriesModel.getRawValue(dataIndex), function (value) { + return getDefaultInterpolatedLabel(data, value); + }); + var emphasisModel = itemModel.getModel(['emphasis']); + toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + setStatesStylesFromModel(el, itemModel); + if (isZeroOnPolar(layout)) { + el.style.fill = 'none'; + el.style.stroke = 'none'; + each(el.states, function (state) { + if (state.style) { + state.style.fill = state.style.stroke = 'none'; + } + }); + } + } + // In case width or height are too small. + function getLineWidth(itemModel, rawLayout) { + // Has no border. + var borderColor = itemModel.get(['itemStyle', 'borderColor']); + if (!borderColor || borderColor === 'none') { + return 0; + } + var lineWidth = itemModel.get(['itemStyle', 'borderWidth']) || 0; + // width or height may be NaN for empty data + var width = isNaN(rawLayout.width) ? Number.MAX_VALUE : Math.abs(rawLayout.width); + var height = isNaN(rawLayout.height) ? Number.MAX_VALUE : Math.abs(rawLayout.height); + return Math.min(lineWidth, width, height); + } + var LagePathShape = /** @class */function () { + function LagePathShape() {} + return LagePathShape; + }(); + var LargePath = /** @class */function (_super) { + __extends(LargePath, _super); + function LargePath(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'largeBar'; + return _this; + } + LargePath.prototype.getDefaultShape = function () { + return new LagePathShape(); + }; + LargePath.prototype.buildPath = function (ctx, shape) { + // Drawing lines is more efficient than drawing + // a whole line or drawing rects. + var points = shape.points; + var baseDimIdx = this.baseDimIdx; + var valueDimIdx = 1 - this.baseDimIdx; + var startPoint = []; + var size = []; + var barWidth = this.barWidth; + for (var i = 0; i < points.length; i += 3) { + size[baseDimIdx] = barWidth; + size[valueDimIdx] = points[i + 2]; + startPoint[baseDimIdx] = points[i + baseDimIdx]; + startPoint[valueDimIdx] = points[i + valueDimIdx]; + ctx.rect(startPoint[0], startPoint[1], size[0], size[1]); + } + }; + return LargePath; + }(Path); + function createLarge(seriesModel, group, progressiveEls, incremental) { + // TODO support polar + var data = seriesModel.getData(); + var baseDimIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0; + var largeDataIndices = data.getLayout('largeDataIndices'); + var barWidth = data.getLayout('size'); + var backgroundModel = seriesModel.getModel('backgroundStyle'); + var bgPoints = data.getLayout('largeBackgroundPoints'); + if (bgPoints) { + var bgEl = new LargePath({ + shape: { + points: bgPoints + }, + incremental: !!incremental, + silent: true, + z2: 0 + }); + bgEl.baseDimIdx = baseDimIdx; + bgEl.largeDataIndices = largeDataIndices; + bgEl.barWidth = barWidth; + bgEl.useStyle(backgroundModel.getItemStyle()); + group.add(bgEl); + progressiveEls && progressiveEls.push(bgEl); + } + var el = new LargePath({ + shape: { + points: data.getLayout('largePoints') + }, + incremental: !!incremental, + ignoreCoarsePointer: true, + z2: 1 + }); + el.baseDimIdx = baseDimIdx; + el.largeDataIndices = largeDataIndices; + el.barWidth = barWidth; + group.add(el); + el.useStyle(data.getVisual('style')); + // Enable tooltip and user mouse/touch event handlers. + getECData(el).seriesIndex = seriesModel.seriesIndex; + if (!seriesModel.get('silent')) { + el.on('mousedown', largePathUpdateDataIndex); + el.on('mousemove', largePathUpdateDataIndex); + } + progressiveEls && progressiveEls.push(el); + } + // Use throttle to avoid frequently traverse to find dataIndex. + var largePathUpdateDataIndex = throttle(function (event) { + var largePath = this; + var dataIndex = largePathFindDataIndex(largePath, event.offsetX, event.offsetY); + getECData(largePath).dataIndex = dataIndex >= 0 ? dataIndex : null; + }, 30, false); + function largePathFindDataIndex(largePath, x, y) { + var baseDimIdx = largePath.baseDimIdx; + var valueDimIdx = 1 - baseDimIdx; + var points = largePath.shape.points; + var largeDataIndices = largePath.largeDataIndices; + var startPoint = []; + var size = []; + var barWidth = largePath.barWidth; + for (var i = 0, len = points.length / 3; i < len; i++) { + var ii = i * 3; + size[baseDimIdx] = barWidth; + size[valueDimIdx] = points[ii + 2]; + startPoint[baseDimIdx] = points[ii + baseDimIdx]; + startPoint[valueDimIdx] = points[ii + valueDimIdx]; + if (size[valueDimIdx] < 0) { + startPoint[valueDimIdx] += size[valueDimIdx]; + size[valueDimIdx] = -size[valueDimIdx]; + } + if (x >= startPoint[0] && x <= startPoint[0] + size[0] && y >= startPoint[1] && y <= startPoint[1] + size[1]) { + return largeDataIndices[i]; + } + } + return -1; + } + function createBackgroundShape(isHorizontalOrRadial, layout, coord) { + if (isCoordinateSystemType(coord, 'cartesian2d')) { + var rectShape = layout; + var coordLayout = coord.getArea(); + return { + x: isHorizontalOrRadial ? rectShape.x : coordLayout.x, + y: isHorizontalOrRadial ? coordLayout.y : rectShape.y, + width: isHorizontalOrRadial ? rectShape.width : coordLayout.width, + height: isHorizontalOrRadial ? coordLayout.height : rectShape.height + }; + } else { + var coordLayout = coord.getArea(); + var sectorShape = layout; + return { + cx: coordLayout.cx, + cy: coordLayout.cy, + r0: isHorizontalOrRadial ? coordLayout.r0 : sectorShape.r0, + r: isHorizontalOrRadial ? coordLayout.r : sectorShape.r, + startAngle: isHorizontalOrRadial ? sectorShape.startAngle : 0, + endAngle: isHorizontalOrRadial ? sectorShape.endAngle : Math.PI * 2 + }; + } + } + function createBackgroundEl(coord, isHorizontalOrRadial, layout) { + var ElementClz = coord.type === 'polar' ? Sector : Rect; + return new ElementClz({ + shape: createBackgroundShape(isHorizontalOrRadial, layout, coord), + silent: true, + z2: 0 + }); + } + + function install$3(registers) { + registers.registerChartView(BarView); + registers.registerSeriesModel(BarSeriesModel); + registers.registerLayout(registers.PRIORITY.VISUAL.LAYOUT, curry(layout, 'bar')); + // Do layout after other overall layout, which can prepare some information. + registers.registerLayout(registers.PRIORITY.VISUAL.PROGRESSIVE_LAYOUT, createProgressiveLayout('bar')); + // Down sample after filter + registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('bar')); + /** + * @payload + * @property {string} [componentType=series] + * @property {number} [dx] + * @property {number} [dy] + * @property {number} [zoom] + * @property {number} [originX] + * @property {number} [originY] + */ + registers.registerAction({ + type: 'changeAxisOrder', + event: 'changeAxisOrder', + update: 'update' + }, function (payload, ecModel) { + var componentType = payload.componentType || 'series'; + ecModel.eachComponent({ + mainType: componentType, + query: payload + }, function (componentModel) { + if (payload.sortInfo) { + componentModel.axis.setCategorySortInfo(payload.sortInfo); + } + }); + }); + } + + var PI2$8 = Math.PI * 2; + var RADIAN = Math.PI / 180; + function getViewRect(seriesModel, api) { + return getLayoutRect(seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }); + } + function getBasicPieLayout(seriesModel, api) { + var viewRect = getViewRect(seriesModel, api); + // center can be string or number when coordinateSystem is specified + var center = seriesModel.get('center'); + var radius = seriesModel.get('radius'); + if (!isArray(radius)) { + radius = [0, radius]; + } + var width = parsePercent$1(viewRect.width, api.getWidth()); + var height = parsePercent$1(viewRect.height, api.getHeight()); + var size = Math.min(width, height); + var r0 = parsePercent$1(radius[0], size / 2); + var r = parsePercent$1(radius[1], size / 2); + var cx; + var cy; + var coordSys = seriesModel.coordinateSystem; + if (coordSys) { + // percentage is not allowed when coordinate system is specified + var point = coordSys.dataToPoint(center); + cx = point[0] || 0; + cy = point[1] || 0; + } else { + if (!isArray(center)) { + center = [center, center]; + } + cx = parsePercent$1(center[0], width) + viewRect.x; + cy = parsePercent$1(center[1], height) + viewRect.y; + } + return { + cx: cx, + cy: cy, + r0: r0, + r: r + }; + } + function pieLayout(seriesType, ecModel, api) { + ecModel.eachSeriesByType(seriesType, function (seriesModel) { + var data = seriesModel.getData(); + var valueDim = data.mapDimension('value'); + var viewRect = getViewRect(seriesModel, api); + var _a = getBasicPieLayout(seriesModel, api), + cx = _a.cx, + cy = _a.cy, + r = _a.r, + r0 = _a.r0; + var startAngle = -seriesModel.get('startAngle') * RADIAN; + var endAngle = seriesModel.get('endAngle'); + var padAngle = seriesModel.get('padAngle') * RADIAN; + endAngle = endAngle === 'auto' ? startAngle - PI2$8 : -endAngle * RADIAN; + var minAngle = seriesModel.get('minAngle') * RADIAN; + var minAndPadAngle = minAngle + padAngle; + var validDataCount = 0; + data.each(valueDim, function (value) { + !isNaN(value) && validDataCount++; + }); + var sum = data.getSum(valueDim); + // Sum may be 0 + var unitRadian = Math.PI / (sum || validDataCount) * 2; + var clockwise = seriesModel.get('clockwise'); + var roseType = seriesModel.get('roseType'); + var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); + // [0...max] + var extent = data.getDataExtent(valueDim); + extent[0] = 0; + var dir = clockwise ? 1 : -1; + var angles = [startAngle, endAngle]; + var halfPadAngle = dir * padAngle / 2; + normalizeArcAngles(angles, !clockwise); + startAngle = angles[0], endAngle = angles[1]; + var angleRange = Math.abs(endAngle - startAngle); + // In the case some sector angle is smaller than minAngle + var restAngle = angleRange; + var valueSumLargerThanMinAngle = 0; + var currentAngle = startAngle; + data.setLayout({ + viewRect: viewRect, + r: r + }); + data.each(valueDim, function (value, idx) { + var angle; + if (isNaN(value)) { + data.setItemLayout(idx, { + angle: NaN, + startAngle: NaN, + endAngle: NaN, + clockwise: clockwise, + cx: cx, + cy: cy, + r0: r0, + r: roseType ? NaN : r + }); + return; + } + // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样? + if (roseType !== 'area') { + angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian; + } else { + angle = angleRange / validDataCount; + } + if (angle < minAndPadAngle) { + angle = minAndPadAngle; + restAngle -= minAndPadAngle; + } else { + valueSumLargerThanMinAngle += value; + } + var endAngle = currentAngle + dir * angle; + // calculate display angle + var actualStartAngle = 0; + var actualEndAngle = 0; + if (padAngle > angle) { + actualStartAngle = currentAngle + dir * angle / 2; + actualEndAngle = actualStartAngle; + } else { + actualStartAngle = currentAngle + halfPadAngle; + actualEndAngle = endAngle - halfPadAngle; + } + data.setItemLayout(idx, { + angle: angle, + startAngle: actualStartAngle, + endAngle: actualEndAngle, + clockwise: clockwise, + cx: cx, + cy: cy, + r0: r0, + r: roseType ? linearMap(value, extent, [r0, r]) : r + }); + currentAngle = endAngle; + }); + // Some sector is constrained by minAngle and padAngle + // Rest sectors needs recalculate angle + if (restAngle < PI2$8 && validDataCount) { + // Average the angle if rest angle is not enough after all angles is + // Constrained by minAngle and padAngle + if (restAngle <= 1e-3) { + var angle_1 = angleRange / validDataCount; + data.each(valueDim, function (value, idx) { + if (!isNaN(value)) { + var layout_1 = data.getItemLayout(idx); + layout_1.angle = angle_1; + var actualStartAngle = 0; + var actualEndAngle = 0; + if (angle_1 < padAngle) { + actualStartAngle = startAngle + dir * (idx + 1 / 2) * angle_1; + actualEndAngle = actualStartAngle; + } else { + actualStartAngle = startAngle + dir * idx * angle_1 + halfPadAngle; + actualEndAngle = startAngle + dir * (idx + 1) * angle_1 - halfPadAngle; + } + layout_1.startAngle = actualStartAngle; + layout_1.endAngle = actualEndAngle; + } + }); + } else { + unitRadian = restAngle / valueSumLargerThanMinAngle; + currentAngle = startAngle; + data.each(valueDim, function (value, idx) { + if (!isNaN(value)) { + var layout_2 = data.getItemLayout(idx); + var angle = layout_2.angle === minAndPadAngle ? minAndPadAngle : value * unitRadian; + var actualStartAngle = 0; + var actualEndAngle = 0; + if (angle < padAngle) { + actualStartAngle = currentAngle + dir * angle / 2; + actualEndAngle = actualStartAngle; + } else { + actualStartAngle = currentAngle + halfPadAngle; + actualEndAngle = currentAngle + dir * angle - halfPadAngle; + } + layout_2.startAngle = actualStartAngle; + layout_2.endAngle = actualEndAngle; + currentAngle += dir * angle; + } + }); + } + } + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function dataFilter(seriesType) { + return { + seriesType: seriesType, + reset: function (seriesModel, ecModel) { + var legendModels = ecModel.findComponents({ + mainType: 'legend' + }); + if (!legendModels || !legendModels.length) { + return; + } + var data = seriesModel.getData(); + data.filterSelf(function (idx) { + var name = data.getName(idx); + // If in any legend component the status is not selected. + for (var i = 0; i < legendModels.length; i++) { + // @ts-ignore FIXME: LegendModel + if (!legendModels[i].isSelected(name)) { + return false; + } + } + return true; + }); + } + }; + } + + var RADIAN$1 = Math.PI / 180; + function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, viewLeft, viewTop, farthestX) { + if (list.length < 2) { + return; + } + function recalculateXOnSemiToAlignOnEllipseCurve(semi) { + var rB = semi.rB; + var rB2 = rB * rB; + for (var i = 0; i < semi.list.length; i++) { + var item = semi.list[i]; + var dy = Math.abs(item.label.y - cy); + // horizontal r is always same with original r because x is not changed. + var rA = r + item.len; + var rA2 = rA * rA; + // Use ellipse implicit function to calculate x + var dx = Math.sqrt((1 - Math.abs(dy * dy / rB2)) * rA2); + var newX = cx + (dx + item.len2) * dir; + var deltaX = newX - item.label.x; + var newTargetWidth = item.targetTextWidth - deltaX * dir; + // text x is changed, so need to recalculate width. + constrainTextWidth(item, newTargetWidth, true); + item.label.x = newX; + } + } + // Adjust X based on the shifted y. Make tight labels aligned on an ellipse curve. + function recalculateX(items) { + // Extremes of + var topSemi = { + list: [], + maxY: 0 + }; + var bottomSemi = { + list: [], + maxY: 0 + }; + for (var i = 0; i < items.length; i++) { + if (items[i].labelAlignTo !== 'none') { + continue; + } + var item = items[i]; + var semi = item.label.y > cy ? bottomSemi : topSemi; + var dy = Math.abs(item.label.y - cy); + if (dy >= semi.maxY) { + var dx = item.label.x - cx - item.len2 * dir; + // horizontal r is always same with original r because x is not changed. + var rA = r + item.len; + // Canculate rB based on the topest / bottemest label. + var rB = Math.abs(dx) < rA ? Math.sqrt(dy * dy / (1 - dx * dx / rA / rA)) : rA; + semi.rB = rB; + semi.maxY = dy; + } + semi.list.push(item); + } + recalculateXOnSemiToAlignOnEllipseCurve(topSemi); + recalculateXOnSemiToAlignOnEllipseCurve(bottomSemi); + } + var len = list.length; + for (var i = 0; i < len; i++) { + if (list[i].position === 'outer' && list[i].labelAlignTo === 'labelLine') { + var dx = list[i].label.x - farthestX; + list[i].linePoints[1][0] += dx; + list[i].label.x = farthestX; + } + } + if (shiftLayoutOnY(list, viewTop, viewTop + viewHeight)) { + recalculateX(list); + } + } + function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop) { + var leftList = []; + var rightList = []; + var leftmostX = Number.MAX_VALUE; + var rightmostX = -Number.MAX_VALUE; + for (var i = 0; i < labelLayoutList.length; i++) { + var label = labelLayoutList[i].label; + if (isPositionCenter(labelLayoutList[i])) { + continue; + } + if (label.x < cx) { + leftmostX = Math.min(leftmostX, label.x); + leftList.push(labelLayoutList[i]); + } else { + rightmostX = Math.max(rightmostX, label.x); + rightList.push(labelLayoutList[i]); + } + } + for (var i = 0; i < labelLayoutList.length; i++) { + var layout = labelLayoutList[i]; + if (!isPositionCenter(layout) && layout.linePoints) { + if (layout.labelStyleWidth != null) { + continue; + } + var label = layout.label; + var linePoints = layout.linePoints; + var targetTextWidth = void 0; + if (layout.labelAlignTo === 'edge') { + if (label.x < cx) { + targetTextWidth = linePoints[2][0] - layout.labelDistance - viewLeft - layout.edgeDistance; + } else { + targetTextWidth = viewLeft + viewWidth - layout.edgeDistance - linePoints[2][0] - layout.labelDistance; + } + } else if (layout.labelAlignTo === 'labelLine') { + if (label.x < cx) { + targetTextWidth = leftmostX - viewLeft - layout.bleedMargin; + } else { + targetTextWidth = viewLeft + viewWidth - rightmostX - layout.bleedMargin; + } + } else { + if (label.x < cx) { + targetTextWidth = label.x - viewLeft - layout.bleedMargin; + } else { + targetTextWidth = viewLeft + viewWidth - label.x - layout.bleedMargin; + } + } + layout.targetTextWidth = targetTextWidth; + constrainTextWidth(layout, targetTextWidth); + } + } + adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, viewLeft, viewTop, rightmostX); + adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, viewLeft, viewTop, leftmostX); + for (var i = 0; i < labelLayoutList.length; i++) { + var layout = labelLayoutList[i]; + if (!isPositionCenter(layout) && layout.linePoints) { + var label = layout.label; + var linePoints = layout.linePoints; + var isAlignToEdge = layout.labelAlignTo === 'edge'; + var padding = label.style.padding; + var paddingH = padding ? padding[1] + padding[3] : 0; + // textRect.width already contains paddingH if bgColor is set + var extraPaddingH = label.style.backgroundColor ? 0 : paddingH; + var realTextWidth = layout.rect.width + extraPaddingH; + var dist = linePoints[1][0] - linePoints[2][0]; + if (isAlignToEdge) { + if (label.x < cx) { + linePoints[2][0] = viewLeft + layout.edgeDistance + realTextWidth + layout.labelDistance; + } else { + linePoints[2][0] = viewLeft + viewWidth - layout.edgeDistance - realTextWidth - layout.labelDistance; + } + } else { + if (label.x < cx) { + linePoints[2][0] = label.x + layout.labelDistance; + } else { + linePoints[2][0] = label.x - layout.labelDistance; + } + linePoints[1][0] = linePoints[2][0] + dist; + } + linePoints[1][1] = linePoints[2][1] = label.y; + } + } + } + /** + * Set max width of each label, and then wrap each label to the max width. + * + * @param layout label layout + * @param availableWidth max width for the label to display + * @param forceRecalculate recaculate the text layout even if the current width + * is smaller than `availableWidth`. This is useful when the text was previously + * wrapped by calling `constrainTextWidth` but now `availableWidth` changed, in + * which case, previous wrapping should be redo. + */ + function constrainTextWidth(layout, availableWidth, forceRecalculate) { + if (forceRecalculate === void 0) { + forceRecalculate = false; + } + if (layout.labelStyleWidth != null) { + // User-defined style.width has the highest priority. + return; + } + var label = layout.label; + var style = label.style; + var textRect = layout.rect; + var bgColor = style.backgroundColor; + var padding = style.padding; + var paddingH = padding ? padding[1] + padding[3] : 0; + var overflow = style.overflow; + // textRect.width already contains paddingH if bgColor is set + var oldOuterWidth = textRect.width + (bgColor ? 0 : paddingH); + if (availableWidth < oldOuterWidth || forceRecalculate) { + var oldHeight = textRect.height; + if (overflow && overflow.match('break')) { + // Temporarily set background to be null to calculate + // the bounding box without background. + label.setStyle('backgroundColor', null); + // Set constraining width + label.setStyle('width', availableWidth - paddingH); + // This is the real bounding box of the text without padding. + var innerRect = label.getBoundingRect(); + label.setStyle('width', Math.ceil(innerRect.width)); + label.setStyle('backgroundColor', bgColor); + } else { + var availableInnerWidth = availableWidth - paddingH; + var newWidth = availableWidth < oldOuterWidth + // Current text is too wide, use `availableWidth` as max width. + ? availableInnerWidth : + // Current available width is enough, but the text may have + // already been wrapped with a smaller available width. + forceRecalculate ? availableInnerWidth > layout.unconstrainedWidth + // Current available is larger than text width, + // so don't constrain width (otherwise it may have + // empty space in the background). + ? null + // Current available is smaller than text width, so + // use the current available width as constraining + // width. + : availableInnerWidth + // Current available width is enough, so no need to + // constrain. + : null; + label.setStyle('width', newWidth); + } + var newRect = label.getBoundingRect(); + textRect.width = newRect.width; + var margin = (label.style.margin || 0) + 2.1; + textRect.height = newRect.height + margin; + textRect.y -= (textRect.height - oldHeight) / 2; + } + } + function isPositionCenter(sectorShape) { + // Not change x for center label + return sectorShape.position === 'center'; + } + function pieLabelLayout(seriesModel) { + var data = seriesModel.getData(); + var labelLayoutList = []; + var cx; + var cy; + var hasLabelRotate = false; + var minShowLabelRadian = (seriesModel.get('minShowLabelAngle') || 0) * RADIAN$1; + var viewRect = data.getLayout('viewRect'); + var r = data.getLayout('r'); + var viewWidth = viewRect.width; + var viewLeft = viewRect.x; + var viewTop = viewRect.y; + var viewHeight = viewRect.height; + function setNotShow(el) { + el.ignore = true; + } + function isLabelShown(label) { + if (!label.ignore) { + return true; + } + for (var key in label.states) { + if (label.states[key].ignore === false) { + return true; + } + } + return false; + } + data.each(function (idx) { + var sector = data.getItemGraphicEl(idx); + var sectorShape = sector.shape; + var label = sector.getTextContent(); + var labelLine = sector.getTextGuideLine(); + var itemModel = data.getItemModel(idx); + var labelModel = itemModel.getModel('label'); + // Use position in normal or emphasis + var labelPosition = labelModel.get('position') || itemModel.get(['emphasis', 'label', 'position']); + var labelDistance = labelModel.get('distanceToLabelLine'); + var labelAlignTo = labelModel.get('alignTo'); + var edgeDistance = parsePercent$1(labelModel.get('edgeDistance'), viewWidth); + var bleedMargin = labelModel.get('bleedMargin'); + var labelLineModel = itemModel.getModel('labelLine'); + var labelLineLen = labelLineModel.get('length'); + labelLineLen = parsePercent$1(labelLineLen, viewWidth); + var labelLineLen2 = labelLineModel.get('length2'); + labelLineLen2 = parsePercent$1(labelLineLen2, viewWidth); + if (Math.abs(sectorShape.endAngle - sectorShape.startAngle) < minShowLabelRadian) { + each(label.states, setNotShow); + label.ignore = true; + if (labelLine) { + each(labelLine.states, setNotShow); + labelLine.ignore = true; + } + return; + } + if (!isLabelShown(label)) { + return; + } + var midAngle = (sectorShape.startAngle + sectorShape.endAngle) / 2; + var nx = Math.cos(midAngle); + var ny = Math.sin(midAngle); + var textX; + var textY; + var linePoints; + var textAlign; + cx = sectorShape.cx; + cy = sectorShape.cy; + var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner'; + if (labelPosition === 'center') { + textX = sectorShape.cx; + textY = sectorShape.cy; + textAlign = 'center'; + } else { + var x1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * nx : sectorShape.r * nx) + cx; + var y1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * ny : sectorShape.r * ny) + cy; + textX = x1 + nx * 3; + textY = y1 + ny * 3; + if (!isLabelInside) { + // For roseType + var x2 = x1 + nx * (labelLineLen + r - sectorShape.r); + var y2 = y1 + ny * (labelLineLen + r - sectorShape.r); + var x3 = x2 + (nx < 0 ? -1 : 1) * labelLineLen2; + var y3 = y2; + if (labelAlignTo === 'edge') { + // Adjust textX because text align of edge is opposite + textX = nx < 0 ? viewLeft + edgeDistance : viewLeft + viewWidth - edgeDistance; + } else { + textX = x3 + (nx < 0 ? -labelDistance : labelDistance); + } + textY = y3; + linePoints = [[x1, y1], [x2, y2], [x3, y3]]; + } + textAlign = isLabelInside ? 'center' : labelAlignTo === 'edge' ? nx > 0 ? 'right' : 'left' : nx > 0 ? 'left' : 'right'; + } + var PI = Math.PI; + var labelRotate = 0; + var rotate = labelModel.get('rotate'); + if (isNumber(rotate)) { + labelRotate = rotate * (PI / 180); + } else if (labelPosition === 'center') { + labelRotate = 0; + } else if (rotate === 'radial' || rotate === true) { + var radialAngle = nx < 0 ? -midAngle + PI : -midAngle; + labelRotate = radialAngle; + } else if (rotate === 'tangential' && labelPosition !== 'outside' && labelPosition !== 'outer') { + var rad = Math.atan2(nx, ny); + if (rad < 0) { + rad = PI * 2 + rad; + } + var isDown = ny > 0; + if (isDown) { + rad = PI + rad; + } + labelRotate = rad - PI; + } + hasLabelRotate = !!labelRotate; + label.x = textX; + label.y = textY; + label.rotation = labelRotate; + label.setStyle({ + verticalAlign: 'middle' + }); + // Not sectorShape the inside label + if (!isLabelInside) { + var textRect = label.getBoundingRect().clone(); + textRect.applyTransform(label.getComputedTransform()); + // Text has a default 1px stroke. Exclude this. + var margin = (label.style.margin || 0) + 2.1; + textRect.y -= margin / 2; + textRect.height += margin; + labelLayoutList.push({ + label: label, + labelLine: labelLine, + position: labelPosition, + len: labelLineLen, + len2: labelLineLen2, + minTurnAngle: labelLineModel.get('minTurnAngle'), + maxSurfaceAngle: labelLineModel.get('maxSurfaceAngle'), + surfaceNormal: new Point(nx, ny), + linePoints: linePoints, + textAlign: textAlign, + labelDistance: labelDistance, + labelAlignTo: labelAlignTo, + edgeDistance: edgeDistance, + bleedMargin: bleedMargin, + rect: textRect, + unconstrainedWidth: textRect.width, + labelStyleWidth: label.style.width + }); + } else { + label.setStyle({ + align: textAlign + }); + var selectState = label.states.select; + if (selectState) { + selectState.x += label.x; + selectState.y += label.y; + } + } + sector.setTextConfig({ + inside: isLabelInside + }); + }); + if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) { + avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop); + } + for (var i = 0; i < labelLayoutList.length; i++) { + var layout = labelLayoutList[i]; + var label = layout.label; + var labelLine = layout.labelLine; + var notShowLabel = isNaN(label.x) || isNaN(label.y); + if (label) { + label.setStyle({ + align: layout.textAlign + }); + if (notShowLabel) { + each(label.states, setNotShow); + label.ignore = true; + } + var selectState = label.states.select; + if (selectState) { + selectState.x += label.x; + selectState.y += label.y; + } + } + if (labelLine) { + var linePoints = layout.linePoints; + if (notShowLabel || !linePoints) { + each(labelLine.states, setNotShow); + labelLine.ignore = true; + } else { + limitTurnAngle(linePoints, layout.minTurnAngle); + limitSurfaceAngle(linePoints, layout.surfaceNormal, layout.maxSurfaceAngle); + labelLine.setShape({ + points: linePoints + }); + // Set the anchor to the midpoint of sector + label.__hostTarget.textGuideLineConfig = { + anchor: new Point(linePoints[0][0], linePoints[0][1]) + }; + } + } + } + } + + /** + * Piece of pie including Sector, Label, LabelLine + */ + var PiePiece = /** @class */function (_super) { + __extends(PiePiece, _super); + function PiePiece(data, idx, startAngle) { + var _this = _super.call(this) || this; + _this.z2 = 2; + var text = new ZRText(); + _this.setTextContent(text); + _this.updateData(data, idx, startAngle, true); + return _this; + } + PiePiece.prototype.updateData = function (data, idx, startAngle, firstCreate) { + var sector = this; + var seriesModel = data.hostModel; + var itemModel = data.getItemModel(idx); + var emphasisModel = itemModel.getModel('emphasis'); + var layout = data.getItemLayout(idx); + // cornerRadius & innerCornerRadius doesn't exist in the item layout. Use `0` if null value is specified. + // see `setItemLayout` in `pieLayout.ts`. + var sectorShape = extend(getSectorCornerRadius(itemModel.getModel('itemStyle'), layout, true), layout); + // Ignore NaN data. + if (isNaN(sectorShape.startAngle)) { + // Use NaN shape to avoid drawing shape. + sector.setShape(sectorShape); + return; + } + if (firstCreate) { + sector.setShape(sectorShape); + var animationType = seriesModel.getShallow('animationType'); + if (seriesModel.ecModel.ssr) { + // Use scale animation in SSR mode(opacity?) + // Because CSS SVG animation doesn't support very customized shape animation. + initProps(sector, { + scaleX: 0, + scaleY: 0 + }, seriesModel, { + dataIndex: idx, + isFrom: true + }); + sector.originX = sectorShape.cx; + sector.originY = sectorShape.cy; + } else if (animationType === 'scale') { + sector.shape.r = layout.r0; + initProps(sector, { + shape: { + r: layout.r + } + }, seriesModel, idx); + } + // Expansion + else { + if (startAngle != null) { + sector.setShape({ + startAngle: startAngle, + endAngle: startAngle + }); + initProps(sector, { + shape: { + startAngle: layout.startAngle, + endAngle: layout.endAngle + } + }, seriesModel, idx); + } else { + sector.shape.endAngle = layout.startAngle; + updateProps(sector, { + shape: { + endAngle: layout.endAngle + } + }, seriesModel, idx); + } + } + } else { + saveOldStyle(sector); + // Transition animation from the old shape + updateProps(sector, { + shape: sectorShape + }, seriesModel, idx); + } + sector.useStyle(data.getItemVisual(idx, 'style')); + setStatesStylesFromModel(sector, itemModel); + var midAngle = (layout.startAngle + layout.endAngle) / 2; + var offset = seriesModel.get('selectedOffset'); + var dx = Math.cos(midAngle) * offset; + var dy = Math.sin(midAngle) * offset; + var cursorStyle = itemModel.getShallow('cursor'); + cursorStyle && sector.attr('cursor', cursorStyle); + this._updateLabel(seriesModel, data, idx); + sector.ensureState('emphasis').shape = extend({ + r: layout.r + (emphasisModel.get('scale') ? emphasisModel.get('scaleSize') || 0 : 0) + }, getSectorCornerRadius(emphasisModel.getModel('itemStyle'), layout)); + extend(sector.ensureState('select'), { + x: dx, + y: dy, + shape: getSectorCornerRadius(itemModel.getModel(['select', 'itemStyle']), layout) + }); + extend(sector.ensureState('blur'), { + shape: getSectorCornerRadius(itemModel.getModel(['blur', 'itemStyle']), layout) + }); + var labelLine = sector.getTextGuideLine(); + var labelText = sector.getTextContent(); + labelLine && extend(labelLine.ensureState('select'), { + x: dx, + y: dy + }); + // TODO: needs dx, dy in zrender? + extend(labelText.ensureState('select'), { + x: dx, + y: dy + }); + toggleHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + }; + PiePiece.prototype._updateLabel = function (seriesModel, data, idx) { + var sector = this; + var itemModel = data.getItemModel(idx); + var labelLineModel = itemModel.getModel('labelLine'); + var style = data.getItemVisual(idx, 'style'); + var visualColor = style && style.fill; + var visualOpacity = style && style.opacity; + setLabelStyle(sector, getLabelStatesModels(itemModel), { + labelFetcher: data.hostModel, + labelDataIndex: idx, + inheritColor: visualColor, + defaultOpacity: visualOpacity, + defaultText: seriesModel.getFormattedLabel(idx, 'normal') || data.getName(idx) + }); + var labelText = sector.getTextContent(); + // Set textConfig on sector. + sector.setTextConfig({ + // reset position, rotation + position: null, + rotation: null + }); + // Make sure update style on labelText after setLabelStyle. + // Because setLabelStyle will replace a new style on it. + labelText.attr({ + z2: 10 + }); + var labelPosition = seriesModel.get(['label', 'position']); + if (labelPosition !== 'outside' && labelPosition !== 'outer') { + sector.removeTextGuideLine(); + } else { + var polyline = this.getTextGuideLine(); + if (!polyline) { + polyline = new Polyline(); + this.setTextGuideLine(polyline); + } + // Default use item visual color + setLabelLineStyle(this, getLabelLineStatesModels(itemModel), { + stroke: visualColor, + opacity: retrieve3(labelLineModel.get(['lineStyle', 'opacity']), visualOpacity, 1) + }); + } + }; + return PiePiece; + }(Sector); + // Pie view + var PieView = /** @class */function (_super) { + __extends(PieView, _super); + function PieView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.ignoreLabelLineUpdate = true; + return _this; + } + PieView.prototype.render = function (seriesModel, ecModel, api, payload) { + var data = seriesModel.getData(); + var oldData = this._data; + var group = this.group; + var startAngle; + // First render + if (!oldData && data.count() > 0) { + var shape = data.getItemLayout(0); + for (var s = 1; isNaN(shape && shape.startAngle) && s < data.count(); ++s) { + shape = data.getItemLayout(s); + } + if (shape) { + startAngle = shape.startAngle; + } + } + // remove empty-circle if it exists + if (this._emptyCircleSector) { + group.remove(this._emptyCircleSector); + } + // when all data are filtered, show lightgray empty circle + if (data.count() === 0 && seriesModel.get('showEmptyCircle')) { + var sector = new Sector({ + shape: getBasicPieLayout(seriesModel, api) + }); + sector.useStyle(seriesModel.getModel('emptyCircleStyle').getItemStyle()); + this._emptyCircleSector = sector; + group.add(sector); + } + data.diff(oldData).add(function (idx) { + var piePiece = new PiePiece(data, idx, startAngle); + data.setItemGraphicEl(idx, piePiece); + group.add(piePiece); + }).update(function (newIdx, oldIdx) { + var piePiece = oldData.getItemGraphicEl(oldIdx); + piePiece.updateData(data, newIdx, startAngle); + piePiece.off('click'); + group.add(piePiece); + data.setItemGraphicEl(newIdx, piePiece); + }).remove(function (idx) { + var piePiece = oldData.getItemGraphicEl(idx); + removeElementWithFadeOut(piePiece, seriesModel, idx); + }).execute(); + pieLabelLayout(seriesModel); + // Always use initial animation. + if (seriesModel.get('animationTypeUpdate') !== 'expansion') { + this._data = data; + } + }; + PieView.prototype.dispose = function () {}; + PieView.prototype.containPoint = function (point, seriesModel) { + var data = seriesModel.getData(); + var itemLayout = data.getItemLayout(0); + if (itemLayout) { + var dx = point[0] - itemLayout.cx; + var dy = point[1] - itemLayout.cy; + var radius = Math.sqrt(dx * dx + dy * dy); + return radius <= itemLayout.r && radius >= itemLayout.r0; + } + }; + PieView.type = 'pie'; + return PieView; + }(ChartView); + + /** + * [Usage]: + * (1) + * createListSimply(seriesModel, ['value']); + * (2) + * createListSimply(seriesModel, { + * coordDimensions: ['value'], + * dimensionsCount: 5 + * }); + */ + function createSeriesDataSimply(seriesModel, opt, nameList) { + opt = isArray(opt) && { + coordDimensions: opt + } || extend({ + encodeDefine: seriesModel.getEncode() + }, opt); + var source = seriesModel.getSource(); + var dimensions = prepareSeriesDataSchema(source, opt).dimensions; + var list = new SeriesData(dimensions, seriesModel); + list.initData(source, nameList); + return list; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /** + * LegendVisualProvider is an bridge that pick encoded color from data and + * provide to the legend component. + */ + var LegendVisualProvider = /** @class */function () { + function LegendVisualProvider( + // Function to get data after filtered. It stores all the encoding info + getDataWithEncodedVisual, + // Function to get raw data before filtered. + getRawData) { + this._getDataWithEncodedVisual = getDataWithEncodedVisual; + this._getRawData = getRawData; + } + LegendVisualProvider.prototype.getAllNames = function () { + var rawData = this._getRawData(); + // We find the name from the raw data. In case it's filtered by the legend component. + // Normally, the name can be found in rawData, but can't be found in filtered data will display as gray. + return rawData.mapArray(rawData.getName); + }; + LegendVisualProvider.prototype.containName = function (name) { + var rawData = this._getRawData(); + return rawData.indexOfName(name) >= 0; + }; + LegendVisualProvider.prototype.indexOfName = function (name) { + // Only get data when necessary. + // Because LegendVisualProvider constructor may be new in the stage that data is not prepared yet. + // Invoking Series#getData immediately will throw an error. + var dataWithEncodedVisual = this._getDataWithEncodedVisual(); + return dataWithEncodedVisual.indexOfName(name); + }; + LegendVisualProvider.prototype.getItemVisual = function (dataIndex, key) { + // Get encoded visual properties from final filtered data. + var dataWithEncodedVisual = this._getDataWithEncodedVisual(); + return dataWithEncodedVisual.getItemVisual(dataIndex, key); + }; + return LegendVisualProvider; + }(); + + var innerData = makeInner(); + var PieSeriesModel = /** @class */function (_super) { + __extends(PieSeriesModel, _super); + function PieSeriesModel() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** + * @overwrite + */ + PieSeriesModel.prototype.init = function (option) { + _super.prototype.init.apply(this, arguments); + // Enable legend selection for each data item + // Use a function instead of direct access because data reference may changed + this.legendVisualProvider = new LegendVisualProvider(bind(this.getData, this), bind(this.getRawData, this)); + this._defaultLabelLine(option); + }; + /** + * @overwrite + */ + PieSeriesModel.prototype.mergeOption = function () { + _super.prototype.mergeOption.apply(this, arguments); + }; + /** + * @overwrite + */ + PieSeriesModel.prototype.getInitialData = function () { + return createSeriesDataSimply(this, { + coordDimensions: ['value'], + encodeDefaulter: curry(makeSeriesEncodeForNameBased, this) + }); + }; + /** + * @overwrite + */ + PieSeriesModel.prototype.getDataParams = function (dataIndex) { + var data = this.getData(); + // update seats when data is changed + var dataInner = innerData(data); + var seats = dataInner.seats; + if (!seats) { + var valueList_1 = []; + data.each(data.mapDimension('value'), function (value) { + valueList_1.push(value); + }); + seats = dataInner.seats = getPercentSeats(valueList_1, data.hostModel.get('percentPrecision')); + } + var params = _super.prototype.getDataParams.call(this, dataIndex); + // seats may be empty when sum is 0 + params.percent = seats[dataIndex] || 0; + params.$vars.push('percent'); + return params; + }; + PieSeriesModel.prototype._defaultLabelLine = function (option) { + // Extend labelLine emphasis + defaultEmphasis(option, 'labelLine', ['show']); + var labelLineNormalOpt = option.labelLine; + var labelLineEmphasisOpt = option.emphasis.labelLine; + // Not show label line if `label.normal.show = false` + labelLineNormalOpt.show = labelLineNormalOpt.show && option.label.show; + labelLineEmphasisOpt.show = labelLineEmphasisOpt.show && option.emphasis.label.show; + }; + PieSeriesModel.type = 'series.pie'; + PieSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + legendHoverLink: true, + colorBy: 'data', + // 默认全局居中 + center: ['50%', '50%'], + radius: [0, '75%'], + // 默认顺时针 + clockwise: true, + startAngle: 90, + endAngle: 'auto', + padAngle: 0, + // 最小角度改为0 + minAngle: 0, + // If the angle of a sector less than `minShowLabelAngle`, + // the label will not be displayed. + minShowLabelAngle: 0, + // 选中时扇区偏移量 + selectedOffset: 10, + // 选择模式,默认关闭,可选single,multiple + // selectedMode: false, + // 南丁格尔玫瑰图模式,'radius'(半径) | 'area'(面积) + // roseType: null, + percentPrecision: 2, + // If still show when all data zero. + stillShowZeroSum: true, + // cursor: null, + left: 0, + top: 0, + right: 0, + bottom: 0, + width: null, + height: null, + label: { + // color: 'inherit', + // If rotate around circle + rotate: 0, + show: true, + overflow: 'truncate', + // 'outer', 'inside', 'center' + position: 'outer', + // 'none', 'labelLine', 'edge'. Works only when position is 'outer' + alignTo: 'none', + // Closest distance between label and chart edge. + // Works only position is 'outer' and alignTo is 'edge'. + edgeDistance: '25%', + // Works only position is 'outer' and alignTo is not 'edge'. + bleedMargin: 10, + // Distance between text and label line. + distanceToLabelLine: 5 + // formatter: 标签文本格式器,同 tooltip.formatter,不支持异步回调 + // 默认使用全局文本样式,详见 textStyle + // distance: 当position为inner时有效,为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数 + }, + + // Enabled when label.normal.position is 'outer' + labelLine: { + show: true, + // 引导线两段中的第一段长度 + length: 15, + // 引导线两段中的第二段长度 + length2: 15, + smooth: false, + minTurnAngle: 90, + maxSurfaceAngle: 90, + lineStyle: { + // color: 各异, + width: 1, + type: 'solid' + } + }, + itemStyle: { + borderWidth: 1, + borderJoin: 'round' + }, + showEmptyCircle: true, + emptyCircleStyle: { + color: 'lightgray', + opacity: 1 + }, + labelLayout: { + // Hide the overlapped label. + hideOverlap: true + }, + emphasis: { + scale: true, + scaleSize: 5 + }, + // If use strategy to avoid label overlapping + avoidLabelOverlap: true, + // Animation type. Valid values: expansion, scale + animationType: 'expansion', + animationDuration: 1000, + // Animation type when update. Valid values: transition, expansion + animationTypeUpdate: 'transition', + animationEasingUpdate: 'cubicInOut', + animationDurationUpdate: 500, + animationEasing: 'cubicInOut' + }; + return PieSeriesModel; + }(SeriesModel); + + function negativeDataFilter(seriesType) { + return { + seriesType: seriesType, + reset: function (seriesModel, ecModel) { + var data = seriesModel.getData(); + data.filterSelf(function (idx) { + // handle negative value condition + var valueDim = data.mapDimension('value'); + var curValue = data.get(valueDim, idx); + if (isNumber(curValue) && !isNaN(curValue) && curValue < 0) { + return false; + } + return true; + }); + } + }; + } + + function install$4(registers) { + registers.registerChartView(PieView); + registers.registerSeriesModel(PieSeriesModel); + createLegacyDataSelectAction('pie', registers.registerAction); + registers.registerLayout(curry(pieLayout, 'pie')); + registers.registerProcessor(dataFilter('pie')); + registers.registerProcessor(negativeDataFilter('pie')); + } + + var ScatterSeriesModel = /** @class */function (_super) { + __extends(ScatterSeriesModel, _super); + function ScatterSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ScatterSeriesModel.type; + _this.hasSymbolVisual = true; + return _this; + } + ScatterSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesData(null, this, { + useEncodeDefaulter: true + }); + }; + ScatterSeriesModel.prototype.getProgressive = function () { + var progressive = this.option.progressive; + if (progressive == null) { + // PENDING + return this.option.large ? 5e3 : this.get('progressive'); + } + return progressive; + }; + ScatterSeriesModel.prototype.getProgressiveThreshold = function () { + var progressiveThreshold = this.option.progressiveThreshold; + if (progressiveThreshold == null) { + // PENDING + return this.option.large ? 1e4 : this.get('progressiveThreshold'); + } + return progressiveThreshold; + }; + ScatterSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) { + return selectors.point(data.getItemLayout(dataIndex)); + }; + ScatterSeriesModel.prototype.getZLevelKey = function () { + // Each progressive series has individual key. + return this.getData().count() > this.getProgressiveThreshold() ? this.id : ''; + }; + ScatterSeriesModel.type = 'series.scatter'; + ScatterSeriesModel.dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar']; + ScatterSeriesModel.defaultOption = { + coordinateSystem: 'cartesian2d', + // zlevel: 0, + z: 2, + legendHoverLink: true, + symbolSize: 10, + // symbolRotate: null, // 图形旋转控制 + large: false, + // Available when large is true + largeThreshold: 2000, + // cursor: null, + itemStyle: { + opacity: 0.8 + // color: 各异 + }, + + emphasis: { + scale: true + }, + // If clip the overflow graphics + // Works on cartesian / polar series + clip: true, + select: { + itemStyle: { + borderColor: '#212121' + } + }, + universalTransition: { + divideShape: 'clone' + } + // progressive: null + }; + + return ScatterSeriesModel; + }(SeriesModel); + + var BOOST_SIZE_THRESHOLD = 4; + var LargeSymbolPathShape = /** @class */function () { + function LargeSymbolPathShape() {} + return LargeSymbolPathShape; + }(); + var LargeSymbolPath = /** @class */function (_super) { + __extends(LargeSymbolPath, _super); + function LargeSymbolPath(opts) { + var _this = _super.call(this, opts) || this; + _this._off = 0; + _this.hoverDataIdx = -1; + return _this; + } + LargeSymbolPath.prototype.getDefaultShape = function () { + return new LargeSymbolPathShape(); + }; + LargeSymbolPath.prototype.reset = function () { + this.notClear = false; + this._off = 0; + }; + LargeSymbolPath.prototype.buildPath = function (path, shape) { + var points = shape.points; + var size = shape.size; + var symbolProxy = this.symbolProxy; + var symbolProxyShape = symbolProxy.shape; + var ctx = path.getContext ? path.getContext() : path; + var canBoost = ctx && size[0] < BOOST_SIZE_THRESHOLD; + var softClipShape = this.softClipShape; + var i; + // Do draw in afterBrush. + if (canBoost) { + this._ctx = ctx; + return; + } + this._ctx = null; + for (i = this._off; i < points.length;) { + var x = points[i++]; + var y = points[i++]; + if (isNaN(x) || isNaN(y)) { + continue; + } + if (softClipShape && !softClipShape.contain(x, y)) { + continue; + } + symbolProxyShape.x = x - size[0] / 2; + symbolProxyShape.y = y - size[1] / 2; + symbolProxyShape.width = size[0]; + symbolProxyShape.height = size[1]; + symbolProxy.buildPath(path, symbolProxyShape, true); + } + if (this.incremental) { + this._off = i; + this.notClear = true; + } + }; + LargeSymbolPath.prototype.afterBrush = function () { + var shape = this.shape; + var points = shape.points; + var size = shape.size; + var ctx = this._ctx; + var softClipShape = this.softClipShape; + var i; + if (!ctx) { + return; + } + // PENDING If style or other canvas status changed? + for (i = this._off; i < points.length;) { + var x = points[i++]; + var y = points[i++]; + if (isNaN(x) || isNaN(y)) { + continue; + } + if (softClipShape && !softClipShape.contain(x, y)) { + continue; + } + // fillRect is faster than building a rect path and draw. + // And it support light globalCompositeOperation. + ctx.fillRect(x - size[0] / 2, y - size[1] / 2, size[0], size[1]); + } + if (this.incremental) { + this._off = i; + this.notClear = true; + } + }; + LargeSymbolPath.prototype.findDataIndex = function (x, y) { + // TODO ??? + // Consider transform + var shape = this.shape; + var points = shape.points; + var size = shape.size; + var w = Math.max(size[0], 4); + var h = Math.max(size[1], 4); + // Not consider transform + // Treat each element as a rect + // top down traverse + for (var idx = points.length / 2 - 1; idx >= 0; idx--) { + var i = idx * 2; + var x0 = points[i] - w / 2; + var y0 = points[i + 1] - h / 2; + if (x >= x0 && y >= y0 && x <= x0 + w && y <= y0 + h) { + return idx; + } + } + return -1; + }; + LargeSymbolPath.prototype.contain = function (x, y) { + var localPos = this.transformCoordToLocal(x, y); + var rect = this.getBoundingRect(); + x = localPos[0]; + y = localPos[1]; + if (rect.contain(x, y)) { + // Cache found data index. + var dataIdx = this.hoverDataIdx = this.findDataIndex(x, y); + return dataIdx >= 0; + } + this.hoverDataIdx = -1; + return false; + }; + LargeSymbolPath.prototype.getBoundingRect = function () { + // Ignore stroke for large symbol draw. + var rect = this._rect; + if (!rect) { + var shape = this.shape; + var points = shape.points; + var size = shape.size; + var w = size[0]; + var h = size[1]; + var minX = Infinity; + var minY = Infinity; + var maxX = -Infinity; + var maxY = -Infinity; + for (var i = 0; i < points.length;) { + var x = points[i++]; + var y = points[i++]; + minX = Math.min(x, minX); + maxX = Math.max(x, maxX); + minY = Math.min(y, minY); + maxY = Math.max(y, maxY); + } + rect = this._rect = new BoundingRect(minX - w / 2, minY - h / 2, maxX - minX + w, maxY - minY + h); + } + return rect; + }; + return LargeSymbolPath; + }(Path); + var LargeSymbolDraw = /** @class */function () { + function LargeSymbolDraw() { + this.group = new Group(); + } + /** + * Update symbols draw by new data + */ + LargeSymbolDraw.prototype.updateData = function (data, opt) { + this._clear(); + var symbolEl = this._create(); + symbolEl.setShape({ + points: data.getLayout('points') + }); + this._setCommon(symbolEl, data, opt); + }; + LargeSymbolDraw.prototype.updateLayout = function (data) { + var points = data.getLayout('points'); + this.group.eachChild(function (child) { + if (child.startIndex != null) { + var len = (child.endIndex - child.startIndex) * 2; + var byteOffset = child.startIndex * 4 * 2; + points = new Float32Array(points.buffer, byteOffset, len); + } + child.setShape('points', points); + // Reset draw cursor. + child.reset(); + }); + }; + LargeSymbolDraw.prototype.incrementalPrepareUpdate = function (data) { + this._clear(); + }; + LargeSymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) { + var lastAdded = this._newAdded[0]; + var points = data.getLayout('points'); + var oldPoints = lastAdded && lastAdded.shape.points; + // Merging the exists. Each element has 1e4 points. + // Consider the performance balance between too much elements and too much points in one shape(may affect hover optimization) + if (oldPoints && oldPoints.length < 2e4) { + var oldLen = oldPoints.length; + var newPoints = new Float32Array(oldLen + points.length); + // Concat two array + newPoints.set(oldPoints); + newPoints.set(points, oldLen); + // Update endIndex + lastAdded.endIndex = taskParams.end; + lastAdded.setShape({ + points: newPoints + }); + } else { + // Clear + this._newAdded = []; + var symbolEl = this._create(); + symbolEl.startIndex = taskParams.start; + symbolEl.endIndex = taskParams.end; + symbolEl.incremental = true; + symbolEl.setShape({ + points: points + }); + this._setCommon(symbolEl, data, opt); + } + }; + LargeSymbolDraw.prototype.eachRendered = function (cb) { + this._newAdded[0] && cb(this._newAdded[0]); + }; + LargeSymbolDraw.prototype._create = function () { + var symbolEl = new LargeSymbolPath({ + cursor: 'default' + }); + symbolEl.ignoreCoarsePointer = true; + this.group.add(symbolEl); + this._newAdded.push(symbolEl); + return symbolEl; + }; + LargeSymbolDraw.prototype._setCommon = function (symbolEl, data, opt) { + var hostModel = data.hostModel; + opt = opt || {}; + var size = data.getVisual('symbolSize'); + symbolEl.setShape('size', size instanceof Array ? size : [size, size]); + symbolEl.softClipShape = opt.clipShape || null; + // Create symbolProxy to build path for each data + symbolEl.symbolProxy = createSymbol(data.getVisual('symbol'), 0, 0, 0, 0); + // Use symbolProxy setColor method + symbolEl.setColor = symbolEl.symbolProxy.setColor; + var extrudeShadow = symbolEl.shape.size[0] < BOOST_SIZE_THRESHOLD; + symbolEl.useStyle( + // Draw shadow when doing fillRect is extremely slow. + hostModel.getModel('itemStyle').getItemStyle(extrudeShadow ? ['color', 'shadowBlur', 'shadowColor'] : ['color'])); + var globalStyle = data.getVisual('style'); + var visualColor = globalStyle && globalStyle.fill; + if (visualColor) { + symbolEl.setColor(visualColor); + } + var ecData = getECData(symbolEl); + // Enable tooltip + // PENDING May have performance issue when path is extremely large + ecData.seriesIndex = hostModel.seriesIndex; + symbolEl.on('mousemove', function (e) { + ecData.dataIndex = null; + var dataIndex = symbolEl.hoverDataIdx; + if (dataIndex >= 0) { + // Provide dataIndex for tooltip + ecData.dataIndex = dataIndex + (symbolEl.startIndex || 0); + } + }); + }; + LargeSymbolDraw.prototype.remove = function () { + this._clear(); + }; + LargeSymbolDraw.prototype._clear = function () { + this._newAdded = []; + this.group.removeAll(); + }; + return LargeSymbolDraw; + }(); + + var ScatterView = /** @class */function (_super) { + __extends(ScatterView, _super); + function ScatterView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ScatterView.type; + return _this; + } + ScatterView.prototype.render = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var symbolDraw = this._updateSymbolDraw(data, seriesModel); + symbolDraw.updateData(data, { + // TODO + // If this parameter should be a shape or a bounding volume + // shape will be more general. + // But bounding volume like bounding rect will be much faster in the contain calculation + clipShape: this._getClipShape(seriesModel) + }); + this._finished = true; + }; + ScatterView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var symbolDraw = this._updateSymbolDraw(data, seriesModel); + symbolDraw.incrementalPrepareUpdate(data); + this._finished = false; + }; + ScatterView.prototype.incrementalRender = function (taskParams, seriesModel, ecModel) { + this._symbolDraw.incrementalUpdate(taskParams, seriesModel.getData(), { + clipShape: this._getClipShape(seriesModel) + }); + this._finished = taskParams.end === seriesModel.getData().count(); + }; + ScatterView.prototype.updateTransform = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + // Must mark group dirty and make sure the incremental layer will be cleared + // PENDING + this.group.dirty(); + if (!this._finished || data.count() > 1e4) { + return { + update: true + }; + } else { + var res = pointsLayout('').reset(seriesModel, ecModel, api); + if (res.progress) { + res.progress({ + start: 0, + end: data.count(), + count: data.count() + }, data); + } + this._symbolDraw.updateLayout(data); + } + }; + ScatterView.prototype.eachRendered = function (cb) { + this._symbolDraw && this._symbolDraw.eachRendered(cb); + }; + ScatterView.prototype._getClipShape = function (seriesModel) { + if (!seriesModel.get('clip', true)) { + return; + } + var coordSys = seriesModel.coordinateSystem; + // PENDING make `0.1` configurable, for example, `clipTolerance`? + return coordSys && coordSys.getArea && coordSys.getArea(.1); + }; + ScatterView.prototype._updateSymbolDraw = function (data, seriesModel) { + var symbolDraw = this._symbolDraw; + var pipelineContext = seriesModel.pipelineContext; + var isLargeDraw = pipelineContext.large; + if (!symbolDraw || isLargeDraw !== this._isLargeDraw) { + symbolDraw && symbolDraw.remove(); + symbolDraw = this._symbolDraw = isLargeDraw ? new LargeSymbolDraw() : new SymbolDraw(); + this._isLargeDraw = isLargeDraw; + this.group.removeAll(); + } + this.group.add(symbolDraw.group); + return symbolDraw; + }; + ScatterView.prototype.remove = function (ecModel, api) { + this._symbolDraw && this._symbolDraw.remove(true); + this._symbolDraw = null; + }; + ScatterView.prototype.dispose = function () {}; + ScatterView.type = 'scatter'; + return ScatterView; + }(ChartView); + + var GridModel = /** @class */function (_super) { + __extends(GridModel, _super); + function GridModel() { + return _super !== null && _super.apply(this, arguments) || this; + } + GridModel.type = 'grid'; + GridModel.dependencies = ['xAxis', 'yAxis']; + GridModel.layoutMode = 'box'; + GridModel.defaultOption = { + show: false, + // zlevel: 0, + z: 0, + left: '10%', + top: 60, + right: '10%', + bottom: 70, + // If grid size contain label + containLabel: false, + // width: {totalWidth} - left - right, + // height: {totalHeight} - top - bottom, + backgroundColor: 'rgba(0,0,0,0)', + borderWidth: 1, + borderColor: '#ccc' + }; + return GridModel; + }(ComponentModel); + + var CartesianAxisModel = /** @class */function (_super) { + __extends(CartesianAxisModel, _super); + function CartesianAxisModel() { + return _super !== null && _super.apply(this, arguments) || this; + } + CartesianAxisModel.prototype.getCoordSysModel = function () { + return this.getReferringComponents('grid', SINGLE_REFERRING).models[0]; + }; + CartesianAxisModel.type = 'cartesian2dAxis'; + return CartesianAxisModel; + }(ComponentModel); + mixin(CartesianAxisModel, AxisModelCommonMixin); + + var defaultOption = { + show: true, + // zlevel: 0, + z: 0, + // Inverse the axis. + inverse: false, + // Axis name displayed. + name: '', + // 'start' | 'middle' | 'end' + nameLocation: 'end', + // By degree. By default auto rotate by nameLocation. + nameRotate: null, + nameTruncate: { + maxWidth: null, + ellipsis: '...', + placeholder: '.' + }, + // Use global text style by default. + nameTextStyle: {}, + // The gap between axisName and axisLine. + nameGap: 15, + // Default `false` to support tooltip. + silent: false, + // Default `false` to avoid legacy user event listener fail. + triggerEvent: false, + tooltip: { + show: false + }, + axisPointer: {}, + axisLine: { + show: true, + onZero: true, + onZeroAxisIndex: null, + lineStyle: { + color: '#6E7079', + width: 1, + type: 'solid' + }, + // The arrow at both ends the the axis. + symbol: ['none', 'none'], + symbolSize: [10, 15] + }, + axisTick: { + show: true, + // Whether axisTick is inside the grid or outside the grid. + inside: false, + // The length of axisTick. + length: 5, + lineStyle: { + width: 1 + } + }, + axisLabel: { + show: true, + // Whether axisLabel is inside the grid or outside the grid. + inside: false, + rotate: 0, + // true | false | null/undefined (auto) + showMinLabel: null, + // true | false | null/undefined (auto) + showMaxLabel: null, + margin: 8, + // formatter: null, + fontSize: 12 + }, + splitLine: { + show: true, + lineStyle: { + color: ['#E0E6F1'], + width: 1, + type: 'solid' + } + }, + splitArea: { + show: false, + areaStyle: { + color: ['rgba(250,250,250,0.2)', 'rgba(210,219,238,0.2)'] + } + } + }; + var categoryAxis = merge({ + // The gap at both ends of the axis. For categoryAxis, boolean. + boundaryGap: true, + // Set false to faster category collection. + deduplication: null, + // splitArea: { + // show: false + // }, + splitLine: { + show: false + }, + axisTick: { + // If tick is align with label when boundaryGap is true + alignWithLabel: false, + interval: 'auto' + }, + axisLabel: { + interval: 'auto' + } + }, defaultOption); + var valueAxis = merge({ + boundaryGap: [0, 0], + axisLine: { + // Not shown when other axis is categoryAxis in cartesian + show: 'auto' + }, + axisTick: { + // Not shown when other axis is categoryAxis in cartesian + show: 'auto' + }, + // TODO + // min/max: [30, datamin, 60] or [20, datamin] or [datamin, 60] + splitNumber: 5, + minorTick: { + // Minor tick, not available for cateogry axis. + show: false, + // Split number of minor ticks. The value should be in range of (0, 100) + splitNumber: 5, + // Length of minor tick + length: 3, + // Line style + lineStyle: { + // Default to be same with axisTick + } + }, + minorSplitLine: { + show: false, + lineStyle: { + color: '#F4F7FD', + width: 1 + } + } + }, defaultOption); + var timeAxis = merge({ + splitNumber: 6, + axisLabel: { + // To eliminate labels that are not nice + showMinLabel: false, + showMaxLabel: false, + rich: { + primary: { + fontWeight: 'bold' + } + } + }, + splitLine: { + show: false + } + }, valueAxis); + var logAxis = defaults({ + logBase: 10 + }, valueAxis); + var axisDefault = { + category: categoryAxis, + value: valueAxis, + time: timeAxis, + log: logAxis + }; + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var AXIS_TYPES = { + value: 1, + category: 1, + time: 1, + log: 1 + }; + + /** + * Generate sub axis model class + * @param axisName 'x' 'y' 'radius' 'angle' 'parallel' ... + */ + function axisModelCreator(registers, axisName, BaseAxisModelClass, extraDefaultOption) { + each(AXIS_TYPES, function (v, axisType) { + var defaultOption = merge(merge({}, axisDefault[axisType], true), extraDefaultOption, true); + var AxisModel = /** @class */function (_super) { + __extends(AxisModel, _super); + function AxisModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = axisName + 'Axis.' + axisType; + return _this; + } + AxisModel.prototype.mergeDefaultAndTheme = function (option, ecModel) { + var layoutMode = fetchLayoutMode(this); + var inputPositionParams = layoutMode ? getLayoutParams(option) : {}; + var themeModel = ecModel.getTheme(); + merge(option, themeModel.get(axisType + 'Axis')); + merge(option, this.getDefaultOption()); + option.type = getAxisType(option); + if (layoutMode) { + mergeLayoutParam(option, inputPositionParams, layoutMode); + } + }; + AxisModel.prototype.optionUpdated = function () { + var thisOption = this.option; + if (thisOption.type === 'category') { + this.__ordinalMeta = OrdinalMeta.createByAxisModel(this); + } + }; + /** + * Should not be called before all of 'getInitailData' finished. + * Because categories are collected during initializing data. + */ + AxisModel.prototype.getCategories = function (rawData) { + var option = this.option; + // FIXME + // warning if called before all of 'getInitailData' finished. + if (option.type === 'category') { + if (rawData) { + return option.data; + } + return this.__ordinalMeta.categories; + } + }; + AxisModel.prototype.getOrdinalMeta = function () { + return this.__ordinalMeta; + }; + AxisModel.type = axisName + 'Axis.' + axisType; + AxisModel.defaultOption = defaultOption; + return AxisModel; + }(BaseAxisModelClass); + registers.registerComponentModel(AxisModel); + }); + registers.registerSubTypeDefaulter(axisName + 'Axis', getAxisType); + } + function getAxisType(option) { + // Default axis with data is category axis + return option.type || (option.data ? 'category' : 'value'); + } + + var Cartesian = /** @class */function () { + function Cartesian(name) { + this.type = 'cartesian'; + this._dimList = []; + this._axes = {}; + this.name = name || ''; + } + Cartesian.prototype.getAxis = function (dim) { + return this._axes[dim]; + }; + Cartesian.prototype.getAxes = function () { + return map(this._dimList, function (dim) { + return this._axes[dim]; + }, this); + }; + Cartesian.prototype.getAxesByScale = function (scaleType) { + scaleType = scaleType.toLowerCase(); + return filter(this.getAxes(), function (axis) { + return axis.scale.type === scaleType; + }); + }; + Cartesian.prototype.addAxis = function (axis) { + var dim = axis.dim; + this._axes[dim] = axis; + this._dimList.push(dim); + }; + return Cartesian; + }(); + + var cartesian2DDimensions = ['x', 'y']; + function canCalculateAffineTransform(scale) { + return scale.type === 'interval' || scale.type === 'time'; + } + var Cartesian2D = /** @class */function (_super) { + __extends(Cartesian2D, _super); + function Cartesian2D() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = 'cartesian2d'; + _this.dimensions = cartesian2DDimensions; + return _this; + } + /** + * Calculate an affine transform matrix if two axes are time or value. + * It's mainly for accelartion on the large time series data. + */ + Cartesian2D.prototype.calcAffineTransform = function () { + this._transform = this._invTransform = null; + var xAxisScale = this.getAxis('x').scale; + var yAxisScale = this.getAxis('y').scale; + if (!canCalculateAffineTransform(xAxisScale) || !canCalculateAffineTransform(yAxisScale)) { + return; + } + var xScaleExtent = xAxisScale.getExtent(); + var yScaleExtent = yAxisScale.getExtent(); + var start = this.dataToPoint([xScaleExtent[0], yScaleExtent[0]]); + var end = this.dataToPoint([xScaleExtent[1], yScaleExtent[1]]); + var xScaleSpan = xScaleExtent[1] - xScaleExtent[0]; + var yScaleSpan = yScaleExtent[1] - yScaleExtent[0]; + if (!xScaleSpan || !yScaleSpan) { + return; + } + // Accelerate data to point calculation on the special large time series data. + var scaleX = (end[0] - start[0]) / xScaleSpan; + var scaleY = (end[1] - start[1]) / yScaleSpan; + var translateX = start[0] - xScaleExtent[0] * scaleX; + var translateY = start[1] - yScaleExtent[0] * scaleY; + var m = this._transform = [scaleX, 0, 0, scaleY, translateX, translateY]; + this._invTransform = invert([], m); + }; + /** + * Base axis will be used on stacking. + */ + Cartesian2D.prototype.getBaseAxis = function () { + return this.getAxesByScale('ordinal')[0] || this.getAxesByScale('time')[0] || this.getAxis('x'); + }; + Cartesian2D.prototype.containPoint = function (point) { + var axisX = this.getAxis('x'); + var axisY = this.getAxis('y'); + return axisX.contain(axisX.toLocalCoord(point[0])) && axisY.contain(axisY.toLocalCoord(point[1])); + }; + Cartesian2D.prototype.containData = function (data) { + return this.getAxis('x').containData(data[0]) && this.getAxis('y').containData(data[1]); + }; + Cartesian2D.prototype.containZone = function (data1, data2) { + var zoneDiag1 = this.dataToPoint(data1); + var zoneDiag2 = this.dataToPoint(data2); + var area = this.getArea(); + var zone = new BoundingRect(zoneDiag1[0], zoneDiag1[1], zoneDiag2[0] - zoneDiag1[0], zoneDiag2[1] - zoneDiag1[1]); + return area.intersect(zone); + }; + Cartesian2D.prototype.dataToPoint = function (data, clamp, out) { + out = out || []; + var xVal = data[0]; + var yVal = data[1]; + // Fast path + if (this._transform + // It's supported that if data is like `[Inifity, 123]`, where only Y pixel calculated. + && xVal != null && isFinite(xVal) && yVal != null && isFinite(yVal)) { + return applyTransform(out, data, this._transform); + } + var xAxis = this.getAxis('x'); + var yAxis = this.getAxis('y'); + out[0] = xAxis.toGlobalCoord(xAxis.dataToCoord(xVal, clamp)); + out[1] = yAxis.toGlobalCoord(yAxis.dataToCoord(yVal, clamp)); + return out; + }; + Cartesian2D.prototype.clampData = function (data, out) { + var xScale = this.getAxis('x').scale; + var yScale = this.getAxis('y').scale; + var xAxisExtent = xScale.getExtent(); + var yAxisExtent = yScale.getExtent(); + var x = xScale.parse(data[0]); + var y = yScale.parse(data[1]); + out = out || []; + out[0] = Math.min(Math.max(Math.min(xAxisExtent[0], xAxisExtent[1]), x), Math.max(xAxisExtent[0], xAxisExtent[1])); + out[1] = Math.min(Math.max(Math.min(yAxisExtent[0], yAxisExtent[1]), y), Math.max(yAxisExtent[0], yAxisExtent[1])); + return out; + }; + Cartesian2D.prototype.pointToData = function (point, clamp) { + var out = []; + if (this._invTransform) { + return applyTransform(out, point, this._invTransform); + } + var xAxis = this.getAxis('x'); + var yAxis = this.getAxis('y'); + out[0] = xAxis.coordToData(xAxis.toLocalCoord(point[0]), clamp); + out[1] = yAxis.coordToData(yAxis.toLocalCoord(point[1]), clamp); + return out; + }; + Cartesian2D.prototype.getOtherAxis = function (axis) { + return this.getAxis(axis.dim === 'x' ? 'y' : 'x'); + }; + /** + * Get rect area of cartesian. + * Area will have a contain function to determine if a point is in the coordinate system. + */ + Cartesian2D.prototype.getArea = function (tolerance) { + tolerance = tolerance || 0; + var xExtent = this.getAxis('x').getGlobalExtent(); + var yExtent = this.getAxis('y').getGlobalExtent(); + var x = Math.min(xExtent[0], xExtent[1]) - tolerance; + var y = Math.min(yExtent[0], yExtent[1]) - tolerance; + var width = Math.max(xExtent[0], xExtent[1]) - x + tolerance; + var height = Math.max(yExtent[0], yExtent[1]) - y + tolerance; + return new BoundingRect(x, y, width, height); + }; + return Cartesian2D; + }(Cartesian); + + var Axis2D = /** @class */function (_super) { + __extends(Axis2D, _super); + function Axis2D(dim, scale, coordExtent, axisType, position) { + var _this = _super.call(this, dim, scale, coordExtent) || this; + /** + * Index of axis, can be used as key + * Injected outside. + */ + _this.index = 0; + _this.type = axisType || 'value'; + _this.position = position || 'bottom'; + return _this; + } + Axis2D.prototype.isHorizontal = function () { + var position = this.position; + return position === 'top' || position === 'bottom'; + }; + /** + * Each item cooresponds to this.getExtent(), which + * means globalExtent[0] may greater than globalExtent[1], + * unless `asc` is input. + * + * @param {boolean} [asc] + * @return {Array.} + */ + Axis2D.prototype.getGlobalExtent = function (asc) { + var ret = this.getExtent(); + ret[0] = this.toGlobalCoord(ret[0]); + ret[1] = this.toGlobalCoord(ret[1]); + asc && ret[0] > ret[1] && ret.reverse(); + return ret; + }; + Axis2D.prototype.pointToData = function (point, clamp) { + return this.coordToData(this.toLocalCoord(point[this.dim === 'x' ? 0 : 1]), clamp); + }; + /** + * Set ordinalSortInfo + * @param info new OrdinalSortInfo + */ + Axis2D.prototype.setCategorySortInfo = function (info) { + if (this.type !== 'category') { + return false; + } + this.model.option.categorySortInfo = info; + this.scale.setSortInfo(info); + }; + return Axis2D; + }(Axis); + + /** + * Can only be called after coordinate system creation stage. + * (Can be called before coordinate system update stage). + */ + function layout$1(gridModel, axisModel, opt) { + opt = opt || {}; + var grid = gridModel.coordinateSystem; + var axis = axisModel.axis; + var layout = {}; + var otherAxisOnZeroOf = axis.getAxesOnZeroOf()[0]; + var rawAxisPosition = axis.position; + var axisPosition = otherAxisOnZeroOf ? 'onZero' : rawAxisPosition; + var axisDim = axis.dim; + var rect = grid.getRect(); + var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height]; + var idx = { + left: 0, + right: 1, + top: 0, + bottom: 1, + onZero: 2 + }; + var axisOffset = axisModel.get('offset') || 0; + var posBound = axisDim === 'x' ? [rectBound[2] - axisOffset, rectBound[3] + axisOffset] : [rectBound[0] - axisOffset, rectBound[1] + axisOffset]; + if (otherAxisOnZeroOf) { + var onZeroCoord = otherAxisOnZeroOf.toGlobalCoord(otherAxisOnZeroOf.dataToCoord(0)); + posBound[idx.onZero] = Math.max(Math.min(onZeroCoord, posBound[1]), posBound[0]); + } + // Axis position + layout.position = [axisDim === 'y' ? posBound[idx[axisPosition]] : rectBound[0], axisDim === 'x' ? posBound[idx[axisPosition]] : rectBound[3]]; + // Axis rotation + layout.rotation = Math.PI / 2 * (axisDim === 'x' ? 0 : 1); + // Tick and label direction, x y is axisDim + var dirMap = { + top: -1, + bottom: 1, + left: -1, + right: 1 + }; + layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition]; + layout.labelOffset = otherAxisOnZeroOf ? posBound[idx[rawAxisPosition]] - posBound[idx.onZero] : 0; + if (axisModel.get(['axisTick', 'inside'])) { + layout.tickDirection = -layout.tickDirection; + } + if (retrieve(opt.labelInside, axisModel.get(['axisLabel', 'inside']))) { + layout.labelDirection = -layout.labelDirection; + } + // Special label rotation + var labelRotate = axisModel.get(['axisLabel', 'rotate']); + layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate; + // Over splitLine and splitArea + layout.z2 = 1; + return layout; + } + function isCartesian2DSeries(seriesModel) { + return seriesModel.get('coordinateSystem') === 'cartesian2d'; + } + function findAxisModels(seriesModel) { + var axisModelMap = { + xAxisModel: null, + yAxisModel: null + }; + each(axisModelMap, function (v, key) { + var axisType = key.replace(/Model$/, ''); + var axisModel = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[0]; + if ("development" !== 'production') { + if (!axisModel) { + throw new Error(axisType + ' "' + retrieve3(seriesModel.get(axisType + 'Index'), seriesModel.get(axisType + 'Id'), 0) + '" not found'); + } + } + axisModelMap[key] = axisModel; + }); + return axisModelMap; + } + + var mathLog$1 = Math.log; + function alignScaleTicks(scale, axisModel, alignToScale) { + var intervalScaleProto = IntervalScale.prototype; + // NOTE: There is a precondition for log scale here: + // In log scale we store _interval and _extent of exponent value. + // So if we use the method of InternalScale to set/get these data. + // It process the exponent value, which is linear and what we want here. + var alignToTicks = intervalScaleProto.getTicks.call(alignToScale); + var alignToNicedTicks = intervalScaleProto.getTicks.call(alignToScale, true); + var alignToSplitNumber = alignToTicks.length - 1; + var alignToInterval = intervalScaleProto.getInterval.call(alignToScale); + var scaleExtent = getScaleExtent(scale, axisModel); + var rawExtent = scaleExtent.extent; + var isMinFixed = scaleExtent.fixMin; + var isMaxFixed = scaleExtent.fixMax; + if (scale.type === 'log') { + var logBase = mathLog$1(scale.base); + rawExtent = [mathLog$1(rawExtent[0]) / logBase, mathLog$1(rawExtent[1]) / logBase]; + } + scale.setExtent(rawExtent[0], rawExtent[1]); + scale.calcNiceExtent({ + splitNumber: alignToSplitNumber, + fixMin: isMinFixed, + fixMax: isMaxFixed + }); + var extent = intervalScaleProto.getExtent.call(scale); + // Need to update the rawExtent. + // Because value in rawExtent may be not parsed. e.g. 'dataMin', 'dataMax' + if (isMinFixed) { + rawExtent[0] = extent[0]; + } + if (isMaxFixed) { + rawExtent[1] = extent[1]; + } + var interval = intervalScaleProto.getInterval.call(scale); + var min = rawExtent[0]; + var max = rawExtent[1]; + if (isMinFixed && isMaxFixed) { + // User set min, max, divide to get new interval + interval = (max - min) / alignToSplitNumber; + } else if (isMinFixed) { + max = rawExtent[0] + interval * alignToSplitNumber; + // User set min, expand extent on the other side + while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1])) { + interval = increaseInterval(interval); + max = rawExtent[0] + interval * alignToSplitNumber; + } + } else if (isMaxFixed) { + // User set max, expand extent on the other side + min = rawExtent[1] - interval * alignToSplitNumber; + while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0])) { + interval = increaseInterval(interval); + min = rawExtent[1] - interval * alignToSplitNumber; + } + } else { + var nicedSplitNumber = scale.getTicks().length - 1; + if (nicedSplitNumber > alignToSplitNumber) { + interval = increaseInterval(interval); + } + var range = interval * alignToSplitNumber; + max = Math.ceil(rawExtent[1] / interval) * interval; + min = round(max - range); + // Not change the result that crossing zero. + if (min < 0 && rawExtent[0] >= 0) { + min = 0; + max = round(range); + } else if (max > 0 && rawExtent[1] <= 0) { + max = 0; + min = -round(range); + } + } + // Adjust min, max based on the extent of alignTo. When min or max is set in alignTo scale + var t0 = (alignToTicks[0].value - alignToNicedTicks[0].value) / alignToInterval; + var t1 = (alignToTicks[alignToSplitNumber].value - alignToNicedTicks[alignToSplitNumber].value) / alignToInterval; + // NOTE: Must in setExtent -> setInterval -> setNiceExtent order. + intervalScaleProto.setExtent.call(scale, min + interval * t0, max + interval * t1); + intervalScaleProto.setInterval.call(scale, interval); + if (t0 || t1) { + intervalScaleProto.setNiceExtent.call(scale, min + interval, max - interval); + } + if ("development" !== 'production') { + var ticks = intervalScaleProto.getTicks.call(scale); + if (ticks[1] && (!isValueNice(interval) || getPrecisionSafe(ticks[1].value) > getPrecisionSafe(interval))) { + warn( + // eslint-disable-next-line + "The ticks may be not readable when set min: " + axisModel.get('min') + ", max: " + axisModel.get('max') + " and alignTicks: true"); + } + } + } + + var Grid = /** @class */function () { + function Grid(gridModel, ecModel, api) { + // FIXME:TS where used (different from registered type 'cartesian2d')? + this.type = 'grid'; + this._coordsMap = {}; + this._coordsList = []; + this._axesMap = {}; + this._axesList = []; + this.axisPointerEnabled = true; + this.dimensions = cartesian2DDimensions; + this._initCartesian(gridModel, ecModel, api); + this.model = gridModel; + } + Grid.prototype.getRect = function () { + return this._rect; + }; + Grid.prototype.update = function (ecModel, api) { + var axesMap = this._axesMap; + this._updateScale(ecModel, this.model); + function updateAxisTicks(axes) { + var alignTo; + // Axis is added in order of axisIndex. + var axesIndices = keys(axes); + var len = axesIndices.length; + if (!len) { + return; + } + var axisNeedsAlign = []; + // Process once and calculate the ticks for those don't use alignTicks. + for (var i = len - 1; i >= 0; i--) { + var idx = +axesIndices[i]; // Convert to number. + var axis = axes[idx]; + var model = axis.model; + var scale = axis.scale; + if ( + // Only value and log axis without interval support alignTicks. + isIntervalOrLogScale(scale) && model.get('alignTicks') && model.get('interval') == null) { + axisNeedsAlign.push(axis); + } else { + niceScaleExtent(scale, model); + if (isIntervalOrLogScale(scale)) { + // Can only align to interval or log axis. + alignTo = axis; + } + } + } + // All axes has set alignTicks. Pick the first one. + // PENDING. Should we find the axis that both set interval, min, max and align to this one? + if (axisNeedsAlign.length) { + if (!alignTo) { + alignTo = axisNeedsAlign.pop(); + niceScaleExtent(alignTo.scale, alignTo.model); + } + each(axisNeedsAlign, function (axis) { + alignScaleTicks(axis.scale, axis.model, alignTo.scale); + }); + } + } + updateAxisTicks(axesMap.x); + updateAxisTicks(axesMap.y); + // Key: axisDim_axisIndex, value: boolean, whether onZero target. + var onZeroRecords = {}; + each(axesMap.x, function (xAxis) { + fixAxisOnZero(axesMap, 'y', xAxis, onZeroRecords); + }); + each(axesMap.y, function (yAxis) { + fixAxisOnZero(axesMap, 'x', yAxis, onZeroRecords); + }); + // Resize again if containLabel is enabled + // FIXME It may cause getting wrong grid size in data processing stage + this.resize(this.model, api); + }; + /** + * Resize the grid + */ + Grid.prototype.resize = function (gridModel, api, ignoreContainLabel) { + var boxLayoutParams = gridModel.getBoxLayoutParams(); + var isContainLabel = !ignoreContainLabel && gridModel.get('containLabel'); + var gridRect = getLayoutRect(boxLayoutParams, { + width: api.getWidth(), + height: api.getHeight() + }); + this._rect = gridRect; + var axesList = this._axesList; + adjustAxes(); + // Minus label size + if (isContainLabel) { + each(axesList, function (axis) { + if (!axis.model.get(['axisLabel', 'inside'])) { + var labelUnionRect = estimateLabelUnionRect(axis); + if (labelUnionRect) { + var dim = axis.isHorizontal() ? 'height' : 'width'; + var margin = axis.model.get(['axisLabel', 'margin']); + gridRect[dim] -= labelUnionRect[dim] + margin; + if (axis.position === 'top') { + gridRect.y += labelUnionRect.height + margin; + } else if (axis.position === 'left') { + gridRect.x += labelUnionRect.width + margin; + } + } + } + }); + adjustAxes(); + } + each(this._coordsList, function (coord) { + // Calculate affine matrix to accelerate the data to point transform. + // If all the axes scales are time or value. + coord.calcAffineTransform(); + }); + function adjustAxes() { + each(axesList, function (axis) { + var isHorizontal = axis.isHorizontal(); + var extent = isHorizontal ? [0, gridRect.width] : [0, gridRect.height]; + var idx = axis.inverse ? 1 : 0; + axis.setExtent(extent[idx], extent[1 - idx]); + updateAxisTransform(axis, isHorizontal ? gridRect.x : gridRect.y); + }); + } + }; + Grid.prototype.getAxis = function (dim, axisIndex) { + var axesMapOnDim = this._axesMap[dim]; + if (axesMapOnDim != null) { + return axesMapOnDim[axisIndex || 0]; + } + }; + Grid.prototype.getAxes = function () { + return this._axesList.slice(); + }; + Grid.prototype.getCartesian = function (xAxisIndex, yAxisIndex) { + if (xAxisIndex != null && yAxisIndex != null) { + var key = 'x' + xAxisIndex + 'y' + yAxisIndex; + return this._coordsMap[key]; + } + if (isObject(xAxisIndex)) { + yAxisIndex = xAxisIndex.yAxisIndex; + xAxisIndex = xAxisIndex.xAxisIndex; + } + for (var i = 0, coordList = this._coordsList; i < coordList.length; i++) { + if (coordList[i].getAxis('x').index === xAxisIndex || coordList[i].getAxis('y').index === yAxisIndex) { + return coordList[i]; + } + } + }; + Grid.prototype.getCartesians = function () { + return this._coordsList.slice(); + }; + /** + * @implements + */ + Grid.prototype.convertToPixel = function (ecModel, finder, value) { + var target = this._findConvertTarget(finder); + return target.cartesian ? target.cartesian.dataToPoint(value) : target.axis ? target.axis.toGlobalCoord(target.axis.dataToCoord(value)) : null; + }; + /** + * @implements + */ + Grid.prototype.convertFromPixel = function (ecModel, finder, value) { + var target = this._findConvertTarget(finder); + return target.cartesian ? target.cartesian.pointToData(value) : target.axis ? target.axis.coordToData(target.axis.toLocalCoord(value)) : null; + }; + Grid.prototype._findConvertTarget = function (finder) { + var seriesModel = finder.seriesModel; + var xAxisModel = finder.xAxisModel || seriesModel && seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0]; + var yAxisModel = finder.yAxisModel || seriesModel && seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0]; + var gridModel = finder.gridModel; + var coordsList = this._coordsList; + var cartesian; + var axis; + if (seriesModel) { + cartesian = seriesModel.coordinateSystem; + indexOf(coordsList, cartesian) < 0 && (cartesian = null); + } else if (xAxisModel && yAxisModel) { + cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex); + } else if (xAxisModel) { + axis = this.getAxis('x', xAxisModel.componentIndex); + } else if (yAxisModel) { + axis = this.getAxis('y', yAxisModel.componentIndex); + } + // Lowest priority. + else if (gridModel) { + var grid = gridModel.coordinateSystem; + if (grid === this) { + cartesian = this._coordsList[0]; + } + } + return { + cartesian: cartesian, + axis: axis + }; + }; + /** + * @implements + */ + Grid.prototype.containPoint = function (point) { + var coord = this._coordsList[0]; + if (coord) { + return coord.containPoint(point); + } + }; + /** + * Initialize cartesian coordinate systems + */ + Grid.prototype._initCartesian = function (gridModel, ecModel, api) { + var _this = this; + var grid = this; + var axisPositionUsed = { + left: false, + right: false, + top: false, + bottom: false + }; + var axesMap = { + x: {}, + y: {} + }; + var axesCount = { + x: 0, + y: 0 + }; + // Create axis + ecModel.eachComponent('xAxis', createAxisCreator('x'), this); + ecModel.eachComponent('yAxis', createAxisCreator('y'), this); + if (!axesCount.x || !axesCount.y) { + // Roll back when there no either x or y axis + this._axesMap = {}; + this._axesList = []; + return; + } + this._axesMap = axesMap; + // Create cartesian2d + each(axesMap.x, function (xAxis, xAxisIndex) { + each(axesMap.y, function (yAxis, yAxisIndex) { + var key = 'x' + xAxisIndex + 'y' + yAxisIndex; + var cartesian = new Cartesian2D(key); + cartesian.master = _this; + cartesian.model = gridModel; + _this._coordsMap[key] = cartesian; + _this._coordsList.push(cartesian); + cartesian.addAxis(xAxis); + cartesian.addAxis(yAxis); + }); + }); + function createAxisCreator(dimName) { + return function (axisModel, idx) { + if (!isAxisUsedInTheGrid(axisModel, gridModel)) { + return; + } + var axisPosition = axisModel.get('position'); + if (dimName === 'x') { + // Fix position + if (axisPosition !== 'top' && axisPosition !== 'bottom') { + // Default bottom of X + axisPosition = axisPositionUsed.bottom ? 'top' : 'bottom'; + } + } else { + // Fix position + if (axisPosition !== 'left' && axisPosition !== 'right') { + // Default left of Y + axisPosition = axisPositionUsed.left ? 'right' : 'left'; + } + } + axisPositionUsed[axisPosition] = true; + var axis = new Axis2D(dimName, createScaleByModel(axisModel), [0, 0], axisModel.get('type'), axisPosition); + var isCategory = axis.type === 'category'; + axis.onBand = isCategory && axisModel.get('boundaryGap'); + axis.inverse = axisModel.get('inverse'); + // Inject axis into axisModel + axisModel.axis = axis; + // Inject axisModel into axis + axis.model = axisModel; + // Inject grid info axis + axis.grid = grid; + // Index of axis, can be used as key + axis.index = idx; + grid._axesList.push(axis); + axesMap[dimName][idx] = axis; + axesCount[dimName]++; + }; + } + }; + /** + * Update cartesian properties from series. + */ + Grid.prototype._updateScale = function (ecModel, gridModel) { + // Reset scale + each(this._axesList, function (axis) { + axis.scale.setExtent(Infinity, -Infinity); + if (axis.type === 'category') { + var categorySortInfo = axis.model.get('categorySortInfo'); + axis.scale.setSortInfo(categorySortInfo); + } + }); + ecModel.eachSeries(function (seriesModel) { + if (isCartesian2DSeries(seriesModel)) { + var axesModelMap = findAxisModels(seriesModel); + var xAxisModel = axesModelMap.xAxisModel; + var yAxisModel = axesModelMap.yAxisModel; + if (!isAxisUsedInTheGrid(xAxisModel, gridModel) || !isAxisUsedInTheGrid(yAxisModel, gridModel)) { + return; + } + var cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex); + var data = seriesModel.getData(); + var xAxis = cartesian.getAxis('x'); + var yAxis = cartesian.getAxis('y'); + unionExtent(data, xAxis); + unionExtent(data, yAxis); + } + }, this); + function unionExtent(data, axis) { + each(getDataDimensionsOnAxis(data, axis.dim), function (dim) { + axis.scale.unionExtentFromData(data, dim); + }); + } + }; + /** + * @param dim 'x' or 'y' or 'auto' or null/undefined + */ + Grid.prototype.getTooltipAxes = function (dim) { + var baseAxes = []; + var otherAxes = []; + each(this.getCartesians(), function (cartesian) { + var baseAxis = dim != null && dim !== 'auto' ? cartesian.getAxis(dim) : cartesian.getBaseAxis(); + var otherAxis = cartesian.getOtherAxis(baseAxis); + indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis); + indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis); + }); + return { + baseAxes: baseAxes, + otherAxes: otherAxes + }; + }; + Grid.create = function (ecModel, api) { + var grids = []; + ecModel.eachComponent('grid', function (gridModel, idx) { + var grid = new Grid(gridModel, ecModel, api); + grid.name = 'grid_' + idx; + // dataSampling requires axis extent, so resize + // should be performed in create stage. + grid.resize(gridModel, api, true); + gridModel.coordinateSystem = grid; + grids.push(grid); + }); + // Inject the coordinateSystems into seriesModel + ecModel.eachSeries(function (seriesModel) { + if (!isCartesian2DSeries(seriesModel)) { + return; + } + var axesModelMap = findAxisModels(seriesModel); + var xAxisModel = axesModelMap.xAxisModel; + var yAxisModel = axesModelMap.yAxisModel; + var gridModel = xAxisModel.getCoordSysModel(); + if ("development" !== 'production') { + if (!gridModel) { + throw new Error('Grid "' + retrieve3(xAxisModel.get('gridIndex'), xAxisModel.get('gridId'), 0) + '" not found'); + } + if (xAxisModel.getCoordSysModel() !== yAxisModel.getCoordSysModel()) { + throw new Error('xAxis and yAxis must use the same grid'); + } + } + var grid = gridModel.coordinateSystem; + seriesModel.coordinateSystem = grid.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex); + }); + return grids; + }; + // For deciding which dimensions to use when creating list data + Grid.dimensions = cartesian2DDimensions; + return Grid; + }(); + /** + * Check if the axis is used in the specified grid. + */ + function isAxisUsedInTheGrid(axisModel, gridModel) { + return axisModel.getCoordSysModel() === gridModel; + } + function fixAxisOnZero(axesMap, otherAxisDim, axis, + // Key: see `getOnZeroRecordKey` + onZeroRecords) { + axis.getAxesOnZeroOf = function () { + // TODO: onZero of multiple axes. + return otherAxisOnZeroOf ? [otherAxisOnZeroOf] : []; + }; + // onZero can not be enabled in these two situations: + // 1. When any other axis is a category axis. + // 2. When no axis is cross 0 point. + var otherAxes = axesMap[otherAxisDim]; + var otherAxisOnZeroOf; + var axisModel = axis.model; + var onZero = axisModel.get(['axisLine', 'onZero']); + var onZeroAxisIndex = axisModel.get(['axisLine', 'onZeroAxisIndex']); + if (!onZero) { + return; + } + // If target axis is specified. + if (onZeroAxisIndex != null) { + if (canOnZeroToAxis(otherAxes[onZeroAxisIndex])) { + otherAxisOnZeroOf = otherAxes[onZeroAxisIndex]; + } + } else { + // Find the first available other axis. + for (var idx in otherAxes) { + if (otherAxes.hasOwnProperty(idx) && canOnZeroToAxis(otherAxes[idx]) + // Consider that two Y axes on one value axis, + // if both onZero, the two Y axes overlap. + && !onZeroRecords[getOnZeroRecordKey(otherAxes[idx])]) { + otherAxisOnZeroOf = otherAxes[idx]; + break; + } + } + } + if (otherAxisOnZeroOf) { + onZeroRecords[getOnZeroRecordKey(otherAxisOnZeroOf)] = true; + } + function getOnZeroRecordKey(axis) { + return axis.dim + '_' + axis.index; + } + } + function canOnZeroToAxis(axis) { + return axis && axis.type !== 'category' && axis.type !== 'time' && ifAxisCrossZero(axis); + } + function updateAxisTransform(axis, coordBase) { + var axisExtent = axis.getExtent(); + var axisExtentSum = axisExtent[0] + axisExtent[1]; + // Fast transform + axis.toGlobalCoord = axis.dim === 'x' ? function (coord) { + return coord + coordBase; + } : function (coord) { + return axisExtentSum - coord + coordBase; + }; + axis.toLocalCoord = axis.dim === 'x' ? function (coord) { + return coord - coordBase; + } : function (coord) { + return axisExtentSum - coord + coordBase; + }; + } + + var PI$5 = Math.PI; + /** + * A final axis is translated and rotated from a "standard axis". + * So opt.position and opt.rotation is required. + * + * A standard axis is and axis from [0, 0] to [0, axisExtent[1]], + * for example: (0, 0) ------------> (0, 50) + * + * nameDirection or tickDirection or labelDirection is 1 means tick + * or label is below the standard axis, whereas is -1 means above + * the standard axis. labelOffset means offset between label and axis, + * which is useful when 'onZero', where axisLabel is in the grid and + * label in outside grid. + * + * Tips: like always, + * positive rotation represents anticlockwise, and negative rotation + * represents clockwise. + * The direction of position coordinate is the same as the direction + * of screen coordinate. + * + * Do not need to consider axis 'inverse', which is auto processed by + * axis extent. + */ + var AxisBuilder = /** @class */function () { + function AxisBuilder(axisModel, opt) { + this.group = new Group(); + this.opt = opt; + this.axisModel = axisModel; + // Default value + defaults(opt, { + labelOffset: 0, + nameDirection: 1, + tickDirection: 1, + labelDirection: 1, + silent: true, + handleAutoShown: function () { + return true; + } + }); + // FIXME Not use a separate text group? + var transformGroup = new Group({ + x: opt.position[0], + y: opt.position[1], + rotation: opt.rotation + }); + // this.group.add(transformGroup); + // this._transformGroup = transformGroup; + transformGroup.updateTransform(); + this._transformGroup = transformGroup; + } + AxisBuilder.prototype.hasBuilder = function (name) { + return !!builders[name]; + }; + AxisBuilder.prototype.add = function (name) { + builders[name](this.opt, this.axisModel, this.group, this._transformGroup); + }; + AxisBuilder.prototype.getGroup = function () { + return this.group; + }; + AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) { + var rotationDiff = remRadian(textRotation - axisRotation); + var textAlign; + var textVerticalAlign; + if (isRadianAroundZero(rotationDiff)) { + // Label is parallel with axis line. + textVerticalAlign = direction > 0 ? 'top' : 'bottom'; + textAlign = 'center'; + } else if (isRadianAroundZero(rotationDiff - PI$5)) { + // Label is inverse parallel with axis line. + textVerticalAlign = direction > 0 ? 'bottom' : 'top'; + textAlign = 'center'; + } else { + textVerticalAlign = 'middle'; + if (rotationDiff > 0 && rotationDiff < PI$5) { + textAlign = direction > 0 ? 'right' : 'left'; + } else { + textAlign = direction > 0 ? 'left' : 'right'; + } + } + return { + rotation: rotationDiff, + textAlign: textAlign, + textVerticalAlign: textVerticalAlign + }; + }; + AxisBuilder.makeAxisEventDataBase = function (axisModel) { + var eventData = { + componentType: axisModel.mainType, + componentIndex: axisModel.componentIndex + }; + eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex; + return eventData; + }; + AxisBuilder.isLabelSilent = function (axisModel) { + var tooltipOpt = axisModel.get('tooltip'); + return axisModel.get('silent') + // Consider mouse cursor, add these restrictions. + || !(axisModel.get('triggerEvent') || tooltipOpt && tooltipOpt.show); + }; + return AxisBuilder; + }(); + var builders = { + axisLine: function (opt, axisModel, group, transformGroup) { + var shown = axisModel.get(['axisLine', 'show']); + if (shown === 'auto' && opt.handleAutoShown) { + shown = opt.handleAutoShown('axisLine'); + } + if (!shown) { + return; + } + var extent = axisModel.axis.getExtent(); + var matrix = transformGroup.transform; + var pt1 = [extent[0], 0]; + var pt2 = [extent[1], 0]; + var inverse = pt1[0] > pt2[0]; + if (matrix) { + applyTransform(pt1, pt1, matrix); + applyTransform(pt2, pt2, matrix); + } + var lineStyle = extend({ + lineCap: 'round' + }, axisModel.getModel(['axisLine', 'lineStyle']).getLineStyle()); + var line = new Line({ + shape: { + x1: pt1[0], + y1: pt1[1], + x2: pt2[0], + y2: pt2[1] + }, + style: lineStyle, + strokeContainThreshold: opt.strokeContainThreshold || 5, + silent: true, + z2: 1 + }); + subPixelOptimizeLine$1(line.shape, line.style.lineWidth); + line.anid = 'line'; + group.add(line); + var arrows = axisModel.get(['axisLine', 'symbol']); + if (arrows != null) { + var arrowSize = axisModel.get(['axisLine', 'symbolSize']); + if (isString(arrows)) { + // Use the same arrow for start and end point + arrows = [arrows, arrows]; + } + if (isString(arrowSize) || isNumber(arrowSize)) { + // Use the same size for width and height + arrowSize = [arrowSize, arrowSize]; + } + var arrowOffset = normalizeSymbolOffset(axisModel.get(['axisLine', 'symbolOffset']) || 0, arrowSize); + var symbolWidth_1 = arrowSize[0]; + var symbolHeight_1 = arrowSize[1]; + each([{ + rotate: opt.rotation + Math.PI / 2, + offset: arrowOffset[0], + r: 0 + }, { + rotate: opt.rotation - Math.PI / 2, + offset: arrowOffset[1], + r: Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1])) + }], function (point, index) { + if (arrows[index] !== 'none' && arrows[index] != null) { + var symbol = createSymbol(arrows[index], -symbolWidth_1 / 2, -symbolHeight_1 / 2, symbolWidth_1, symbolHeight_1, lineStyle.stroke, true); + // Calculate arrow position with offset + var r = point.r + point.offset; + var pt = inverse ? pt2 : pt1; + symbol.attr({ + rotation: point.rotate, + x: pt[0] + r * Math.cos(opt.rotation), + y: pt[1] - r * Math.sin(opt.rotation), + silent: true, + z2: 11 + }); + group.add(symbol); + } + }); + } + }, + axisTickLabel: function (opt, axisModel, group, transformGroup) { + var ticksEls = buildAxisMajorTicks(group, transformGroup, axisModel, opt); + var labelEls = buildAxisLabel(group, transformGroup, axisModel, opt); + fixMinMaxLabelShow(axisModel, labelEls, ticksEls); + buildAxisMinorTicks(group, transformGroup, axisModel, opt.tickDirection); + // This bit fixes the label overlap issue for the time chart. + // See https://github.com/apache/echarts/issues/14266 for more. + if (axisModel.get(['axisLabel', 'hideOverlap'])) { + var labelList = prepareLayoutList(map(labelEls, function (label) { + return { + label: label, + priority: label.z2, + defaultAttr: { + ignore: label.ignore + } + }; + })); + hideOverlap(labelList); + } + }, + axisName: function (opt, axisModel, group, transformGroup) { + var name = retrieve(opt.axisName, axisModel.get('name')); + if (!name) { + return; + } + var nameLocation = axisModel.get('nameLocation'); + var nameDirection = opt.nameDirection; + var textStyleModel = axisModel.getModel('nameTextStyle'); + var gap = axisModel.get('nameGap') || 0; + var extent = axisModel.axis.getExtent(); + var gapSignal = extent[0] > extent[1] ? -1 : 1; + var pos = [nameLocation === 'start' ? extent[0] - gapSignal * gap : nameLocation === 'end' ? extent[1] + gapSignal * gap : (extent[0] + extent[1]) / 2, + // Reuse labelOffset. + isNameLocationCenter(nameLocation) ? opt.labelOffset + nameDirection * gap : 0]; + var labelLayout; + var nameRotation = axisModel.get('nameRotate'); + if (nameRotation != null) { + nameRotation = nameRotation * PI$5 / 180; // To radian. + } + + var axisNameAvailableWidth; + if (isNameLocationCenter(nameLocation)) { + labelLayout = AxisBuilder.innerTextLayout(opt.rotation, nameRotation != null ? nameRotation : opt.rotation, + // Adapt to axis. + nameDirection); + } else { + labelLayout = endTextLayout(opt.rotation, nameLocation, nameRotation || 0, extent); + axisNameAvailableWidth = opt.axisNameAvailableWidth; + if (axisNameAvailableWidth != null) { + axisNameAvailableWidth = Math.abs(axisNameAvailableWidth / Math.sin(labelLayout.rotation)); + !isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null); + } + } + var textFont = textStyleModel.getFont(); + var truncateOpt = axisModel.get('nameTruncate', true) || {}; + var ellipsis = truncateOpt.ellipsis; + var maxWidth = retrieve(opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth); + var textEl = new ZRText({ + x: pos[0], + y: pos[1], + rotation: labelLayout.rotation, + silent: AxisBuilder.isLabelSilent(axisModel), + style: createTextStyle(textStyleModel, { + text: name, + font: textFont, + overflow: 'truncate', + width: maxWidth, + ellipsis: ellipsis, + fill: textStyleModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']), + align: textStyleModel.get('align') || labelLayout.textAlign, + verticalAlign: textStyleModel.get('verticalAlign') || labelLayout.textVerticalAlign + }), + z2: 1 + }); + setTooltipConfig({ + el: textEl, + componentModel: axisModel, + itemName: name + }); + textEl.__fullText = name; + // Id for animation + textEl.anid = 'name'; + if (axisModel.get('triggerEvent')) { + var eventData = AxisBuilder.makeAxisEventDataBase(axisModel); + eventData.targetType = 'axisName'; + eventData.name = name; + getECData(textEl).eventData = eventData; + } + // FIXME + transformGroup.add(textEl); + textEl.updateTransform(); + group.add(textEl); + textEl.decomposeTransform(); + } + }; + function endTextLayout(rotation, textPosition, textRotate, extent) { + var rotationDiff = remRadian(textRotate - rotation); + var textAlign; + var textVerticalAlign; + var inverse = extent[0] > extent[1]; + var onLeft = textPosition === 'start' && !inverse || textPosition !== 'start' && inverse; + if (isRadianAroundZero(rotationDiff - PI$5 / 2)) { + textVerticalAlign = onLeft ? 'bottom' : 'top'; + textAlign = 'center'; + } else if (isRadianAroundZero(rotationDiff - PI$5 * 1.5)) { + textVerticalAlign = onLeft ? 'top' : 'bottom'; + textAlign = 'center'; + } else { + textVerticalAlign = 'middle'; + if (rotationDiff < PI$5 * 1.5 && rotationDiff > PI$5 / 2) { + textAlign = onLeft ? 'left' : 'right'; + } else { + textAlign = onLeft ? 'right' : 'left'; + } + } + return { + rotation: rotationDiff, + textAlign: textAlign, + textVerticalAlign: textVerticalAlign + }; + } + function fixMinMaxLabelShow(axisModel, labelEls, tickEls) { + if (shouldShowAllLabels(axisModel.axis)) { + return; + } + // If min or max are user set, we need to check + // If the tick on min(max) are overlap on their neighbour tick + // If they are overlapped, we need to hide the min(max) tick label + var showMinLabel = axisModel.get(['axisLabel', 'showMinLabel']); + var showMaxLabel = axisModel.get(['axisLabel', 'showMaxLabel']); + // FIXME + // Have not consider onBand yet, where tick els is more than label els. + labelEls = labelEls || []; + tickEls = tickEls || []; + var firstLabel = labelEls[0]; + var nextLabel = labelEls[1]; + var lastLabel = labelEls[labelEls.length - 1]; + var prevLabel = labelEls[labelEls.length - 2]; + var firstTick = tickEls[0]; + var nextTick = tickEls[1]; + var lastTick = tickEls[tickEls.length - 1]; + var prevTick = tickEls[tickEls.length - 2]; + if (showMinLabel === false) { + ignoreEl(firstLabel); + ignoreEl(firstTick); + } else if (isTwoLabelOverlapped(firstLabel, nextLabel)) { + if (showMinLabel) { + ignoreEl(nextLabel); + ignoreEl(nextTick); + } else { + ignoreEl(firstLabel); + ignoreEl(firstTick); + } + } + if (showMaxLabel === false) { + ignoreEl(lastLabel); + ignoreEl(lastTick); + } else if (isTwoLabelOverlapped(prevLabel, lastLabel)) { + if (showMaxLabel) { + ignoreEl(prevLabel); + ignoreEl(prevTick); + } else { + ignoreEl(lastLabel); + ignoreEl(lastTick); + } + } + } + function ignoreEl(el) { + el && (el.ignore = true); + } + function isTwoLabelOverlapped(current, next) { + // current and next has the same rotation. + var firstRect = current && current.getBoundingRect().clone(); + var nextRect = next && next.getBoundingRect().clone(); + if (!firstRect || !nextRect) { + return; + } + // When checking intersect of two rotated labels, we use mRotationBack + // to avoid that boundingRect is enlarge when using `boundingRect.applyTransform`. + var mRotationBack = identity([]); + rotate(mRotationBack, mRotationBack, -current.rotation); + firstRect.applyTransform(mul$1([], mRotationBack, current.getLocalTransform())); + nextRect.applyTransform(mul$1([], mRotationBack, next.getLocalTransform())); + return firstRect.intersect(nextRect); + } + function isNameLocationCenter(nameLocation) { + return nameLocation === 'middle' || nameLocation === 'center'; + } + function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, anidPrefix) { + var tickEls = []; + var pt1 = []; + var pt2 = []; + for (var i = 0; i < ticksCoords.length; i++) { + var tickCoord = ticksCoords[i].coord; + pt1[0] = tickCoord; + pt1[1] = 0; + pt2[0] = tickCoord; + pt2[1] = tickEndCoord; + if (tickTransform) { + applyTransform(pt1, pt1, tickTransform); + applyTransform(pt2, pt2, tickTransform); + } + // Tick line, Not use group transform to have better line draw + var tickEl = new Line({ + shape: { + x1: pt1[0], + y1: pt1[1], + x2: pt2[0], + y2: pt2[1] + }, + style: tickLineStyle, + z2: 2, + autoBatch: true, + silent: true + }); + subPixelOptimizeLine$1(tickEl.shape, tickEl.style.lineWidth); + tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue; + tickEls.push(tickEl); + } + return tickEls; + } + function buildAxisMajorTicks(group, transformGroup, axisModel, opt) { + var axis = axisModel.axis; + var tickModel = axisModel.getModel('axisTick'); + var shown = tickModel.get('show'); + if (shown === 'auto' && opt.handleAutoShown) { + shown = opt.handleAutoShown('axisTick'); + } + if (!shown || axis.scale.isBlank()) { + return; + } + var lineStyleModel = tickModel.getModel('lineStyle'); + var tickEndCoord = opt.tickDirection * tickModel.get('length'); + var ticksCoords = axis.getTicksCoords(); + var ticksEls = createTicks(ticksCoords, transformGroup.transform, tickEndCoord, defaults(lineStyleModel.getLineStyle(), { + stroke: axisModel.get(['axisLine', 'lineStyle', 'color']) + }), 'ticks'); + for (var i = 0; i < ticksEls.length; i++) { + group.add(ticksEls[i]); + } + return ticksEls; + } + function buildAxisMinorTicks(group, transformGroup, axisModel, tickDirection) { + var axis = axisModel.axis; + var minorTickModel = axisModel.getModel('minorTick'); + if (!minorTickModel.get('show') || axis.scale.isBlank()) { + return; + } + var minorTicksCoords = axis.getMinorTicksCoords(); + if (!minorTicksCoords.length) { + return; + } + var lineStyleModel = minorTickModel.getModel('lineStyle'); + var tickEndCoord = tickDirection * minorTickModel.get('length'); + var minorTickLineStyle = defaults(lineStyleModel.getLineStyle(), defaults(axisModel.getModel('axisTick').getLineStyle(), { + stroke: axisModel.get(['axisLine', 'lineStyle', 'color']) + })); + for (var i = 0; i < minorTicksCoords.length; i++) { + var minorTicksEls = createTicks(minorTicksCoords[i], transformGroup.transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i); + for (var k = 0; k < minorTicksEls.length; k++) { + group.add(minorTicksEls[k]); + } + } + } + function buildAxisLabel(group, transformGroup, axisModel, opt) { + var axis = axisModel.axis; + var show = retrieve(opt.axisLabelShow, axisModel.get(['axisLabel', 'show'])); + if (!show || axis.scale.isBlank()) { + return; + } + var labelModel = axisModel.getModel('axisLabel'); + var labelMargin = labelModel.get('margin'); + var labels = axis.getViewLabels(); + // Special label rotate. + var labelRotation = (retrieve(opt.labelRotate, labelModel.get('rotate')) || 0) * PI$5 / 180; + var labelLayout = AxisBuilder.innerTextLayout(opt.rotation, labelRotation, opt.labelDirection); + var rawCategoryData = axisModel.getCategories && axisModel.getCategories(true); + var labelEls = []; + var silent = AxisBuilder.isLabelSilent(axisModel); + var triggerEvent = axisModel.get('triggerEvent'); + each(labels, function (labelItem, index) { + var tickValue = axis.scale.type === 'ordinal' ? axis.scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue; + var formattedLabel = labelItem.formattedLabel; + var rawLabel = labelItem.rawLabel; + var itemLabelModel = labelModel; + if (rawCategoryData && rawCategoryData[tickValue]) { + var rawCategoryItem = rawCategoryData[tickValue]; + if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) { + itemLabelModel = new Model(rawCategoryItem.textStyle, labelModel, axisModel.ecModel); + } + } + var textColor = itemLabelModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']); + var tickCoord = axis.dataToCoord(tickValue); + var align = itemLabelModel.getShallow('align', true) || labelLayout.textAlign; + var alignMin = retrieve2(itemLabelModel.getShallow('alignMinLabel', true), align); + var alignMax = retrieve2(itemLabelModel.getShallow('alignMaxLabel', true), align); + var verticalAlign = itemLabelModel.getShallow('verticalAlign', true) || itemLabelModel.getShallow('baseline', true) || labelLayout.textVerticalAlign; + var verticalAlignMin = retrieve2(itemLabelModel.getShallow('verticalAlignMinLabel', true), verticalAlign); + var verticalAlignMax = retrieve2(itemLabelModel.getShallow('verticalAlignMaxLabel', true), verticalAlign); + var textEl = new ZRText({ + x: tickCoord, + y: opt.labelOffset + opt.labelDirection * labelMargin, + rotation: labelLayout.rotation, + silent: silent, + z2: 10 + (labelItem.level || 0), + style: createTextStyle(itemLabelModel, { + text: formattedLabel, + align: index === 0 ? alignMin : index === labels.length - 1 ? alignMax : align, + verticalAlign: index === 0 ? verticalAlignMin : index === labels.length - 1 ? verticalAlignMax : verticalAlign, + fill: isFunction(textColor) ? textColor( + // (1) In category axis with data zoom, tick is not the original + // index of axis.data. So tick should not be exposed to user + // in category axis. + // (2) Compatible with previous version, which always use formatted label as + // input. But in interval scale the formatted label is like '223,445', which + // maked user replace ','. So we modify it to return original val but remain + // it as 'string' to avoid error in replacing. + axis.type === 'category' ? rawLabel : axis.type === 'value' ? tickValue + '' : tickValue, index) : textColor + }) + }); + textEl.anid = 'label_' + tickValue; + // Pack data for mouse event + if (triggerEvent) { + var eventData = AxisBuilder.makeAxisEventDataBase(axisModel); + eventData.targetType = 'axisLabel'; + eventData.value = rawLabel; + eventData.tickIndex = index; + if (axis.type === 'category') { + eventData.dataIndex = tickValue; + } + getECData(textEl).eventData = eventData; + } + // FIXME + transformGroup.add(textEl); + textEl.updateTransform(); + labelEls.push(textEl); + group.add(textEl); + textEl.decomposeTransform(); + }); + return labelEls; + } + + // Build axisPointerModel, mergin tooltip.axisPointer model for each axis. + // allAxesInfo should be updated when setOption performed. + function collect(ecModel, api) { + var result = { + /** + * key: makeKey(axis.model) + * value: { + * axis, + * coordSys, + * axisPointerModel, + * triggerTooltip, + * triggerEmphasis, + * involveSeries, + * snap, + * seriesModels, + * seriesDataCount + * } + */ + axesInfo: {}, + seriesInvolved: false, + /** + * key: makeKey(coordSys.model) + * value: Object: key makeKey(axis.model), value: axisInfo + */ + coordSysAxesInfo: {}, + coordSysMap: {} + }; + collectAxesInfo(result, ecModel, api); + // Check seriesInvolved for performance, in case too many series in some chart. + result.seriesInvolved && collectSeriesInfo(result, ecModel); + return result; + } + function collectAxesInfo(result, ecModel, api) { + var globalTooltipModel = ecModel.getComponent('tooltip'); + var globalAxisPointerModel = ecModel.getComponent('axisPointer'); + // links can only be set on global. + var linksOption = globalAxisPointerModel.get('link', true) || []; + var linkGroups = []; + // Collect axes info. + each(api.getCoordinateSystems(), function (coordSys) { + // Some coordinate system do not support axes, like geo. + if (!coordSys.axisPointerEnabled) { + return; + } + var coordSysKey = makeKey(coordSys.model); + var axesInfoInCoordSys = result.coordSysAxesInfo[coordSysKey] = {}; + result.coordSysMap[coordSysKey] = coordSys; + // Set tooltip (like 'cross') is a convenient way to show axisPointer + // for user. So we enable setting tooltip on coordSys model. + var coordSysModel = coordSys.model; + var baseTooltipModel = coordSysModel.getModel('tooltip', globalTooltipModel); + each(coordSys.getAxes(), curry(saveTooltipAxisInfo, false, null)); + // If axis tooltip used, choose tooltip axis for each coordSys. + // Notice this case: coordSys is `grid` but not `cartesian2D` here. + if (coordSys.getTooltipAxes && globalTooltipModel + // If tooltip.showContent is set as false, tooltip will not + // show but axisPointer will show as normal. + && baseTooltipModel.get('show')) { + // Compatible with previous logic. But series.tooltip.trigger: 'axis' + // or series.data[n].tooltip.trigger: 'axis' are not support any more. + var triggerAxis = baseTooltipModel.get('trigger') === 'axis'; + var cross = baseTooltipModel.get(['axisPointer', 'type']) === 'cross'; + var tooltipAxes = coordSys.getTooltipAxes(baseTooltipModel.get(['axisPointer', 'axis'])); + if (triggerAxis || cross) { + each(tooltipAxes.baseAxes, curry(saveTooltipAxisInfo, cross ? 'cross' : true, triggerAxis)); + } + if (cross) { + each(tooltipAxes.otherAxes, curry(saveTooltipAxisInfo, 'cross', false)); + } + } + // fromTooltip: true | false | 'cross' + // triggerTooltip: true | false | null + function saveTooltipAxisInfo(fromTooltip, triggerTooltip, axis) { + var axisPointerModel = axis.model.getModel('axisPointer', globalAxisPointerModel); + var axisPointerShow = axisPointerModel.get('show'); + if (!axisPointerShow || axisPointerShow === 'auto' && !fromTooltip && !isHandleTrigger(axisPointerModel)) { + return; + } + if (triggerTooltip == null) { + triggerTooltip = axisPointerModel.get('triggerTooltip'); + } + axisPointerModel = fromTooltip ? makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) : axisPointerModel; + var snap = axisPointerModel.get('snap'); + var triggerEmphasis = axisPointerModel.get('triggerEmphasis'); + var axisKey = makeKey(axis.model); + var involveSeries = triggerTooltip || snap || axis.type === 'category'; + // If result.axesInfo[key] exist, override it (tooltip has higher priority). + var axisInfo = result.axesInfo[axisKey] = { + key: axisKey, + axis: axis, + coordSys: coordSys, + axisPointerModel: axisPointerModel, + triggerTooltip: triggerTooltip, + triggerEmphasis: triggerEmphasis, + involveSeries: involveSeries, + snap: snap, + useHandle: isHandleTrigger(axisPointerModel), + seriesModels: [], + linkGroup: null + }; + axesInfoInCoordSys[axisKey] = axisInfo; + result.seriesInvolved = result.seriesInvolved || involveSeries; + var groupIndex = getLinkGroupIndex(linksOption, axis); + if (groupIndex != null) { + var linkGroup = linkGroups[groupIndex] || (linkGroups[groupIndex] = { + axesInfo: {} + }); + linkGroup.axesInfo[axisKey] = axisInfo; + linkGroup.mapper = linksOption[groupIndex].mapper; + axisInfo.linkGroup = linkGroup; + } + } + }); + } + function makeAxisPointerModel(axis, baseTooltipModel, globalAxisPointerModel, ecModel, fromTooltip, triggerTooltip) { + var tooltipAxisPointerModel = baseTooltipModel.getModel('axisPointer'); + var fields = ['type', 'snap', 'lineStyle', 'shadowStyle', 'label', 'animation', 'animationDurationUpdate', 'animationEasingUpdate', 'z']; + var volatileOption = {}; + each(fields, function (field) { + volatileOption[field] = clone(tooltipAxisPointerModel.get(field)); + }); + // category axis do not auto snap, otherwise some tick that do not + // has value can not be hovered. value/time/log axis default snap if + // triggered from tooltip and trigger tooltip. + volatileOption.snap = axis.type !== 'category' && !!triggerTooltip; + // Compatible with previous behavior, tooltip axis does not show label by default. + // Only these properties can be overridden from tooltip to axisPointer. + if (tooltipAxisPointerModel.get('type') === 'cross') { + volatileOption.type = 'line'; + } + var labelOption = volatileOption.label || (volatileOption.label = {}); + // Follow the convention, do not show label when triggered by tooltip by default. + labelOption.show == null && (labelOption.show = false); + if (fromTooltip === 'cross') { + // When 'cross', both axes show labels. + var tooltipAxisPointerLabelShow = tooltipAxisPointerModel.get(['label', 'show']); + labelOption.show = tooltipAxisPointerLabelShow != null ? tooltipAxisPointerLabelShow : true; + // If triggerTooltip, this is a base axis, which should better not use cross style + // (cross style is dashed by default) + if (!triggerTooltip) { + var crossStyle = volatileOption.lineStyle = tooltipAxisPointerModel.get('crossStyle'); + crossStyle && defaults(labelOption, crossStyle.textStyle); + } + } + return axis.model.getModel('axisPointer', new Model(volatileOption, globalAxisPointerModel, ecModel)); + } + function collectSeriesInfo(result, ecModel) { + // Prepare data for axis trigger + ecModel.eachSeries(function (seriesModel) { + // Notice this case: this coordSys is `cartesian2D` but not `grid`. + var coordSys = seriesModel.coordinateSystem; + var seriesTooltipTrigger = seriesModel.get(['tooltip', 'trigger'], true); + var seriesTooltipShow = seriesModel.get(['tooltip', 'show'], true); + if (!coordSys || seriesTooltipTrigger === 'none' || seriesTooltipTrigger === false || seriesTooltipTrigger === 'item' || seriesTooltipShow === false || seriesModel.get(['axisPointer', 'show'], true) === false) { + return; + } + each(result.coordSysAxesInfo[makeKey(coordSys.model)], function (axisInfo) { + var axis = axisInfo.axis; + if (coordSys.getAxis(axis.dim) === axis) { + axisInfo.seriesModels.push(seriesModel); + axisInfo.seriesDataCount == null && (axisInfo.seriesDataCount = 0); + axisInfo.seriesDataCount += seriesModel.getData().count(); + } + }); + }); + } + /** + * For example: + * { + * axisPointer: { + * links: [{ + * xAxisIndex: [2, 4], + * yAxisIndex: 'all' + * }, { + * xAxisId: ['a5', 'a7'], + * xAxisName: 'xxx' + * }] + * } + * } + */ + function getLinkGroupIndex(linksOption, axis) { + var axisModel = axis.model; + var dim = axis.dim; + for (var i = 0; i < linksOption.length; i++) { + var linkOption = linksOption[i] || {}; + if (checkPropInLink(linkOption[dim + 'AxisId'], axisModel.id) || checkPropInLink(linkOption[dim + 'AxisIndex'], axisModel.componentIndex) || checkPropInLink(linkOption[dim + 'AxisName'], axisModel.name)) { + return i; + } + } + } + function checkPropInLink(linkPropValue, axisPropValue) { + return linkPropValue === 'all' || isArray(linkPropValue) && indexOf(linkPropValue, axisPropValue) >= 0 || linkPropValue === axisPropValue; + } + function fixValue(axisModel) { + var axisInfo = getAxisInfo(axisModel); + if (!axisInfo) { + return; + } + var axisPointerModel = axisInfo.axisPointerModel; + var scale = axisInfo.axis.scale; + var option = axisPointerModel.option; + var status = axisPointerModel.get('status'); + var value = axisPointerModel.get('value'); + // Parse init value for category and time axis. + if (value != null) { + value = scale.parse(value); + } + var useHandle = isHandleTrigger(axisPointerModel); + // If `handle` used, `axisPointer` will always be displayed, so value + // and status should be initialized. + if (status == null) { + option.status = useHandle ? 'show' : 'hide'; + } + var extent = scale.getExtent().slice(); + extent[0] > extent[1] && extent.reverse(); + if ( + // Pick a value on axis when initializing. + value == null + // If both `handle` and `dataZoom` are used, value may be out of axis extent, + // where we should re-pick a value to keep `handle` displaying normally. + || value > extent[1]) { + // Make handle displayed on the end of the axis when init, which looks better. + value = extent[1]; + } + if (value < extent[0]) { + value = extent[0]; + } + option.value = value; + if (useHandle) { + option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show'; + } + } + function getAxisInfo(axisModel) { + var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo; + return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)]; + } + function getAxisPointerModel(axisModel) { + var axisInfo = getAxisInfo(axisModel); + return axisInfo && axisInfo.axisPointerModel; + } + function isHandleTrigger(axisPointerModel) { + return !!axisPointerModel.get(['handle', 'show']); + } + /** + * @param {module:echarts/model/Model} model + * @return {string} unique key + */ + function makeKey(model) { + return model.type + '||' + model.id; + } + + var axisPointerClazz = {}; + /** + * Base class of AxisView. + */ + var AxisView = /** @class */function (_super) { + __extends(AxisView, _super); + function AxisView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = AxisView.type; + return _this; + } + /** + * @override + */ + AxisView.prototype.render = function (axisModel, ecModel, api, payload) { + // FIXME + // This process should proformed after coordinate systems updated + // (axis scale updated), and should be performed each time update. + // So put it here temporarily, although it is not appropriate to + // put a model-writing procedure in `view`. + this.axisPointerClass && fixValue(axisModel); + _super.prototype.render.apply(this, arguments); + this._doUpdateAxisPointerClass(axisModel, api, true); + }; + /** + * Action handler. + */ + AxisView.prototype.updateAxisPointer = function (axisModel, ecModel, api, payload) { + this._doUpdateAxisPointerClass(axisModel, api, false); + }; + /** + * @override + */ + AxisView.prototype.remove = function (ecModel, api) { + var axisPointer = this._axisPointer; + axisPointer && axisPointer.remove(api); + }; + /** + * @override + */ + AxisView.prototype.dispose = function (ecModel, api) { + this._disposeAxisPointer(api); + _super.prototype.dispose.apply(this, arguments); + }; + AxisView.prototype._doUpdateAxisPointerClass = function (axisModel, api, forceRender) { + var Clazz = AxisView.getAxisPointerClass(this.axisPointerClass); + if (!Clazz) { + return; + } + var axisPointerModel = getAxisPointerModel(axisModel); + axisPointerModel ? (this._axisPointer || (this._axisPointer = new Clazz())).render(axisModel, axisPointerModel, api, forceRender) : this._disposeAxisPointer(api); + }; + AxisView.prototype._disposeAxisPointer = function (api) { + this._axisPointer && this._axisPointer.dispose(api); + this._axisPointer = null; + }; + AxisView.registerAxisPointerClass = function (type, clazz) { + if ("development" !== 'production') { + if (axisPointerClazz[type]) { + throw new Error('axisPointer ' + type + ' exists'); + } + } + axisPointerClazz[type] = clazz; + }; + AxisView.getAxisPointerClass = function (type) { + return type && axisPointerClazz[type]; + }; + AxisView.type = 'axis'; + return AxisView; + }(ComponentView); + + var inner$6 = makeInner(); + function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel) { + var axis = axisModel.axis; + if (axis.scale.isBlank()) { + return; + } + // TODO: TYPE + var splitAreaModel = axisModel.getModel('splitArea'); + var areaStyleModel = splitAreaModel.getModel('areaStyle'); + var areaColors = areaStyleModel.get('color'); + var gridRect = gridModel.coordinateSystem.getRect(); + var ticksCoords = axis.getTicksCoords({ + tickModel: splitAreaModel, + clamp: true + }); + if (!ticksCoords.length) { + return; + } + // For Making appropriate splitArea animation, the color and anid + // should be corresponding to previous one if possible. + var areaColorsLen = areaColors.length; + var lastSplitAreaColors = inner$6(axisView).splitAreaColors; + var newSplitAreaColors = createHashMap(); + var colorIndex = 0; + if (lastSplitAreaColors) { + for (var i = 0; i < ticksCoords.length; i++) { + var cIndex = lastSplitAreaColors.get(ticksCoords[i].tickValue); + if (cIndex != null) { + colorIndex = (cIndex + (areaColorsLen - 1) * i) % areaColorsLen; + break; + } + } + } + var prev = axis.toGlobalCoord(ticksCoords[0].coord); + var areaStyle = areaStyleModel.getAreaStyle(); + areaColors = isArray(areaColors) ? areaColors : [areaColors]; + for (var i = 1; i < ticksCoords.length; i++) { + var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord); + var x = void 0; + var y = void 0; + var width = void 0; + var height = void 0; + if (axis.isHorizontal()) { + x = prev; + y = gridRect.y; + width = tickCoord - x; + height = gridRect.height; + prev = x + width; + } else { + x = gridRect.x; + y = prev; + width = gridRect.width; + height = tickCoord - y; + prev = y + height; + } + var tickValue = ticksCoords[i - 1].tickValue; + tickValue != null && newSplitAreaColors.set(tickValue, colorIndex); + axisGroup.add(new Rect({ + anid: tickValue != null ? 'area_' + tickValue : null, + shape: { + x: x, + y: y, + width: width, + height: height + }, + style: defaults({ + fill: areaColors[colorIndex] + }, areaStyle), + autoBatch: true, + silent: true + })); + colorIndex = (colorIndex + 1) % areaColorsLen; + } + inner$6(axisView).splitAreaColors = newSplitAreaColors; + } + function rectCoordAxisHandleRemove(axisView) { + inner$6(axisView).splitAreaColors = null; + } + + var axisBuilderAttrs = ['axisLine', 'axisTickLabel', 'axisName']; + var selfBuilderAttrs = ['splitArea', 'splitLine', 'minorSplitLine']; + var CartesianAxisView = /** @class */function (_super) { + __extends(CartesianAxisView, _super); + function CartesianAxisView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CartesianAxisView.type; + _this.axisPointerClass = 'CartesianAxisPointer'; + return _this; + } + /** + * @override + */ + CartesianAxisView.prototype.render = function (axisModel, ecModel, api, payload) { + this.group.removeAll(); + var oldAxisGroup = this._axisGroup; + this._axisGroup = new Group(); + this.group.add(this._axisGroup); + if (!axisModel.get('show')) { + return; + } + var gridModel = axisModel.getCoordSysModel(); + var layout = layout$1(gridModel, axisModel); + var axisBuilder = new AxisBuilder(axisModel, extend({ + handleAutoShown: function (elementType) { + var cartesians = gridModel.coordinateSystem.getCartesians(); + for (var i = 0; i < cartesians.length; i++) { + if (isIntervalOrLogScale(cartesians[i].getOtherAxis(axisModel.axis).scale)) { + // Still show axis tick or axisLine if other axis is value / log + return true; + } + } + // Not show axisTick or axisLine if other axis is category / time + return false; + } + }, layout)); + each(axisBuilderAttrs, axisBuilder.add, axisBuilder); + this._axisGroup.add(axisBuilder.getGroup()); + each(selfBuilderAttrs, function (name) { + if (axisModel.get([name, 'show'])) { + axisElementBuilders[name](this, this._axisGroup, axisModel, gridModel); + } + }, this); + // THIS is a special case for bar racing chart. + // Update the axis label from the natural initial layout to + // sorted layout should has no animation. + var isInitialSortFromBarRacing = payload && payload.type === 'changeAxisOrder' && payload.isInitSort; + if (!isInitialSortFromBarRacing) { + groupTransition(oldAxisGroup, this._axisGroup, axisModel); + } + _super.prototype.render.call(this, axisModel, ecModel, api, payload); + }; + CartesianAxisView.prototype.remove = function () { + rectCoordAxisHandleRemove(this); + }; + CartesianAxisView.type = 'cartesianAxis'; + return CartesianAxisView; + }(AxisView); + var axisElementBuilders = { + splitLine: function (axisView, axisGroup, axisModel, gridModel) { + var axis = axisModel.axis; + if (axis.scale.isBlank()) { + return; + } + var splitLineModel = axisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineColors = lineStyleModel.get('color'); + lineColors = isArray(lineColors) ? lineColors : [lineColors]; + var gridRect = gridModel.coordinateSystem.getRect(); + var isHorizontal = axis.isHorizontal(); + var lineCount = 0; + var ticksCoords = axis.getTicksCoords({ + tickModel: splitLineModel + }); + var p1 = []; + var p2 = []; + var lineStyle = lineStyleModel.getLineStyle(); + for (var i = 0; i < ticksCoords.length; i++) { + var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord); + if (isHorizontal) { + p1[0] = tickCoord; + p1[1] = gridRect.y; + p2[0] = tickCoord; + p2[1] = gridRect.y + gridRect.height; + } else { + p1[0] = gridRect.x; + p1[1] = tickCoord; + p2[0] = gridRect.x + gridRect.width; + p2[1] = tickCoord; + } + var colorIndex = lineCount++ % lineColors.length; + var tickValue = ticksCoords[i].tickValue; + var line = new Line({ + anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null, + autoBatch: true, + shape: { + x1: p1[0], + y1: p1[1], + x2: p2[0], + y2: p2[1] + }, + style: defaults({ + stroke: lineColors[colorIndex] + }, lineStyle), + silent: true + }); + subPixelOptimizeLine$1(line.shape, lineStyle.lineWidth); + axisGroup.add(line); + } + }, + minorSplitLine: function (axisView, axisGroup, axisModel, gridModel) { + var axis = axisModel.axis; + var minorSplitLineModel = axisModel.getModel('minorSplitLine'); + var lineStyleModel = minorSplitLineModel.getModel('lineStyle'); + var gridRect = gridModel.coordinateSystem.getRect(); + var isHorizontal = axis.isHorizontal(); + var minorTicksCoords = axis.getMinorTicksCoords(); + if (!minorTicksCoords.length) { + return; + } + var p1 = []; + var p2 = []; + var lineStyle = lineStyleModel.getLineStyle(); + for (var i = 0; i < minorTicksCoords.length; i++) { + for (var k = 0; k < minorTicksCoords[i].length; k++) { + var tickCoord = axis.toGlobalCoord(minorTicksCoords[i][k].coord); + if (isHorizontal) { + p1[0] = tickCoord; + p1[1] = gridRect.y; + p2[0] = tickCoord; + p2[1] = gridRect.y + gridRect.height; + } else { + p1[0] = gridRect.x; + p1[1] = tickCoord; + p2[0] = gridRect.x + gridRect.width; + p2[1] = tickCoord; + } + var line = new Line({ + anid: 'minor_line_' + minorTicksCoords[i][k].tickValue, + autoBatch: true, + shape: { + x1: p1[0], + y1: p1[1], + x2: p2[0], + y2: p2[1] + }, + style: lineStyle, + silent: true + }); + subPixelOptimizeLine$1(line.shape, lineStyle.lineWidth); + axisGroup.add(line); + } + } + }, + splitArea: function (axisView, axisGroup, axisModel, gridModel) { + rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel); + } + }; + var CartesianXAxisView = /** @class */function (_super) { + __extends(CartesianXAxisView, _super); + function CartesianXAxisView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CartesianXAxisView.type; + return _this; + } + CartesianXAxisView.type = 'xAxis'; + return CartesianXAxisView; + }(CartesianAxisView); + var CartesianYAxisView = /** @class */function (_super) { + __extends(CartesianYAxisView, _super); + function CartesianYAxisView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CartesianXAxisView.type; + return _this; + } + CartesianYAxisView.type = 'yAxis'; + return CartesianYAxisView; + }(CartesianAxisView); + + // Grid view + var GridView = /** @class */function (_super) { + __extends(GridView, _super); + function GridView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = 'grid'; + return _this; + } + GridView.prototype.render = function (gridModel, ecModel) { + this.group.removeAll(); + if (gridModel.get('show')) { + this.group.add(new Rect({ + shape: gridModel.coordinateSystem.getRect(), + style: defaults({ + fill: gridModel.get('backgroundColor') + }, gridModel.getItemStyle()), + silent: true, + z2: -1 + })); + } + }; + GridView.type = 'grid'; + return GridView; + }(ComponentView); + var extraOption = { + // gridIndex: 0, + // gridId: '', + offset: 0 + }; + function install$5(registers) { + registers.registerComponentView(GridView); + registers.registerComponentModel(GridModel); + registers.registerCoordinateSystem('cartesian2d', Grid); + axisModelCreator(registers, 'x', CartesianAxisModel, extraOption); + axisModelCreator(registers, 'y', CartesianAxisModel, extraOption); + registers.registerComponentView(CartesianXAxisView); + registers.registerComponentView(CartesianYAxisView); + registers.registerPreprocessor(function (option) { + // Only create grid when need + if (option.xAxis && option.yAxis && !option.grid) { + option.grid = {}; + } + }); + } + + function install$6(registers) { + // In case developer forget to include grid component + use(install$5); + registers.registerSeriesModel(ScatterSeriesModel); + registers.registerChartView(ScatterView); + registers.registerLayout(pointsLayout('scatter')); + } + + function radarLayout(ecModel) { + ecModel.eachSeriesByType('radar', function (seriesModel) { + var data = seriesModel.getData(); + var points = []; + var coordSys = seriesModel.coordinateSystem; + if (!coordSys) { + return; + } + var axes = coordSys.getIndicatorAxes(); + each(axes, function (axis, axisIndex) { + data.each(data.mapDimension(axes[axisIndex].dim), function (val, dataIndex) { + points[dataIndex] = points[dataIndex] || []; + var point = coordSys.dataToPoint(val, axisIndex); + points[dataIndex][axisIndex] = isValidPoint(point) ? point : getValueMissingPoint(coordSys); + }); + }); + // Close polygon + data.each(function (idx) { + // TODO + // Is it appropriate to connect to the next data when some data is missing? + // Or, should trade it like `connectNull` in line chart? + var firstPoint = find(points[idx], function (point) { + return isValidPoint(point); + }) || getValueMissingPoint(coordSys); + // Copy the first actual point to the end of the array + points[idx].push(firstPoint.slice()); + data.setItemLayout(idx, points[idx]); + }); + }); + } + function isValidPoint(point) { + return !isNaN(point[0]) && !isNaN(point[1]); + } + function getValueMissingPoint(coordSys) { + // It is error-prone to input [NaN, NaN] into polygon, polygon. + // (probably cause problem when refreshing or animating) + return [coordSys.cx, coordSys.cy]; + } + + function radarBackwardCompat(option) { + var polarOptArr = option.polar; + if (polarOptArr) { + if (!isArray(polarOptArr)) { + polarOptArr = [polarOptArr]; + } + var polarNotRadar_1 = []; + each(polarOptArr, function (polarOpt, idx) { + if (polarOpt.indicator) { + if (polarOpt.type && !polarOpt.shape) { + polarOpt.shape = polarOpt.type; + } + option.radar = option.radar || []; + if (!isArray(option.radar)) { + option.radar = [option.radar]; + } + option.radar.push(polarOpt); + } else { + polarNotRadar_1.push(polarOpt); + } + }); + option.polar = polarNotRadar_1; + } + each(option.series, function (seriesOpt) { + if (seriesOpt && seriesOpt.type === 'radar' && seriesOpt.polarIndex) { + seriesOpt.radarIndex = seriesOpt.polarIndex; + } + }); + } + + var RadarView = /** @class */function (_super) { + __extends(RadarView, _super); + function RadarView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = RadarView.type; + return _this; + } + RadarView.prototype.render = function (seriesModel, ecModel, api) { + var polar = seriesModel.coordinateSystem; + var group = this.group; + var data = seriesModel.getData(); + var oldData = this._data; + function createSymbol$1(data, idx) { + var symbolType = data.getItemVisual(idx, 'symbol') || 'circle'; + if (symbolType === 'none') { + return; + } + var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize')); + var symbolPath = createSymbol(symbolType, -1, -1, 2, 2); + var symbolRotate = data.getItemVisual(idx, 'symbolRotate') || 0; + symbolPath.attr({ + style: { + strokeNoScale: true + }, + z2: 100, + scaleX: symbolSize[0] / 2, + scaleY: symbolSize[1] / 2, + rotation: symbolRotate * Math.PI / 180 || 0 + }); + return symbolPath; + } + function updateSymbols(oldPoints, newPoints, symbolGroup, data, idx, isInit) { + // Simply rerender all + symbolGroup.removeAll(); + for (var i = 0; i < newPoints.length - 1; i++) { + var symbolPath = createSymbol$1(data, idx); + if (symbolPath) { + symbolPath.__dimIdx = i; + if (oldPoints[i]) { + symbolPath.setPosition(oldPoints[i]); + graphic[isInit ? 'initProps' : 'updateProps'](symbolPath, { + x: newPoints[i][0], + y: newPoints[i][1] + }, seriesModel, idx); + } else { + symbolPath.setPosition(newPoints[i]); + } + symbolGroup.add(symbolPath); + } + } + } + function getInitialPoints(points) { + return map(points, function (pt) { + return [polar.cx, polar.cy]; + }); + } + data.diff(oldData).add(function (idx) { + var points = data.getItemLayout(idx); + if (!points) { + return; + } + var polygon = new Polygon(); + var polyline = new Polyline(); + var target = { + shape: { + points: points + } + }; + polygon.shape.points = getInitialPoints(points); + polyline.shape.points = getInitialPoints(points); + initProps(polygon, target, seriesModel, idx); + initProps(polyline, target, seriesModel, idx); + var itemGroup = new Group(); + var symbolGroup = new Group(); + itemGroup.add(polyline); + itemGroup.add(polygon); + itemGroup.add(symbolGroup); + updateSymbols(polyline.shape.points, points, symbolGroup, data, idx, true); + data.setItemGraphicEl(idx, itemGroup); + }).update(function (newIdx, oldIdx) { + var itemGroup = oldData.getItemGraphicEl(oldIdx); + var polyline = itemGroup.childAt(0); + var polygon = itemGroup.childAt(1); + var symbolGroup = itemGroup.childAt(2); + var target = { + shape: { + points: data.getItemLayout(newIdx) + } + }; + if (!target.shape.points) { + return; + } + updateSymbols(polyline.shape.points, target.shape.points, symbolGroup, data, newIdx, false); + saveOldStyle(polygon); + saveOldStyle(polyline); + updateProps(polyline, target, seriesModel); + updateProps(polygon, target, seriesModel); + data.setItemGraphicEl(newIdx, itemGroup); + }).remove(function (idx) { + group.remove(oldData.getItemGraphicEl(idx)); + }).execute(); + data.eachItemGraphicEl(function (itemGroup, idx) { + var itemModel = data.getItemModel(idx); + var polyline = itemGroup.childAt(0); + var polygon = itemGroup.childAt(1); + var symbolGroup = itemGroup.childAt(2); + // Radar uses the visual encoded from itemStyle. + var itemStyle = data.getItemVisual(idx, 'style'); + var color = itemStyle.fill; + group.add(itemGroup); + polyline.useStyle(defaults(itemModel.getModel('lineStyle').getLineStyle(), { + fill: 'none', + stroke: color + })); + setStatesStylesFromModel(polyline, itemModel, 'lineStyle'); + setStatesStylesFromModel(polygon, itemModel, 'areaStyle'); + var areaStyleModel = itemModel.getModel('areaStyle'); + var polygonIgnore = areaStyleModel.isEmpty() && areaStyleModel.parentModel.isEmpty(); + polygon.ignore = polygonIgnore; + each(['emphasis', 'select', 'blur'], function (stateName) { + var stateModel = itemModel.getModel([stateName, 'areaStyle']); + var stateIgnore = stateModel.isEmpty() && stateModel.parentModel.isEmpty(); + // Won't be ignore if normal state is not ignore. + polygon.ensureState(stateName).ignore = stateIgnore && polygonIgnore; + }); + polygon.useStyle(defaults(areaStyleModel.getAreaStyle(), { + fill: color, + opacity: 0.7, + decal: itemStyle.decal + })); + var emphasisModel = itemModel.getModel('emphasis'); + var itemHoverStyle = emphasisModel.getModel('itemStyle').getItemStyle(); + symbolGroup.eachChild(function (symbolPath) { + if (symbolPath instanceof ZRImage) { + var pathStyle = symbolPath.style; + symbolPath.useStyle(extend({ + // TODO other properties like x, y ? + image: pathStyle.image, + x: pathStyle.x, + y: pathStyle.y, + width: pathStyle.width, + height: pathStyle.height + }, itemStyle)); + } else { + symbolPath.useStyle(itemStyle); + symbolPath.setColor(color); + symbolPath.style.strokeNoScale = true; + } + var pathEmphasisState = symbolPath.ensureState('emphasis'); + pathEmphasisState.style = clone(itemHoverStyle); + var defaultText = data.getStore().get(data.getDimensionIndex(symbolPath.__dimIdx), idx); + (defaultText == null || isNaN(defaultText)) && (defaultText = ''); + setLabelStyle(symbolPath, getLabelStatesModels(itemModel), { + labelFetcher: data.hostModel, + labelDataIndex: idx, + labelDimIndex: symbolPath.__dimIdx, + defaultText: defaultText, + inheritColor: color, + defaultOpacity: itemStyle.opacity + }); + }); + toggleHoverEmphasis(itemGroup, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + }); + this._data = data; + }; + RadarView.prototype.remove = function () { + this.group.removeAll(); + this._data = null; + }; + RadarView.type = 'radar'; + return RadarView; + }(ChartView); + + var RadarSeriesModel = /** @class */function (_super) { + __extends(RadarSeriesModel, _super); + function RadarSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = RadarSeriesModel.type; + _this.hasSymbolVisual = true; + return _this; + } + // Overwrite + RadarSeriesModel.prototype.init = function (option) { + _super.prototype.init.apply(this, arguments); + // Enable legend selection for each data item + // Use a function instead of direct access because data reference may changed + this.legendVisualProvider = new LegendVisualProvider(bind(this.getData, this), bind(this.getRawData, this)); + }; + RadarSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesDataSimply(this, { + generateCoord: 'indicator_', + generateCoordCount: Infinity + }); + }; + RadarSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + var data = this.getData(); + var coordSys = this.coordinateSystem; + var indicatorAxes = coordSys.getIndicatorAxes(); + var name = this.getData().getName(dataIndex); + var nameToDisplay = name === '' ? this.name : name; + var markerColor = retrieveVisualColorForTooltipMarker(this, dataIndex); + return createTooltipMarkup('section', { + header: nameToDisplay, + sortBlocks: true, + blocks: map(indicatorAxes, function (axis) { + var val = data.get(data.mapDimension(axis.dim), dataIndex); + return createTooltipMarkup('nameValue', { + markerType: 'subItem', + markerColor: markerColor, + name: axis.name, + value: val, + sortParam: val + }); + }) + }); + }; + RadarSeriesModel.prototype.getTooltipPosition = function (dataIndex) { + if (dataIndex != null) { + var data_1 = this.getData(); + var coordSys = this.coordinateSystem; + var values = data_1.getValues(map(coordSys.dimensions, function (dim) { + return data_1.mapDimension(dim); + }), dataIndex); + for (var i = 0, len = values.length; i < len; i++) { + if (!isNaN(values[i])) { + var indicatorAxes = coordSys.getIndicatorAxes(); + return coordSys.coordToPoint(indicatorAxes[i].dataToCoord(values[i]), i); + } + } + } + }; + RadarSeriesModel.type = 'series.radar'; + RadarSeriesModel.dependencies = ['radar']; + RadarSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + colorBy: 'data', + coordinateSystem: 'radar', + legendHoverLink: true, + radarIndex: 0, + lineStyle: { + width: 2, + type: 'solid', + join: 'round' + }, + label: { + position: 'top' + }, + // areaStyle: { + // }, + // itemStyle: {} + symbolSize: 8 + // symbolRotate: null + }; + + return RadarSeriesModel; + }(SeriesModel); + + var valueAxisDefault = axisDefault.value; + function defaultsShow(opt, show) { + return defaults({ + show: show + }, opt); + } + var RadarModel = /** @class */function (_super) { + __extends(RadarModel, _super); + function RadarModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = RadarModel.type; + return _this; + } + RadarModel.prototype.optionUpdated = function () { + var boundaryGap = this.get('boundaryGap'); + var splitNumber = this.get('splitNumber'); + var scale = this.get('scale'); + var axisLine = this.get('axisLine'); + var axisTick = this.get('axisTick'); + // let axisType = this.get('axisType'); + var axisLabel = this.get('axisLabel'); + var nameTextStyle = this.get('axisName'); + var showName = this.get(['axisName', 'show']); + var nameFormatter = this.get(['axisName', 'formatter']); + var nameGap = this.get('axisNameGap'); + var triggerEvent = this.get('triggerEvent'); + var indicatorModels = map(this.get('indicator') || [], function (indicatorOpt) { + // PENDING + if (indicatorOpt.max != null && indicatorOpt.max > 0 && !indicatorOpt.min) { + indicatorOpt.min = 0; + } else if (indicatorOpt.min != null && indicatorOpt.min < 0 && !indicatorOpt.max) { + indicatorOpt.max = 0; + } + var iNameTextStyle = nameTextStyle; + if (indicatorOpt.color != null) { + iNameTextStyle = defaults({ + color: indicatorOpt.color + }, nameTextStyle); + } + // Use same configuration + var innerIndicatorOpt = merge(clone(indicatorOpt), { + boundaryGap: boundaryGap, + splitNumber: splitNumber, + scale: scale, + axisLine: axisLine, + axisTick: axisTick, + // axisType: axisType, + axisLabel: axisLabel, + // Compatible with 2 and use text + name: indicatorOpt.text, + showName: showName, + nameLocation: 'end', + nameGap: nameGap, + // min: 0, + nameTextStyle: iNameTextStyle, + triggerEvent: triggerEvent + }, false); + if (isString(nameFormatter)) { + var indName = innerIndicatorOpt.name; + innerIndicatorOpt.name = nameFormatter.replace('{value}', indName != null ? indName : ''); + } else if (isFunction(nameFormatter)) { + innerIndicatorOpt.name = nameFormatter(innerIndicatorOpt.name, innerIndicatorOpt); + } + var model = new Model(innerIndicatorOpt, null, this.ecModel); + mixin(model, AxisModelCommonMixin.prototype); + // For triggerEvent. + model.mainType = 'radar'; + model.componentIndex = this.componentIndex; + return model; + }, this); + this._indicatorModels = indicatorModels; + }; + RadarModel.prototype.getIndicatorModels = function () { + return this._indicatorModels; + }; + RadarModel.type = 'radar'; + RadarModel.defaultOption = { + // zlevel: 0, + z: 0, + center: ['50%', '50%'], + radius: '75%', + startAngle: 90, + axisName: { + show: true + // formatter: null + // textStyle: {} + }, + + boundaryGap: [0, 0], + splitNumber: 5, + axisNameGap: 15, + scale: false, + // Polygon or circle + shape: 'polygon', + axisLine: merge({ + lineStyle: { + color: '#bbb' + } + }, valueAxisDefault.axisLine), + axisLabel: defaultsShow(valueAxisDefault.axisLabel, false), + axisTick: defaultsShow(valueAxisDefault.axisTick, false), + // axisType: 'value', + splitLine: defaultsShow(valueAxisDefault.splitLine, true), + splitArea: defaultsShow(valueAxisDefault.splitArea, true), + // {text, min, max} + indicator: [] + }; + return RadarModel; + }(ComponentModel); + + var axisBuilderAttrs$1 = ['axisLine', 'axisTickLabel', 'axisName']; + var RadarView$1 = /** @class */function (_super) { + __extends(RadarView, _super); + function RadarView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = RadarView.type; + return _this; + } + RadarView.prototype.render = function (radarModel, ecModel, api) { + var group = this.group; + group.removeAll(); + this._buildAxes(radarModel); + this._buildSplitLineAndArea(radarModel); + }; + RadarView.prototype._buildAxes = function (radarModel) { + var radar = radarModel.coordinateSystem; + var indicatorAxes = radar.getIndicatorAxes(); + var axisBuilders = map(indicatorAxes, function (indicatorAxis) { + var axisName = indicatorAxis.model.get('showName') ? indicatorAxis.name : ''; // hide name + var axisBuilder = new AxisBuilder(indicatorAxis.model, { + axisName: axisName, + position: [radar.cx, radar.cy], + rotation: indicatorAxis.angle, + labelDirection: -1, + tickDirection: -1, + nameDirection: 1 + }); + return axisBuilder; + }); + each(axisBuilders, function (axisBuilder) { + each(axisBuilderAttrs$1, axisBuilder.add, axisBuilder); + this.group.add(axisBuilder.getGroup()); + }, this); + }; + RadarView.prototype._buildSplitLineAndArea = function (radarModel) { + var radar = radarModel.coordinateSystem; + var indicatorAxes = radar.getIndicatorAxes(); + if (!indicatorAxes.length) { + return; + } + var shape = radarModel.get('shape'); + var splitLineModel = radarModel.getModel('splitLine'); + var splitAreaModel = radarModel.getModel('splitArea'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var areaStyleModel = splitAreaModel.getModel('areaStyle'); + var showSplitLine = splitLineModel.get('show'); + var showSplitArea = splitAreaModel.get('show'); + var splitLineColors = lineStyleModel.get('color'); + var splitAreaColors = areaStyleModel.get('color'); + var splitLineColorsArr = isArray(splitLineColors) ? splitLineColors : [splitLineColors]; + var splitAreaColorsArr = isArray(splitAreaColors) ? splitAreaColors : [splitAreaColors]; + var splitLines = []; + var splitAreas = []; + function getColorIndex(areaOrLine, areaOrLineColorList, idx) { + var colorIndex = idx % areaOrLineColorList.length; + areaOrLine[colorIndex] = areaOrLine[colorIndex] || []; + return colorIndex; + } + if (shape === 'circle') { + var ticksRadius = indicatorAxes[0].getTicksCoords(); + var cx = radar.cx; + var cy = radar.cy; + for (var i = 0; i < ticksRadius.length; i++) { + if (showSplitLine) { + var colorIndex = getColorIndex(splitLines, splitLineColorsArr, i); + splitLines[colorIndex].push(new Circle({ + shape: { + cx: cx, + cy: cy, + r: ticksRadius[i].coord + } + })); + } + if (showSplitArea && i < ticksRadius.length - 1) { + var colorIndex = getColorIndex(splitAreas, splitAreaColorsArr, i); + splitAreas[colorIndex].push(new Ring({ + shape: { + cx: cx, + cy: cy, + r0: ticksRadius[i].coord, + r: ticksRadius[i + 1].coord + } + })); + } + } + } + // Polyyon + else { + var realSplitNumber_1; + var axesTicksPoints = map(indicatorAxes, function (indicatorAxis, idx) { + var ticksCoords = indicatorAxis.getTicksCoords(); + realSplitNumber_1 = realSplitNumber_1 == null ? ticksCoords.length - 1 : Math.min(ticksCoords.length - 1, realSplitNumber_1); + return map(ticksCoords, function (tickCoord) { + return radar.coordToPoint(tickCoord.coord, idx); + }); + }); + var prevPoints = []; + for (var i = 0; i <= realSplitNumber_1; i++) { + var points = []; + for (var j = 0; j < indicatorAxes.length; j++) { + points.push(axesTicksPoints[j][i]); + } + // Close + if (points[0]) { + points.push(points[0].slice()); + } else { + if ("development" !== 'production') { + console.error('Can\'t draw value axis ' + i); + } + } + if (showSplitLine) { + var colorIndex = getColorIndex(splitLines, splitLineColorsArr, i); + splitLines[colorIndex].push(new Polyline({ + shape: { + points: points + } + })); + } + if (showSplitArea && prevPoints) { + var colorIndex = getColorIndex(splitAreas, splitAreaColorsArr, i - 1); + splitAreas[colorIndex].push(new Polygon({ + shape: { + points: points.concat(prevPoints) + } + })); + } + prevPoints = points.slice().reverse(); + } + } + var lineStyle = lineStyleModel.getLineStyle(); + var areaStyle = areaStyleModel.getAreaStyle(); + // Add splitArea before splitLine + each(splitAreas, function (splitAreas, idx) { + this.group.add(mergePath$1(splitAreas, { + style: defaults({ + stroke: 'none', + fill: splitAreaColorsArr[idx % splitAreaColorsArr.length] + }, areaStyle), + silent: true + })); + }, this); + each(splitLines, function (splitLines, idx) { + this.group.add(mergePath$1(splitLines, { + style: defaults({ + fill: 'none', + stroke: splitLineColorsArr[idx % splitLineColorsArr.length] + }, lineStyle), + silent: true + })); + }, this); + }; + RadarView.type = 'radar'; + return RadarView; + }(ComponentView); + + var IndicatorAxis = /** @class */function (_super) { + __extends(IndicatorAxis, _super); + function IndicatorAxis(dim, scale, radiusExtent) { + var _this = _super.call(this, dim, scale, radiusExtent) || this; + _this.type = 'value'; + _this.angle = 0; + _this.name = ''; + return _this; + } + return IndicatorAxis; + }(Axis); + + var Radar = /** @class */function () { + function Radar(radarModel, ecModel, api) { + /** + * + * Radar dimensions + */ + this.dimensions = []; + this._model = radarModel; + this._indicatorAxes = map(radarModel.getIndicatorModels(), function (indicatorModel, idx) { + var dim = 'indicator_' + idx; + var indicatorAxis = new IndicatorAxis(dim, new IntervalScale() + // (indicatorModel.get('axisType') === 'log') ? new LogScale() : new IntervalScale() + ); + + indicatorAxis.name = indicatorModel.get('name'); + // Inject model and axis + indicatorAxis.model = indicatorModel; + indicatorModel.axis = indicatorAxis; + this.dimensions.push(dim); + return indicatorAxis; + }, this); + this.resize(radarModel, api); + } + Radar.prototype.getIndicatorAxes = function () { + return this._indicatorAxes; + }; + Radar.prototype.dataToPoint = function (value, indicatorIndex) { + var indicatorAxis = this._indicatorAxes[indicatorIndex]; + return this.coordToPoint(indicatorAxis.dataToCoord(value), indicatorIndex); + }; + // TODO: API should be coordToPoint([coord, indicatorIndex]) + Radar.prototype.coordToPoint = function (coord, indicatorIndex) { + var indicatorAxis = this._indicatorAxes[indicatorIndex]; + var angle = indicatorAxis.angle; + var x = this.cx + coord * Math.cos(angle); + var y = this.cy - coord * Math.sin(angle); + return [x, y]; + }; + Radar.prototype.pointToData = function (pt) { + var dx = pt[0] - this.cx; + var dy = pt[1] - this.cy; + var radius = Math.sqrt(dx * dx + dy * dy); + dx /= radius; + dy /= radius; + var radian = Math.atan2(-dy, dx); + // Find the closest angle + // FIXME index can calculated directly + var minRadianDiff = Infinity; + var closestAxis; + var closestAxisIdx = -1; + for (var i = 0; i < this._indicatorAxes.length; i++) { + var indicatorAxis = this._indicatorAxes[i]; + var diff = Math.abs(radian - indicatorAxis.angle); + if (diff < minRadianDiff) { + closestAxis = indicatorAxis; + closestAxisIdx = i; + minRadianDiff = diff; + } + } + return [closestAxisIdx, +(closestAxis && closestAxis.coordToData(radius))]; + }; + Radar.prototype.resize = function (radarModel, api) { + var center = radarModel.get('center'); + var viewWidth = api.getWidth(); + var viewHeight = api.getHeight(); + var viewSize = Math.min(viewWidth, viewHeight) / 2; + this.cx = parsePercent$1(center[0], viewWidth); + this.cy = parsePercent$1(center[1], viewHeight); + this.startAngle = radarModel.get('startAngle') * Math.PI / 180; + // radius may be single value like `20`, `'80%'`, or array like `[10, '80%']` + var radius = radarModel.get('radius'); + if (isString(radius) || isNumber(radius)) { + radius = [0, radius]; + } + this.r0 = parsePercent$1(radius[0], viewSize); + this.r = parsePercent$1(radius[1], viewSize); + each(this._indicatorAxes, function (indicatorAxis, idx) { + indicatorAxis.setExtent(this.r0, this.r); + var angle = this.startAngle + idx * Math.PI * 2 / this._indicatorAxes.length; + // Normalize to [-PI, PI] + angle = Math.atan2(Math.sin(angle), Math.cos(angle)); + indicatorAxis.angle = angle; + }, this); + }; + Radar.prototype.update = function (ecModel, api) { + var indicatorAxes = this._indicatorAxes; + var radarModel = this._model; + each(indicatorAxes, function (indicatorAxis) { + indicatorAxis.scale.setExtent(Infinity, -Infinity); + }); + ecModel.eachSeriesByType('radar', function (radarSeries, idx) { + if (radarSeries.get('coordinateSystem') !== 'radar' + // @ts-ignore + || ecModel.getComponent('radar', radarSeries.get('radarIndex')) !== radarModel) { + return; + } + var data = radarSeries.getData(); + each(indicatorAxes, function (indicatorAxis) { + indicatorAxis.scale.unionExtentFromData(data, data.mapDimension(indicatorAxis.dim)); + }); + }, this); + var splitNumber = radarModel.get('splitNumber'); + var dummyScale = new IntervalScale(); + dummyScale.setExtent(0, splitNumber); + dummyScale.setInterval(1); + // Force all the axis fixing the maxSplitNumber. + each(indicatorAxes, function (indicatorAxis, idx) { + alignScaleTicks(indicatorAxis.scale, indicatorAxis.model, dummyScale); + }); + }; + Radar.prototype.convertToPixel = function (ecModel, finder, value) { + console.warn('Not implemented.'); + return null; + }; + Radar.prototype.convertFromPixel = function (ecModel, finder, pixel) { + console.warn('Not implemented.'); + return null; + }; + Radar.prototype.containPoint = function (point) { + console.warn('Not implemented.'); + return false; + }; + Radar.create = function (ecModel, api) { + var radarList = []; + ecModel.eachComponent('radar', function (radarModel) { + var radar = new Radar(radarModel, ecModel, api); + radarList.push(radar); + radarModel.coordinateSystem = radar; + }); + ecModel.eachSeriesByType('radar', function (radarSeries) { + if (radarSeries.get('coordinateSystem') === 'radar') { + // Inject coordinate system + // @ts-ignore + radarSeries.coordinateSystem = radarList[radarSeries.get('radarIndex') || 0]; + } + }); + return radarList; + }; + /** + * Radar dimensions is based on the data + */ + Radar.dimensions = []; + return Radar; + }(); + + function install$7(registers) { + registers.registerCoordinateSystem('radar', Radar); + registers.registerComponentModel(RadarModel); + registers.registerComponentView(RadarView$1); + registers.registerVisual({ + seriesType: 'radar', + reset: function (seriesModel) { + var data = seriesModel.getData(); + // itemVisual symbol is for selected data + data.each(function (idx) { + data.setItemVisual(idx, 'legendIcon', 'roundRect'); + }); + // visual is for unselected data + data.setVisual('legendIcon', 'roundRect'); + } + }); + } + + function install$8(registers) { + use(install$7); + registers.registerChartView(RadarView); + registers.registerSeriesModel(RadarSeriesModel); + registers.registerLayout(radarLayout); + registers.registerProcessor(dataFilter('radar')); + registers.registerPreprocessor(radarBackwardCompat); + } + + var ATTR = '\0_ec_interaction_mutex'; + function take(zr, resourceKey, userKey) { + var store = getStore(zr); + store[resourceKey] = userKey; + } + function release(zr, resourceKey, userKey) { + var store = getStore(zr); + var uKey = store[resourceKey]; + if (uKey === userKey) { + store[resourceKey] = null; + } + } + function isTaken(zr, resourceKey) { + return !!getStore(zr)[resourceKey]; + } + function getStore(zr) { + return zr[ATTR] || (zr[ATTR] = {}); + } + /** + * payload: { + * type: 'takeGlobalCursor', + * key: 'dataZoomSelect', or 'brush', or ..., + * If no userKey, release global cursor. + * } + */ + // TODO: SELF REGISTERED. + registerAction({ + type: 'takeGlobalCursor', + event: 'globalCursorTaken', + update: 'update' + }, noop); + + var RoamController = /** @class */function (_super) { + __extends(RoamController, _super); + function RoamController(zr) { + var _this = _super.call(this) || this; + _this._zr = zr; + // Avoid two roamController bind the same handler + var mousedownHandler = bind(_this._mousedownHandler, _this); + var mousemoveHandler = bind(_this._mousemoveHandler, _this); + var mouseupHandler = bind(_this._mouseupHandler, _this); + var mousewheelHandler = bind(_this._mousewheelHandler, _this); + var pinchHandler = bind(_this._pinchHandler, _this); + /** + * Notice: only enable needed types. For example, if 'zoom' + * is not needed, 'zoom' should not be enabled, otherwise + * default mousewheel behaviour (scroll page) will be disabled. + */ + _this.enable = function (controlType, opt) { + // Disable previous first + this.disable(); + this._opt = defaults(clone(opt) || {}, { + zoomOnMouseWheel: true, + moveOnMouseMove: true, + // By default, wheel do not trigger move. + moveOnMouseWheel: false, + preventDefaultMouseMove: true + }); + if (controlType == null) { + controlType = true; + } + if (controlType === true || controlType === 'move' || controlType === 'pan') { + zr.on('mousedown', mousedownHandler); + zr.on('mousemove', mousemoveHandler); + zr.on('mouseup', mouseupHandler); + } + if (controlType === true || controlType === 'scale' || controlType === 'zoom') { + zr.on('mousewheel', mousewheelHandler); + zr.on('pinch', pinchHandler); + } + }; + _this.disable = function () { + zr.off('mousedown', mousedownHandler); + zr.off('mousemove', mousemoveHandler); + zr.off('mouseup', mouseupHandler); + zr.off('mousewheel', mousewheelHandler); + zr.off('pinch', pinchHandler); + }; + return _this; + } + RoamController.prototype.isDragging = function () { + return this._dragging; + }; + RoamController.prototype.isPinching = function () { + return this._pinching; + }; + RoamController.prototype.setPointerChecker = function (pointerChecker) { + this.pointerChecker = pointerChecker; + }; + RoamController.prototype.dispose = function () { + this.disable(); + }; + RoamController.prototype._mousedownHandler = function (e) { + if (isMiddleOrRightButtonOnMouseUpDown(e)) { + return; + } + var el = e.target; + while (el) { + if (el.draggable) { + return; + } + // check if host is draggable + el = el.__hostTarget || el.parent; + } + var x = e.offsetX; + var y = e.offsetY; + // Only check on mosedown, but not mousemove. + // Mouse can be out of target when mouse moving. + if (this.pointerChecker && this.pointerChecker(e, x, y)) { + this._x = x; + this._y = y; + this._dragging = true; + } + }; + RoamController.prototype._mousemoveHandler = function (e) { + if (!this._dragging || !isAvailableBehavior('moveOnMouseMove', e, this._opt) || e.gestureEvent === 'pinch' || isTaken(this._zr, 'globalPan')) { + return; + } + var x = e.offsetX; + var y = e.offsetY; + var oldX = this._x; + var oldY = this._y; + var dx = x - oldX; + var dy = y - oldY; + this._x = x; + this._y = y; + this._opt.preventDefaultMouseMove && stop(e.event); + trigger(this, 'pan', 'moveOnMouseMove', e, { + dx: dx, + dy: dy, + oldX: oldX, + oldY: oldY, + newX: x, + newY: y, + isAvailableBehavior: null + }); + }; + RoamController.prototype._mouseupHandler = function (e) { + if (!isMiddleOrRightButtonOnMouseUpDown(e)) { + this._dragging = false; + } + }; + RoamController.prototype._mousewheelHandler = function (e) { + var shouldZoom = isAvailableBehavior('zoomOnMouseWheel', e, this._opt); + var shouldMove = isAvailableBehavior('moveOnMouseWheel', e, this._opt); + var wheelDelta = e.wheelDelta; + var absWheelDeltaDelta = Math.abs(wheelDelta); + var originX = e.offsetX; + var originY = e.offsetY; + // wheelDelta maybe -0 in chrome mac. + if (wheelDelta === 0 || !shouldZoom && !shouldMove) { + return; + } + // If both `shouldZoom` and `shouldMove` is true, trigger + // their event both, and the final behavior is determined + // by event listener themselves. + if (shouldZoom) { + // Convenience: + // Mac and VM Windows on Mac: scroll up: zoom out. + // Windows: scroll up: zoom in. + // FIXME: Should do more test in different environment. + // wheelDelta is too complicated in difference nvironment + // (https://developer.mozilla.org/en-US/docs/Web/Events/mousewheel), + // although it has been normallized by zrender. + // wheelDelta of mouse wheel is bigger than touch pad. + var factor = absWheelDeltaDelta > 3 ? 1.4 : absWheelDeltaDelta > 1 ? 1.2 : 1.1; + var scale = wheelDelta > 0 ? factor : 1 / factor; + checkPointerAndTrigger(this, 'zoom', 'zoomOnMouseWheel', e, { + scale: scale, + originX: originX, + originY: originY, + isAvailableBehavior: null + }); + } + if (shouldMove) { + // FIXME: Should do more test in different environment. + var absDelta = Math.abs(wheelDelta); + // wheelDelta of mouse wheel is bigger than touch pad. + var scrollDelta = (wheelDelta > 0 ? 1 : -1) * (absDelta > 3 ? 0.4 : absDelta > 1 ? 0.15 : 0.05); + checkPointerAndTrigger(this, 'scrollMove', 'moveOnMouseWheel', e, { + scrollDelta: scrollDelta, + originX: originX, + originY: originY, + isAvailableBehavior: null + }); + } + }; + RoamController.prototype._pinchHandler = function (e) { + if (isTaken(this._zr, 'globalPan')) { + return; + } + var scale = e.pinchScale > 1 ? 1.1 : 1 / 1.1; + checkPointerAndTrigger(this, 'zoom', null, e, { + scale: scale, + originX: e.pinchX, + originY: e.pinchY, + isAvailableBehavior: null + }); + }; + return RoamController; + }(Eventful); + function checkPointerAndTrigger(controller, eventName, behaviorToCheck, e, contollerEvent) { + if (controller.pointerChecker && controller.pointerChecker(e, contollerEvent.originX, contollerEvent.originY)) { + // When mouse is out of roamController rect, + // default befavoius should not be be disabled, otherwise + // page sliding is disabled, contrary to expectation. + stop(e.event); + trigger(controller, eventName, behaviorToCheck, e, contollerEvent); + } + } + function trigger(controller, eventName, behaviorToCheck, e, contollerEvent) { + // Also provide behavior checker for event listener, for some case that + // multiple components share one listener. + contollerEvent.isAvailableBehavior = bind(isAvailableBehavior, null, behaviorToCheck, e); + // TODO should not have type issue. + controller.trigger(eventName, contollerEvent); + } + // settings: { + // zoomOnMouseWheel + // moveOnMouseMove + // moveOnMouseWheel + // } + // The value can be: true / false / 'shift' / 'ctrl' / 'alt'. + function isAvailableBehavior(behaviorToCheck, e, settings) { + var setting = settings[behaviorToCheck]; + return !behaviorToCheck || setting && (!isString(setting) || e.event[setting + 'Key']); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /** + * For geo and graph. + */ + function updateViewOnPan(controllerHost, dx, dy) { + var target = controllerHost.target; + target.x += dx; + target.y += dy; + target.dirty(); + } + /** + * For geo and graph. + */ + function updateViewOnZoom(controllerHost, zoomDelta, zoomX, zoomY) { + var target = controllerHost.target; + var zoomLimit = controllerHost.zoomLimit; + var newZoom = controllerHost.zoom = controllerHost.zoom || 1; + newZoom *= zoomDelta; + if (zoomLimit) { + var zoomMin = zoomLimit.min || 0; + var zoomMax = zoomLimit.max || Infinity; + newZoom = Math.max(Math.min(zoomMax, newZoom), zoomMin); + } + var zoomScale = newZoom / controllerHost.zoom; + controllerHost.zoom = newZoom; + // Keep the mouse center when scaling + target.x -= (zoomX - target.x) * (zoomScale - 1); + target.y -= (zoomY - target.y) * (zoomScale - 1); + target.scaleX *= zoomScale; + target.scaleY *= zoomScale; + target.dirty(); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var IRRELEVANT_EXCLUDES = { + 'axisPointer': 1, + 'tooltip': 1, + 'brush': 1 + }; + /** + * Avoid that: mouse click on a elements that is over geo or graph, + * but roam is triggered. + */ + function onIrrelevantElement(e, api, targetCoordSysModel) { + var model = api.getComponentByElement(e.topTarget); + // If model is axisModel, it works only if it is injected with coordinateSystem. + var coordSys = model && model.coordinateSystem; + return model && model !== targetCoordSysModel && !IRRELEVANT_EXCLUDES.hasOwnProperty(model.mainType) && coordSys && coordSys.model !== targetCoordSysModel; + } + + function parseXML(svg) { + if (isString(svg)) { + var parser = new DOMParser(); + svg = parser.parseFromString(svg, 'text/xml'); + } + var svgNode = svg; + if (svgNode.nodeType === 9) { + svgNode = svgNode.firstChild; + } + while (svgNode.nodeName.toLowerCase() !== 'svg' || svgNode.nodeType !== 1) { + svgNode = svgNode.nextSibling; + } + return svgNode; + } + + var nodeParsers; + var INHERITABLE_STYLE_ATTRIBUTES_MAP = { + 'fill': 'fill', + 'stroke': 'stroke', + 'stroke-width': 'lineWidth', + 'opacity': 'opacity', + 'fill-opacity': 'fillOpacity', + 'stroke-opacity': 'strokeOpacity', + 'stroke-dasharray': 'lineDash', + 'stroke-dashoffset': 'lineDashOffset', + 'stroke-linecap': 'lineCap', + 'stroke-linejoin': 'lineJoin', + 'stroke-miterlimit': 'miterLimit', + 'font-family': 'fontFamily', + 'font-size': 'fontSize', + 'font-style': 'fontStyle', + 'font-weight': 'fontWeight', + 'text-anchor': 'textAlign', + 'visibility': 'visibility', + 'display': 'display' + }; + var INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS = keys(INHERITABLE_STYLE_ATTRIBUTES_MAP); + var SELF_STYLE_ATTRIBUTES_MAP = { + 'alignment-baseline': 'textBaseline', + 'stop-color': 'stopColor' + }; + var SELF_STYLE_ATTRIBUTES_MAP_KEYS = keys(SELF_STYLE_ATTRIBUTES_MAP); + var SVGParser = (function () { + function SVGParser() { + this._defs = {}; + this._root = null; + } + SVGParser.prototype.parse = function (xml, opt) { + opt = opt || {}; + var svg = parseXML(xml); + if ("development" !== 'production') { + if (!svg) { + throw new Error('Illegal svg'); + } + } + this._defsUsePending = []; + var root = new Group(); + this._root = root; + var named = []; + var viewBox = svg.getAttribute('viewBox') || ''; + var width = parseFloat((svg.getAttribute('width') || opt.width)); + var height = parseFloat((svg.getAttribute('height') || opt.height)); + isNaN(width) && (width = null); + isNaN(height) && (height = null); + parseAttributes(svg, root, null, true, false); + var child = svg.firstChild; + while (child) { + this._parseNode(child, root, named, null, false, false); + child = child.nextSibling; + } + applyDefs(this._defs, this._defsUsePending); + this._defsUsePending = []; + var viewBoxRect; + var viewBoxTransform; + if (viewBox) { + var viewBoxArr = splitNumberSequence(viewBox); + if (viewBoxArr.length >= 4) { + viewBoxRect = { + x: parseFloat((viewBoxArr[0] || 0)), + y: parseFloat((viewBoxArr[1] || 0)), + width: parseFloat(viewBoxArr[2]), + height: parseFloat(viewBoxArr[3]) + }; + } + } + if (viewBoxRect && width != null && height != null) { + viewBoxTransform = makeViewBoxTransform(viewBoxRect, { x: 0, y: 0, width: width, height: height }); + if (!opt.ignoreViewBox) { + var elRoot = root; + root = new Group(); + root.add(elRoot); + elRoot.scaleX = elRoot.scaleY = viewBoxTransform.scale; + elRoot.x = viewBoxTransform.x; + elRoot.y = viewBoxTransform.y; + } + } + if (!opt.ignoreRootClip && width != null && height != null) { + root.setClipPath(new Rect({ + shape: { x: 0, y: 0, width: width, height: height } + })); + } + return { + root: root, + width: width, + height: height, + viewBoxRect: viewBoxRect, + viewBoxTransform: viewBoxTransform, + named: named + }; + }; + SVGParser.prototype._parseNode = function (xmlNode, parentGroup, named, namedFrom, isInDefs, isInText) { + var nodeName = xmlNode.nodeName.toLowerCase(); + var el; + var namedFromForSub = namedFrom; + if (nodeName === 'defs') { + isInDefs = true; + } + if (nodeName === 'text') { + isInText = true; + } + if (nodeName === 'defs' || nodeName === 'switch') { + el = parentGroup; + } + else { + if (!isInDefs) { + var parser_1 = nodeParsers[nodeName]; + if (parser_1 && hasOwn(nodeParsers, nodeName)) { + el = parser_1.call(this, xmlNode, parentGroup); + var nameAttr = xmlNode.getAttribute('name'); + if (nameAttr) { + var newNamed = { + name: nameAttr, + namedFrom: null, + svgNodeTagLower: nodeName, + el: el + }; + named.push(newNamed); + if (nodeName === 'g') { + namedFromForSub = newNamed; + } + } + else if (namedFrom) { + named.push({ + name: namedFrom.name, + namedFrom: namedFrom, + svgNodeTagLower: nodeName, + el: el + }); + } + parentGroup.add(el); + } + } + var parser = paintServerParsers[nodeName]; + if (parser && hasOwn(paintServerParsers, nodeName)) { + var def = parser.call(this, xmlNode); + var id = xmlNode.getAttribute('id'); + if (id) { + this._defs[id] = def; + } + } + } + if (el && el.isGroup) { + var child = xmlNode.firstChild; + while (child) { + if (child.nodeType === 1) { + this._parseNode(child, el, named, namedFromForSub, isInDefs, isInText); + } + else if (child.nodeType === 3 && isInText) { + this._parseText(child, el); + } + child = child.nextSibling; + } + } + }; + SVGParser.prototype._parseText = function (xmlNode, parentGroup) { + var text = new TSpan({ + style: { + text: xmlNode.textContent + }, + silent: true, + x: this._textX || 0, + y: this._textY || 0 + }); + inheritStyle(parentGroup, text); + parseAttributes(xmlNode, text, this._defsUsePending, false, false); + applyTextAlignment(text, parentGroup); + var textStyle = text.style; + var fontSize = textStyle.fontSize; + if (fontSize && fontSize < 9) { + textStyle.fontSize = 9; + text.scaleX *= fontSize / 9; + text.scaleY *= fontSize / 9; + } + var font = (textStyle.fontSize || textStyle.fontFamily) && [ + textStyle.fontStyle, + textStyle.fontWeight, + (textStyle.fontSize || 12) + 'px', + textStyle.fontFamily || 'sans-serif' + ].join(' '); + textStyle.font = font; + var rect = text.getBoundingRect(); + this._textX += rect.width; + parentGroup.add(text); + return text; + }; + SVGParser.internalField = (function () { + nodeParsers = { + 'g': function (xmlNode, parentGroup) { + var g = new Group(); + inheritStyle(parentGroup, g); + parseAttributes(xmlNode, g, this._defsUsePending, false, false); + return g; + }, + 'rect': function (xmlNode, parentGroup) { + var rect = new Rect(); + inheritStyle(parentGroup, rect); + parseAttributes(xmlNode, rect, this._defsUsePending, false, false); + rect.setShape({ + x: parseFloat(xmlNode.getAttribute('x') || '0'), + y: parseFloat(xmlNode.getAttribute('y') || '0'), + width: parseFloat(xmlNode.getAttribute('width') || '0'), + height: parseFloat(xmlNode.getAttribute('height') || '0') + }); + rect.silent = true; + return rect; + }, + 'circle': function (xmlNode, parentGroup) { + var circle = new Circle(); + inheritStyle(parentGroup, circle); + parseAttributes(xmlNode, circle, this._defsUsePending, false, false); + circle.setShape({ + cx: parseFloat(xmlNode.getAttribute('cx') || '0'), + cy: parseFloat(xmlNode.getAttribute('cy') || '0'), + r: parseFloat(xmlNode.getAttribute('r') || '0') + }); + circle.silent = true; + return circle; + }, + 'line': function (xmlNode, parentGroup) { + var line = new Line(); + inheritStyle(parentGroup, line); + parseAttributes(xmlNode, line, this._defsUsePending, false, false); + line.setShape({ + x1: parseFloat(xmlNode.getAttribute('x1') || '0'), + y1: parseFloat(xmlNode.getAttribute('y1') || '0'), + x2: parseFloat(xmlNode.getAttribute('x2') || '0'), + y2: parseFloat(xmlNode.getAttribute('y2') || '0') + }); + line.silent = true; + return line; + }, + 'ellipse': function (xmlNode, parentGroup) { + var ellipse = new Ellipse(); + inheritStyle(parentGroup, ellipse); + parseAttributes(xmlNode, ellipse, this._defsUsePending, false, false); + ellipse.setShape({ + cx: parseFloat(xmlNode.getAttribute('cx') || '0'), + cy: parseFloat(xmlNode.getAttribute('cy') || '0'), + rx: parseFloat(xmlNode.getAttribute('rx') || '0'), + ry: parseFloat(xmlNode.getAttribute('ry') || '0') + }); + ellipse.silent = true; + return ellipse; + }, + 'polygon': function (xmlNode, parentGroup) { + var pointsStr = xmlNode.getAttribute('points'); + var pointsArr; + if (pointsStr) { + pointsArr = parsePoints(pointsStr); + } + var polygon = new Polygon({ + shape: { + points: pointsArr || [] + }, + silent: true + }); + inheritStyle(parentGroup, polygon); + parseAttributes(xmlNode, polygon, this._defsUsePending, false, false); + return polygon; + }, + 'polyline': function (xmlNode, parentGroup) { + var pointsStr = xmlNode.getAttribute('points'); + var pointsArr; + if (pointsStr) { + pointsArr = parsePoints(pointsStr); + } + var polyline = new Polyline({ + shape: { + points: pointsArr || [] + }, + silent: true + }); + inheritStyle(parentGroup, polyline); + parseAttributes(xmlNode, polyline, this._defsUsePending, false, false); + return polyline; + }, + 'image': function (xmlNode, parentGroup) { + var img = new ZRImage(); + inheritStyle(parentGroup, img); + parseAttributes(xmlNode, img, this._defsUsePending, false, false); + img.setStyle({ + image: xmlNode.getAttribute('xlink:href') || xmlNode.getAttribute('href'), + x: +xmlNode.getAttribute('x'), + y: +xmlNode.getAttribute('y'), + width: +xmlNode.getAttribute('width'), + height: +xmlNode.getAttribute('height') + }); + img.silent = true; + return img; + }, + 'text': function (xmlNode, parentGroup) { + var x = xmlNode.getAttribute('x') || '0'; + var y = xmlNode.getAttribute('y') || '0'; + var dx = xmlNode.getAttribute('dx') || '0'; + var dy = xmlNode.getAttribute('dy') || '0'; + this._textX = parseFloat(x) + parseFloat(dx); + this._textY = parseFloat(y) + parseFloat(dy); + var g = new Group(); + inheritStyle(parentGroup, g); + parseAttributes(xmlNode, g, this._defsUsePending, false, true); + return g; + }, + 'tspan': function (xmlNode, parentGroup) { + var x = xmlNode.getAttribute('x'); + var y = xmlNode.getAttribute('y'); + if (x != null) { + this._textX = parseFloat(x); + } + if (y != null) { + this._textY = parseFloat(y); + } + var dx = xmlNode.getAttribute('dx') || '0'; + var dy = xmlNode.getAttribute('dy') || '0'; + var g = new Group(); + inheritStyle(parentGroup, g); + parseAttributes(xmlNode, g, this._defsUsePending, false, true); + this._textX += parseFloat(dx); + this._textY += parseFloat(dy); + return g; + }, + 'path': function (xmlNode, parentGroup) { + var d = xmlNode.getAttribute('d') || ''; + var path = createFromString(d); + inheritStyle(parentGroup, path); + parseAttributes(xmlNode, path, this._defsUsePending, false, false); + path.silent = true; + return path; + } + }; + })(); + return SVGParser; + }()); + var paintServerParsers = { + 'lineargradient': function (xmlNode) { + var x1 = parseInt(xmlNode.getAttribute('x1') || '0', 10); + var y1 = parseInt(xmlNode.getAttribute('y1') || '0', 10); + var x2 = parseInt(xmlNode.getAttribute('x2') || '10', 10); + var y2 = parseInt(xmlNode.getAttribute('y2') || '0', 10); + var gradient = new LinearGradient(x1, y1, x2, y2); + parsePaintServerUnit(xmlNode, gradient); + parseGradientColorStops(xmlNode, gradient); + return gradient; + }, + 'radialgradient': function (xmlNode) { + var cx = parseInt(xmlNode.getAttribute('cx') || '0', 10); + var cy = parseInt(xmlNode.getAttribute('cy') || '0', 10); + var r = parseInt(xmlNode.getAttribute('r') || '0', 10); + var gradient = new RadialGradient(cx, cy, r); + parsePaintServerUnit(xmlNode, gradient); + parseGradientColorStops(xmlNode, gradient); + return gradient; + } + }; + function parsePaintServerUnit(xmlNode, gradient) { + var gradientUnits = xmlNode.getAttribute('gradientUnits'); + if (gradientUnits === 'userSpaceOnUse') { + gradient.global = true; + } + } + function parseGradientColorStops(xmlNode, gradient) { + var stop = xmlNode.firstChild; + while (stop) { + if (stop.nodeType === 1 + && stop.nodeName.toLocaleLowerCase() === 'stop') { + var offsetStr = stop.getAttribute('offset'); + var offset = void 0; + if (offsetStr && offsetStr.indexOf('%') > 0) { + offset = parseInt(offsetStr, 10) / 100; + } + else if (offsetStr) { + offset = parseFloat(offsetStr); + } + else { + offset = 0; + } + var styleVals = {}; + parseInlineStyle(stop, styleVals, styleVals); + var stopColor = styleVals.stopColor + || stop.getAttribute('stop-color') + || '#000000'; + gradient.colorStops.push({ + offset: offset, + color: stopColor + }); + } + stop = stop.nextSibling; + } + } + function inheritStyle(parent, child) { + if (parent && parent.__inheritedStyle) { + if (!child.__inheritedStyle) { + child.__inheritedStyle = {}; + } + defaults(child.__inheritedStyle, parent.__inheritedStyle); + } + } + function parsePoints(pointsString) { + var list = splitNumberSequence(pointsString); + var points = []; + for (var i = 0; i < list.length; i += 2) { + var x = parseFloat(list[i]); + var y = parseFloat(list[i + 1]); + points.push([x, y]); + } + return points; + } + function parseAttributes(xmlNode, el, defsUsePending, onlyInlineStyle, isTextGroup) { + var disp = el; + var inheritedStyle = disp.__inheritedStyle = disp.__inheritedStyle || {}; + var selfStyle = {}; + if (xmlNode.nodeType === 1) { + parseTransformAttribute(xmlNode, el); + parseInlineStyle(xmlNode, inheritedStyle, selfStyle); + if (!onlyInlineStyle) { + parseAttributeStyle(xmlNode, inheritedStyle, selfStyle); + } + } + disp.style = disp.style || {}; + if (inheritedStyle.fill != null) { + disp.style.fill = getFillStrokeStyle(disp, 'fill', inheritedStyle.fill, defsUsePending); + } + if (inheritedStyle.stroke != null) { + disp.style.stroke = getFillStrokeStyle(disp, 'stroke', inheritedStyle.stroke, defsUsePending); + } + each([ + 'lineWidth', 'opacity', 'fillOpacity', 'strokeOpacity', 'miterLimit', 'fontSize' + ], function (propName) { + if (inheritedStyle[propName] != null) { + disp.style[propName] = parseFloat(inheritedStyle[propName]); + } + }); + each([ + 'lineDashOffset', 'lineCap', 'lineJoin', 'fontWeight', 'fontFamily', 'fontStyle', 'textAlign' + ], function (propName) { + if (inheritedStyle[propName] != null) { + disp.style[propName] = inheritedStyle[propName]; + } + }); + if (isTextGroup) { + disp.__selfStyle = selfStyle; + } + if (inheritedStyle.lineDash) { + disp.style.lineDash = map(splitNumberSequence(inheritedStyle.lineDash), function (str) { + return parseFloat(str); + }); + } + if (inheritedStyle.visibility === 'hidden' || inheritedStyle.visibility === 'collapse') { + disp.invisible = true; + } + if (inheritedStyle.display === 'none') { + disp.ignore = true; + } + } + function applyTextAlignment(text, parentGroup) { + var parentSelfStyle = parentGroup.__selfStyle; + if (parentSelfStyle) { + var textBaseline = parentSelfStyle.textBaseline; + var zrTextBaseline = textBaseline; + if (!textBaseline || textBaseline === 'auto') { + zrTextBaseline = 'alphabetic'; + } + else if (textBaseline === 'baseline') { + zrTextBaseline = 'alphabetic'; + } + else if (textBaseline === 'before-edge' || textBaseline === 'text-before-edge') { + zrTextBaseline = 'top'; + } + else if (textBaseline === 'after-edge' || textBaseline === 'text-after-edge') { + zrTextBaseline = 'bottom'; + } + else if (textBaseline === 'central' || textBaseline === 'mathematical') { + zrTextBaseline = 'middle'; + } + text.style.textBaseline = zrTextBaseline; + } + var parentInheritedStyle = parentGroup.__inheritedStyle; + if (parentInheritedStyle) { + var textAlign = parentInheritedStyle.textAlign; + var zrTextAlign = textAlign; + if (textAlign) { + if (textAlign === 'middle') { + zrTextAlign = 'center'; + } + text.style.textAlign = zrTextAlign; + } + } + } + var urlRegex = /^url\(\s*#(.*?)\)/; + function getFillStrokeStyle(el, method, str, defsUsePending) { + var urlMatch = str && str.match(urlRegex); + if (urlMatch) { + var url = trim(urlMatch[1]); + defsUsePending.push([el, method, url]); + return; + } + if (str === 'none') { + str = null; + } + return str; + } + function applyDefs(defs, defsUsePending) { + for (var i = 0; i < defsUsePending.length; i++) { + var item = defsUsePending[i]; + item[0].style[item[1]] = defs[item[2]]; + } + } + var numberReg$1 = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g; + function splitNumberSequence(rawStr) { + return rawStr.match(numberReg$1) || []; + } + var transformRegex = /(translate|scale|rotate|skewX|skewY|matrix)\(([\-\s0-9\.eE,]*)\)/g; + var DEGREE_TO_ANGLE = Math.PI / 180; + function parseTransformAttribute(xmlNode, node) { + var transform = xmlNode.getAttribute('transform'); + if (transform) { + transform = transform.replace(/,/g, ' '); + var transformOps_1 = []; + var mt = null; + transform.replace(transformRegex, function (str, type, value) { + transformOps_1.push(type, value); + return ''; + }); + for (var i = transformOps_1.length - 1; i > 0; i -= 2) { + var value = transformOps_1[i]; + var type = transformOps_1[i - 1]; + var valueArr = splitNumberSequence(value); + mt = mt || create$1(); + switch (type) { + case 'translate': + translate(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || '0')]); + break; + case 'scale': + scale$1(mt, mt, [parseFloat(valueArr[0]), parseFloat(valueArr[1] || valueArr[0])]); + break; + case 'rotate': + rotate(mt, mt, -parseFloat(valueArr[0]) * DEGREE_TO_ANGLE, [ + parseFloat(valueArr[1] || '0'), + parseFloat(valueArr[2] || '0') + ]); + break; + case 'skewX': + var sx = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE); + mul$1(mt, [1, 0, sx, 1, 0, 0], mt); + break; + case 'skewY': + var sy = Math.tan(parseFloat(valueArr[0]) * DEGREE_TO_ANGLE); + mul$1(mt, [1, sy, 0, 1, 0, 0], mt); + break; + case 'matrix': + mt[0] = parseFloat(valueArr[0]); + mt[1] = parseFloat(valueArr[1]); + mt[2] = parseFloat(valueArr[2]); + mt[3] = parseFloat(valueArr[3]); + mt[4] = parseFloat(valueArr[4]); + mt[5] = parseFloat(valueArr[5]); + break; + } + } + node.setLocalTransform(mt); + } + } + var styleRegex = /([^\s:;]+)\s*:\s*([^:;]+)/g; + function parseInlineStyle(xmlNode, inheritableStyleResult, selfStyleResult) { + var style = xmlNode.getAttribute('style'); + if (!style) { + return; + } + styleRegex.lastIndex = 0; + var styleRegResult; + while ((styleRegResult = styleRegex.exec(style)) != null) { + var svgStlAttr = styleRegResult[1]; + var zrInheritableStlAttr = hasOwn(INHERITABLE_STYLE_ATTRIBUTES_MAP, svgStlAttr) + ? INHERITABLE_STYLE_ATTRIBUTES_MAP[svgStlAttr] + : null; + if (zrInheritableStlAttr) { + inheritableStyleResult[zrInheritableStlAttr] = styleRegResult[2]; + } + var zrSelfStlAttr = hasOwn(SELF_STYLE_ATTRIBUTES_MAP, svgStlAttr) + ? SELF_STYLE_ATTRIBUTES_MAP[svgStlAttr] + : null; + if (zrSelfStlAttr) { + selfStyleResult[zrSelfStlAttr] = styleRegResult[2]; + } + } + } + function parseAttributeStyle(xmlNode, inheritableStyleResult, selfStyleResult) { + for (var i = 0; i < INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS.length; i++) { + var svgAttrName = INHERITABLE_STYLE_ATTRIBUTES_MAP_KEYS[i]; + var attrValue = xmlNode.getAttribute(svgAttrName); + if (attrValue != null) { + inheritableStyleResult[INHERITABLE_STYLE_ATTRIBUTES_MAP[svgAttrName]] = attrValue; + } + } + for (var i = 0; i < SELF_STYLE_ATTRIBUTES_MAP_KEYS.length; i++) { + var svgAttrName = SELF_STYLE_ATTRIBUTES_MAP_KEYS[i]; + var attrValue = xmlNode.getAttribute(svgAttrName); + if (attrValue != null) { + selfStyleResult[SELF_STYLE_ATTRIBUTES_MAP[svgAttrName]] = attrValue; + } + } + } + function makeViewBoxTransform(viewBoxRect, boundingRect) { + var scaleX = boundingRect.width / viewBoxRect.width; + var scaleY = boundingRect.height / viewBoxRect.height; + var scale = Math.min(scaleX, scaleY); + return { + scale: scale, + x: -(viewBoxRect.x + viewBoxRect.width / 2) * scale + (boundingRect.x + boundingRect.width / 2), + y: -(viewBoxRect.y + viewBoxRect.height / 2) * scale + (boundingRect.y + boundingRect.height / 2) + }; + } + function parseSVG(xml, opt) { + var parser = new SVGParser(); + return parser.parse(xml, opt); + } + + /** + * "region available" means that: enable users to set attribute `name="xxx"` on those tags + * to make it be a region. + * 1. region styles and its label styles can be defined in echarts opton: + * ```js + * geo: { + * regions: [{ + * name: 'xxx', + * itemStyle: { ... }, + * label: { ... } + * }, { + * ... + * }, + * ...] + * }; + * ``` + * 2. name can be duplicated in different SVG tag. All of the tags with the same name share + * a region option. For exampel if there are two representing two lung lobes. They have + * no common parents but both of them need to display label "lung" inside. + */ + var REGION_AVAILABLE_SVG_TAG_MAP = createHashMap(['rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path', + // are also enabled because some SVG might paint text itself, + // but still need to trigger events or tooltip. + 'text', 'tspan', + // is also enabled because this case: if multiple tags share one name + // and need label displayed, every tags will display the name, which is not + // expected. So we can put them into a . Thereby only one label + // displayed and located based on the bounding rect of the . + 'g']); + var GeoSVGResource = /** @class */function () { + function GeoSVGResource(mapName, svg) { + this.type = 'geoSVG'; + // All used graphics. key: hostKey, value: root + this._usedGraphicMap = createHashMap(); + // All unused graphics. + this._freedGraphics = []; + this._mapName = mapName; + // Only perform parse to XML object here, which might be time + // consiming for large SVG. + // Although convert XML to zrender element is also time consiming, + // if we do it here, the clone of zrender elements has to be + // required. So we do it once for each geo instance, util real + // performance issues call for optimizing it. + this._parsedXML = parseXML(svg); + } + GeoSVGResource.prototype.load = function /* nameMap: NameMap */ + () { + // In the "load" stage, graphic need to be built to + // get boundingRect for geo coordinate system. + var firstGraphic = this._firstGraphic; + // Create the return data structure only when first graphic created. + // Because they will be used in geo coordinate system update stage, + // and `regions` will be mounted at `geo` coordinate system, + // in which there is no "view" info, so that it should better not to + // make references to graphic elements. + if (!firstGraphic) { + firstGraphic = this._firstGraphic = this._buildGraphic(this._parsedXML); + this._freedGraphics.push(firstGraphic); + this._boundingRect = this._firstGraphic.boundingRect.clone(); + // PENDING: `nameMap` will not be supported until some real requirement come. + // if (nameMap) { + // named = applyNameMap(named, nameMap); + // } + var _a = createRegions(firstGraphic.named), + regions = _a.regions, + regionsMap = _a.regionsMap; + this._regions = regions; + this._regionsMap = regionsMap; + } + return { + boundingRect: this._boundingRect, + regions: this._regions, + regionsMap: this._regionsMap + }; + }; + GeoSVGResource.prototype._buildGraphic = function (svgXML) { + var result; + var rootFromParse; + try { + result = svgXML && parseSVG(svgXML, { + ignoreViewBox: true, + ignoreRootClip: true + }) || {}; + rootFromParse = result.root; + assert(rootFromParse != null); + } catch (e) { + throw new Error('Invalid svg format\n' + e.message); + } + // Note: we keep the covenant that the root has no transform. So always add an extra root. + var root = new Group(); + root.add(rootFromParse); + root.isGeoSVGGraphicRoot = true; + // [THE_RULE_OF_VIEWPORT_AND_VIEWBOX] + // + // Consider: `` + // - the `width/height` we call it `svgWidth/svgHeight` for short. + // - `(0, 0, svgWidth, svgHeight)` defines the viewport of the SVG, or say, + // "viewport boundingRect", or `boundingRect` for short. + // - `viewBox` defines the transform from the real content ot the viewport. + // `viewBox` has the same unit as the content of SVG. + // If `viewBox` exists, a transform is defined, so the unit of `svgWidth/svgHeight` become + // different from the content of SVG. Otherwise, they are the same. + // + // If both `svgWidth/svgHeight/viewBox` are specified in a SVG file, the transform rule will be: + // 0. `boundingRect` is `(0, 0, svgWidth, svgHeight)`. Set it to Geo['_rect'] (View['_rect']). + // 1. Make a transform from `viewBox` to `boundingRect`. + // Note: only support `preserveAspectRatio 'xMidYMid'` here. That is, this transform will preserve + // the aspect ratio. + // 2. Make a transform from boundingRect to Geo['_viewRect'] (View['_viewRect']) + // (`Geo`/`View` will do this job). + // Note: this transform might not preserve aspect radio, which depending on how users specify + // viewRect in echarts option (e.g., `geo.left/top/width/height` will not preserve aspect ratio, + // but `geo.layoutCenter/layoutSize` will preserve aspect ratio). + // + // If `svgWidth/svgHeight` not specified, we use `viewBox` as the `boundingRect` to make the SVG + // layout look good. + // + // If neither `svgWidth/svgHeight` nor `viewBox` are not specified, we calculate the boundingRect + // of the SVG content and use them to make SVG layout look good. + var svgWidth = result.width; + var svgHeight = result.height; + var viewBoxRect = result.viewBoxRect; + var boundingRect = this._boundingRect; + if (!boundingRect) { + var bRectX = void 0; + var bRectY = void 0; + var bRectWidth = void 0; + var bRectHeight = void 0; + if (svgWidth != null) { + bRectX = 0; + bRectWidth = svgWidth; + } else if (viewBoxRect) { + bRectX = viewBoxRect.x; + bRectWidth = viewBoxRect.width; + } + if (svgHeight != null) { + bRectY = 0; + bRectHeight = svgHeight; + } else if (viewBoxRect) { + bRectY = viewBoxRect.y; + bRectHeight = viewBoxRect.height; + } + // If both viewBox and svgWidth/svgHeight not specified, + // we have to determine how to layout those element to make them look good. + if (bRectX == null || bRectY == null) { + var calculatedBoundingRect = rootFromParse.getBoundingRect(); + if (bRectX == null) { + bRectX = calculatedBoundingRect.x; + bRectWidth = calculatedBoundingRect.width; + } + if (bRectY == null) { + bRectY = calculatedBoundingRect.y; + bRectHeight = calculatedBoundingRect.height; + } + } + boundingRect = this._boundingRect = new BoundingRect(bRectX, bRectY, bRectWidth, bRectHeight); + } + if (viewBoxRect) { + var viewBoxTransform = makeViewBoxTransform(viewBoxRect, boundingRect); + // Only support `preserveAspectRatio 'xMidYMid'` + rootFromParse.scaleX = rootFromParse.scaleY = viewBoxTransform.scale; + rootFromParse.x = viewBoxTransform.x; + rootFromParse.y = viewBoxTransform.y; + } + // SVG needs to clip based on `viewBox`. And some SVG files really rely on this feature. + // They do not strictly confine all of the content inside a display rect, but deliberately + // use a `viewBox` to define a displayable rect. + // PENDING: + // The drawback of the `setClipPath` here is: the region label (genereted by echarts) near the + // edge might also be clipped, because region labels are put as `textContent` of the SVG path. + root.setClipPath(new Rect({ + shape: boundingRect.plain() + })); + var named = []; + each(result.named, function (namedItem) { + if (REGION_AVAILABLE_SVG_TAG_MAP.get(namedItem.svgNodeTagLower) != null) { + named.push(namedItem); + setSilent(namedItem.el); + } + }); + return { + root: root, + boundingRect: boundingRect, + named: named + }; + }; + /** + * Consider: + * (1) One graphic element can not be shared by different `geoView` running simultaneously. + * Notice, also need to consider multiple echarts instances share a `mapRecord`. + * (2) Converting SVG to graphic elements is time consuming. + * (3) In the current architecture, `load` should be called frequently to get boundingRect, + * and it is called without view info. + * So we maintain graphic elements in this module, and enables `view` to use/return these + * graphics from/to the pool with it's uid. + */ + GeoSVGResource.prototype.useGraphic = function (hostKey /* , nameMap: NameMap */) { + var usedRootMap = this._usedGraphicMap; + var svgGraphic = usedRootMap.get(hostKey); + if (svgGraphic) { + return svgGraphic; + } + svgGraphic = this._freedGraphics.pop() + // use the first boundingRect to avoid duplicated boundingRect calculation. + || this._buildGraphic(this._parsedXML); + usedRootMap.set(hostKey, svgGraphic); + // PENDING: `nameMap` will not be supported until some real requirement come. + // `nameMap` can only be obtained from echarts option. + // The original `named` must not be modified. + // if (nameMap) { + // svgGraphic = extend({}, svgGraphic); + // svgGraphic.named = applyNameMap(svgGraphic.named, nameMap); + // } + return svgGraphic; + }; + GeoSVGResource.prototype.freeGraphic = function (hostKey) { + var usedRootMap = this._usedGraphicMap; + var svgGraphic = usedRootMap.get(hostKey); + if (svgGraphic) { + usedRootMap.removeKey(hostKey); + this._freedGraphics.push(svgGraphic); + } + }; + return GeoSVGResource; + }(); + function setSilent(el) { + // Only named element has silent: false, other elements should + // act as background and has no user interaction. + el.silent = false; + // text|tspan will be converted to group. + if (el.isGroup) { + el.traverse(function (child) { + child.silent = false; + }); + } + } + function createRegions(named) { + var regions = []; + var regionsMap = createHashMap(); + // Create resions only for the first graphic. + each(named, function (namedItem) { + // Region has feature to calculate center for tooltip or other features. + // If there is a , the center should be the center of the + // bounding rect of the g. + if (namedItem.namedFrom != null) { + return; + } + var region = new GeoSVGRegion(namedItem.name, namedItem.el); + // PENDING: if `nameMap` supported, this region can not be mounted on + // `this`, but can only be created each time `load()` called. + regions.push(region); + // PENDING: if multiple tag named with the same name, only one will be + // found by `_regionsMap`. `_regionsMap` is used to find a coordinate + // by name. We use `region.getCenter()` as the coordinate. + regionsMap.set(namedItem.name, region); + }); + return { + regions: regions, + regionsMap: regionsMap + }; + } + // PENDING: `nameMap` will not be supported until some real requirement come. + // /** + // * Use the alias in geoNameMap. + // * The input `named` must not be modified. + // */ + // function applyNameMap( + // named: GeoSVGGraphicRecord['named'], + // nameMap: NameMap + // ): GeoSVGGraphicRecord['named'] { + // const result = [] as GeoSVGGraphicRecord['named']; + // for (let i = 0; i < named.length; i++) { + // let regionGraphic = named[i]; + // const name = regionGraphic.name; + // if (nameMap && nameMap.hasOwnProperty(name)) { + // regionGraphic = extend({}, regionGraphic); + // regionGraphic.name = name; + // } + // result.push(regionGraphic); + // } + // return result; + // } + + var geoCoord = [126, 25]; + var nanhaiName = '南海诸岛'; + var points$1 = [[[0, 3.5], [7, 11.2], [15, 11.9], [30, 7], [42, 0.7], [52, 0.7], [56, 7.7], [59, 0.7], [64, 0.7], [64, 0], [5, 0], [0, 3.5]], [[13, 16.1], [19, 14.7], [16, 21.7], [11, 23.1], [13, 16.1]], [[12, 32.2], [14, 38.5], [15, 38.5], [13, 32.2], [12, 32.2]], [[16, 47.6], [12, 53.2], [13, 53.2], [18, 47.6], [16, 47.6]], [[6, 64.4], [8, 70], [9, 70], [8, 64.4], [6, 64.4]], [[23, 82.6], [29, 79.8], [30, 79.8], [25, 82.6], [23, 82.6]], [[37, 70.7], [43, 62.3], [44, 62.3], [39, 70.7], [37, 70.7]], [[48, 51.1], [51, 45.5], [53, 45.5], [50, 51.1], [48, 51.1]], [[51, 35], [51, 28.7], [53, 28.7], [53, 35], [51, 35]], [[52, 22.4], [55, 17.5], [56, 17.5], [53, 22.4], [52, 22.4]], [[58, 12.6], [62, 7], [63, 7], [60, 12.6], [58, 12.6]], [[0, 3.5], [0, 93.1], [64, 93.1], [64, 0], [63, 0], [63, 92.4], [1, 92.4], [1, 3.5], [0, 3.5]]]; + for (var i = 0; i < points$1.length; i++) { + for (var k = 0; k < points$1[i].length; k++) { + points$1[i][k][0] /= 10.5; + points$1[i][k][1] /= -10.5 / 0.75; + points$1[i][k][0] += geoCoord[0]; + points$1[i][k][1] += geoCoord[1]; + } + } + function fixNanhai(mapType, regions) { + if (mapType === 'china') { + for (var i = 0; i < regions.length; i++) { + // Already exists. + if (regions[i].name === nanhaiName) { + return; + } + } + regions.push(new GeoJSONRegion(nanhaiName, map(points$1, function (exterior) { + return { + type: 'polygon', + exterior: exterior + }; + }), geoCoord)); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var coordsOffsetMap = { + '南海诸岛': [32, 80], + // 全国 + '广东': [0, -10], + '香港': [10, 5], + '澳门': [-10, 10], + // '北京': [-10, 0], + '天津': [5, 5] + }; + function fixTextCoords(mapType, region) { + if (mapType === 'china') { + var coordFix = coordsOffsetMap[region.name]; + if (coordFix) { + var cp = region.getCenter(); + cp[0] += coordFix[0] / 10.5; + cp[1] += -coordFix[1] / (10.5 / 0.75); + region.setCenter(cp); + } + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + // Fix for 钓鱼岛 + // let Region = require('../Region'); + // let zrUtil = require('zrender/lib/core/util'); + // let geoCoord = [126, 25]; + var points$2 = [[[123.45165252685547, 25.73527164402261], [123.49731445312499, 25.73527164402261], [123.49731445312499, 25.750734064600884], [123.45165252685547, 25.750734064600884], [123.45165252685547, 25.73527164402261]]]; + function fixDiaoyuIsland(mapType, region) { + if (mapType === 'china' && region.name === '台湾') { + region.geometries.push({ + type: 'polygon', + exterior: points$2[0] + }); + } + } + + var DEFAULT_NAME_PROPERTY = 'name'; + var GeoJSONResource = /** @class */function () { + function GeoJSONResource(mapName, geoJSON, specialAreas) { + this.type = 'geoJSON'; + this._parsedMap = createHashMap(); + this._mapName = mapName; + this._specialAreas = specialAreas; + // PENDING: delay the parse to the first usage to rapid up the FMP? + this._geoJSON = parseInput(geoJSON); + } + /** + * @param nameMap can be null/undefined + * @param nameProperty can be null/undefined + */ + GeoJSONResource.prototype.load = function (nameMap, nameProperty) { + nameProperty = nameProperty || DEFAULT_NAME_PROPERTY; + var parsed = this._parsedMap.get(nameProperty); + if (!parsed) { + var rawRegions = this._parseToRegions(nameProperty); + parsed = this._parsedMap.set(nameProperty, { + regions: rawRegions, + boundingRect: calculateBoundingRect(rawRegions) + }); + } + var regionsMap = createHashMap(); + var finalRegions = []; + each(parsed.regions, function (region) { + var regionName = region.name; + // Try use the alias in geoNameMap + if (nameMap && hasOwn(nameMap, regionName)) { + region = region.cloneShallow(regionName = nameMap[regionName]); + } + finalRegions.push(region); + regionsMap.set(regionName, region); + }); + return { + regions: finalRegions, + boundingRect: parsed.boundingRect || new BoundingRect(0, 0, 0, 0), + regionsMap: regionsMap + }; + }; + GeoJSONResource.prototype._parseToRegions = function (nameProperty) { + var mapName = this._mapName; + var geoJSON = this._geoJSON; + var rawRegions; + // https://jsperf.com/try-catch-performance-overhead + try { + rawRegions = geoJSON ? parseGeoJSON(geoJSON, nameProperty) : []; + } catch (e) { + throw new Error('Invalid geoJson format\n' + e.message); + } + fixNanhai(mapName, rawRegions); + each(rawRegions, function (region) { + var regionName = region.name; + fixTextCoords(mapName, region); + fixDiaoyuIsland(mapName, region); + // Some area like Alaska in USA map needs to be tansformed + // to look better + var specialArea = this._specialAreas && this._specialAreas[regionName]; + if (specialArea) { + region.transformTo(specialArea.left, specialArea.top, specialArea.width, specialArea.height); + } + }, this); + return rawRegions; + }; + /** + * Only for exporting to users. + * **MUST NOT** used internally. + */ + GeoJSONResource.prototype.getMapForUser = function () { + return { + // For backward compatibility, use geoJson + // PENDING: it has been returning them without clone. + // do we need to avoid outsite modification? + geoJson: this._geoJSON, + geoJSON: this._geoJSON, + specialAreas: this._specialAreas + }; + }; + return GeoJSONResource; + }(); + function calculateBoundingRect(regions) { + var rect; + for (var i = 0; i < regions.length; i++) { + var regionRect = regions[i].getBoundingRect(); + rect = rect || regionRect.clone(); + rect.union(regionRect); + } + return rect; + } + function parseInput(source) { + return !isString(source) ? source : typeof JSON !== 'undefined' && JSON.parse ? JSON.parse(source) : new Function('return (' + source + ');')(); + } + + var storage = createHashMap(); + var geoSourceManager = { + /** + * Compatible with previous `echarts.registerMap`. + * + * @usage + * ```js + * + * echarts.registerMap('USA', geoJson, specialAreas); + * + * echarts.registerMap('USA', { + * geoJson: geoJson, + * specialAreas: {...} + * }); + * echarts.registerMap('USA', { + * geoJSON: geoJson, + * specialAreas: {...} + * }); + * + * echarts.registerMap('airport', { + * svg: svg + * } + * ``` + * + * Note: + * Do not support that register multiple geoJSON or SVG + * one map name. Because different geoJSON and SVG have + * different unit. It's not easy to make sure how those + * units are mapping/normalize. + * If intending to use multiple geoJSON or SVG, we can + * use multiple geo coordinate system. + */ + registerMap: function (mapName, rawDef, rawSpecialAreas) { + if (rawDef.svg) { + var resource = new GeoSVGResource(mapName, rawDef.svg); + storage.set(mapName, resource); + } else { + // Recommend: + // echarts.registerMap('eu', { geoJSON: xxx, specialAreas: xxx }); + // Backward compatibility: + // echarts.registerMap('eu', geoJSON, specialAreas); + // echarts.registerMap('eu', { geoJson: xxx, specialAreas: xxx }); + var geoJSON = rawDef.geoJson || rawDef.geoJSON; + if (geoJSON && !rawDef.features) { + rawSpecialAreas = rawDef.specialAreas; + } else { + geoJSON = rawDef; + } + var resource = new GeoJSONResource(mapName, geoJSON, rawSpecialAreas); + storage.set(mapName, resource); + } + }, + getGeoResource: function (mapName) { + return storage.get(mapName); + }, + /** + * Only for exporting to users. + * **MUST NOT** used internally. + */ + getMapForUser: function (mapName) { + var resource = storage.get(mapName); + // Do not support return SVG until some real requirement come. + return resource && resource.type === 'geoJSON' && resource.getMapForUser(); + }, + load: function (mapName, nameMap, nameProperty) { + var resource = storage.get(mapName); + if (!resource) { + if ("development" !== 'production') { + console.error('Map ' + mapName + ' not exists. The GeoJSON of the map must be provided.'); + } + return; + } + return resource.load(nameMap, nameProperty); + } + }; + + /** + * Only these tags enable use `itemStyle` if they are named in SVG. + * Other tags like might not suitable for `itemStyle`. + * They will not be considered to be styled until some requirements come. + */ + var OPTION_STYLE_ENABLED_TAGS = ['rect', 'circle', 'line', 'ellipse', 'polygon', 'polyline', 'path']; + var OPTION_STYLE_ENABLED_TAG_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS); + var STATE_TRIGGER_TAG_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(['g'])); + var LABEL_HOST_MAP = createHashMap(OPTION_STYLE_ENABLED_TAGS.concat(['g'])); + var mapLabelRaw = makeInner(); + function getFixedItemStyle(model) { + var itemStyle = model.getItemStyle(); + var areaColor = model.get('areaColor'); + // If user want the color not to be changed when hover, + // they should both set areaColor and color to be null. + if (areaColor != null) { + itemStyle.fill = areaColor; + } + return itemStyle; + } + // Only stroke can be used for line. + // Using fill in style if stroke not exits. + // TODO Not sure yet. Perhaps a separate `lineStyle`? + function fixLineStyle(styleHost) { + var style = styleHost.style; + if (style) { + style.stroke = style.stroke || style.fill; + style.fill = null; + } + } + var MapDraw = /** @class */function () { + function MapDraw(api) { + var group = new Group(); + this.uid = getUID('ec_map_draw'); + this._controller = new RoamController(api.getZr()); + this._controllerHost = { + target: group + }; + this.group = group; + group.add(this._regionsGroup = new Group()); + group.add(this._svgGroup = new Group()); + } + MapDraw.prototype.draw = function (mapOrGeoModel, ecModel, api, fromView, payload) { + var isGeo = mapOrGeoModel.mainType === 'geo'; + // Map series has data. GEO model that controlled by map series + // will be assigned with map data. Other GEO model has no data. + var data = mapOrGeoModel.getData && mapOrGeoModel.getData(); + isGeo && ecModel.eachComponent({ + mainType: 'series', + subType: 'map' + }, function (mapSeries) { + if (!data && mapSeries.getHostGeoModel() === mapOrGeoModel) { + data = mapSeries.getData(); + } + }); + var geo = mapOrGeoModel.coordinateSystem; + var regionsGroup = this._regionsGroup; + var group = this.group; + var transformInfo = geo.getTransformInfo(); + var transformInfoRaw = transformInfo.raw; + var transformInfoRoam = transformInfo.roam; + // No animation when first draw or in action + var isFirstDraw = !regionsGroup.childAt(0) || payload; + if (isFirstDraw) { + group.x = transformInfoRoam.x; + group.y = transformInfoRoam.y; + group.scaleX = transformInfoRoam.scaleX; + group.scaleY = transformInfoRoam.scaleY; + group.dirty(); + } else { + updateProps(group, transformInfoRoam, mapOrGeoModel); + } + var isVisualEncodedByVisualMap = data && data.getVisual('visualMeta') && data.getVisual('visualMeta').length > 0; + var viewBuildCtx = { + api: api, + geo: geo, + mapOrGeoModel: mapOrGeoModel, + data: data, + isVisualEncodedByVisualMap: isVisualEncodedByVisualMap, + isGeo: isGeo, + transformInfoRaw: transformInfoRaw + }; + if (geo.resourceType === 'geoJSON') { + this._buildGeoJSON(viewBuildCtx); + } else if (geo.resourceType === 'geoSVG') { + this._buildSVG(viewBuildCtx); + } + this._updateController(mapOrGeoModel, ecModel, api); + this._updateMapSelectHandler(mapOrGeoModel, regionsGroup, api, fromView); + }; + MapDraw.prototype._buildGeoJSON = function (viewBuildCtx) { + var regionsGroupByName = this._regionsGroupByName = createHashMap(); + var regionsInfoByName = createHashMap(); + var regionsGroup = this._regionsGroup; + var transformInfoRaw = viewBuildCtx.transformInfoRaw; + var mapOrGeoModel = viewBuildCtx.mapOrGeoModel; + var data = viewBuildCtx.data; + var projection = viewBuildCtx.geo.projection; + var projectionStream = projection && projection.stream; + function transformPoint(point, project) { + if (project) { + // projection may return null point. + point = project(point); + } + return point && [point[0] * transformInfoRaw.scaleX + transformInfoRaw.x, point[1] * transformInfoRaw.scaleY + transformInfoRaw.y]; + } + function transformPolygonPoints(inPoints) { + var outPoints = []; + // If projectionStream is provided. Use it instead of single point project. + var project = !projectionStream && projection && projection.project; + for (var i = 0; i < inPoints.length; ++i) { + var newPt = transformPoint(inPoints[i], project); + newPt && outPoints.push(newPt); + } + return outPoints; + } + function getPolyShape(points) { + return { + shape: { + points: transformPolygonPoints(points) + } + }; + } + regionsGroup.removeAll(); + // Only when the resource is GeoJSON, there is `geo.regions`. + each(viewBuildCtx.geo.regions, function (region) { + var regionName = region.name; + // Consider in GeoJson properties.name may be duplicated, for example, + // there is multiple region named "United Kindom" or "France" (so many + // colonies). And it is not appropriate to merge them in geo, which + // will make them share the same label and bring trouble in label + // location calculation. + var regionGroup = regionsGroupByName.get(regionName); + var _a = regionsInfoByName.get(regionName) || {}, + dataIdx = _a.dataIdx, + regionModel = _a.regionModel; + if (!regionGroup) { + regionGroup = regionsGroupByName.set(regionName, new Group()); + regionsGroup.add(regionGroup); + dataIdx = data ? data.indexOfName(regionName) : null; + regionModel = viewBuildCtx.isGeo ? mapOrGeoModel.getRegionModel(regionName) : data ? data.getItemModel(dataIdx) : null; + regionsInfoByName.set(regionName, { + dataIdx: dataIdx, + regionModel: regionModel + }); + } + var polygonSubpaths = []; + var polylineSubpaths = []; + each(region.geometries, function (geometry) { + // Polygon and MultiPolygon + if (geometry.type === 'polygon') { + var polys = [geometry.exterior].concat(geometry.interiors || []); + if (projectionStream) { + polys = projectPolys(polys, projectionStream); + } + each(polys, function (poly) { + polygonSubpaths.push(new Polygon(getPolyShape(poly))); + }); + } + // LineString and MultiLineString + else { + var points = geometry.points; + if (projectionStream) { + points = projectPolys(points, projectionStream, true); + } + each(points, function (points) { + polylineSubpaths.push(new Polyline(getPolyShape(points))); + }); + } + }); + var centerPt = transformPoint(region.getCenter(), projection && projection.project); + function createCompoundPath(subpaths, isLine) { + if (!subpaths.length) { + return; + } + var compoundPath = new CompoundPath({ + culling: true, + segmentIgnoreThreshold: 1, + shape: { + paths: subpaths + } + }); + regionGroup.add(compoundPath); + applyOptionStyleForRegion(viewBuildCtx, compoundPath, dataIdx, regionModel); + resetLabelForRegion(viewBuildCtx, compoundPath, regionName, regionModel, mapOrGeoModel, dataIdx, centerPt); + if (isLine) { + fixLineStyle(compoundPath); + each(compoundPath.states, fixLineStyle); + } + } + createCompoundPath(polygonSubpaths); + createCompoundPath(polylineSubpaths, true); + }); + // Ensure children have been added to `regionGroup` before calling them. + regionsGroupByName.each(function (regionGroup, regionName) { + var _a = regionsInfoByName.get(regionName), + dataIdx = _a.dataIdx, + regionModel = _a.regionModel; + resetEventTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel, dataIdx); + resetTooltipForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel); + resetStateTriggerForRegion(viewBuildCtx, regionGroup, regionName, regionModel, mapOrGeoModel); + }, this); + }; + MapDraw.prototype._buildSVG = function (viewBuildCtx) { + var mapName = viewBuildCtx.geo.map; + var transformInfoRaw = viewBuildCtx.transformInfoRaw; + this._svgGroup.x = transformInfoRaw.x; + this._svgGroup.y = transformInfoRaw.y; + this._svgGroup.scaleX = transformInfoRaw.scaleX; + this._svgGroup.scaleY = transformInfoRaw.scaleY; + if (this._svgResourceChanged(mapName)) { + this._freeSVG(); + this._useSVG(mapName); + } + var svgDispatcherMap = this._svgDispatcherMap = createHashMap(); + var focusSelf = false; + each(this._svgGraphicRecord.named, function (namedItem) { + // Note that we also allow different elements have the same name. + // For example, a glyph of a city and the label of the city have + // the same name and their tooltip info can be defined in a single + // region option. + var regionName = namedItem.name; + var mapOrGeoModel = viewBuildCtx.mapOrGeoModel; + var data = viewBuildCtx.data; + var svgNodeTagLower = namedItem.svgNodeTagLower; + var el = namedItem.el; + var dataIdx = data ? data.indexOfName(regionName) : null; + var regionModel = mapOrGeoModel.getRegionModel(regionName); + if (OPTION_STYLE_ENABLED_TAG_MAP.get(svgNodeTagLower) != null && el instanceof Displayable) { + applyOptionStyleForRegion(viewBuildCtx, el, dataIdx, regionModel); + } + if (el instanceof Displayable) { + el.culling = true; + } + // We do not know how the SVG like so we'd better not to change z2. + // Otherwise it might bring some unexpected result. For example, + // an area hovered that make some inner city can not be clicked. + el.z2EmphasisLift = 0; + // If self named: + if (!namedItem.namedFrom) { + // label should batter to be displayed based on the center of + // if it is named rather than displayed on each child. + if (LABEL_HOST_MAP.get(svgNodeTagLower) != null) { + resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx, null); + } + resetEventTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, dataIdx); + resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel); + if (STATE_TRIGGER_TAG_MAP.get(svgNodeTagLower) != null) { + var focus_1 = resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel); + if (focus_1 === 'self') { + focusSelf = true; + } + var els = svgDispatcherMap.get(regionName) || svgDispatcherMap.set(regionName, []); + els.push(el); + } + } + }, this); + this._enableBlurEntireSVG(focusSelf, viewBuildCtx); + }; + MapDraw.prototype._enableBlurEntireSVG = function (focusSelf, viewBuildCtx) { + // It's a little complicated to support blurring the entire geoSVG in series-map. + // So do not support it until some requirements come. + // At present, in series-map, only regions can be blurred. + if (focusSelf && viewBuildCtx.isGeo) { + var blurStyle = viewBuildCtx.mapOrGeoModel.getModel(['blur', 'itemStyle']).getItemStyle(); + // Only support `opacity` here. Because not sure that other props are suitable for + // all of the elements generated by SVG (especially for Text/TSpan/Image/... ). + var opacity_1 = blurStyle.opacity; + this._svgGraphicRecord.root.traverse(function (el) { + if (!el.isGroup) { + // PENDING: clear those settings to SVG elements when `_freeSVG`. + // (Currently it happen not to be needed.) + setDefaultStateProxy(el); + var style = el.ensureState('blur').style || {}; + // Do not overwrite the region style that already set from region option. + if (style.opacity == null && opacity_1 != null) { + style.opacity = opacity_1; + } + // If `ensureState('blur').style = {}`, there will be default opacity. + // Enable `stateTransition` (animation). + el.ensureState('emphasis'); + } + }); + } + }; + MapDraw.prototype.remove = function () { + this._regionsGroup.removeAll(); + this._regionsGroupByName = null; + this._svgGroup.removeAll(); + this._freeSVG(); + this._controller.dispose(); + this._controllerHost = null; + }; + MapDraw.prototype.findHighDownDispatchers = function (name, geoModel) { + if (name == null) { + return []; + } + var geo = geoModel.coordinateSystem; + if (geo.resourceType === 'geoJSON') { + var regionsGroupByName = this._regionsGroupByName; + if (regionsGroupByName) { + var regionGroup = regionsGroupByName.get(name); + return regionGroup ? [regionGroup] : []; + } + } else if (geo.resourceType === 'geoSVG') { + return this._svgDispatcherMap && this._svgDispatcherMap.get(name) || []; + } + }; + MapDraw.prototype._svgResourceChanged = function (mapName) { + return this._svgMapName !== mapName; + }; + MapDraw.prototype._useSVG = function (mapName) { + var resource = geoSourceManager.getGeoResource(mapName); + if (resource && resource.type === 'geoSVG') { + var svgGraphic = resource.useGraphic(this.uid); + this._svgGroup.add(svgGraphic.root); + this._svgGraphicRecord = svgGraphic; + this._svgMapName = mapName; + } + }; + MapDraw.prototype._freeSVG = function () { + var mapName = this._svgMapName; + if (mapName == null) { + return; + } + var resource = geoSourceManager.getGeoResource(mapName); + if (resource && resource.type === 'geoSVG') { + resource.freeGraphic(this.uid); + } + this._svgGraphicRecord = null; + this._svgDispatcherMap = null; + this._svgGroup.removeAll(); + this._svgMapName = null; + }; + MapDraw.prototype._updateController = function (mapOrGeoModel, ecModel, api) { + var geo = mapOrGeoModel.coordinateSystem; + var controller = this._controller; + var controllerHost = this._controllerHost; + // @ts-ignore FIXME:TS + controllerHost.zoomLimit = mapOrGeoModel.get('scaleLimit'); + controllerHost.zoom = geo.getZoom(); + // roamType is will be set default true if it is null + // @ts-ignore FIXME:TS + controller.enable(mapOrGeoModel.get('roam') || false); + var mainType = mapOrGeoModel.mainType; + function makeActionBase() { + var action = { + type: 'geoRoam', + componentType: mainType + }; + action[mainType + 'Id'] = mapOrGeoModel.id; + return action; + } + controller.off('pan').on('pan', function (e) { + this._mouseDownFlag = false; + updateViewOnPan(controllerHost, e.dx, e.dy); + api.dispatchAction(extend(makeActionBase(), { + dx: e.dx, + dy: e.dy, + animation: { + duration: 0 + } + })); + }, this); + controller.off('zoom').on('zoom', function (e) { + this._mouseDownFlag = false; + updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY); + api.dispatchAction(extend(makeActionBase(), { + zoom: e.scale, + originX: e.originX, + originY: e.originY, + animation: { + duration: 0 + } + })); + }, this); + controller.setPointerChecker(function (e, x, y) { + return geo.containPoint([x, y]) && !onIrrelevantElement(e, api, mapOrGeoModel); + }); + }; + /** + * FIXME: this is a temporarily workaround. + * When `geoRoam` the elements need to be reset in `MapView['render']`, because the props like + * `ignore` might have been modified by `LabelManager`, and `LabelManager#addLabelsOfSeries` + * will subsequently cache `defaultAttr` like `ignore`. If do not do this reset, the modified + * props will have no chance to be restored. + * Note: This reset should be after `clearStates` in `renderSeries` because `useStates` in + * `renderSeries` will cache the modified `ignore` to `el._normalState`. + * TODO: + * Use clone/immutable in `LabelManager`? + */ + MapDraw.prototype.resetForLabelLayout = function () { + this.group.traverse(function (el) { + var label = el.getTextContent(); + if (label) { + label.ignore = mapLabelRaw(label).ignore; + } + }); + }; + MapDraw.prototype._updateMapSelectHandler = function (mapOrGeoModel, regionsGroup, api, fromView) { + var mapDraw = this; + regionsGroup.off('mousedown'); + regionsGroup.off('click'); + // @ts-ignore FIXME:TS resolve type conflict + if (mapOrGeoModel.get('selectedMode')) { + regionsGroup.on('mousedown', function () { + mapDraw._mouseDownFlag = true; + }); + regionsGroup.on('click', function (e) { + if (!mapDraw._mouseDownFlag) { + return; + } + mapDraw._mouseDownFlag = false; + }); + } + }; + return MapDraw; + }(); + function applyOptionStyleForRegion(viewBuildCtx, el, dataIndex, regionModel) { + // All of the path are using `itemStyle`, because + // (1) Some SVG also use fill on polyline (The different between + // polyline and polygon is "open" or "close" but not fill or not). + // (2) For the common props like opacity, if some use itemStyle + // and some use `lineStyle`, it might confuse users. + // (3) Most SVG use , where can not detect whether to draw a "line" + // or a filled shape, so use `itemStyle` for . + var normalStyleModel = regionModel.getModel('itemStyle'); + var emphasisStyleModel = regionModel.getModel(['emphasis', 'itemStyle']); + var blurStyleModel = regionModel.getModel(['blur', 'itemStyle']); + var selectStyleModel = regionModel.getModel(['select', 'itemStyle']); + // NOTE: DON'T use 'style' in visual when drawing map. + // This component is used for drawing underlying map for both geo component and map series. + var normalStyle = getFixedItemStyle(normalStyleModel); + var emphasisStyle = getFixedItemStyle(emphasisStyleModel); + var selectStyle = getFixedItemStyle(selectStyleModel); + var blurStyle = getFixedItemStyle(blurStyleModel); + // Update the itemStyle if has data visual + var data = viewBuildCtx.data; + if (data) { + // Only visual color of each item will be used. It can be encoded by visualMap + // But visual color of series is used in symbol drawing + // Visual color for each series is for the symbol draw + var style = data.getItemVisual(dataIndex, 'style'); + var decal = data.getItemVisual(dataIndex, 'decal'); + if (viewBuildCtx.isVisualEncodedByVisualMap && style.fill) { + normalStyle.fill = style.fill; + } + if (decal) { + normalStyle.decal = createOrUpdatePatternFromDecal(decal, viewBuildCtx.api); + } + } + // SVG text, tspan and image can be named but not supporeted + // to be styled by region option yet. + el.setStyle(normalStyle); + el.style.strokeNoScale = true; + el.ensureState('emphasis').style = emphasisStyle; + el.ensureState('select').style = selectStyle; + el.ensureState('blur').style = blurStyle; + // Enable blur + setDefaultStateProxy(el); + } + function resetLabelForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel, + // Exist only if `viewBuildCtx.data` exists. + dataIdx, + // If labelXY not provided, use `textConfig.position: 'inside'` + labelXY) { + var data = viewBuildCtx.data; + var isGeo = viewBuildCtx.isGeo; + var isDataNaN = data && isNaN(data.get(data.mapDimension('value'), dataIdx)); + var itemLayout = data && data.getItemLayout(dataIdx); + // In the following cases label will be drawn + // 1. In map series and data value is NaN + // 2. In geo component + // 3. Region has no series legendIcon, which will be add a showLabel flag in mapSymbolLayout + if (isGeo || isDataNaN || itemLayout && itemLayout.showLabel) { + var query = !isGeo ? dataIdx : regionName; + var labelFetcher = void 0; + // Consider dataIdx not found. + if (!data || dataIdx >= 0) { + labelFetcher = mapOrGeoModel; + } + var specifiedTextOpt = labelXY ? { + normal: { + align: 'center', + verticalAlign: 'middle' + } + } : null; + // Caveat: must be called after `setDefaultStateProxy(el);` called. + // because textContent will be assign with `el.stateProxy` inside. + setLabelStyle(el, getLabelStatesModels(regionModel), { + labelFetcher: labelFetcher, + labelDataIndex: query, + defaultText: regionName + }, specifiedTextOpt); + var textEl = el.getTextContent(); + if (textEl) { + mapLabelRaw(textEl).ignore = textEl.ignore; + if (el.textConfig && labelXY) { + // Compute a relative offset based on the el bounding rect. + var rect = el.getBoundingRect().clone(); + // Need to make sure the percent position base on the same rect in normal and + // emphasis state. Otherwise if using boundingRect of el, but the emphasis state + // has borderWidth (even 0.5px), the text position will be changed obviously + // if the position is very big like ['1234%', '1345%']. + el.textConfig.layoutRect = rect; + el.textConfig.position = [(labelXY[0] - rect.x) / rect.width * 100 + '%', (labelXY[1] - rect.y) / rect.height * 100 + '%']; + } + } + // PENDING: + // If labelLayout is enabled (test/label-layout.html), el.dataIndex should be specified. + // But el.dataIndex is also used to determine whether user event should be triggered, + // where el.seriesIndex or el.dataModel must be specified. At present for a single el + // there is not case that "only label layout enabled but user event disabled", so here + // we depends `resetEventTriggerForRegion` to do the job of setting `el.dataIndex`. + el.disableLabelAnimation = true; + } else { + el.removeTextContent(); + el.removeTextConfig(); + el.disableLabelAnimation = null; + } + } + function resetEventTriggerForRegion(viewBuildCtx, eventTrigger, regionName, regionModel, mapOrGeoModel, + // Exist only if `viewBuildCtx.data` exists. + dataIdx) { + // setItemGraphicEl, setHoverStyle after all polygons and labels + // are added to the regionGroup + if (viewBuildCtx.data) { + // FIXME: when series-map use a SVG map, and there are duplicated name specified + // on different SVG elements, after `data.setItemGraphicEl(...)`: + // (1) all of them will be mounted with `dataIndex`, `seriesIndex`, so that tooltip + // can be triggered only mouse hover. That's correct. + // (2) only the last element will be kept in `data`, so that if trigger tooltip + // by `dispatchAction`, only the last one can be found and triggered. That might be + // not correct. We will fix it in future if anyone demanding that. + viewBuildCtx.data.setItemGraphicEl(dataIdx, eventTrigger); + } + // series-map will not trigger "geoselectchange" no matter it is + // based on a declared geo component. Because series-map will + // trigger "selectchange". If it trigger both the two events, + // If users call `chart.dispatchAction({type: 'toggleSelect'})`, + // it not easy to also fire event "geoselectchanged". + else { + // Package custom mouse event for geo component + getECData(eventTrigger).eventData = { + componentType: 'geo', + componentIndex: mapOrGeoModel.componentIndex, + geoIndex: mapOrGeoModel.componentIndex, + name: regionName, + region: regionModel && regionModel.option || {} + }; + } + } + function resetTooltipForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) { + if (!viewBuildCtx.data) { + setTooltipConfig({ + el: el, + componentModel: mapOrGeoModel, + itemName: regionName, + // @ts-ignore FIXME:TS fix the "compatible with each other"? + itemTooltipOption: regionModel.get('tooltip') + }); + } + } + function resetStateTriggerForRegion(viewBuildCtx, el, regionName, regionModel, mapOrGeoModel) { + // @ts-ignore FIXME:TS fix the "compatible with each other"? + el.highDownSilentOnTouch = !!mapOrGeoModel.get('selectedMode'); + // @ts-ignore FIXME:TS fix the "compatible with each other"? + var emphasisModel = regionModel.getModel('emphasis'); + var focus = emphasisModel.get('focus'); + toggleHoverEmphasis(el, focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + if (viewBuildCtx.isGeo) { + enableComponentHighDownFeatures(el, mapOrGeoModel, regionName); + } + return focus; + } + function projectPolys(rings, + // Polygons include exterior and interiors. Or polylines. + createStream, isLine) { + var polygons = []; + var curPoly; + function startPolygon() { + curPoly = []; + } + function endPolygon() { + if (curPoly.length) { + polygons.push(curPoly); + curPoly = []; + } + } + var stream = createStream({ + polygonStart: startPolygon, + polygonEnd: endPolygon, + lineStart: startPolygon, + lineEnd: endPolygon, + point: function (x, y) { + // May have NaN values from stream. + if (isFinite(x) && isFinite(y)) { + curPoly.push([x, y]); + } + }, + sphere: function () {} + }); + !isLine && stream.polygonStart(); + each(rings, function (ring) { + stream.lineStart(); + for (var i = 0; i < ring.length; i++) { + stream.point(ring[i][0], ring[i][1]); + } + stream.lineEnd(); + }); + !isLine && stream.polygonEnd(); + return polygons; + } + // @ts-ignore FIXME:TS fix the "compatible with each other"? + + var MapView = /** @class */function (_super) { + __extends(MapView, _super); + function MapView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MapView.type; + return _this; + } + MapView.prototype.render = function (mapModel, ecModel, api, payload) { + // Not render if it is an toggleSelect action from self + if (payload && payload.type === 'mapToggleSelect' && payload.from === this.uid) { + return; + } + var group = this.group; + group.removeAll(); + if (mapModel.getHostGeoModel()) { + return; + } + if (this._mapDraw && payload && payload.type === 'geoRoam') { + this._mapDraw.resetForLabelLayout(); + } + // Not update map if it is an roam action from self + if (!(payload && payload.type === 'geoRoam' && payload.componentType === 'series' && payload.seriesId === mapModel.id)) { + if (mapModel.needsDrawMap) { + var mapDraw = this._mapDraw || new MapDraw(api); + group.add(mapDraw.group); + mapDraw.draw(mapModel, ecModel, api, this, payload); + this._mapDraw = mapDraw; + } else { + // Remove drawn map + this._mapDraw && this._mapDraw.remove(); + this._mapDraw = null; + } + } else { + var mapDraw = this._mapDraw; + mapDraw && group.add(mapDraw.group); + } + mapModel.get('showLegendSymbol') && ecModel.getComponent('legend') && this._renderSymbols(mapModel, ecModel, api); + }; + MapView.prototype.remove = function () { + this._mapDraw && this._mapDraw.remove(); + this._mapDraw = null; + this.group.removeAll(); + }; + MapView.prototype.dispose = function () { + this._mapDraw && this._mapDraw.remove(); + this._mapDraw = null; + }; + MapView.prototype._renderSymbols = function (mapModel, ecModel, api) { + var originalData = mapModel.originalData; + var group = this.group; + originalData.each(originalData.mapDimension('value'), function (value, originalDataIndex) { + if (isNaN(value)) { + return; + } + var layout = originalData.getItemLayout(originalDataIndex); + if (!layout || !layout.point) { + // Not exists in map + return; + } + var point = layout.point; + var offset = layout.offset; + var circle = new Circle({ + style: { + // Because the special of map draw. + // Which needs statistic of multiple series and draw on one map. + // And each series also need a symbol with legend color + // + // Layout and visual are put one the different data + // TODO + fill: mapModel.getData().getVisual('style').fill + }, + shape: { + cx: point[0] + offset * 9, + cy: point[1], + r: 3 + }, + silent: true, + // Do not overlap the first series, on which labels are displayed. + z2: 8 + (!offset ? Z2_EMPHASIS_LIFT + 1 : 0) + }); + // Only the series that has the first value on the same region is in charge of rendering the label. + // But consider the case: + // series: [ + // {id: 'X', type: 'map', map: 'm', {data: [{name: 'A', value: 11}, {name: 'B', {value: 22}]}, + // {id: 'Y', type: 'map', map: 'm', {data: [{name: 'A', value: 21}, {name: 'C', {value: 33}]} + // ] + // The offset `0` of item `A` is at series `X`, but of item `C` is at series `Y`. + // For backward compatibility, we follow the rule that render label `A` by the + // settings on series `X` but render label `C` by the settings on series `Y`. + if (!offset) { + var fullData = mapModel.mainSeries.getData(); + var name_1 = originalData.getName(originalDataIndex); + var fullIndex_1 = fullData.indexOfName(name_1); + var itemModel = originalData.getItemModel(originalDataIndex); + var labelModel = itemModel.getModel('label'); + var regionGroup = fullData.getItemGraphicEl(fullIndex_1); + // `getFormattedLabel` needs to use `getData` inside. Here + // `mapModel.getData()` is shallow cloned from `mainSeries.getData()`. + // FIXME + // If this is not the `mainSeries`, the item model (like label formatter) + // set on original data item will never get. But it has been working + // like that from the beginning, and this scenario is rarely encountered. + // So it won't be fixed until we have to. + setLabelStyle(circle, getLabelStatesModels(itemModel), { + labelFetcher: { + getFormattedLabel: function (idx, state) { + return mapModel.getFormattedLabel(fullIndex_1, state); + } + }, + defaultText: name_1 + }); + circle.disableLabelAnimation = true; + if (!labelModel.get('position')) { + circle.setTextConfig({ + position: 'bottom' + }); + } + regionGroup.onHoverStateChange = function (toState) { + setStatesFlag(circle, toState); + }; + } + group.add(circle); + }); + }; + MapView.type = 'map'; + return MapView; + }(ChartView); + + var MapSeries = /** @class */function (_super) { + __extends(MapSeries, _super); + function MapSeries() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MapSeries.type; + // Only first map series of same mapType will drawMap. + _this.needsDrawMap = false; + // Group of all map series with same mapType + _this.seriesGroup = []; + _this.getTooltipPosition = function (dataIndex) { + if (dataIndex != null) { + var name_1 = this.getData().getName(dataIndex); + var geo = this.coordinateSystem; + var region = geo.getRegion(name_1); + return region && geo.dataToPoint(region.getCenter()); + } + }; + return _this; + } + MapSeries.prototype.getInitialData = function (option) { + var data = createSeriesDataSimply(this, { + coordDimensions: ['value'], + encodeDefaulter: curry(makeSeriesEncodeForNameBased, this) + }); + var dataNameMap = createHashMap(); + var toAppendNames = []; + for (var i = 0, len = data.count(); i < len; i++) { + var name_2 = data.getName(i); + dataNameMap.set(name_2, true); + } + var geoSource = geoSourceManager.load(this.getMapType(), this.option.nameMap, this.option.nameProperty); + each(geoSource.regions, function (region) { + var name = region.name; + if (!dataNameMap.get(name)) { + toAppendNames.push(name); + } + }); + // Complete data with missing regions. The consequent processes (like visual + // map and render) can not be performed without a "full data". For example, + // find `dataIndex` by name. + data.appendValues([], toAppendNames); + return data; + }; + /** + * If no host geo model, return null, which means using a + * inner exclusive geo model. + */ + MapSeries.prototype.getHostGeoModel = function () { + var geoIndex = this.option.geoIndex; + return geoIndex != null ? this.ecModel.getComponent('geo', geoIndex) : null; + }; + MapSeries.prototype.getMapType = function () { + return (this.getHostGeoModel() || this).option.map; + }; + // _fillOption(option, mapName) { + // Shallow clone + // option = zrUtil.extend({}, option); + // option.data = geoCreator.getFilledRegions(option.data, mapName, option.nameMap); + // return option; + // } + MapSeries.prototype.getRawValue = function (dataIndex) { + // Use value stored in data instead because it is calculated from multiple series + // FIXME Provide all value of multiple series ? + var data = this.getData(); + return data.get(data.mapDimension('value'), dataIndex); + }; + /** + * Get model of region + */ + MapSeries.prototype.getRegionModel = function (regionName) { + var data = this.getData(); + return data.getItemModel(data.indexOfName(regionName)); + }; + /** + * Map tooltip formatter + */ + MapSeries.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + // FIXME orignalData and data is a bit confusing + var data = this.getData(); + var value = this.getRawValue(dataIndex); + var name = data.getName(dataIndex); + var seriesGroup = this.seriesGroup; + var seriesNames = []; + for (var i = 0; i < seriesGroup.length; i++) { + var otherIndex = seriesGroup[i].originalData.indexOfName(name); + var valueDim = data.mapDimension('value'); + if (!isNaN(seriesGroup[i].originalData.get(valueDim, otherIndex))) { + seriesNames.push(seriesGroup[i].name); + } + } + return createTooltipMarkup('section', { + header: seriesNames.join(', '), + noHeader: !seriesNames.length, + blocks: [createTooltipMarkup('nameValue', { + name: name, + value: value + })] + }); + }; + MapSeries.prototype.setZoom = function (zoom) { + this.option.zoom = zoom; + }; + MapSeries.prototype.setCenter = function (center) { + this.option.center = center; + }; + MapSeries.prototype.getLegendIcon = function (opt) { + var iconType = opt.icon || 'roundRect'; + var icon = createSymbol(iconType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill); + icon.setStyle(opt.itemStyle); + // Map do not use itemStyle.borderWidth as border width + icon.style.stroke = 'none'; + // No rotation because no series visual symbol for map + if (iconType.indexOf('empty') > -1) { + icon.style.stroke = icon.style.fill; + icon.style.fill = '#fff'; + icon.style.lineWidth = 2; + } + return icon; + }; + MapSeries.type = 'series.map'; + MapSeries.dependencies = ['geo']; + MapSeries.layoutMode = 'box'; + MapSeries.defaultOption = { + // 一级层叠 + // zlevel: 0, + // 二级层叠 + z: 2, + coordinateSystem: 'geo', + // map should be explicitly specified since ec3. + map: '', + // If `geoIndex` is not specified, a exclusive geo will be + // created. Otherwise use the specified geo component, and + // `map` and `mapType` are ignored. + // geoIndex: 0, + // 'center' | 'left' | 'right' | 'x%' | {number} + left: 'center', + // 'center' | 'top' | 'bottom' | 'x%' | {number} + top: 'center', + // right + // bottom + // width: + // height + // Aspect is width / height. Inited to be geoJson bbox aspect + // This parameter is used for scale this aspect + // Default value: + // for geoSVG source: 1, + // for geoJSON source: 0.75. + aspectScale: null, + // Layout with center and size + // If you want to put map in a fixed size box with right aspect ratio + // This two properties may be more convenient. + // layoutCenter: [50%, 50%] + // layoutSize: 100 + showLegendSymbol: true, + // Define left-top, right-bottom coords to control view + // For example, [ [180, 90], [-180, -90] ], + // higher priority than center and zoom + boundingCoords: null, + // Default on center of map + center: null, + zoom: 1, + scaleLimit: null, + selectedMode: true, + label: { + show: false, + color: '#000' + }, + // scaleLimit: null, + itemStyle: { + borderWidth: 0.5, + borderColor: '#444', + areaColor: '#eee' + }, + emphasis: { + label: { + show: true, + color: 'rgb(100,0,0)' + }, + itemStyle: { + areaColor: 'rgba(255,215,0,0.8)' + } + }, + select: { + label: { + show: true, + color: 'rgb(100,0,0)' + }, + itemStyle: { + color: 'rgba(255,215,0,0.8)' + } + }, + nameProperty: 'name' + }; + return MapSeries; + }(SeriesModel); + + // FIXME 公用? + function dataStatistics(datas, statisticType) { + var dataNameMap = {}; + each(datas, function (data) { + data.each(data.mapDimension('value'), function (value, idx) { + // Add prefix to avoid conflict with Object.prototype. + var mapKey = 'ec-' + data.getName(idx); + dataNameMap[mapKey] = dataNameMap[mapKey] || []; + if (!isNaN(value)) { + dataNameMap[mapKey].push(value); + } + }); + }); + return datas[0].map(datas[0].mapDimension('value'), function (value, idx) { + var mapKey = 'ec-' + datas[0].getName(idx); + var sum = 0; + var min = Infinity; + var max = -Infinity; + var len = dataNameMap[mapKey].length; + for (var i = 0; i < len; i++) { + min = Math.min(min, dataNameMap[mapKey][i]); + max = Math.max(max, dataNameMap[mapKey][i]); + sum += dataNameMap[mapKey][i]; + } + var result; + if (statisticType === 'min') { + result = min; + } else if (statisticType === 'max') { + result = max; + } else if (statisticType === 'average') { + result = sum / len; + } else { + result = sum; + } + return len === 0 ? NaN : result; + }); + } + function mapDataStatistic(ecModel) { + var seriesGroups = {}; + ecModel.eachSeriesByType('map', function (seriesModel) { + var hostGeoModel = seriesModel.getHostGeoModel(); + var key = hostGeoModel ? 'o' + hostGeoModel.id : 'i' + seriesModel.getMapType(); + (seriesGroups[key] = seriesGroups[key] || []).push(seriesModel); + }); + each(seriesGroups, function (seriesList, key) { + var data = dataStatistics(map(seriesList, function (seriesModel) { + return seriesModel.getData(); + }), seriesList[0].get('mapValueCalculation')); + for (var i = 0; i < seriesList.length; i++) { + seriesList[i].originalData = seriesList[i].getData(); + } + // FIXME Put where? + for (var i = 0; i < seriesList.length; i++) { + seriesList[i].seriesGroup = seriesList; + seriesList[i].needsDrawMap = i === 0 && !seriesList[i].getHostGeoModel(); + seriesList[i].setData(data.cloneShallow()); + seriesList[i].mainSeries = seriesList[0]; + } + }); + } + + function mapSymbolLayout(ecModel) { + var processedMapType = {}; + ecModel.eachSeriesByType('map', function (mapSeries) { + var mapType = mapSeries.getMapType(); + if (mapSeries.getHostGeoModel() || processedMapType[mapType]) { + return; + } + var mapSymbolOffsets = {}; + each(mapSeries.seriesGroup, function (subMapSeries) { + var geo = subMapSeries.coordinateSystem; + var data = subMapSeries.originalData; + if (subMapSeries.get('showLegendSymbol') && ecModel.getComponent('legend')) { + data.each(data.mapDimension('value'), function (value, idx) { + var name = data.getName(idx); + var region = geo.getRegion(name); + // If input series.data is [11, 22, '-'/null/undefined, 44], + // it will be filled with NaN: [11, 22, NaN, 44] and NaN will + // not be drawn. So here must validate if value is NaN. + if (!region || isNaN(value)) { + return; + } + var offset = mapSymbolOffsets[name] || 0; + var point = geo.dataToPoint(region.getCenter()); + mapSymbolOffsets[name] = offset + 1; + data.setItemLayout(idx, { + point: point, + offset: offset + }); + }); + } + }); + // Show label of those region not has legendIcon (which is offset 0) + var data = mapSeries.getData(); + data.each(function (idx) { + var name = data.getName(idx); + var layout = data.getItemLayout(idx) || {}; + layout.showLabel = !mapSymbolOffsets[name]; + data.setItemLayout(idx, layout); + }); + processedMapType[mapType] = true; + }); + } + + var v2ApplyTransform = applyTransform; + var View = /** @class */function (_super) { + __extends(View, _super); + function View(name) { + var _this = _super.call(this) || this; + _this.type = 'view'; + _this.dimensions = ['x', 'y']; + /** + * Represents the transform brought by roam/zoom. + * If `View['_viewRect']` applies roam transform, + * we can get the final displayed rect. + */ + _this._roamTransformable = new Transformable(); + /** + * Represents the transform from `View['_rect']` to `View['_viewRect']`. + */ + _this._rawTransformable = new Transformable(); + _this.name = name; + return _this; + } + View.prototype.setBoundingRect = function (x, y, width, height) { + this._rect = new BoundingRect(x, y, width, height); + return this._rect; + }; + /** + * @return {module:zrender/core/BoundingRect} + */ + View.prototype.getBoundingRect = function () { + return this._rect; + }; + View.prototype.setViewRect = function (x, y, width, height) { + this._transformTo(x, y, width, height); + this._viewRect = new BoundingRect(x, y, width, height); + }; + /** + * Transformed to particular position and size + */ + View.prototype._transformTo = function (x, y, width, height) { + var rect = this.getBoundingRect(); + var rawTransform = this._rawTransformable; + rawTransform.transform = rect.calculateTransform(new BoundingRect(x, y, width, height)); + var rawParent = rawTransform.parent; + rawTransform.parent = null; + rawTransform.decomposeTransform(); + rawTransform.parent = rawParent; + this._updateTransform(); + }; + /** + * Set center of view + */ + View.prototype.setCenter = function (centerCoord, api) { + if (!centerCoord) { + return; + } + this._center = [parsePercent$1(centerCoord[0], api.getWidth()), parsePercent$1(centerCoord[1], api.getHeight())]; + this._updateCenterAndZoom(); + }; + View.prototype.setZoom = function (zoom) { + zoom = zoom || 1; + var zoomLimit = this.zoomLimit; + if (zoomLimit) { + if (zoomLimit.max != null) { + zoom = Math.min(zoomLimit.max, zoom); + } + if (zoomLimit.min != null) { + zoom = Math.max(zoomLimit.min, zoom); + } + } + this._zoom = zoom; + this._updateCenterAndZoom(); + }; + /** + * Get default center without roam + */ + View.prototype.getDefaultCenter = function () { + // Rect before any transform + var rawRect = this.getBoundingRect(); + var cx = rawRect.x + rawRect.width / 2; + var cy = rawRect.y + rawRect.height / 2; + return [cx, cy]; + }; + View.prototype.getCenter = function () { + return this._center || this.getDefaultCenter(); + }; + View.prototype.getZoom = function () { + return this._zoom || 1; + }; + View.prototype.getRoamTransform = function () { + return this._roamTransformable.getLocalTransform(); + }; + /** + * Remove roam + */ + View.prototype._updateCenterAndZoom = function () { + // Must update after view transform updated + var rawTransformMatrix = this._rawTransformable.getLocalTransform(); + var roamTransform = this._roamTransformable; + var defaultCenter = this.getDefaultCenter(); + var center = this.getCenter(); + var zoom = this.getZoom(); + center = applyTransform([], center, rawTransformMatrix); + defaultCenter = applyTransform([], defaultCenter, rawTransformMatrix); + roamTransform.originX = center[0]; + roamTransform.originY = center[1]; + roamTransform.x = defaultCenter[0] - center[0]; + roamTransform.y = defaultCenter[1] - center[1]; + roamTransform.scaleX = roamTransform.scaleY = zoom; + this._updateTransform(); + }; + /** + * Update transform props on `this` based on the current + * `this._roamTransformable` and `this._rawTransformable`. + */ + View.prototype._updateTransform = function () { + var roamTransformable = this._roamTransformable; + var rawTransformable = this._rawTransformable; + rawTransformable.parent = roamTransformable; + roamTransformable.updateTransform(); + rawTransformable.updateTransform(); + copy$1(this.transform || (this.transform = []), rawTransformable.transform || create$1()); + this._rawTransform = rawTransformable.getLocalTransform(); + this.invTransform = this.invTransform || []; + invert(this.invTransform, this.transform); + this.decomposeTransform(); + }; + View.prototype.getTransformInfo = function () { + var rawTransformable = this._rawTransformable; + var roamTransformable = this._roamTransformable; + // Because roamTransformabel has `originX/originY` modified, + // but the caller of `getTransformInfo` can not handle `originX/originY`, + // so need to recalculate them. + var dummyTransformable = new Transformable(); + dummyTransformable.transform = roamTransformable.transform; + dummyTransformable.decomposeTransform(); + return { + roam: { + x: dummyTransformable.x, + y: dummyTransformable.y, + scaleX: dummyTransformable.scaleX, + scaleY: dummyTransformable.scaleY + }, + raw: { + x: rawTransformable.x, + y: rawTransformable.y, + scaleX: rawTransformable.scaleX, + scaleY: rawTransformable.scaleY + } + }; + }; + View.prototype.getViewRect = function () { + return this._viewRect; + }; + /** + * Get view rect after roam transform + */ + View.prototype.getViewRectAfterRoam = function () { + var rect = this.getBoundingRect().clone(); + rect.applyTransform(this.transform); + return rect; + }; + /** + * Convert a single (lon, lat) data item to (x, y) point. + */ + View.prototype.dataToPoint = function (data, noRoam, out) { + var transform = noRoam ? this._rawTransform : this.transform; + out = out || []; + return transform ? v2ApplyTransform(out, data, transform) : copy(out, data); + }; + /** + * Convert a (x, y) point to (lon, lat) data + */ + View.prototype.pointToData = function (point) { + var invTransform = this.invTransform; + return invTransform ? v2ApplyTransform([], point, invTransform) : [point[0], point[1]]; + }; + View.prototype.convertToPixel = function (ecModel, finder, value) { + var coordSys = getCoordSys(finder); + return coordSys === this ? coordSys.dataToPoint(value) : null; + }; + View.prototype.convertFromPixel = function (ecModel, finder, pixel) { + var coordSys = getCoordSys(finder); + return coordSys === this ? coordSys.pointToData(pixel) : null; + }; + /** + * @implements + */ + View.prototype.containPoint = function (point) { + return this.getViewRectAfterRoam().contain(point[0], point[1]); + }; + View.dimensions = ['x', 'y']; + return View; + }(Transformable); + function getCoordSys(finder) { + var seriesModel = finder.seriesModel; + return seriesModel ? seriesModel.coordinateSystem : null; // e.g., graph. + } + + var GEO_DEFAULT_PARAMS = { + 'geoJSON': { + aspectScale: 0.75, + invertLongitute: true + }, + 'geoSVG': { + aspectScale: 1, + invertLongitute: false + } + }; + var geo2DDimensions = ['lng', 'lat']; + var Geo = /** @class */function (_super) { + __extends(Geo, _super); + function Geo(name, map, opt) { + var _this = _super.call(this, name) || this; + _this.dimensions = geo2DDimensions; + _this.type = 'geo'; + // Only store specified name coord via `addGeoCoord`. + _this._nameCoordMap = createHashMap(); + _this.map = map; + var projection = opt.projection; + var source = geoSourceManager.load(map, opt.nameMap, opt.nameProperty); + var resource = geoSourceManager.getGeoResource(map); + var resourceType = _this.resourceType = resource ? resource.type : null; + var regions = _this.regions = source.regions; + var defaultParams = GEO_DEFAULT_PARAMS[resource.type]; + _this._regionsMap = source.regionsMap; + _this.regions = source.regions; + if ("development" !== 'production' && projection) { + // Do some check + if (resourceType === 'geoSVG') { + if ("development" !== 'production') { + warn("Map " + map + " with SVG source can't use projection. Only GeoJSON source supports projection."); + } + projection = null; + } + if (!(projection.project && projection.unproject)) { + if ("development" !== 'production') { + warn('project and unproject must be both provided in the projeciton.'); + } + projection = null; + } + } + _this.projection = projection; + var boundingRect; + if (projection) { + // Can't reuse the raw bounding rect + for (var i = 0; i < regions.length; i++) { + var regionRect = regions[i].getBoundingRect(projection); + boundingRect = boundingRect || regionRect.clone(); + boundingRect.union(regionRect); + } + } else { + boundingRect = source.boundingRect; + } + _this.setBoundingRect(boundingRect.x, boundingRect.y, boundingRect.width, boundingRect.height); + // aspectScale and invertLongitute actually is the parameters default raw projection. + // So we ignore them if projection is given. + // Ignore default aspect scale if projection exits. + _this.aspectScale = projection ? 1 : retrieve2(opt.aspectScale, defaultParams.aspectScale); + // Not invert longitude if projection exits. + _this._invertLongitute = projection ? false : defaultParams.invertLongitute; + return _this; + } + Geo.prototype._transformTo = function (x, y, width, height) { + var rect = this.getBoundingRect(); + var invertLongitute = this._invertLongitute; + rect = rect.clone(); + if (invertLongitute) { + // Longitude is inverted. + rect.y = -rect.y - rect.height; + } + var rawTransformable = this._rawTransformable; + rawTransformable.transform = rect.calculateTransform(new BoundingRect(x, y, width, height)); + var rawParent = rawTransformable.parent; + rawTransformable.parent = null; + rawTransformable.decomposeTransform(); + rawTransformable.parent = rawParent; + if (invertLongitute) { + rawTransformable.scaleY = -rawTransformable.scaleY; + } + this._updateTransform(); + }; + Geo.prototype.getRegion = function (name) { + return this._regionsMap.get(name); + }; + Geo.prototype.getRegionByCoord = function (coord) { + var regions = this.regions; + for (var i = 0; i < regions.length; i++) { + var region = regions[i]; + if (region.type === 'geoJSON' && region.contain(coord)) { + return regions[i]; + } + } + }; + /** + * Add geoCoord for indexing by name + */ + Geo.prototype.addGeoCoord = function (name, geoCoord) { + this._nameCoordMap.set(name, geoCoord); + }; + /** + * Get geoCoord by name + */ + Geo.prototype.getGeoCoord = function (name) { + var region = this._regionsMap.get(name); + // Calculate center only on demand. + return this._nameCoordMap.get(name) || region && region.getCenter(); + }; + Geo.prototype.dataToPoint = function (data, noRoam, out) { + if (isString(data)) { + // Map area name to geoCoord + data = this.getGeoCoord(data); + } + if (data) { + var projection = this.projection; + if (projection) { + // projection may return null point. + data = projection.project(data); + } + return data && this.projectedToPoint(data, noRoam, out); + } + }; + Geo.prototype.pointToData = function (point) { + var projection = this.projection; + if (projection) { + // projection may return null point. + point = projection.unproject(point); + } + return point && this.pointToProjected(point); + }; + /** + * Point to projected data. Same with pointToData when projection is used. + */ + Geo.prototype.pointToProjected = function (point) { + return _super.prototype.pointToData.call(this, point); + }; + Geo.prototype.projectedToPoint = function (projected, noRoam, out) { + return _super.prototype.dataToPoint.call(this, projected, noRoam, out); + }; + Geo.prototype.convertToPixel = function (ecModel, finder, value) { + var coordSys = getCoordSys$1(finder); + return coordSys === this ? coordSys.dataToPoint(value) : null; + }; + Geo.prototype.convertFromPixel = function (ecModel, finder, pixel) { + var coordSys = getCoordSys$1(finder); + return coordSys === this ? coordSys.pointToData(pixel) : null; + }; + return Geo; + }(View); + mixin(Geo, View); + function getCoordSys$1(finder) { + var geoModel = finder.geoModel; + var seriesModel = finder.seriesModel; + return geoModel ? geoModel.coordinateSystem : seriesModel ? seriesModel.coordinateSystem // For map series. + || (seriesModel.getReferringComponents('geo', SINGLE_REFERRING).models[0] || {}).coordinateSystem : null; + } + + /** + * Resize method bound to the geo + */ + function resizeGeo(geoModel, api) { + var boundingCoords = geoModel.get('boundingCoords'); + if (boundingCoords != null) { + var leftTop_1 = boundingCoords[0]; + var rightBottom_1 = boundingCoords[1]; + if (!(isFinite(leftTop_1[0]) && isFinite(leftTop_1[1]) && isFinite(rightBottom_1[0]) && isFinite(rightBottom_1[1]))) { + if ("development" !== 'production') { + console.error('Invalid boundingCoords'); + } + } else { + // Sample around the lng/lat rect and use projection to calculate actual bounding rect. + var projection_1 = this.projection; + if (projection_1) { + var xMin = leftTop_1[0]; + var yMin = leftTop_1[1]; + var xMax = rightBottom_1[0]; + var yMax = rightBottom_1[1]; + leftTop_1 = [Infinity, Infinity]; + rightBottom_1 = [-Infinity, -Infinity]; + // TODO better way? + var sampleLine = function (x0, y0, x1, y1) { + var dx = x1 - x0; + var dy = y1 - y0; + for (var i = 0; i <= 100; i++) { + var p = i / 100; + var pt = projection_1.project([x0 + dx * p, y0 + dy * p]); + min(leftTop_1, leftTop_1, pt); + max(rightBottom_1, rightBottom_1, pt); + } + }; + // Top + sampleLine(xMin, yMin, xMax, yMin); + // Right + sampleLine(xMax, yMin, xMax, yMax); + // Bottom + sampleLine(xMax, yMax, xMin, yMax); + // Left + sampleLine(xMin, yMax, xMax, yMin); + } + this.setBoundingRect(leftTop_1[0], leftTop_1[1], rightBottom_1[0] - leftTop_1[0], rightBottom_1[1] - leftTop_1[1]); + } + } + var rect = this.getBoundingRect(); + var centerOption = geoModel.get('layoutCenter'); + var sizeOption = geoModel.get('layoutSize'); + var viewWidth = api.getWidth(); + var viewHeight = api.getHeight(); + var aspect = rect.width / rect.height * this.aspectScale; + var useCenterAndSize = false; + var center; + var size; + if (centerOption && sizeOption) { + center = [parsePercent$1(centerOption[0], viewWidth), parsePercent$1(centerOption[1], viewHeight)]; + size = parsePercent$1(sizeOption, Math.min(viewWidth, viewHeight)); + if (!isNaN(center[0]) && !isNaN(center[1]) && !isNaN(size)) { + useCenterAndSize = true; + } else { + if ("development" !== 'production') { + console.warn('Given layoutCenter or layoutSize data are invalid. Use left/top/width/height instead.'); + } + } + } + var viewRect; + if (useCenterAndSize) { + viewRect = {}; + if (aspect > 1) { + // Width is same with size + viewRect.width = size; + viewRect.height = size / aspect; + } else { + viewRect.height = size; + viewRect.width = size * aspect; + } + viewRect.y = center[1] - viewRect.height / 2; + viewRect.x = center[0] - viewRect.width / 2; + } else { + // Use left/top/width/height + var boxLayoutOption = geoModel.getBoxLayoutParams(); + boxLayoutOption.aspect = aspect; + viewRect = getLayoutRect(boxLayoutOption, { + width: viewWidth, + height: viewHeight + }); + } + this.setViewRect(viewRect.x, viewRect.y, viewRect.width, viewRect.height); + this.setCenter(geoModel.get('center'), api); + this.setZoom(geoModel.get('zoom')); + } + // Back compat for ECharts2, where the coord map is set on map series: + // {type: 'map', geoCoord: {'cityA': [116.46,39.92], 'cityA': [119.12,24.61]}}, + function setGeoCoords(geo, model) { + each(model.get('geoCoord'), function (geoCoord, name) { + geo.addGeoCoord(name, geoCoord); + }); + } + var GeoCreator = /** @class */function () { + function GeoCreator() { + // For deciding which dimensions to use when creating list data + this.dimensions = geo2DDimensions; + } + GeoCreator.prototype.create = function (ecModel, api) { + var geoList = []; + function getCommonGeoProperties(model) { + return { + nameProperty: model.get('nameProperty'), + aspectScale: model.get('aspectScale'), + projection: model.get('projection') + }; + } + // FIXME Create each time may be slow + ecModel.eachComponent('geo', function (geoModel, idx) { + var mapName = geoModel.get('map'); + var geo = new Geo(mapName + idx, mapName, extend({ + nameMap: geoModel.get('nameMap') + }, getCommonGeoProperties(geoModel))); + geo.zoomLimit = geoModel.get('scaleLimit'); + geoList.push(geo); + // setGeoCoords(geo, geoModel); + geoModel.coordinateSystem = geo; + geo.model = geoModel; + // Inject resize method + geo.resize = resizeGeo; + geo.resize(geoModel, api); + }); + ecModel.eachSeries(function (seriesModel) { + var coordSys = seriesModel.get('coordinateSystem'); + if (coordSys === 'geo') { + var geoIndex = seriesModel.get('geoIndex') || 0; + seriesModel.coordinateSystem = geoList[geoIndex]; + } + }); + // If has map series + var mapModelGroupBySeries = {}; + ecModel.eachSeriesByType('map', function (seriesModel) { + if (!seriesModel.getHostGeoModel()) { + var mapType = seriesModel.getMapType(); + mapModelGroupBySeries[mapType] = mapModelGroupBySeries[mapType] || []; + mapModelGroupBySeries[mapType].push(seriesModel); + } + }); + each(mapModelGroupBySeries, function (mapSeries, mapType) { + var nameMapList = map(mapSeries, function (singleMapSeries) { + return singleMapSeries.get('nameMap'); + }); + var geo = new Geo(mapType, mapType, extend({ + nameMap: mergeAll(nameMapList) + }, getCommonGeoProperties(mapSeries[0]))); + geo.zoomLimit = retrieve.apply(null, map(mapSeries, function (singleMapSeries) { + return singleMapSeries.get('scaleLimit'); + })); + geoList.push(geo); + // Inject resize method + geo.resize = resizeGeo; + geo.resize(mapSeries[0], api); + each(mapSeries, function (singleMapSeries) { + singleMapSeries.coordinateSystem = geo; + setGeoCoords(geo, singleMapSeries); + }); + }); + return geoList; + }; + /** + * Fill given regions array + */ + GeoCreator.prototype.getFilledRegions = function (originRegionArr, mapName, nameMap, nameProperty) { + // Not use the original + var regionsArr = (originRegionArr || []).slice(); + var dataNameMap = createHashMap(); + for (var i = 0; i < regionsArr.length; i++) { + dataNameMap.set(regionsArr[i].name, regionsArr[i]); + } + var source = geoSourceManager.load(mapName, nameMap, nameProperty); + each(source.regions, function (region) { + var name = region.name; + !dataNameMap.get(name) && regionsArr.push({ + name: name + }); + }); + return regionsArr; + }; + return GeoCreator; + }(); + var geoCreator = new GeoCreator(); + + var GeoModel = /** @class */function (_super) { + __extends(GeoModel, _super); + function GeoModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = GeoModel.type; + return _this; + } + GeoModel.prototype.init = function (option, parentModel, ecModel) { + var source = geoSourceManager.getGeoResource(option.map); + if (source && source.type === 'geoJSON') { + var itemStyle = option.itemStyle = option.itemStyle || {}; + if (!('color' in itemStyle)) { + itemStyle.color = '#eee'; + } + } + this.mergeDefaultAndTheme(option, ecModel); + // Default label emphasis `show` + defaultEmphasis(option, 'label', ['show']); + }; + GeoModel.prototype.optionUpdated = function () { + var _this = this; + var option = this.option; + option.regions = geoCreator.getFilledRegions(option.regions, option.map, option.nameMap, option.nameProperty); + var selectedMap = {}; + this._optionModelMap = reduce(option.regions || [], function (optionModelMap, regionOpt) { + var regionName = regionOpt.name; + if (regionName) { + optionModelMap.set(regionName, new Model(regionOpt, _this, _this.ecModel)); + if (regionOpt.selected) { + selectedMap[regionName] = true; + } + } + return optionModelMap; + }, createHashMap()); + if (!option.selectedMap) { + option.selectedMap = selectedMap; + } + }; + /** + * Get model of region. + */ + GeoModel.prototype.getRegionModel = function (name) { + return this._optionModelMap.get(name) || new Model(null, this, this.ecModel); + }; + /** + * Format label + * @param name Region name + */ + GeoModel.prototype.getFormattedLabel = function (name, status) { + var regionModel = this.getRegionModel(name); + var formatter = status === 'normal' ? regionModel.get(['label', 'formatter']) : regionModel.get(['emphasis', 'label', 'formatter']); + var params = { + name: name + }; + if (isFunction(formatter)) { + params.status = status; + return formatter(params); + } else if (isString(formatter)) { + return formatter.replace('{a}', name != null ? name : ''); + } + }; + GeoModel.prototype.setZoom = function (zoom) { + this.option.zoom = zoom; + }; + GeoModel.prototype.setCenter = function (center) { + this.option.center = center; + }; + // PENGING If selectedMode is null ? + GeoModel.prototype.select = function (name) { + var option = this.option; + var selectedMode = option.selectedMode; + if (!selectedMode) { + return; + } + if (selectedMode !== 'multiple') { + option.selectedMap = null; + } + var selectedMap = option.selectedMap || (option.selectedMap = {}); + selectedMap[name] = true; + }; + GeoModel.prototype.unSelect = function (name) { + var selectedMap = this.option.selectedMap; + if (selectedMap) { + selectedMap[name] = false; + } + }; + GeoModel.prototype.toggleSelected = function (name) { + this[this.isSelected(name) ? 'unSelect' : 'select'](name); + }; + GeoModel.prototype.isSelected = function (name) { + var selectedMap = this.option.selectedMap; + return !!(selectedMap && selectedMap[name]); + }; + GeoModel.type = 'geo'; + GeoModel.layoutMode = 'box'; + GeoModel.defaultOption = { + // zlevel: 0, + z: 0, + show: true, + left: 'center', + top: 'center', + // Default value: + // for geoSVG source: 1, + // for geoJSON source: 0.75. + aspectScale: null, + // /// Layout with center and size + // If you want to put map in a fixed size box with right aspect ratio + // This two properties may be more convenient + // layoutCenter: [50%, 50%] + // layoutSize: 100 + silent: false, + // Map type + map: '', + // Define left-top, right-bottom coords to control view + // For example, [ [180, 90], [-180, -90] ] + boundingCoords: null, + // Default on center of map + center: null, + zoom: 1, + scaleLimit: null, + // selectedMode: false + label: { + show: false, + color: '#000' + }, + itemStyle: { + borderWidth: 0.5, + borderColor: '#444' + // Default color: + // + geoJSON: #eee + // + geoSVG: null (use SVG original `fill`) + // color: '#eee' + }, + + emphasis: { + label: { + show: true, + color: 'rgb(100,0,0)' + }, + itemStyle: { + color: 'rgba(255,215,0,0.8)' + } + }, + select: { + label: { + show: true, + color: 'rgb(100,0,0)' + }, + itemStyle: { + color: 'rgba(255,215,0,0.8)' + } + }, + regions: [] + // tooltip: { + // show: false + // } + }; + + return GeoModel; + }(ComponentModel); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function getCenterCoord(view, point) { + // Use projected coord as center because it's linear. + return view.pointToProjected ? view.pointToProjected(point) : view.pointToData(point); + } + function updateCenterAndZoom(view, payload, zoomLimit, api) { + var previousZoom = view.getZoom(); + var center = view.getCenter(); + var zoom = payload.zoom; + var point = view.projectedToPoint ? view.projectedToPoint(center) : view.dataToPoint(center); + if (payload.dx != null && payload.dy != null) { + point[0] -= payload.dx; + point[1] -= payload.dy; + view.setCenter(getCenterCoord(view, point), api); + } + if (zoom != null) { + if (zoomLimit) { + var zoomMin = zoomLimit.min || 0; + var zoomMax = zoomLimit.max || Infinity; + zoom = Math.max(Math.min(previousZoom * zoom, zoomMax), zoomMin) / previousZoom; + } + // Zoom on given point(originX, originY) + view.scaleX *= zoom; + view.scaleY *= zoom; + var fixX = (payload.originX - view.x) * (zoom - 1); + var fixY = (payload.originY - view.y) * (zoom - 1); + view.x -= fixX; + view.y -= fixY; + view.updateTransform(); + // Get the new center + view.setCenter(getCenterCoord(view, point), api); + view.setZoom(zoom * previousZoom); + } + return { + center: view.getCenter(), + zoom: view.getZoom() + }; + } + + var GeoView = /** @class */function (_super) { + __extends(GeoView, _super); + function GeoView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = GeoView.type; + _this.focusBlurEnabled = true; + return _this; + } + GeoView.prototype.init = function (ecModel, api) { + this._api = api; + }; + GeoView.prototype.render = function (geoModel, ecModel, api, payload) { + this._model = geoModel; + if (!geoModel.get('show')) { + this._mapDraw && this._mapDraw.remove(); + this._mapDraw = null; + return; + } + if (!this._mapDraw) { + this._mapDraw = new MapDraw(api); + } + var mapDraw = this._mapDraw; + mapDraw.draw(geoModel, ecModel, api, this, payload); + mapDraw.group.on('click', this._handleRegionClick, this); + mapDraw.group.silent = geoModel.get('silent'); + this.group.add(mapDraw.group); + this.updateSelectStatus(geoModel, ecModel, api); + }; + GeoView.prototype._handleRegionClick = function (e) { + var eventData; + findEventDispatcher(e.target, function (current) { + return (eventData = getECData(current).eventData) != null; + }, true); + if (eventData) { + this._api.dispatchAction({ + type: 'geoToggleSelect', + geoId: this._model.id, + name: eventData.name + }); + } + }; + GeoView.prototype.updateSelectStatus = function (model, ecModel, api) { + var _this = this; + this._mapDraw.group.traverse(function (node) { + var eventData = getECData(node).eventData; + if (eventData) { + _this._model.isSelected(eventData.name) ? api.enterSelect(node) : api.leaveSelect(node); + // No need to traverse children. + return true; + } + }); + }; + GeoView.prototype.findHighDownDispatchers = function (name) { + return this._mapDraw && this._mapDraw.findHighDownDispatchers(name, this._model); + }; + GeoView.prototype.dispose = function () { + this._mapDraw && this._mapDraw.remove(); + }; + GeoView.type = 'geo'; + return GeoView; + }(ComponentView); + + function registerMap$1(mapName, geoJson, specialAreas) { + geoSourceManager.registerMap(mapName, geoJson, specialAreas); + } + function install$9(registers) { + registers.registerCoordinateSystem('geo', geoCreator); + registers.registerComponentModel(GeoModel); + registers.registerComponentView(GeoView); + registers.registerImpl('registerMap', registerMap$1); + registers.registerImpl('getMap', function (mapName) { + return geoSourceManager.getMapForUser(mapName); + }); + function makeAction(method, actionInfo) { + actionInfo.update = 'geo:updateSelectStatus'; + registers.registerAction(actionInfo, function (payload, ecModel) { + var selected = {}; + var allSelected = []; + ecModel.eachComponent({ + mainType: 'geo', + query: payload + }, function (geoModel) { + geoModel[method](payload.name); + var geo = geoModel.coordinateSystem; + each(geo.regions, function (region) { + selected[region.name] = geoModel.isSelected(region.name) || false; + }); + // Notice: there might be duplicated name in different regions. + var names = []; + each(selected, function (v, name) { + selected[name] && names.push(name); + }); + allSelected.push({ + geoIndex: geoModel.componentIndex, + // Use singular, the same naming convention as the event `selectchanged`. + name: names + }); + }); + return { + selected: selected, + allSelected: allSelected, + name: payload.name + }; + }); + } + makeAction('toggleSelected', { + type: 'geoToggleSelect', + event: 'geoselectchanged' + }); + makeAction('select', { + type: 'geoSelect', + event: 'geoselected' + }); + makeAction('unSelect', { + type: 'geoUnSelect', + event: 'geounselected' + }); + /** + * @payload + * @property {string} [componentType=series] + * @property {number} [dx] + * @property {number} [dy] + * @property {number} [zoom] + * @property {number} [originX] + * @property {number} [originY] + */ + registers.registerAction({ + type: 'geoRoam', + event: 'geoRoam', + update: 'updateTransform' + }, function (payload, ecModel, api) { + var componentType = payload.componentType || 'series'; + ecModel.eachComponent({ + mainType: componentType, + query: payload + }, function (componentModel) { + var geo = componentModel.coordinateSystem; + if (geo.type !== 'geo') { + return; + } + var res = updateCenterAndZoom(geo, payload, componentModel.get('scaleLimit'), api); + componentModel.setCenter && componentModel.setCenter(res.center); + componentModel.setZoom && componentModel.setZoom(res.zoom); + // All map series with same `map` use the same geo coordinate system + // So the center and zoom must be in sync. Include the series not selected by legend + if (componentType === 'series') { + each(componentModel.seriesGroup, function (seriesModel) { + seriesModel.setCenter(res.center); + seriesModel.setZoom(res.zoom); + }); + } + }); + }); + } + + function install$a(registers) { + use(install$9); + registers.registerChartView(MapView); + registers.registerSeriesModel(MapSeries); + registers.registerLayout(mapSymbolLayout); + registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, mapDataStatistic); + createLegacyDataSelectAction('map', registers.registerAction); + } + + /** + * Initialize all computational message for following algorithm. + */ + function init$2(inRoot) { + var root = inRoot; + root.hierNode = { + defaultAncestor: null, + ancestor: root, + prelim: 0, + modifier: 0, + change: 0, + shift: 0, + i: 0, + thread: null + }; + var nodes = [root]; + var node; + var children; + while (node = nodes.pop()) { + // jshint ignore:line + children = node.children; + if (node.isExpand && children.length) { + var n = children.length; + for (var i = n - 1; i >= 0; i--) { + var child = children[i]; + child.hierNode = { + defaultAncestor: null, + ancestor: child, + prelim: 0, + modifier: 0, + change: 0, + shift: 0, + i: i, + thread: null + }; + nodes.push(child); + } + } + } + } + /** + * The implementation of this function was originally copied from "d3.js" + * + * with some modifications made for this program. + * See the license statement at the head of this file. + * + * Computes a preliminary x coordinate for node. Before that, this function is + * applied recursively to the children of node, as well as the function + * apportion(). After spacing out the children by calling executeShifts(), the + * node is placed to the midpoint of its outermost children. + */ + function firstWalk(node, separation) { + var children = node.isExpand ? node.children : []; + var siblings = node.parentNode.children; + var subtreeW = node.hierNode.i ? siblings[node.hierNode.i - 1] : null; + if (children.length) { + executeShifts(node); + var midPoint = (children[0].hierNode.prelim + children[children.length - 1].hierNode.prelim) / 2; + if (subtreeW) { + node.hierNode.prelim = subtreeW.hierNode.prelim + separation(node, subtreeW); + node.hierNode.modifier = node.hierNode.prelim - midPoint; + } else { + node.hierNode.prelim = midPoint; + } + } else if (subtreeW) { + node.hierNode.prelim = subtreeW.hierNode.prelim + separation(node, subtreeW); + } + node.parentNode.hierNode.defaultAncestor = apportion(node, subtreeW, node.parentNode.hierNode.defaultAncestor || siblings[0], separation); + } + /** + * The implementation of this function was originally copied from "d3.js" + * + * with some modifications made for this program. + * See the license statement at the head of this file. + * + * Computes all real x-coordinates by summing up the modifiers recursively. + */ + function secondWalk(node) { + var nodeX = node.hierNode.prelim + node.parentNode.hierNode.modifier; + node.setLayout({ + x: nodeX + }, true); + node.hierNode.modifier += node.parentNode.hierNode.modifier; + } + function separation(cb) { + return arguments.length ? cb : defaultSeparation; + } + /** + * Transform the common coordinate to radial coordinate. + */ + function radialCoordinate(rad, r) { + rad -= Math.PI / 2; + return { + x: r * Math.cos(rad), + y: r * Math.sin(rad) + }; + } + /** + * Get the layout position of the whole view. + */ + function getViewRect$1(seriesModel, api) { + return getLayoutRect(seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }); + } + /** + * All other shifts, applied to the smaller subtrees between w- and w+, are + * performed by this function. + * + * The implementation of this function was originally copied from "d3.js" + * + * with some modifications made for this program. + * See the license statement at the head of this file. + */ + function executeShifts(node) { + var children = node.children; + var n = children.length; + var shift = 0; + var change = 0; + while (--n >= 0) { + var child = children[n]; + child.hierNode.prelim += shift; + child.hierNode.modifier += shift; + change += child.hierNode.change; + shift += child.hierNode.shift + change; + } + } + /** + * The implementation of this function was originally copied from "d3.js" + * + * with some modifications made for this program. + * See the license statement at the head of this file. + * + * The core of the algorithm. Here, a new subtree is combined with the + * previous subtrees. Threads are used to traverse the inside and outside + * contours of the left and right subtree up to the highest common level. + * Whenever two nodes of the inside contours conflict, we compute the left + * one of the greatest uncommon ancestors using the function nextAncestor() + * and call moveSubtree() to shift the subtree and prepare the shifts of + * smaller subtrees. Finally, we add a new thread (if necessary). + */ + function apportion(subtreeV, subtreeW, ancestor, separation) { + if (subtreeW) { + var nodeOutRight = subtreeV; + var nodeInRight = subtreeV; + var nodeOutLeft = nodeInRight.parentNode.children[0]; + var nodeInLeft = subtreeW; + var sumOutRight = nodeOutRight.hierNode.modifier; + var sumInRight = nodeInRight.hierNode.modifier; + var sumOutLeft = nodeOutLeft.hierNode.modifier; + var sumInLeft = nodeInLeft.hierNode.modifier; + while (nodeInLeft = nextRight(nodeInLeft), nodeInRight = nextLeft(nodeInRight), nodeInLeft && nodeInRight) { + nodeOutRight = nextRight(nodeOutRight); + nodeOutLeft = nextLeft(nodeOutLeft); + nodeOutRight.hierNode.ancestor = subtreeV; + var shift = nodeInLeft.hierNode.prelim + sumInLeft - nodeInRight.hierNode.prelim - sumInRight + separation(nodeInLeft, nodeInRight); + if (shift > 0) { + moveSubtree(nextAncestor(nodeInLeft, subtreeV, ancestor), subtreeV, shift); + sumInRight += shift; + sumOutRight += shift; + } + sumInLeft += nodeInLeft.hierNode.modifier; + sumInRight += nodeInRight.hierNode.modifier; + sumOutRight += nodeOutRight.hierNode.modifier; + sumOutLeft += nodeOutLeft.hierNode.modifier; + } + if (nodeInLeft && !nextRight(nodeOutRight)) { + nodeOutRight.hierNode.thread = nodeInLeft; + nodeOutRight.hierNode.modifier += sumInLeft - sumOutRight; + } + if (nodeInRight && !nextLeft(nodeOutLeft)) { + nodeOutLeft.hierNode.thread = nodeInRight; + nodeOutLeft.hierNode.modifier += sumInRight - sumOutLeft; + ancestor = subtreeV; + } + } + return ancestor; + } + /** + * This function is used to traverse the right contour of a subtree. + * It returns the rightmost child of node or the thread of node. The function + * returns null if and only if node is on the highest depth of its subtree. + */ + function nextRight(node) { + var children = node.children; + return children.length && node.isExpand ? children[children.length - 1] : node.hierNode.thread; + } + /** + * This function is used to traverse the left contour of a subtree (or a subforest). + * It returns the leftmost child of node or the thread of node. The function + * returns null if and only if node is on the highest depth of its subtree. + */ + function nextLeft(node) { + var children = node.children; + return children.length && node.isExpand ? children[0] : node.hierNode.thread; + } + /** + * If nodeInLeft’s ancestor is a sibling of node, returns nodeInLeft’s ancestor. + * Otherwise, returns the specified ancestor. + */ + function nextAncestor(nodeInLeft, node, ancestor) { + return nodeInLeft.hierNode.ancestor.parentNode === node.parentNode ? nodeInLeft.hierNode.ancestor : ancestor; + } + /** + * The implementation of this function was originally copied from "d3.js" + * + * with some modifications made for this program. + * See the license statement at the head of this file. + * + * Shifts the current subtree rooted at wr. + * This is done by increasing prelim(w+) and modifier(w+) by shift. + */ + function moveSubtree(wl, wr, shift) { + var change = shift / (wr.hierNode.i - wl.hierNode.i); + wr.hierNode.change -= change; + wr.hierNode.shift += shift; + wr.hierNode.modifier += shift; + wr.hierNode.prelim += shift; + wl.hierNode.change += change; + } + /** + * The implementation of this function was originally copied from "d3.js" + * + * with some modifications made for this program. + * See the license statement at the head of this file. + */ + function defaultSeparation(node1, node2) { + return node1.parentNode === node2.parentNode ? 1 : 2; + } + + var TreeEdgeShape = /** @class */function () { + function TreeEdgeShape() { + this.parentPoint = []; + this.childPoints = []; + } + return TreeEdgeShape; + }(); + var TreePath = /** @class */function (_super) { + __extends(TreePath, _super); + function TreePath(opts) { + return _super.call(this, opts) || this; + } + TreePath.prototype.getDefaultStyle = function () { + return { + stroke: '#000', + fill: null + }; + }; + TreePath.prototype.getDefaultShape = function () { + return new TreeEdgeShape(); + }; + TreePath.prototype.buildPath = function (ctx, shape) { + var childPoints = shape.childPoints; + var childLen = childPoints.length; + var parentPoint = shape.parentPoint; + var firstChildPos = childPoints[0]; + var lastChildPos = childPoints[childLen - 1]; + if (childLen === 1) { + ctx.moveTo(parentPoint[0], parentPoint[1]); + ctx.lineTo(firstChildPos[0], firstChildPos[1]); + return; + } + var orient = shape.orient; + var forkDim = orient === 'TB' || orient === 'BT' ? 0 : 1; + var otherDim = 1 - forkDim; + var forkPosition = parsePercent$1(shape.forkPosition, 1); + var tmpPoint = []; + tmpPoint[forkDim] = parentPoint[forkDim]; + tmpPoint[otherDim] = parentPoint[otherDim] + (lastChildPos[otherDim] - parentPoint[otherDim]) * forkPosition; + ctx.moveTo(parentPoint[0], parentPoint[1]); + ctx.lineTo(tmpPoint[0], tmpPoint[1]); + ctx.moveTo(firstChildPos[0], firstChildPos[1]); + tmpPoint[forkDim] = firstChildPos[forkDim]; + ctx.lineTo(tmpPoint[0], tmpPoint[1]); + tmpPoint[forkDim] = lastChildPos[forkDim]; + ctx.lineTo(tmpPoint[0], tmpPoint[1]); + ctx.lineTo(lastChildPos[0], lastChildPos[1]); + for (var i = 1; i < childLen - 1; i++) { + var point = childPoints[i]; + ctx.moveTo(point[0], point[1]); + tmpPoint[forkDim] = point[forkDim]; + ctx.lineTo(tmpPoint[0], tmpPoint[1]); + } + }; + return TreePath; + }(Path); + var TreeView = /** @class */function (_super) { + __extends(TreeView, _super); + function TreeView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TreeView.type; + _this._mainGroup = new Group(); + return _this; + } + TreeView.prototype.init = function (ecModel, api) { + this._controller = new RoamController(api.getZr()); + this._controllerHost = { + target: this.group + }; + this.group.add(this._mainGroup); + }; + TreeView.prototype.render = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var layoutInfo = seriesModel.layoutInfo; + var group = this._mainGroup; + var layout = seriesModel.get('layout'); + if (layout === 'radial') { + group.x = layoutInfo.x + layoutInfo.width / 2; + group.y = layoutInfo.y + layoutInfo.height / 2; + } else { + group.x = layoutInfo.x; + group.y = layoutInfo.y; + } + this._updateViewCoordSys(seriesModel, api); + this._updateController(seriesModel, ecModel, api); + var oldData = this._data; + data.diff(oldData).add(function (newIdx) { + if (symbolNeedsDraw$1(data, newIdx)) { + // Create node and edge + updateNode(data, newIdx, null, group, seriesModel); + } + }).update(function (newIdx, oldIdx) { + var symbolEl = oldData.getItemGraphicEl(oldIdx); + if (!symbolNeedsDraw$1(data, newIdx)) { + symbolEl && removeNode(oldData, oldIdx, symbolEl, group, seriesModel); + return; + } + // Update node and edge + updateNode(data, newIdx, symbolEl, group, seriesModel); + }).remove(function (oldIdx) { + var symbolEl = oldData.getItemGraphicEl(oldIdx); + // When remove a collapsed node of subtree, since the collapsed + // node haven't been initialized with a symbol element, + // you can't found it's symbol element through index. + // so if we want to remove the symbol element we should insure + // that the symbol element is not null. + if (symbolEl) { + removeNode(oldData, oldIdx, symbolEl, group, seriesModel); + } + }).execute(); + this._nodeScaleRatio = seriesModel.get('nodeScaleRatio'); + this._updateNodeAndLinkScale(seriesModel); + if (seriesModel.get('expandAndCollapse') === true) { + data.eachItemGraphicEl(function (el, dataIndex) { + el.off('click').on('click', function () { + api.dispatchAction({ + type: 'treeExpandAndCollapse', + seriesId: seriesModel.id, + dataIndex: dataIndex + }); + }); + }); + } + this._data = data; + }; + TreeView.prototype._updateViewCoordSys = function (seriesModel, api) { + var data = seriesModel.getData(); + var points = []; + data.each(function (idx) { + var layout = data.getItemLayout(idx); + if (layout && !isNaN(layout.x) && !isNaN(layout.y)) { + points.push([+layout.x, +layout.y]); + } + }); + var min = []; + var max = []; + fromPoints(points, min, max); + // If don't Store min max when collapse the root node after roam, + // the root node will disappear. + var oldMin = this._min; + var oldMax = this._max; + // If width or height is 0 + if (max[0] - min[0] === 0) { + min[0] = oldMin ? oldMin[0] : min[0] - 1; + max[0] = oldMax ? oldMax[0] : max[0] + 1; + } + if (max[1] - min[1] === 0) { + min[1] = oldMin ? oldMin[1] : min[1] - 1; + max[1] = oldMax ? oldMax[1] : max[1] + 1; + } + var viewCoordSys = seriesModel.coordinateSystem = new View(); + viewCoordSys.zoomLimit = seriesModel.get('scaleLimit'); + viewCoordSys.setBoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]); + viewCoordSys.setCenter(seriesModel.get('center'), api); + viewCoordSys.setZoom(seriesModel.get('zoom')); + // Here we use viewCoordSys just for computing the 'position' and 'scale' of the group + this.group.attr({ + x: viewCoordSys.x, + y: viewCoordSys.y, + scaleX: viewCoordSys.scaleX, + scaleY: viewCoordSys.scaleY + }); + this._min = min; + this._max = max; + }; + TreeView.prototype._updateController = function (seriesModel, ecModel, api) { + var _this = this; + var controller = this._controller; + var controllerHost = this._controllerHost; + var group = this.group; + controller.setPointerChecker(function (e, x, y) { + var rect = group.getBoundingRect(); + rect.applyTransform(group.transform); + return rect.contain(x, y) && !onIrrelevantElement(e, api, seriesModel); + }); + controller.enable(seriesModel.get('roam')); + controllerHost.zoomLimit = seriesModel.get('scaleLimit'); + controllerHost.zoom = seriesModel.coordinateSystem.getZoom(); + controller.off('pan').off('zoom').on('pan', function (e) { + updateViewOnPan(controllerHost, e.dx, e.dy); + api.dispatchAction({ + seriesId: seriesModel.id, + type: 'treeRoam', + dx: e.dx, + dy: e.dy + }); + }).on('zoom', function (e) { + updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY); + api.dispatchAction({ + seriesId: seriesModel.id, + type: 'treeRoam', + zoom: e.scale, + originX: e.originX, + originY: e.originY + }); + _this._updateNodeAndLinkScale(seriesModel); + // Only update label layout on zoom + api.updateLabelLayout(); + }); + }; + TreeView.prototype._updateNodeAndLinkScale = function (seriesModel) { + var data = seriesModel.getData(); + var nodeScale = this._getNodeGlobalScale(seriesModel); + data.eachItemGraphicEl(function (el, idx) { + el.setSymbolScale(nodeScale); + }); + }; + TreeView.prototype._getNodeGlobalScale = function (seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys.type !== 'view') { + return 1; + } + var nodeScaleRatio = this._nodeScaleRatio; + var groupZoom = coordSys.scaleX || 1; + // Scale node when zoom changes + var roamZoom = coordSys.getZoom(); + var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1; + return nodeScale / groupZoom; + }; + TreeView.prototype.dispose = function () { + this._controller && this._controller.dispose(); + this._controllerHost = null; + }; + TreeView.prototype.remove = function () { + this._mainGroup.removeAll(); + this._data = null; + }; + TreeView.type = 'tree'; + return TreeView; + }(ChartView); + function symbolNeedsDraw$1(data, dataIndex) { + var layout = data.getItemLayout(dataIndex); + return layout && !isNaN(layout.x) && !isNaN(layout.y); + } + function updateNode(data, dataIndex, symbolEl, group, seriesModel) { + var isInit = !symbolEl; + var node = data.tree.getNodeByDataIndex(dataIndex); + var itemModel = node.getModel(); + var visualColor = node.getVisual('style').fill; + var symbolInnerColor = node.isExpand === false && node.children.length !== 0 ? visualColor : '#fff'; + var virtualRoot = data.tree.root; + var source = node.parentNode === virtualRoot ? node : node.parentNode || node; + var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex); + var sourceLayout = source.getLayout(); + var sourceOldLayout = sourceSymbolEl ? { + x: sourceSymbolEl.__oldX, + y: sourceSymbolEl.__oldY, + rawX: sourceSymbolEl.__radialOldRawX, + rawY: sourceSymbolEl.__radialOldRawY + } : sourceLayout; + var targetLayout = node.getLayout(); + if (isInit) { + symbolEl = new Symbol(data, dataIndex, null, { + symbolInnerColor: symbolInnerColor, + useNameLabel: true + }); + symbolEl.x = sourceOldLayout.x; + symbolEl.y = sourceOldLayout.y; + } else { + symbolEl.updateData(data, dataIndex, null, { + symbolInnerColor: symbolInnerColor, + useNameLabel: true + }); + } + symbolEl.__radialOldRawX = symbolEl.__radialRawX; + symbolEl.__radialOldRawY = symbolEl.__radialRawY; + symbolEl.__radialRawX = targetLayout.rawX; + symbolEl.__radialRawY = targetLayout.rawY; + group.add(symbolEl); + data.setItemGraphicEl(dataIndex, symbolEl); + symbolEl.__oldX = symbolEl.x; + symbolEl.__oldY = symbolEl.y; + updateProps(symbolEl, { + x: targetLayout.x, + y: targetLayout.y + }, seriesModel); + var symbolPath = symbolEl.getSymbolPath(); + if (seriesModel.get('layout') === 'radial') { + var realRoot = virtualRoot.children[0]; + var rootLayout = realRoot.getLayout(); + var length_1 = realRoot.children.length; + var rad = void 0; + var isLeft = void 0; + if (targetLayout.x === rootLayout.x && node.isExpand === true && realRoot.children.length) { + var center = { + x: (realRoot.children[0].getLayout().x + realRoot.children[length_1 - 1].getLayout().x) / 2, + y: (realRoot.children[0].getLayout().y + realRoot.children[length_1 - 1].getLayout().y) / 2 + }; + rad = Math.atan2(center.y - rootLayout.y, center.x - rootLayout.x); + if (rad < 0) { + rad = Math.PI * 2 + rad; + } + isLeft = center.x < rootLayout.x; + if (isLeft) { + rad = rad - Math.PI; + } + } else { + rad = Math.atan2(targetLayout.y - rootLayout.y, targetLayout.x - rootLayout.x); + if (rad < 0) { + rad = Math.PI * 2 + rad; + } + if (node.children.length === 0 || node.children.length !== 0 && node.isExpand === false) { + isLeft = targetLayout.x < rootLayout.x; + if (isLeft) { + rad = rad - Math.PI; + } + } else { + isLeft = targetLayout.x > rootLayout.x; + if (!isLeft) { + rad = rad - Math.PI; + } + } + } + var textPosition = isLeft ? 'left' : 'right'; + var normalLabelModel = itemModel.getModel('label'); + var rotate = normalLabelModel.get('rotate'); + var labelRotateRadian = rotate * (Math.PI / 180); + var textContent = symbolPath.getTextContent(); + if (textContent) { + symbolPath.setTextConfig({ + position: normalLabelModel.get('position') || textPosition, + rotation: rotate == null ? -rad : labelRotateRadian, + origin: 'center' + }); + textContent.setStyle('verticalAlign', 'middle'); + } + } + // Handle status + var focus = itemModel.get(['emphasis', 'focus']); + var focusDataIndices = focus === 'relative' ? concatArray(node.getAncestorsIndices(), node.getDescendantIndices()) : focus === 'ancestor' ? node.getAncestorsIndices() : focus === 'descendant' ? node.getDescendantIndices() : null; + if (focusDataIndices) { + // Modify the focus to data indices. + getECData(symbolEl).focus = focusDataIndices; + } + drawEdge(seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, targetLayout, group); + if (symbolEl.__edge) { + symbolEl.onHoverStateChange = function (toState) { + if (toState !== 'blur') { + // NOTE: Ensure the parent elements will been blurred firstly. + // According to the return of getAncestorsIndices and getDescendantIndices + // TODO: A bit tricky. + var parentEl = node.parentNode && data.getItemGraphicEl(node.parentNode.dataIndex); + if (!(parentEl && parentEl.hoverState === HOVER_STATE_BLUR)) { + setStatesFlag(symbolEl.__edge, toState); + } + } + }; + } + } + function drawEdge(seriesModel, node, virtualRoot, symbolEl, sourceOldLayout, sourceLayout, targetLayout, group) { + var itemModel = node.getModel(); + var edgeShape = seriesModel.get('edgeShape'); + var layout = seriesModel.get('layout'); + var orient = seriesModel.getOrient(); + var curvature = seriesModel.get(['lineStyle', 'curveness']); + var edgeForkPosition = seriesModel.get('edgeForkPosition'); + var lineStyle = itemModel.getModel('lineStyle').getLineStyle(); + var edge = symbolEl.__edge; + // curve edge from node -> parent + // polyline edge from node -> children + if (edgeShape === 'curve') { + if (node.parentNode && node.parentNode !== virtualRoot) { + if (!edge) { + edge = symbolEl.__edge = new BezierCurve({ + shape: getEdgeShape(layout, orient, curvature, sourceOldLayout, sourceOldLayout) + }); + } + updateProps(edge, { + shape: getEdgeShape(layout, orient, curvature, sourceLayout, targetLayout) + }, seriesModel); + } + } else if (edgeShape === 'polyline') { + if (layout === 'orthogonal') { + if (node !== virtualRoot && node.children && node.children.length !== 0 && node.isExpand === true) { + var children = node.children; + var childPoints = []; + for (var i = 0; i < children.length; i++) { + var childLayout = children[i].getLayout(); + childPoints.push([childLayout.x, childLayout.y]); + } + if (!edge) { + edge = symbolEl.__edge = new TreePath({ + shape: { + parentPoint: [targetLayout.x, targetLayout.y], + childPoints: [[targetLayout.x, targetLayout.y]], + orient: orient, + forkPosition: edgeForkPosition + } + }); + } + updateProps(edge, { + shape: { + parentPoint: [targetLayout.x, targetLayout.y], + childPoints: childPoints + } + }, seriesModel); + } + } else { + if ("development" !== 'production') { + throw new Error('The polyline edgeShape can only be used in orthogonal layout'); + } + } + } + // show all edge when edgeShape is 'curve', filter node `isExpand` is false when edgeShape is 'polyline' + if (edge && !(edgeShape === 'polyline' && !node.isExpand)) { + edge.useStyle(defaults({ + strokeNoScale: true, + fill: null + }, lineStyle)); + setStatesStylesFromModel(edge, itemModel, 'lineStyle'); + setDefaultStateProxy(edge); + group.add(edge); + } + } + function removeNodeEdge(node, data, group, seriesModel, removeAnimationOpt) { + var virtualRoot = data.tree.root; + var _a = getSourceNode(virtualRoot, node), + source = _a.source, + sourceLayout = _a.sourceLayout; + var symbolEl = data.getItemGraphicEl(node.dataIndex); + if (!symbolEl) { + return; + } + var sourceSymbolEl = data.getItemGraphicEl(source.dataIndex); + var sourceEdge = sourceSymbolEl.__edge; + // 1. when expand the sub tree, delete the children node should delete the edge of + // the source at the same time. because the polyline edge shape is only owned by the source. + // 2.when the node is the only children of the source, delete the node should delete the edge of + // the source at the same time. the same reason as above. + var edge = symbolEl.__edge || (source.isExpand === false || source.children.length === 1 ? sourceEdge : undefined); + var edgeShape = seriesModel.get('edgeShape'); + var layoutOpt = seriesModel.get('layout'); + var orient = seriesModel.get('orient'); + var curvature = seriesModel.get(['lineStyle', 'curveness']); + if (edge) { + if (edgeShape === 'curve') { + removeElement(edge, { + shape: getEdgeShape(layoutOpt, orient, curvature, sourceLayout, sourceLayout), + style: { + opacity: 0 + } + }, seriesModel, { + cb: function () { + group.remove(edge); + }, + removeOpt: removeAnimationOpt + }); + } else if (edgeShape === 'polyline' && seriesModel.get('layout') === 'orthogonal') { + removeElement(edge, { + shape: { + parentPoint: [sourceLayout.x, sourceLayout.y], + childPoints: [[sourceLayout.x, sourceLayout.y]] + }, + style: { + opacity: 0 + } + }, seriesModel, { + cb: function () { + group.remove(edge); + }, + removeOpt: removeAnimationOpt + }); + } + } + } + function getSourceNode(virtualRoot, node) { + var source = node.parentNode === virtualRoot ? node : node.parentNode || node; + var sourceLayout; + while (sourceLayout = source.getLayout(), sourceLayout == null) { + source = source.parentNode === virtualRoot ? source : source.parentNode || source; + } + return { + source: source, + sourceLayout: sourceLayout + }; + } + function removeNode(data, dataIndex, symbolEl, group, seriesModel) { + var node = data.tree.getNodeByDataIndex(dataIndex); + var virtualRoot = data.tree.root; + var sourceLayout = getSourceNode(virtualRoot, node).sourceLayout; + // Use same duration and easing with update to have more consistent animation. + var removeAnimationOpt = { + duration: seriesModel.get('animationDurationUpdate'), + easing: seriesModel.get('animationEasingUpdate') + }; + removeElement(symbolEl, { + x: sourceLayout.x + 1, + y: sourceLayout.y + 1 + }, seriesModel, { + cb: function () { + group.remove(symbolEl); + data.setItemGraphicEl(dataIndex, null); + }, + removeOpt: removeAnimationOpt + }); + symbolEl.fadeOut(null, data.hostModel, { + fadeLabel: true, + animation: removeAnimationOpt + }); + // remove edge as parent node + node.children.forEach(function (childNode) { + removeNodeEdge(childNode, data, group, seriesModel, removeAnimationOpt); + }); + // remove edge as child node + removeNodeEdge(node, data, group, seriesModel, removeAnimationOpt); + } + function getEdgeShape(layoutOpt, orient, curvature, sourceLayout, targetLayout) { + var cpx1; + var cpy1; + var cpx2; + var cpy2; + var x1; + var x2; + var y1; + var y2; + if (layoutOpt === 'radial') { + x1 = sourceLayout.rawX; + y1 = sourceLayout.rawY; + x2 = targetLayout.rawX; + y2 = targetLayout.rawY; + var radialCoor1 = radialCoordinate(x1, y1); + var radialCoor2 = radialCoordinate(x1, y1 + (y2 - y1) * curvature); + var radialCoor3 = radialCoordinate(x2, y2 + (y1 - y2) * curvature); + var radialCoor4 = radialCoordinate(x2, y2); + return { + x1: radialCoor1.x || 0, + y1: radialCoor1.y || 0, + x2: radialCoor4.x || 0, + y2: radialCoor4.y || 0, + cpx1: radialCoor2.x || 0, + cpy1: radialCoor2.y || 0, + cpx2: radialCoor3.x || 0, + cpy2: radialCoor3.y || 0 + }; + } else { + x1 = sourceLayout.x; + y1 = sourceLayout.y; + x2 = targetLayout.x; + y2 = targetLayout.y; + if (orient === 'LR' || orient === 'RL') { + cpx1 = x1 + (x2 - x1) * curvature; + cpy1 = y1; + cpx2 = x2 + (x1 - x2) * curvature; + cpy2 = y2; + } + if (orient === 'TB' || orient === 'BT') { + cpx1 = x1; + cpy1 = y1 + (y2 - y1) * curvature; + cpx2 = x2; + cpy2 = y2 + (y1 - y2) * curvature; + } + } + return { + x1: x1, + y1: y1, + x2: x2, + y2: y2, + cpx1: cpx1, + cpy1: cpy1, + cpx2: cpx2, + cpy2: cpy2 + }; + } + + var inner$7 = makeInner(); + function linkSeriesData(opt) { + var mainData = opt.mainData; + var datas = opt.datas; + if (!datas) { + datas = { + main: mainData + }; + opt.datasAttr = { + main: 'data' + }; + } + opt.datas = opt.mainData = null; + linkAll(mainData, datas, opt); + // Porxy data original methods. + each(datas, function (data) { + each(mainData.TRANSFERABLE_METHODS, function (methodName) { + data.wrapMethod(methodName, curry(transferInjection, opt)); + }); + }); + // Beyond transfer, additional features should be added to `cloneShallow`. + mainData.wrapMethod('cloneShallow', curry(cloneShallowInjection, opt)); + // Only mainData trigger change, because struct.update may trigger + // another changable methods, which may bring about dead lock. + each(mainData.CHANGABLE_METHODS, function (methodName) { + mainData.wrapMethod(methodName, curry(changeInjection, opt)); + }); + // Make sure datas contains mainData. + assert(datas[mainData.dataType] === mainData); + } + function transferInjection(opt, res) { + if (isMainData(this)) { + // Transfer datas to new main data. + var datas = extend({}, inner$7(this).datas); + datas[this.dataType] = res; + linkAll(res, datas, opt); + } else { + // Modify the reference in main data to point newData. + linkSingle(res, this.dataType, inner$7(this).mainData, opt); + } + return res; + } + function changeInjection(opt, res) { + opt.struct && opt.struct.update(); + return res; + } + function cloneShallowInjection(opt, res) { + // cloneShallow, which brings about some fragilities, may be inappropriate + // to be exposed as an API. So for implementation simplicity we can make + // the restriction that cloneShallow of not-mainData should not be invoked + // outside, but only be invoked here. + each(inner$7(res).datas, function (data, dataType) { + data !== res && linkSingle(data.cloneShallow(), dataType, res, opt); + }); + return res; + } + /** + * Supplement method to List. + * + * @public + * @param [dataType] If not specified, return mainData. + */ + function getLinkedData(dataType) { + var mainData = inner$7(this).mainData; + return dataType == null || mainData == null ? mainData : inner$7(mainData).datas[dataType]; + } + /** + * Get list of all linked data + */ + function getLinkedDataAll() { + var mainData = inner$7(this).mainData; + return mainData == null ? [{ + data: mainData + }] : map(keys(inner$7(mainData).datas), function (type) { + return { + type: type, + data: inner$7(mainData).datas[type] + }; + }); + } + function isMainData(data) { + return inner$7(data).mainData === data; + } + function linkAll(mainData, datas, opt) { + inner$7(mainData).datas = {}; + each(datas, function (data, dataType) { + linkSingle(data, dataType, mainData, opt); + }); + } + function linkSingle(data, dataType, mainData, opt) { + inner$7(mainData).datas[dataType] = data; + inner$7(data).mainData = mainData; + data.dataType = dataType; + if (opt.struct) { + data[opt.structAttr] = opt.struct; + opt.struct[opt.datasAttr[dataType]] = data; + } + // Supplement method. + data.getLinkedData = getLinkedData; + data.getLinkedDataAll = getLinkedDataAll; + } + + var TreeNode = /** @class */function () { + function TreeNode(name, hostTree) { + this.depth = 0; + this.height = 0; + /** + * Reference to list item. + * Do not persistent dataIndex outside, + * besause it may be changed by list. + * If dataIndex -1, + * this node is logical deleted (filtered) in list. + */ + this.dataIndex = -1; + this.children = []; + this.viewChildren = []; + this.isExpand = false; + this.name = name || ''; + this.hostTree = hostTree; + } + /** + * The node is removed. + */ + TreeNode.prototype.isRemoved = function () { + return this.dataIndex < 0; + }; + TreeNode.prototype.eachNode = function (options, cb, context) { + if (isFunction(options)) { + context = cb; + cb = options; + options = null; + } + options = options || {}; + if (isString(options)) { + options = { + order: options + }; + } + var order = options.order || 'preorder'; + var children = this[options.attr || 'children']; + var suppressVisitSub; + order === 'preorder' && (suppressVisitSub = cb.call(context, this)); + for (var i = 0; !suppressVisitSub && i < children.length; i++) { + children[i].eachNode(options, cb, context); + } + order === 'postorder' && cb.call(context, this); + }; + /** + * Update depth and height of this subtree. + */ + TreeNode.prototype.updateDepthAndHeight = function (depth) { + var height = 0; + this.depth = depth; + for (var i = 0; i < this.children.length; i++) { + var child = this.children[i]; + child.updateDepthAndHeight(depth + 1); + if (child.height > height) { + height = child.height; + } + } + this.height = height + 1; + }; + TreeNode.prototype.getNodeById = function (id) { + if (this.getId() === id) { + return this; + } + for (var i = 0, children = this.children, len = children.length; i < len; i++) { + var res = children[i].getNodeById(id); + if (res) { + return res; + } + } + }; + TreeNode.prototype.contains = function (node) { + if (node === this) { + return true; + } + for (var i = 0, children = this.children, len = children.length; i < len; i++) { + var res = children[i].contains(node); + if (res) { + return res; + } + } + }; + /** + * @param includeSelf Default false. + * @return order: [root, child, grandchild, ...] + */ + TreeNode.prototype.getAncestors = function (includeSelf) { + var ancestors = []; + var node = includeSelf ? this : this.parentNode; + while (node) { + ancestors.push(node); + node = node.parentNode; + } + ancestors.reverse(); + return ancestors; + }; + TreeNode.prototype.getAncestorsIndices = function () { + var indices = []; + var currNode = this; + while (currNode) { + indices.push(currNode.dataIndex); + currNode = currNode.parentNode; + } + indices.reverse(); + return indices; + }; + TreeNode.prototype.getDescendantIndices = function () { + var indices = []; + this.eachNode(function (childNode) { + indices.push(childNode.dataIndex); + }); + return indices; + }; + TreeNode.prototype.getValue = function (dimension) { + var data = this.hostTree.data; + return data.getStore().get(data.getDimensionIndex(dimension || 'value'), this.dataIndex); + }; + TreeNode.prototype.setLayout = function (layout, merge) { + this.dataIndex >= 0 && this.hostTree.data.setItemLayout(this.dataIndex, layout, merge); + }; + /** + * @return {Object} layout + */ + TreeNode.prototype.getLayout = function () { + return this.hostTree.data.getItemLayout(this.dataIndex); + }; + // @depcrecated + // getModel(path: S): Model + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TreeNode.prototype.getModel = function (path) { + if (this.dataIndex < 0) { + return; + } + var hostTree = this.hostTree; + var itemModel = hostTree.data.getItemModel(this.dataIndex); + return itemModel.getModel(path); + }; + // TODO: TYPE More specific model + TreeNode.prototype.getLevelModel = function () { + return (this.hostTree.levelModels || [])[this.depth]; + }; + TreeNode.prototype.setVisual = function (key, value) { + this.dataIndex >= 0 && this.hostTree.data.setItemVisual(this.dataIndex, key, value); + }; + /** + * Get item visual + * FIXME: make return type better + */ + TreeNode.prototype.getVisual = function (key) { + return this.hostTree.data.getItemVisual(this.dataIndex, key); + }; + TreeNode.prototype.getRawIndex = function () { + return this.hostTree.data.getRawIndex(this.dataIndex); + }; + TreeNode.prototype.getId = function () { + return this.hostTree.data.getId(this.dataIndex); + }; + /** + * index in parent's children + */ + TreeNode.prototype.getChildIndex = function () { + if (this.parentNode) { + var children = this.parentNode.children; + for (var i = 0; i < children.length; ++i) { + if (children[i] === this) { + return i; + } + } + return -1; + } + return -1; + }; + /** + * if this is an ancestor of another node + * + * @param node another node + * @return if is ancestor + */ + TreeNode.prototype.isAncestorOf = function (node) { + var parent = node.parentNode; + while (parent) { + if (parent === this) { + return true; + } + parent = parent.parentNode; + } + return false; + }; + /** + * if this is an descendant of another node + * + * @param node another node + * @return if is descendant + */ + TreeNode.prototype.isDescendantOf = function (node) { + return node !== this && node.isAncestorOf(this); + }; + return TreeNode; + }(); + var Tree = /** @class */function () { + function Tree(hostModel) { + this.type = 'tree'; + this._nodes = []; + this.hostModel = hostModel; + } + Tree.prototype.eachNode = function (options, cb, context) { + this.root.eachNode(options, cb, context); + }; + Tree.prototype.getNodeByDataIndex = function (dataIndex) { + var rawIndex = this.data.getRawIndex(dataIndex); + return this._nodes[rawIndex]; + }; + Tree.prototype.getNodeById = function (name) { + return this.root.getNodeById(name); + }; + /** + * Update item available by list, + * when list has been performed options like 'filterSelf' or 'map'. + */ + Tree.prototype.update = function () { + var data = this.data; + var nodes = this._nodes; + for (var i = 0, len = nodes.length; i < len; i++) { + nodes[i].dataIndex = -1; + } + for (var i = 0, len = data.count(); i < len; i++) { + nodes[data.getRawIndex(i)].dataIndex = i; + } + }; + /** + * Clear all layouts + */ + Tree.prototype.clearLayouts = function () { + this.data.clearItemLayouts(); + }; + /** + * data node format: + * { + * name: ... + * value: ... + * children: [ + * { + * name: ... + * value: ... + * children: ... + * }, + * ... + * ] + * } + */ + Tree.createTree = function (dataRoot, hostModel, beforeLink) { + var tree = new Tree(hostModel); + var listData = []; + var dimMax = 1; + buildHierarchy(dataRoot); + function buildHierarchy(dataNode, parentNode) { + var value = dataNode.value; + dimMax = Math.max(dimMax, isArray(value) ? value.length : 1); + listData.push(dataNode); + var node = new TreeNode(convertOptionIdName(dataNode.name, ''), tree); + parentNode ? addChild(node, parentNode) : tree.root = node; + tree._nodes.push(node); + var children = dataNode.children; + if (children) { + for (var i = 0; i < children.length; i++) { + buildHierarchy(children[i], node); + } + } + } + tree.root.updateDepthAndHeight(0); + var dimensions = prepareSeriesDataSchema(listData, { + coordDimensions: ['value'], + dimensionsCount: dimMax + }).dimensions; + var list = new SeriesData(dimensions, hostModel); + list.initData(listData); + beforeLink && beforeLink(list); + linkSeriesData({ + mainData: list, + struct: tree, + structAttr: 'tree' + }); + tree.update(); + return tree; + }; + return Tree; + }(); + /** + * It is needed to consider the mess of 'list', 'hostModel' when creating a TreeNote, + * so this function is not ready and not necessary to be public. + */ + function addChild(child, node) { + var children = node.children; + if (child.parentNode === node) { + return; + } + children.push(child); + child.parentNode = node; + } + + function retrieveTargetInfo(payload, validPayloadTypes, seriesModel) { + if (payload && indexOf(validPayloadTypes, payload.type) >= 0) { + var root = seriesModel.getData().tree.root; + var targetNode = payload.targetNode; + if (isString(targetNode)) { + targetNode = root.getNodeById(targetNode); + } + if (targetNode && root.contains(targetNode)) { + return { + node: targetNode + }; + } + var targetNodeId = payload.targetNodeId; + if (targetNodeId != null && (targetNode = root.getNodeById(targetNodeId))) { + return { + node: targetNode + }; + } + } + } + // Not includes the given node at the last item. + function getPathToRoot(node) { + var path = []; + while (node) { + node = node.parentNode; + node && path.push(node); + } + return path.reverse(); + } + function aboveViewRoot(viewRoot, node) { + var viewPath = getPathToRoot(viewRoot); + return indexOf(viewPath, node) >= 0; + } + // From root to the input node (the input node will be included). + function wrapTreePathInfo(node, seriesModel) { + var treePathInfo = []; + while (node) { + var nodeDataIndex = node.dataIndex; + treePathInfo.push({ + name: node.name, + dataIndex: nodeDataIndex, + value: seriesModel.getRawValue(nodeDataIndex) + }); + node = node.parentNode; + } + treePathInfo.reverse(); + return treePathInfo; + } + + var TreeSeriesModel = /** @class */function (_super) { + __extends(TreeSeriesModel, _super); + function TreeSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.hasSymbolVisual = true; + // Do it self. + _this.ignoreStyleOnData = true; + return _this; + } + /** + * Init a tree data structure from data in option series + */ + TreeSeriesModel.prototype.getInitialData = function (option) { + // create a virtual root + var root = { + name: option.name, + children: option.data + }; + var leaves = option.leaves || {}; + var leavesModel = new Model(leaves, this, this.ecModel); + var tree = Tree.createTree(root, this, beforeLink); + function beforeLink(nodeData) { + nodeData.wrapMethod('getItemModel', function (model, idx) { + var node = tree.getNodeByDataIndex(idx); + if (!(node && node.children.length && node.isExpand)) { + model.parentModel = leavesModel; + } + return model; + }); + } + var treeDepth = 0; + tree.eachNode('preorder', function (node) { + if (node.depth > treeDepth) { + treeDepth = node.depth; + } + }); + var expandAndCollapse = option.expandAndCollapse; + var expandTreeDepth = expandAndCollapse && option.initialTreeDepth >= 0 ? option.initialTreeDepth : treeDepth; + tree.root.eachNode('preorder', function (node) { + var item = node.hostTree.data.getRawDataItem(node.dataIndex); + // Add item.collapsed != null, because users can collapse node original in the series.data. + node.isExpand = item && item.collapsed != null ? !item.collapsed : node.depth <= expandTreeDepth; + }); + return tree.data; + }; + /** + * Make the configuration 'orient' backward compatibly, with 'horizontal = LR', 'vertical = TB'. + * @returns {string} orient + */ + TreeSeriesModel.prototype.getOrient = function () { + var orient = this.get('orient'); + if (orient === 'horizontal') { + orient = 'LR'; + } else if (orient === 'vertical') { + orient = 'TB'; + } + return orient; + }; + TreeSeriesModel.prototype.setZoom = function (zoom) { + this.option.zoom = zoom; + }; + TreeSeriesModel.prototype.setCenter = function (center) { + this.option.center = center; + }; + TreeSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + var tree = this.getData().tree; + var realRoot = tree.root.children[0]; + var node = tree.getNodeByDataIndex(dataIndex); + var value = node.getValue(); + var name = node.name; + while (node && node !== realRoot) { + name = node.parentNode.name + '.' + name; + node = node.parentNode; + } + return createTooltipMarkup('nameValue', { + name: name, + value: value, + noValue: isNaN(value) || value == null + }); + }; + // Add tree path to tooltip param + TreeSeriesModel.prototype.getDataParams = function (dataIndex) { + var params = _super.prototype.getDataParams.apply(this, arguments); + var node = this.getData().tree.getNodeByDataIndex(dataIndex); + params.treeAncestors = wrapTreePathInfo(node, this); + params.collapsed = !node.isExpand; + return params; + }; + TreeSeriesModel.type = 'series.tree'; + // can support the position parameters 'left', 'top','right','bottom', 'width', + // 'height' in the setOption() with 'merge' mode normal. + TreeSeriesModel.layoutMode = 'box'; + TreeSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + coordinateSystem: 'view', + // the position of the whole view + left: '12%', + top: '12%', + right: '12%', + bottom: '12%', + // the layout of the tree, two value can be selected, 'orthogonal' or 'radial' + layout: 'orthogonal', + // value can be 'polyline' + edgeShape: 'curve', + edgeForkPosition: '50%', + // true | false | 'move' | 'scale', see module:component/helper/RoamController. + roam: false, + // Symbol size scale ratio in roam + nodeScaleRatio: 0.4, + // Default on center of graph + center: null, + zoom: 1, + orient: 'LR', + symbol: 'emptyCircle', + symbolSize: 7, + expandAndCollapse: true, + initialTreeDepth: 2, + lineStyle: { + color: '#ccc', + width: 1.5, + curveness: 0.5 + }, + itemStyle: { + color: 'lightsteelblue', + // borderColor: '#c23531', + borderWidth: 1.5 + }, + label: { + show: true + }, + animationEasing: 'linear', + animationDuration: 700, + animationDurationUpdate: 500 + }; + return TreeSeriesModel; + }(SeriesModel); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /** + * Traverse the tree from bottom to top and do something + */ + function eachAfter(root, callback, separation) { + var nodes = [root]; + var next = []; + var node; + while (node = nodes.pop()) { + // jshint ignore:line + next.push(node); + if (node.isExpand) { + var children = node.children; + if (children.length) { + for (var i = 0; i < children.length; i++) { + nodes.push(children[i]); + } + } + } + } + while (node = next.pop()) { + // jshint ignore:line + callback(node, separation); + } + } + /** + * Traverse the tree from top to bottom and do something + */ + function eachBefore(root, callback) { + var nodes = [root]; + var node; + while (node = nodes.pop()) { + // jshint ignore:line + callback(node); + if (node.isExpand) { + var children = node.children; + if (children.length) { + for (var i = children.length - 1; i >= 0; i--) { + nodes.push(children[i]); + } + } + } + } + } + + function treeLayout(ecModel, api) { + ecModel.eachSeriesByType('tree', function (seriesModel) { + commonLayout(seriesModel, api); + }); + } + function commonLayout(seriesModel, api) { + var layoutInfo = getViewRect$1(seriesModel, api); + seriesModel.layoutInfo = layoutInfo; + var layout = seriesModel.get('layout'); + var width = 0; + var height = 0; + var separation$1 = null; + if (layout === 'radial') { + width = 2 * Math.PI; + height = Math.min(layoutInfo.height, layoutInfo.width) / 2; + separation$1 = separation(function (node1, node2) { + return (node1.parentNode === node2.parentNode ? 1 : 2) / node1.depth; + }); + } else { + width = layoutInfo.width; + height = layoutInfo.height; + separation$1 = separation(); + } + var virtualRoot = seriesModel.getData().tree.root; + var realRoot = virtualRoot.children[0]; + if (realRoot) { + init$2(virtualRoot); + eachAfter(realRoot, firstWalk, separation$1); + virtualRoot.hierNode.modifier = -realRoot.hierNode.prelim; + eachBefore(realRoot, secondWalk); + var left_1 = realRoot; + var right_1 = realRoot; + var bottom_1 = realRoot; + eachBefore(realRoot, function (node) { + var x = node.getLayout().x; + if (x < left_1.getLayout().x) { + left_1 = node; + } + if (x > right_1.getLayout().x) { + right_1 = node; + } + if (node.depth > bottom_1.depth) { + bottom_1 = node; + } + }); + var delta = left_1 === right_1 ? 1 : separation$1(left_1, right_1) / 2; + var tx_1 = delta - left_1.getLayout().x; + var kx_1 = 0; + var ky_1 = 0; + var coorX_1 = 0; + var coorY_1 = 0; + if (layout === 'radial') { + kx_1 = width / (right_1.getLayout().x + delta + tx_1); + // here we use (node.depth - 1), bucause the real root's depth is 1 + ky_1 = height / (bottom_1.depth - 1 || 1); + eachBefore(realRoot, function (node) { + coorX_1 = (node.getLayout().x + tx_1) * kx_1; + coorY_1 = (node.depth - 1) * ky_1; + var finalCoor = radialCoordinate(coorX_1, coorY_1); + node.setLayout({ + x: finalCoor.x, + y: finalCoor.y, + rawX: coorX_1, + rawY: coorY_1 + }, true); + }); + } else { + var orient_1 = seriesModel.getOrient(); + if (orient_1 === 'RL' || orient_1 === 'LR') { + ky_1 = height / (right_1.getLayout().x + delta + tx_1); + kx_1 = width / (bottom_1.depth - 1 || 1); + eachBefore(realRoot, function (node) { + coorY_1 = (node.getLayout().x + tx_1) * ky_1; + coorX_1 = orient_1 === 'LR' ? (node.depth - 1) * kx_1 : width - (node.depth - 1) * kx_1; + node.setLayout({ + x: coorX_1, + y: coorY_1 + }, true); + }); + } else if (orient_1 === 'TB' || orient_1 === 'BT') { + kx_1 = width / (right_1.getLayout().x + delta + tx_1); + ky_1 = height / (bottom_1.depth - 1 || 1); + eachBefore(realRoot, function (node) { + coorX_1 = (node.getLayout().x + tx_1) * kx_1; + coorY_1 = orient_1 === 'TB' ? (node.depth - 1) * ky_1 : height - (node.depth - 1) * ky_1; + node.setLayout({ + x: coorX_1, + y: coorY_1 + }, true); + }); + } + } + } + } + + function treeVisual(ecModel) { + ecModel.eachSeriesByType('tree', function (seriesModel) { + var data = seriesModel.getData(); + var tree = data.tree; + tree.eachNode(function (node) { + var model = node.getModel(); + // TODO Optimize + var style = model.getModel('itemStyle').getItemStyle(); + var existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style'); + extend(existsStyle, style); + }); + }); + } + + function installTreeAction(registers) { + registers.registerAction({ + type: 'treeExpandAndCollapse', + event: 'treeExpandAndCollapse', + update: 'update' + }, function (payload, ecModel) { + ecModel.eachComponent({ + mainType: 'series', + subType: 'tree', + query: payload + }, function (seriesModel) { + var dataIndex = payload.dataIndex; + var tree = seriesModel.getData().tree; + var node = tree.getNodeByDataIndex(dataIndex); + node.isExpand = !node.isExpand; + }); + }); + registers.registerAction({ + type: 'treeRoam', + event: 'treeRoam', + // Here we set 'none' instead of 'update', because roam action + // just need to update the transform matrix without having to recalculate + // the layout. So don't need to go through the whole update process, such + // as 'dataPrcocess', 'coordSystemUpdate', 'layout' and so on. + update: 'none' + }, function (payload, ecModel, api) { + ecModel.eachComponent({ + mainType: 'series', + subType: 'tree', + query: payload + }, function (seriesModel) { + var coordSys = seriesModel.coordinateSystem; + var res = updateCenterAndZoom(coordSys, payload, undefined, api); + seriesModel.setCenter && seriesModel.setCenter(res.center); + seriesModel.setZoom && seriesModel.setZoom(res.zoom); + }); + }); + } + + function install$b(registers) { + registers.registerChartView(TreeView); + registers.registerSeriesModel(TreeSeriesModel); + registers.registerLayout(treeLayout); + registers.registerVisual(treeVisual); + installTreeAction(registers); + } + + var actionTypes = ['treemapZoomToNode', 'treemapRender', 'treemapMove']; + function installTreemapAction(registers) { + for (var i = 0; i < actionTypes.length; i++) { + registers.registerAction({ + type: actionTypes[i], + update: 'updateView' + }, noop); + } + registers.registerAction({ + type: 'treemapRootToNode', + update: 'updateView' + }, function (payload, ecModel) { + ecModel.eachComponent({ + mainType: 'series', + subType: 'treemap', + query: payload + }, handleRootToNode); + function handleRootToNode(model, index) { + var types = ['treemapZoomToNode', 'treemapRootToNode']; + var targetInfo = retrieveTargetInfo(payload, types, model); + if (targetInfo) { + var originViewRoot = model.getViewRoot(); + if (originViewRoot) { + payload.direction = aboveViewRoot(originViewRoot, targetInfo.node) ? 'rollUp' : 'drillDown'; + } + model.resetViewRoot(targetInfo.node); + } + } + }); + } + + function enableAriaDecalForTree(seriesModel) { + var data = seriesModel.getData(); + var tree = data.tree; + var decalPaletteScope = {}; + tree.eachNode(function (node) { + // Use decal of level 1 node + var current = node; + while (current && current.depth > 1) { + current = current.parentNode; + } + var decal = getDecalFromPalette(seriesModel.ecModel, current.name || current.dataIndex + '', decalPaletteScope); + node.setVisual('decal', decal); + }); + } + + var TreemapSeriesModel = /** @class */function (_super) { + __extends(TreemapSeriesModel, _super); + function TreemapSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TreemapSeriesModel.type; + _this.preventUsingHoverLayer = true; + return _this; + } + /** + * @override + */ + TreemapSeriesModel.prototype.getInitialData = function (option, ecModel) { + // Create a virtual root. + var root = { + name: option.name, + children: option.data + }; + completeTreeValue(root); + var levels = option.levels || []; + // Used in "visual priority" in `treemapVisual.js`. + // This way is a little tricky, must satisfy the precondition: + // 1. There is no `treeNode.getModel('itemStyle.xxx')` used. + // 2. The `Model.prototype.getModel()` will not use any clone-like way. + var designatedVisualItemStyle = this.designatedVisualItemStyle = {}; + var designatedVisualModel = new Model({ + itemStyle: designatedVisualItemStyle + }, this, ecModel); + levels = option.levels = setDefault(levels, ecModel); + var levelModels = map(levels || [], function (levelDefine) { + return new Model(levelDefine, designatedVisualModel, ecModel); + }, this); + // Make sure always a new tree is created when setOption, + // in TreemapView, we check whether oldTree === newTree + // to choose mappings approach among old shapes and new shapes. + var tree = Tree.createTree(root, this, beforeLink); + function beforeLink(nodeData) { + nodeData.wrapMethod('getItemModel', function (model, idx) { + var node = tree.getNodeByDataIndex(idx); + var levelModel = node ? levelModels[node.depth] : null; + // If no levelModel, we also need `designatedVisualModel`. + model.parentModel = levelModel || designatedVisualModel; + return model; + }); + } + return tree.data; + }; + TreemapSeriesModel.prototype.optionUpdated = function () { + this.resetViewRoot(); + }; + /** + * @override + * @param {number} dataIndex + * @param {boolean} [mutipleSeries=false] + */ + TreemapSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + var data = this.getData(); + var value = this.getRawValue(dataIndex); + var name = data.getName(dataIndex); + return createTooltipMarkup('nameValue', { + name: name, + value: value + }); + }; + /** + * Add tree path to tooltip param + * + * @override + * @param {number} dataIndex + * @return {Object} + */ + TreemapSeriesModel.prototype.getDataParams = function (dataIndex) { + var params = _super.prototype.getDataParams.apply(this, arguments); + var node = this.getData().tree.getNodeByDataIndex(dataIndex); + params.treeAncestors = wrapTreePathInfo(node, this); + // compatitable the previous code. + params.treePathInfo = params.treeAncestors; + return params; + }; + /** + * @public + * @param {Object} layoutInfo { + * x: containerGroup x + * y: containerGroup y + * width: containerGroup width + * height: containerGroup height + * } + */ + TreemapSeriesModel.prototype.setLayoutInfo = function (layoutInfo) { + /** + * @readOnly + * @type {Object} + */ + this.layoutInfo = this.layoutInfo || {}; + extend(this.layoutInfo, layoutInfo); + }; + /** + * @param {string} id + * @return {number} index + */ + TreemapSeriesModel.prototype.mapIdToIndex = function (id) { + // A feature is implemented: + // index is monotone increasing with the sequence of + // input id at the first time. + // This feature can make sure that each data item and its + // mapped color have the same index between data list and + // color list at the beginning, which is useful for user + // to adjust data-color mapping. + /** + * @private + * @type {Object} + */ + var idIndexMap = this._idIndexMap; + if (!idIndexMap) { + idIndexMap = this._idIndexMap = createHashMap(); + /** + * @private + * @type {number} + */ + this._idIndexMapCount = 0; + } + var index = idIndexMap.get(id); + if (index == null) { + idIndexMap.set(id, index = this._idIndexMapCount++); + } + return index; + }; + TreemapSeriesModel.prototype.getViewRoot = function () { + return this._viewRoot; + }; + TreemapSeriesModel.prototype.resetViewRoot = function (viewRoot) { + viewRoot ? this._viewRoot = viewRoot : viewRoot = this._viewRoot; + var root = this.getRawData().tree.root; + if (!viewRoot || viewRoot !== root && !root.contains(viewRoot)) { + this._viewRoot = root; + } + }; + TreemapSeriesModel.prototype.enableAriaDecal = function () { + enableAriaDecalForTree(this); + }; + TreemapSeriesModel.type = 'series.treemap'; + TreemapSeriesModel.layoutMode = 'box'; + TreemapSeriesModel.defaultOption = { + // Disable progressive rendering + progressive: 0, + // size: ['80%', '80%'], // deprecated, compatible with ec2. + left: 'center', + top: 'middle', + width: '80%', + height: '80%', + sort: true, + clipWindow: 'origin', + squareRatio: 0.5 * (1 + Math.sqrt(5)), + leafDepth: null, + drillDownIcon: '▶', + // to align specialized icon. ▷▶❒❐▼✚ + zoomToNodeRatio: 0.32 * 0.32, + roam: true, + nodeClick: 'zoomToNode', + animation: true, + animationDurationUpdate: 900, + animationEasing: 'quinticInOut', + breadcrumb: { + show: true, + height: 22, + left: 'center', + top: 'bottom', + // right + // bottom + emptyItemWidth: 25, + itemStyle: { + color: 'rgba(0,0,0,0.7)', + textStyle: { + color: '#fff' + } + }, + emphasis: { + itemStyle: { + color: 'rgba(0,0,0,0.9)' // '#5793f3', + } + } + }, + + label: { + show: true, + // Do not use textDistance, for ellipsis rect just the same as treemap node rect. + distance: 0, + padding: 5, + position: 'inside', + // formatter: null, + color: '#fff', + overflow: 'truncate' + // align + // verticalAlign + }, + + upperLabel: { + show: false, + position: [0, '50%'], + height: 20, + // formatter: null, + // color: '#fff', + overflow: 'truncate', + // align: null, + verticalAlign: 'middle' + }, + itemStyle: { + color: null, + colorAlpha: null, + colorSaturation: null, + borderWidth: 0, + gapWidth: 0, + borderColor: '#fff', + borderColorSaturation: null // If specified, borderColor will be ineffective, and the + // border color is evaluated by color of current node and + // borderColorSaturation. + }, + + emphasis: { + upperLabel: { + show: true, + position: [0, '50%'], + overflow: 'truncate', + verticalAlign: 'middle' + } + }, + visualDimension: 0, + visualMin: null, + visualMax: null, + color: [], + // level[n].color (if necessary). + // + Specify color list of each level. level[0].color would be global + // color list if not specified. (see method `setDefault`). + // + But set as a empty array to forbid fetch color from global palette + // when using nodeModel.get('color'), otherwise nodes on deep level + // will always has color palette set and are not able to inherit color + // from parent node. + // + TreemapSeries.color can not be set as 'none', otherwise effect + // legend color fetching (see seriesColor.js). + colorAlpha: null, + colorSaturation: null, + colorMappingBy: 'index', + visibleMin: 10, + // be rendered. Only works when sort is 'asc' or 'desc'. + childrenVisibleMin: null, + // grandchildren will not show. + // Why grandchildren? If not grandchildren but children, + // some siblings show children and some not, + // the appearance may be mess and not consistent, + levels: [] // Each item: { + // visibleMin, itemStyle, visualDimension, label + // } + }; + + return TreemapSeriesModel; + }(SeriesModel); + /** + * @param {Object} dataNode + */ + function completeTreeValue(dataNode) { + // Postorder travel tree. + // If value of none-leaf node is not set, + // calculate it by suming up the value of all children. + var sum = 0; + each(dataNode.children, function (child) { + completeTreeValue(child); + var childValue = child.value; + isArray(childValue) && (childValue = childValue[0]); + sum += childValue; + }); + var thisValue = dataNode.value; + if (isArray(thisValue)) { + thisValue = thisValue[0]; + } + if (thisValue == null || isNaN(thisValue)) { + thisValue = sum; + } + // Value should not less than 0. + if (thisValue < 0) { + thisValue = 0; + } + isArray(dataNode.value) ? dataNode.value[0] = thisValue : dataNode.value = thisValue; + } + /** + * set default to level configuration + */ + function setDefault(levels, ecModel) { + var globalColorList = normalizeToArray(ecModel.get('color')); + var globalDecalList = normalizeToArray(ecModel.get(['aria', 'decal', 'decals'])); + if (!globalColorList) { + return; + } + levels = levels || []; + var hasColorDefine; + var hasDecalDefine; + each(levels, function (levelDefine) { + var model = new Model(levelDefine); + var modelColor = model.get('color'); + var modelDecal = model.get('decal'); + if (model.get(['itemStyle', 'color']) || modelColor && modelColor !== 'none') { + hasColorDefine = true; + } + if (model.get(['itemStyle', 'decal']) || modelDecal && modelDecal !== 'none') { + hasDecalDefine = true; + } + }); + var level0 = levels[0] || (levels[0] = {}); + if (!hasColorDefine) { + level0.color = globalColorList.slice(); + } + if (!hasDecalDefine && globalDecalList) { + level0.decal = globalDecalList.slice(); + } + return levels; + } + + var TEXT_PADDING = 8; + var ITEM_GAP = 8; + var ARRAY_LENGTH = 5; + var Breadcrumb = /** @class */function () { + function Breadcrumb(containerGroup) { + this.group = new Group(); + containerGroup.add(this.group); + } + Breadcrumb.prototype.render = function (seriesModel, api, targetNode, onSelect) { + var model = seriesModel.getModel('breadcrumb'); + var thisGroup = this.group; + thisGroup.removeAll(); + if (!model.get('show') || !targetNode) { + return; + } + var normalStyleModel = model.getModel('itemStyle'); + var emphasisModel = model.getModel('emphasis'); + var textStyleModel = normalStyleModel.getModel('textStyle'); + var emphasisTextStyleModel = emphasisModel.getModel(['itemStyle', 'textStyle']); + var layoutParam = { + pos: { + left: model.get('left'), + right: model.get('right'), + top: model.get('top'), + bottom: model.get('bottom') + }, + box: { + width: api.getWidth(), + height: api.getHeight() + }, + emptyItemWidth: model.get('emptyItemWidth'), + totalWidth: 0, + renderList: [] + }; + this._prepare(targetNode, layoutParam, textStyleModel); + this._renderContent(seriesModel, layoutParam, normalStyleModel, emphasisModel, textStyleModel, emphasisTextStyleModel, onSelect); + positionElement(thisGroup, layoutParam.pos, layoutParam.box); + }; + /** + * Prepare render list and total width + * @private + */ + Breadcrumb.prototype._prepare = function (targetNode, layoutParam, textStyleModel) { + for (var node = targetNode; node; node = node.parentNode) { + var text = convertOptionIdName(node.getModel().get('name'), ''); + var textRect = textStyleModel.getTextRect(text); + var itemWidth = Math.max(textRect.width + TEXT_PADDING * 2, layoutParam.emptyItemWidth); + layoutParam.totalWidth += itemWidth + ITEM_GAP; + layoutParam.renderList.push({ + node: node, + text: text, + width: itemWidth + }); + } + }; + /** + * @private + */ + Breadcrumb.prototype._renderContent = function (seriesModel, layoutParam, normalStyleModel, emphasisModel, textStyleModel, emphasisTextStyleModel, onSelect) { + // Start rendering. + var lastX = 0; + var emptyItemWidth = layoutParam.emptyItemWidth; + var height = seriesModel.get(['breadcrumb', 'height']); + var availableSize = getAvailableSize(layoutParam.pos, layoutParam.box); + var totalWidth = layoutParam.totalWidth; + var renderList = layoutParam.renderList; + var emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle(); + for (var i = renderList.length - 1; i >= 0; i--) { + var item = renderList[i]; + var itemNode = item.node; + var itemWidth = item.width; + var text = item.text; + // Hdie text and shorten width if necessary. + if (totalWidth > availableSize.width) { + totalWidth -= itemWidth - emptyItemWidth; + itemWidth = emptyItemWidth; + text = null; + } + var el = new Polygon({ + shape: { + points: makeItemPoints(lastX, 0, itemWidth, height, i === renderList.length - 1, i === 0) + }, + style: defaults(normalStyleModel.getItemStyle(), { + lineJoin: 'bevel' + }), + textContent: new ZRText({ + style: createTextStyle(textStyleModel, { + text: text + }) + }), + textConfig: { + position: 'inside' + }, + z2: Z2_EMPHASIS_LIFT * 1e4, + onclick: curry(onSelect, itemNode) + }); + el.disableLabelAnimation = true; + el.getTextContent().ensureState('emphasis').style = createTextStyle(emphasisTextStyleModel, { + text: text + }); + el.ensureState('emphasis').style = emphasisItemStyle; + toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + this.group.add(el); + packEventData(el, seriesModel, itemNode); + lastX += itemWidth + ITEM_GAP; + } + }; + Breadcrumb.prototype.remove = function () { + this.group.removeAll(); + }; + return Breadcrumb; + }(); + function makeItemPoints(x, y, itemWidth, itemHeight, head, tail) { + var points = [[head ? x : x - ARRAY_LENGTH, y], [x + itemWidth, y], [x + itemWidth, y + itemHeight], [head ? x : x - ARRAY_LENGTH, y + itemHeight]]; + !tail && points.splice(2, 0, [x + itemWidth + ARRAY_LENGTH, y + itemHeight / 2]); + !head && points.push([x, y + itemHeight / 2]); + return points; + } + // Package custom mouse event. + function packEventData(el, seriesModel, itemNode) { + getECData(el).eventData = { + componentType: 'series', + componentSubType: 'treemap', + componentIndex: seriesModel.componentIndex, + seriesIndex: seriesModel.seriesIndex, + seriesName: seriesModel.name, + seriesType: 'treemap', + selfType: 'breadcrumb', + nodeData: { + dataIndex: itemNode && itemNode.dataIndex, + name: itemNode && itemNode.name + }, + treePathInfo: itemNode && wrapTreePathInfo(itemNode, seriesModel) + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /** + * Animate multiple elements with a single done-callback. + * + * @example + * animation + * .createWrap() + * .add(el1, {x: 10, y: 10}) + * .add(el2, {shape: {width: 500}, style: {fill: 'red'}}, 400) + * .done(function () { // done }) + * .start('cubicOut'); + */ + var AnimationWrap = /** @class */function () { + function AnimationWrap() { + this._storage = []; + this._elExistsMap = {}; + } + /** + * Caution: a el can only be added once, otherwise 'done' + * might not be called. This method checks this (by el.id), + * suppresses adding and returns false when existing el found. + * + * @return Whether adding succeeded. + */ + AnimationWrap.prototype.add = function (el, target, duration, delay, easing) { + if (this._elExistsMap[el.id]) { + return false; + } + this._elExistsMap[el.id] = true; + this._storage.push({ + el: el, + target: target, + duration: duration, + delay: delay, + easing: easing + }); + return true; + }; + /** + * Only execute when animation done/aborted. + */ + AnimationWrap.prototype.finished = function (callback) { + this._finishedCallback = callback; + return this; + }; + /** + * Will stop exist animation firstly. + */ + AnimationWrap.prototype.start = function () { + var _this = this; + var count = this._storage.length; + var checkTerminate = function () { + count--; + if (count <= 0) { + // Guard. + _this._storage.length = 0; + _this._elExistsMap = {}; + _this._finishedCallback && _this._finishedCallback(); + } + }; + for (var i = 0, len = this._storage.length; i < len; i++) { + var item = this._storage[i]; + item.el.animateTo(item.target, { + duration: item.duration, + delay: item.delay, + easing: item.easing, + setToFinal: true, + done: checkTerminate, + aborted: checkTerminate + }); + } + return this; + }; + return AnimationWrap; + }(); + function createWrap() { + return new AnimationWrap(); + } + + var Group$1 = Group; + var Rect$1 = Rect; + var DRAG_THRESHOLD = 3; + var PATH_LABEL_NOAMAL = 'label'; + var PATH_UPPERLABEL_NORMAL = 'upperLabel'; + // Should larger than emphasis states lift z + var Z2_BASE = Z2_EMPHASIS_LIFT * 10; // Should bigger than every z2. + var Z2_BG = Z2_EMPHASIS_LIFT * 2; + var Z2_CONTENT = Z2_EMPHASIS_LIFT * 3; + var getStateItemStyle = makeStyleMapper([['fill', 'color'], + // `borderColor` and `borderWidth` has been occupied, + // so use `stroke` to indicate the stroke of the rect. + ['stroke', 'strokeColor'], ['lineWidth', 'strokeWidth'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'] + // Option decal is in `DecalObject` but style.decal is in `PatternObject`. + // So do not transfer decal directly. + ]); + + var getItemStyleNormal = function (model) { + // Normal style props should include emphasis style props. + var itemStyle = getStateItemStyle(model); + // Clear styles set by emphasis. + itemStyle.stroke = itemStyle.fill = itemStyle.lineWidth = null; + return itemStyle; + }; + var inner$8 = makeInner(); + var TreemapView = /** @class */function (_super) { + __extends(TreemapView, _super); + function TreemapView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TreemapView.type; + _this._state = 'ready'; + _this._storage = createStorage(); + return _this; + } + /** + * @override + */ + TreemapView.prototype.render = function (seriesModel, ecModel, api, payload) { + var models = ecModel.findComponents({ + mainType: 'series', + subType: 'treemap', + query: payload + }); + if (indexOf(models, seriesModel) < 0) { + return; + } + this.seriesModel = seriesModel; + this.api = api; + this.ecModel = ecModel; + var types = ['treemapZoomToNode', 'treemapRootToNode']; + var targetInfo = retrieveTargetInfo(payload, types, seriesModel); + var payloadType = payload && payload.type; + var layoutInfo = seriesModel.layoutInfo; + var isInit = !this._oldTree; + var thisStorage = this._storage; + // Mark new root when action is treemapRootToNode. + var reRoot = payloadType === 'treemapRootToNode' && targetInfo && thisStorage ? { + rootNodeGroup: thisStorage.nodeGroup[targetInfo.node.getRawIndex()], + direction: payload.direction + } : null; + var containerGroup = this._giveContainerGroup(layoutInfo); + var hasAnimation = seriesModel.get('animation'); + var renderResult = this._doRender(containerGroup, seriesModel, reRoot); + hasAnimation && !isInit && (!payloadType || payloadType === 'treemapZoomToNode' || payloadType === 'treemapRootToNode') ? this._doAnimation(containerGroup, renderResult, seriesModel, reRoot) : renderResult.renderFinally(); + this._resetController(api); + this._renderBreadcrumb(seriesModel, api, targetInfo); + }; + TreemapView.prototype._giveContainerGroup = function (layoutInfo) { + var containerGroup = this._containerGroup; + if (!containerGroup) { + // FIXME + // 加一层containerGroup是为了clip,但是现在clip功能并没有实现。 + containerGroup = this._containerGroup = new Group$1(); + this._initEvents(containerGroup); + this.group.add(containerGroup); + } + containerGroup.x = layoutInfo.x; + containerGroup.y = layoutInfo.y; + return containerGroup; + }; + TreemapView.prototype._doRender = function (containerGroup, seriesModel, reRoot) { + var thisTree = seriesModel.getData().tree; + var oldTree = this._oldTree; + // Clear last shape records. + var lastsForAnimation = createStorage(); + var thisStorage = createStorage(); + var oldStorage = this._storage; + var willInvisibleEls = []; + function doRenderNode(thisNode, oldNode, parentGroup, depth) { + return renderNode(seriesModel, thisStorage, oldStorage, reRoot, lastsForAnimation, willInvisibleEls, thisNode, oldNode, parentGroup, depth); + } + // Notice: When thisTree and oldTree are the same tree (see list.cloneShallow), + // the oldTree is actually losted, so we cannot find all of the old graphic + // elements from tree. So we use this strategy: make element storage, move + // from old storage to new storage, clear old storage. + dualTravel(thisTree.root ? [thisTree.root] : [], oldTree && oldTree.root ? [oldTree.root] : [], containerGroup, thisTree === oldTree || !oldTree, 0); + // Process all removing. + var willDeleteEls = clearStorage(oldStorage); + this._oldTree = thisTree; + this._storage = thisStorage; + return { + lastsForAnimation: lastsForAnimation, + willDeleteEls: willDeleteEls, + renderFinally: renderFinally + }; + function dualTravel(thisViewChildren, oldViewChildren, parentGroup, sameTree, depth) { + // When 'render' is triggered by action, + // 'this' and 'old' may be the same tree, + // we use rawIndex in that case. + if (sameTree) { + oldViewChildren = thisViewChildren; + each(thisViewChildren, function (child, index) { + !child.isRemoved() && processNode(index, index); + }); + } + // Diff hierarchically (diff only in each subtree, but not whole). + // because, consistency of view is important. + else { + new DataDiffer(oldViewChildren, thisViewChildren, getKey, getKey).add(processNode).update(processNode).remove(curry(processNode, null)).execute(); + } + function getKey(node) { + // Identify by name or raw index. + return node.getId(); + } + function processNode(newIndex, oldIndex) { + var thisNode = newIndex != null ? thisViewChildren[newIndex] : null; + var oldNode = oldIndex != null ? oldViewChildren[oldIndex] : null; + var group = doRenderNode(thisNode, oldNode, parentGroup, depth); + group && dualTravel(thisNode && thisNode.viewChildren || [], oldNode && oldNode.viewChildren || [], group, sameTree, depth + 1); + } + } + function clearStorage(storage) { + var willDeleteEls = createStorage(); + storage && each(storage, function (store, storageName) { + var delEls = willDeleteEls[storageName]; + each(store, function (el) { + el && (delEls.push(el), inner$8(el).willDelete = true); + }); + }); + return willDeleteEls; + } + function renderFinally() { + each(willDeleteEls, function (els) { + each(els, function (el) { + el.parent && el.parent.remove(el); + }); + }); + each(willInvisibleEls, function (el) { + el.invisible = true; + // Setting invisible is for optimizing, so no need to set dirty, + // just mark as invisible. + el.dirty(); + }); + } + }; + TreemapView.prototype._doAnimation = function (containerGroup, renderResult, seriesModel, reRoot) { + var durationOption = seriesModel.get('animationDurationUpdate'); + var easingOption = seriesModel.get('animationEasing'); + // TODO: do not support function until necessary. + var duration = (isFunction(durationOption) ? 0 : durationOption) || 0; + var easing = (isFunction(easingOption) ? null : easingOption) || 'cubicOut'; + var animationWrap = createWrap(); + // Make delete animations. + each(renderResult.willDeleteEls, function (store, storageName) { + each(store, function (el, rawIndex) { + if (el.invisible) { + return; + } + var parent = el.parent; // Always has parent, and parent is nodeGroup. + var target; + var innerStore = inner$8(parent); + if (reRoot && reRoot.direction === 'drillDown') { + target = parent === reRoot.rootNodeGroup + // This is the content element of view root. + // Only `content` will enter this branch, because + // `background` and `nodeGroup` will not be deleted. + ? { + shape: { + x: 0, + y: 0, + width: innerStore.nodeWidth, + height: innerStore.nodeHeight + }, + style: { + opacity: 0 + } + } + // Others. + : { + style: { + opacity: 0 + } + }; + } else { + var targetX = 0; + var targetY = 0; + if (!innerStore.willDelete) { + // Let node animate to right-bottom corner, cooperating with fadeout, + // which is appropriate for user understanding. + // Divided by 2 for reRoot rolling up effect. + targetX = innerStore.nodeWidth / 2; + targetY = innerStore.nodeHeight / 2; + } + target = storageName === 'nodeGroup' ? { + x: targetX, + y: targetY, + style: { + opacity: 0 + } + } : { + shape: { + x: targetX, + y: targetY, + width: 0, + height: 0 + }, + style: { + opacity: 0 + } + }; + } + // TODO: do not support delay until necessary. + target && animationWrap.add(el, target, duration, 0, easing); + }); + }); + // Make other animations + each(this._storage, function (store, storageName) { + each(store, function (el, rawIndex) { + var last = renderResult.lastsForAnimation[storageName][rawIndex]; + var target = {}; + if (!last) { + return; + } + if (el instanceof Group) { + if (last.oldX != null) { + target.x = el.x; + target.y = el.y; + el.x = last.oldX; + el.y = last.oldY; + } + } else { + if (last.oldShape) { + target.shape = extend({}, el.shape); + el.setShape(last.oldShape); + } + if (last.fadein) { + el.setStyle('opacity', 0); + target.style = { + opacity: 1 + }; + } + // When animation is stopped for succedent animation starting, + // el.style.opacity might not be 1 + else if (el.style.opacity !== 1) { + target.style = { + opacity: 1 + }; + } + } + animationWrap.add(el, target, duration, 0, easing); + }); + }, this); + this._state = 'animating'; + animationWrap.finished(bind(function () { + this._state = 'ready'; + renderResult.renderFinally(); + }, this)).start(); + }; + TreemapView.prototype._resetController = function (api) { + var controller = this._controller; + // Init controller. + if (!controller) { + controller = this._controller = new RoamController(api.getZr()); + controller.enable(this.seriesModel.get('roam')); + controller.on('pan', bind(this._onPan, this)); + controller.on('zoom', bind(this._onZoom, this)); + } + var rect = new BoundingRect(0, 0, api.getWidth(), api.getHeight()); + controller.setPointerChecker(function (e, x, y) { + return rect.contain(x, y); + }); + }; + TreemapView.prototype._clearController = function () { + var controller = this._controller; + if (controller) { + controller.dispose(); + controller = null; + } + }; + TreemapView.prototype._onPan = function (e) { + if (this._state !== 'animating' && (Math.abs(e.dx) > DRAG_THRESHOLD || Math.abs(e.dy) > DRAG_THRESHOLD)) { + // These param must not be cached. + var root = this.seriesModel.getData().tree.root; + if (!root) { + return; + } + var rootLayout = root.getLayout(); + if (!rootLayout) { + return; + } + this.api.dispatchAction({ + type: 'treemapMove', + from: this.uid, + seriesId: this.seriesModel.id, + rootRect: { + x: rootLayout.x + e.dx, + y: rootLayout.y + e.dy, + width: rootLayout.width, + height: rootLayout.height + } + }); + } + }; + TreemapView.prototype._onZoom = function (e) { + var mouseX = e.originX; + var mouseY = e.originY; + if (this._state !== 'animating') { + // These param must not be cached. + var root = this.seriesModel.getData().tree.root; + if (!root) { + return; + } + var rootLayout = root.getLayout(); + if (!rootLayout) { + return; + } + var rect = new BoundingRect(rootLayout.x, rootLayout.y, rootLayout.width, rootLayout.height); + var layoutInfo = this.seriesModel.layoutInfo; + // Transform mouse coord from global to containerGroup. + mouseX -= layoutInfo.x; + mouseY -= layoutInfo.y; + // Scale root bounding rect. + var m = create$1(); + translate(m, m, [-mouseX, -mouseY]); + scale$1(m, m, [e.scale, e.scale]); + translate(m, m, [mouseX, mouseY]); + rect.applyTransform(m); + this.api.dispatchAction({ + type: 'treemapRender', + from: this.uid, + seriesId: this.seriesModel.id, + rootRect: { + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + } + }); + } + }; + TreemapView.prototype._initEvents = function (containerGroup) { + var _this = this; + containerGroup.on('click', function (e) { + if (_this._state !== 'ready') { + return; + } + var nodeClick = _this.seriesModel.get('nodeClick', true); + if (!nodeClick) { + return; + } + var targetInfo = _this.findTarget(e.offsetX, e.offsetY); + if (!targetInfo) { + return; + } + var node = targetInfo.node; + if (node.getLayout().isLeafRoot) { + _this._rootToNode(targetInfo); + } else { + if (nodeClick === 'zoomToNode') { + _this._zoomToNode(targetInfo); + } else if (nodeClick === 'link') { + var itemModel = node.hostTree.data.getItemModel(node.dataIndex); + var link = itemModel.get('link', true); + var linkTarget = itemModel.get('target', true) || 'blank'; + link && windowOpen(link, linkTarget); + } + } + }, this); + }; + TreemapView.prototype._renderBreadcrumb = function (seriesModel, api, targetInfo) { + var _this = this; + if (!targetInfo) { + targetInfo = seriesModel.get('leafDepth', true) != null ? { + node: seriesModel.getViewRoot() + } + // FIXME + // better way? + // Find breadcrumb tail on center of containerGroup. + : this.findTarget(api.getWidth() / 2, api.getHeight() / 2); + if (!targetInfo) { + targetInfo = { + node: seriesModel.getData().tree.root + }; + } + } + (this._breadcrumb || (this._breadcrumb = new Breadcrumb(this.group))).render(seriesModel, api, targetInfo.node, function (node) { + if (_this._state !== 'animating') { + aboveViewRoot(seriesModel.getViewRoot(), node) ? _this._rootToNode({ + node: node + }) : _this._zoomToNode({ + node: node + }); + } + }); + }; + /** + * @override + */ + TreemapView.prototype.remove = function () { + this._clearController(); + this._containerGroup && this._containerGroup.removeAll(); + this._storage = createStorage(); + this._state = 'ready'; + this._breadcrumb && this._breadcrumb.remove(); + }; + TreemapView.prototype.dispose = function () { + this._clearController(); + }; + TreemapView.prototype._zoomToNode = function (targetInfo) { + this.api.dispatchAction({ + type: 'treemapZoomToNode', + from: this.uid, + seriesId: this.seriesModel.id, + targetNode: targetInfo.node + }); + }; + TreemapView.prototype._rootToNode = function (targetInfo) { + this.api.dispatchAction({ + type: 'treemapRootToNode', + from: this.uid, + seriesId: this.seriesModel.id, + targetNode: targetInfo.node + }); + }; + /** + * @public + * @param {number} x Global coord x. + * @param {number} y Global coord y. + * @return {Object} info If not found, return undefined; + * @return {number} info.node Target node. + * @return {number} info.offsetX x refer to target node. + * @return {number} info.offsetY y refer to target node. + */ + TreemapView.prototype.findTarget = function (x, y) { + var targetInfo; + var viewRoot = this.seriesModel.getViewRoot(); + viewRoot.eachNode({ + attr: 'viewChildren', + order: 'preorder' + }, function (node) { + var bgEl = this._storage.background[node.getRawIndex()]; + // If invisible, there might be no element. + if (bgEl) { + var point = bgEl.transformCoordToLocal(x, y); + var shape = bgEl.shape; + // For performance consideration, don't use 'getBoundingRect'. + if (shape.x <= point[0] && point[0] <= shape.x + shape.width && shape.y <= point[1] && point[1] <= shape.y + shape.height) { + targetInfo = { + node: node, + offsetX: point[0], + offsetY: point[1] + }; + } else { + return false; // Suppress visit subtree. + } + } + }, this); + return targetInfo; + }; + TreemapView.type = 'treemap'; + return TreemapView; + }(ChartView); + /** + * @inner + */ + function createStorage() { + return { + nodeGroup: [], + background: [], + content: [] + }; + } + /** + * @inner + * @return Return undefined means do not travel further. + */ + function renderNode(seriesModel, thisStorage, oldStorage, reRoot, lastsForAnimation, willInvisibleEls, thisNode, oldNode, parentGroup, depth) { + // Whether under viewRoot. + if (!thisNode) { + // Deleting nodes will be performed finally. This method just find + // element from old storage, or create new element, set them to new + // storage, and set styles. + return; + } + // ------------------------------------------------------------------- + // Start of closure variables available in "Procedures in renderNode". + var thisLayout = thisNode.getLayout(); + var data = seriesModel.getData(); + var nodeModel = thisNode.getModel(); + // Only for enabling highlight/downplay. Clear firstly. + // Because some node will not be rendered. + data.setItemGraphicEl(thisNode.dataIndex, null); + if (!thisLayout || !thisLayout.isInView) { + return; + } + var thisWidth = thisLayout.width; + var thisHeight = thisLayout.height; + var borderWidth = thisLayout.borderWidth; + var thisInvisible = thisLayout.invisible; + var thisRawIndex = thisNode.getRawIndex(); + var oldRawIndex = oldNode && oldNode.getRawIndex(); + var thisViewChildren = thisNode.viewChildren; + var upperHeight = thisLayout.upperHeight; + var isParent = thisViewChildren && thisViewChildren.length; + var itemStyleNormalModel = nodeModel.getModel('itemStyle'); + var itemStyleEmphasisModel = nodeModel.getModel(['emphasis', 'itemStyle']); + var itemStyleBlurModel = nodeModel.getModel(['blur', 'itemStyle']); + var itemStyleSelectModel = nodeModel.getModel(['select', 'itemStyle']); + var borderRadius = itemStyleNormalModel.get('borderRadius') || 0; + // End of closure ariables available in "Procedures in renderNode". + // ----------------------------------------------------------------- + // Node group + var group = giveGraphic('nodeGroup', Group$1); + if (!group) { + return; + } + parentGroup.add(group); + // x,y are not set when el is above view root. + group.x = thisLayout.x || 0; + group.y = thisLayout.y || 0; + group.markRedraw(); + inner$8(group).nodeWidth = thisWidth; + inner$8(group).nodeHeight = thisHeight; + if (thisLayout.isAboveViewRoot) { + return group; + } + // Background + var bg = giveGraphic('background', Rect$1, depth, Z2_BG); + bg && renderBackground(group, bg, isParent && thisLayout.upperLabelHeight); + var emphasisModel = nodeModel.getModel('emphasis'); + var focus = emphasisModel.get('focus'); + var blurScope = emphasisModel.get('blurScope'); + var isDisabled = emphasisModel.get('disabled'); + var focusOrIndices = focus === 'ancestor' ? thisNode.getAncestorsIndices() : focus === 'descendant' ? thisNode.getDescendantIndices() : focus; + // No children, render content. + if (isParent) { + // Because of the implementation about "traverse" in graphic hover style, we + // can not set hover listener on the "group" of non-leaf node. Otherwise the + // hover event from the descendents will be listenered. + if (isHighDownDispatcher(group)) { + setAsHighDownDispatcher(group, false); + } + if (bg) { + setAsHighDownDispatcher(bg, !isDisabled); + // Only for enabling highlight/downplay. + data.setItemGraphicEl(thisNode.dataIndex, bg); + enableHoverFocus(bg, focusOrIndices, blurScope); + } + } else { + var content = giveGraphic('content', Rect$1, depth, Z2_CONTENT); + content && renderContent(group, content); + bg.disableMorphing = true; + if (bg && isHighDownDispatcher(bg)) { + setAsHighDownDispatcher(bg, false); + } + setAsHighDownDispatcher(group, !isDisabled); + // Only for enabling highlight/downplay. + data.setItemGraphicEl(thisNode.dataIndex, group); + enableHoverFocus(group, focusOrIndices, blurScope); + } + return group; + // ---------------------------- + // | Procedures in renderNode | + // ---------------------------- + function renderBackground(group, bg, useUpperLabel) { + var ecData = getECData(bg); + // For tooltip. + ecData.dataIndex = thisNode.dataIndex; + ecData.seriesIndex = seriesModel.seriesIndex; + bg.setShape({ + x: 0, + y: 0, + width: thisWidth, + height: thisHeight, + r: borderRadius + }); + if (thisInvisible) { + // If invisible, do not set visual, otherwise the element will + // change immediately before animation. We think it is OK to + // remain its origin color when moving out of the view window. + processInvisible(bg); + } else { + bg.invisible = false; + var style = thisNode.getVisual('style'); + var visualBorderColor = style.stroke; + var normalStyle = getItemStyleNormal(itemStyleNormalModel); + normalStyle.fill = visualBorderColor; + var emphasisStyle = getStateItemStyle(itemStyleEmphasisModel); + emphasisStyle.fill = itemStyleEmphasisModel.get('borderColor'); + var blurStyle = getStateItemStyle(itemStyleBlurModel); + blurStyle.fill = itemStyleBlurModel.get('borderColor'); + var selectStyle = getStateItemStyle(itemStyleSelectModel); + selectStyle.fill = itemStyleSelectModel.get('borderColor'); + if (useUpperLabel) { + var upperLabelWidth = thisWidth - 2 * borderWidth; + prepareText( + // PENDING: convert ZRColor to ColorString for text. + bg, visualBorderColor, style.opacity, { + x: borderWidth, + y: 0, + width: upperLabelWidth, + height: upperHeight + }); + } + // For old bg. + else { + bg.removeTextContent(); + } + bg.setStyle(normalStyle); + bg.ensureState('emphasis').style = emphasisStyle; + bg.ensureState('blur').style = blurStyle; + bg.ensureState('select').style = selectStyle; + setDefaultStateProxy(bg); + } + group.add(bg); + } + function renderContent(group, content) { + var ecData = getECData(content); + // For tooltip. + ecData.dataIndex = thisNode.dataIndex; + ecData.seriesIndex = seriesModel.seriesIndex; + var contentWidth = Math.max(thisWidth - 2 * borderWidth, 0); + var contentHeight = Math.max(thisHeight - 2 * borderWidth, 0); + content.culling = true; + content.setShape({ + x: borderWidth, + y: borderWidth, + width: contentWidth, + height: contentHeight, + r: borderRadius + }); + if (thisInvisible) { + // If invisible, do not set visual, otherwise the element will + // change immediately before animation. We think it is OK to + // remain its origin color when moving out of the view window. + processInvisible(content); + } else { + content.invisible = false; + var nodeStyle = thisNode.getVisual('style'); + var visualColor = nodeStyle.fill; + var normalStyle = getItemStyleNormal(itemStyleNormalModel); + normalStyle.fill = visualColor; + normalStyle.decal = nodeStyle.decal; + var emphasisStyle = getStateItemStyle(itemStyleEmphasisModel); + var blurStyle = getStateItemStyle(itemStyleBlurModel); + var selectStyle = getStateItemStyle(itemStyleSelectModel); + // PENDING: convert ZRColor to ColorString for text. + prepareText(content, visualColor, nodeStyle.opacity, null); + content.setStyle(normalStyle); + content.ensureState('emphasis').style = emphasisStyle; + content.ensureState('blur').style = blurStyle; + content.ensureState('select').style = selectStyle; + setDefaultStateProxy(content); + } + group.add(content); + } + function processInvisible(element) { + // Delay invisible setting utill animation finished, + // avoid element vanish suddenly before animation. + !element.invisible && willInvisibleEls.push(element); + } + function prepareText(rectEl, visualColor, visualOpacity, + // Can be null/undefined + upperLabelRect) { + var normalLabelModel = nodeModel.getModel(upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL); + var defaultText = convertOptionIdName(nodeModel.get('name'), null); + var isShow = normalLabelModel.getShallow('show'); + setLabelStyle(rectEl, getLabelStatesModels(nodeModel, upperLabelRect ? PATH_UPPERLABEL_NORMAL : PATH_LABEL_NOAMAL), { + defaultText: isShow ? defaultText : null, + inheritColor: visualColor, + defaultOpacity: visualOpacity, + labelFetcher: seriesModel, + labelDataIndex: thisNode.dataIndex + }); + var textEl = rectEl.getTextContent(); + if (!textEl) { + return; + } + var textStyle = textEl.style; + var textPadding = normalizeCssArray(textStyle.padding || 0); + if (upperLabelRect) { + rectEl.setTextConfig({ + layoutRect: upperLabelRect + }); + textEl.disableLabelLayout = true; + } + textEl.beforeUpdate = function () { + var width = Math.max((upperLabelRect ? upperLabelRect.width : rectEl.shape.width) - textPadding[1] - textPadding[3], 0); + var height = Math.max((upperLabelRect ? upperLabelRect.height : rectEl.shape.height) - textPadding[0] - textPadding[2], 0); + if (textStyle.width !== width || textStyle.height !== height) { + textEl.setStyle({ + width: width, + height: height + }); + } + }; + textStyle.truncateMinChar = 2; + textStyle.lineOverflow = 'truncate'; + addDrillDownIcon(textStyle, upperLabelRect, thisLayout); + var textEmphasisState = textEl.getState('emphasis'); + addDrillDownIcon(textEmphasisState ? textEmphasisState.style : null, upperLabelRect, thisLayout); + } + function addDrillDownIcon(style, upperLabelRect, thisLayout) { + var text = style ? style.text : null; + if (!upperLabelRect && thisLayout.isLeafRoot && text != null) { + var iconChar = seriesModel.get('drillDownIcon', true); + style.text = iconChar ? iconChar + ' ' + text : text; + } + } + function giveGraphic(storageName, Ctor, depth, z) { + var element = oldRawIndex != null && oldStorage[storageName][oldRawIndex]; + var lasts = lastsForAnimation[storageName]; + if (element) { + // Remove from oldStorage + oldStorage[storageName][oldRawIndex] = null; + prepareAnimationWhenHasOld(lasts, element); + } + // If invisible and no old element, do not create new element (for optimizing). + else if (!thisInvisible) { + element = new Ctor(); + if (element instanceof Displayable) { + element.z2 = calculateZ2(depth, z); + } + prepareAnimationWhenNoOld(lasts, element); + } + // Set to thisStorage + return thisStorage[storageName][thisRawIndex] = element; + } + function prepareAnimationWhenHasOld(lasts, element) { + var lastCfg = lasts[thisRawIndex] = {}; + if (element instanceof Group$1) { + lastCfg.oldX = element.x; + lastCfg.oldY = element.y; + } else { + lastCfg.oldShape = extend({}, element.shape); + } + } + // If a element is new, we need to find the animation start point carefully, + // otherwise it will looks strange when 'zoomToNode'. + function prepareAnimationWhenNoOld(lasts, element) { + var lastCfg = lasts[thisRawIndex] = {}; + var parentNode = thisNode.parentNode; + var isGroup = element instanceof Group; + if (parentNode && (!reRoot || reRoot.direction === 'drillDown')) { + var parentOldX = 0; + var parentOldY = 0; + // New nodes appear from right-bottom corner in 'zoomToNode' animation. + // For convenience, get old bounding rect from background. + var parentOldBg = lastsForAnimation.background[parentNode.getRawIndex()]; + if (!reRoot && parentOldBg && parentOldBg.oldShape) { + parentOldX = parentOldBg.oldShape.width; + parentOldY = parentOldBg.oldShape.height; + } + // When no parent old shape found, its parent is new too, + // so we can just use {x:0, y:0}. + if (isGroup) { + lastCfg.oldX = 0; + lastCfg.oldY = parentOldY; + } else { + lastCfg.oldShape = { + x: parentOldX, + y: parentOldY, + width: 0, + height: 0 + }; + } + } + // Fade in, user can be aware that these nodes are new. + lastCfg.fadein = !isGroup; + } + } + // We cannot set all background with the same z, because the behaviour of + // drill down and roll up differ background creation sequence from tree + // hierarchy sequence, which cause lower background elements to overlap + // upper ones. So we calculate z based on depth. + // Moreover, we try to shrink down z interval to [0, 1] to avoid that + // treemap with large z overlaps other components. + function calculateZ2(depth, z2InLevel) { + return depth * Z2_BASE + z2InLevel; + } + + var each$3 = each; + var isObject$3 = isObject; + var CATEGORY_DEFAULT_VISUAL_INDEX = -1; + var VisualMapping = /** @class */function () { + function VisualMapping(option) { + var mappingMethod = option.mappingMethod; + var visualType = option.type; + var thisOption = this.option = clone(option); + this.type = visualType; + this.mappingMethod = mappingMethod; + this._normalizeData = normalizers[mappingMethod]; + var visualHandler = VisualMapping.visualHandlers[visualType]; + this.applyVisual = visualHandler.applyVisual; + this.getColorMapper = visualHandler.getColorMapper; + this._normalizedToVisual = visualHandler._normalizedToVisual[mappingMethod]; + if (mappingMethod === 'piecewise') { + normalizeVisualRange(thisOption); + preprocessForPiecewise(thisOption); + } else if (mappingMethod === 'category') { + thisOption.categories ? preprocessForSpecifiedCategory(thisOption) + // categories is ordinal when thisOption.categories not specified, + // which need no more preprocess except normalize visual. + : normalizeVisualRange(thisOption, true); + } else { + // mappingMethod === 'linear' or 'fixed' + assert(mappingMethod !== 'linear' || thisOption.dataExtent); + normalizeVisualRange(thisOption); + } + } + VisualMapping.prototype.mapValueToVisual = function (value) { + var normalized = this._normalizeData(value); + return this._normalizedToVisual(normalized, value); + }; + VisualMapping.prototype.getNormalizer = function () { + return bind(this._normalizeData, this); + }; + /** + * List available visual types. + * + * @public + * @return {Array.} + */ + VisualMapping.listVisualTypes = function () { + return keys(VisualMapping.visualHandlers); + }; + // /** + // * @public + // */ + // static addVisualHandler(name, handler) { + // visualHandlers[name] = handler; + // } + /** + * @public + */ + VisualMapping.isValidType = function (visualType) { + return VisualMapping.visualHandlers.hasOwnProperty(visualType); + }; + /** + * Convenient method. + * Visual can be Object or Array or primary type. + */ + VisualMapping.eachVisual = function (visual, callback, context) { + if (isObject(visual)) { + each(visual, callback, context); + } else { + callback.call(context, visual); + } + }; + VisualMapping.mapVisual = function (visual, callback, context) { + var isPrimary; + var newVisual = isArray(visual) ? [] : isObject(visual) ? {} : (isPrimary = true, null); + VisualMapping.eachVisual(visual, function (v, key) { + var newVal = callback.call(context, v, key); + isPrimary ? newVisual = newVal : newVisual[key] = newVal; + }); + return newVisual; + }; + /** + * Retrieve visual properties from given object. + */ + VisualMapping.retrieveVisuals = function (obj) { + var ret = {}; + var hasVisual; + obj && each$3(VisualMapping.visualHandlers, function (h, visualType) { + if (obj.hasOwnProperty(visualType)) { + ret[visualType] = obj[visualType]; + hasVisual = true; + } + }); + return hasVisual ? ret : null; + }; + /** + * Give order to visual types, considering colorSaturation, colorAlpha depends on color. + * + * @public + * @param {(Object|Array)} visualTypes If Object, like: {color: ..., colorSaturation: ...} + * IF Array, like: ['color', 'symbol', 'colorSaturation'] + * @return {Array.} Sorted visual types. + */ + VisualMapping.prepareVisualTypes = function (visualTypes) { + if (isArray(visualTypes)) { + visualTypes = visualTypes.slice(); + } else if (isObject$3(visualTypes)) { + var types_1 = []; + each$3(visualTypes, function (item, type) { + types_1.push(type); + }); + visualTypes = types_1; + } else { + return []; + } + visualTypes.sort(function (type1, type2) { + // color should be front of colorSaturation, colorAlpha, ... + // symbol and symbolSize do not matter. + return type2 === 'color' && type1 !== 'color' && type1.indexOf('color') === 0 ? 1 : -1; + }); + return visualTypes; + }; + /** + * 'color', 'colorSaturation', 'colorAlpha', ... are depends on 'color'. + * Other visuals are only depends on themself. + */ + VisualMapping.dependsOn = function (visualType1, visualType2) { + return visualType2 === 'color' ? !!(visualType1 && visualType1.indexOf(visualType2) === 0) : visualType1 === visualType2; + }; + /** + * @param value + * @param pieceList [{value: ..., interval: [min, max]}, ...] + * Always from small to big. + * @param findClosestWhenOutside Default to be false + * @return index + */ + VisualMapping.findPieceIndex = function (value, pieceList, findClosestWhenOutside) { + var possibleI; + var abs = Infinity; + // value has the higher priority. + for (var i = 0, len = pieceList.length; i < len; i++) { + var pieceValue = pieceList[i].value; + if (pieceValue != null) { + if (pieceValue === value + // FIXME + // It is supposed to compare value according to value type of dimension, + // but currently value type can exactly be string or number. + // Compromise for numeric-like string (like '12'), especially + // in the case that visualMap.categories is ['22', '33']. + || isString(pieceValue) && pieceValue === value + '') { + return i; + } + findClosestWhenOutside && updatePossible(pieceValue, i); + } + } + for (var i = 0, len = pieceList.length; i < len; i++) { + var piece = pieceList[i]; + var interval = piece.interval; + var close_1 = piece.close; + if (interval) { + if (interval[0] === -Infinity) { + if (littleThan(close_1[1], value, interval[1])) { + return i; + } + } else if (interval[1] === Infinity) { + if (littleThan(close_1[0], interval[0], value)) { + return i; + } + } else if (littleThan(close_1[0], interval[0], value) && littleThan(close_1[1], value, interval[1])) { + return i; + } + findClosestWhenOutside && updatePossible(interval[0], i); + findClosestWhenOutside && updatePossible(interval[1], i); + } + } + if (findClosestWhenOutside) { + return value === Infinity ? pieceList.length - 1 : value === -Infinity ? 0 : possibleI; + } + function updatePossible(val, index) { + var newAbs = Math.abs(val - value); + if (newAbs < abs) { + abs = newAbs; + possibleI = index; + } + } + }; + VisualMapping.visualHandlers = { + color: { + applyVisual: makeApplyVisual('color'), + getColorMapper: function () { + var thisOption = this.option; + return bind(thisOption.mappingMethod === 'category' ? function (value, isNormalized) { + !isNormalized && (value = this._normalizeData(value)); + return doMapCategory.call(this, value); + } : function (value, isNormalized, out) { + // If output rgb array + // which will be much faster and useful in pixel manipulation + var returnRGBArray = !!out; + !isNormalized && (value = this._normalizeData(value)); + out = fastLerp(value, thisOption.parsedVisual, out); + return returnRGBArray ? out : stringify(out, 'rgba'); + }, this); + }, + _normalizedToVisual: { + linear: function (normalized) { + return stringify(fastLerp(normalized, this.option.parsedVisual), 'rgba'); + }, + category: doMapCategory, + piecewise: function (normalized, value) { + var result = getSpecifiedVisual.call(this, value); + if (result == null) { + result = stringify(fastLerp(normalized, this.option.parsedVisual), 'rgba'); + } + return result; + }, + fixed: doMapFixed + } + }, + colorHue: makePartialColorVisualHandler(function (color$1, value) { + return modifyHSL(color$1, value); + }), + colorSaturation: makePartialColorVisualHandler(function (color$1, value) { + return modifyHSL(color$1, null, value); + }), + colorLightness: makePartialColorVisualHandler(function (color$1, value) { + return modifyHSL(color$1, null, null, value); + }), + colorAlpha: makePartialColorVisualHandler(function (color$1, value) { + return modifyAlpha(color$1, value); + }), + decal: { + applyVisual: makeApplyVisual('decal'), + _normalizedToVisual: { + linear: null, + category: doMapCategory, + piecewise: null, + fixed: null + } + }, + opacity: { + applyVisual: makeApplyVisual('opacity'), + _normalizedToVisual: createNormalizedToNumericVisual([0, 1]) + }, + liftZ: { + applyVisual: makeApplyVisual('liftZ'), + _normalizedToVisual: { + linear: doMapFixed, + category: doMapFixed, + piecewise: doMapFixed, + fixed: doMapFixed + } + }, + symbol: { + applyVisual: function (value, getter, setter) { + var symbolCfg = this.mapValueToVisual(value); + setter('symbol', symbolCfg); + }, + _normalizedToVisual: { + linear: doMapToArray, + category: doMapCategory, + piecewise: function (normalized, value) { + var result = getSpecifiedVisual.call(this, value); + if (result == null) { + result = doMapToArray.call(this, normalized); + } + return result; + }, + fixed: doMapFixed + } + }, + symbolSize: { + applyVisual: makeApplyVisual('symbolSize'), + _normalizedToVisual: createNormalizedToNumericVisual([0, 1]) + } + }; + return VisualMapping; + }(); + function preprocessForPiecewise(thisOption) { + var pieceList = thisOption.pieceList; + thisOption.hasSpecialVisual = false; + each(pieceList, function (piece, index) { + piece.originIndex = index; + // piece.visual is "result visual value" but not + // a visual range, so it does not need to be normalized. + if (piece.visual != null) { + thisOption.hasSpecialVisual = true; + } + }); + } + function preprocessForSpecifiedCategory(thisOption) { + // Hash categories. + var categories = thisOption.categories; + var categoryMap = thisOption.categoryMap = {}; + var visual = thisOption.visual; + each$3(categories, function (cate, index) { + categoryMap[cate] = index; + }); + // Process visual map input. + if (!isArray(visual)) { + var visualArr_1 = []; + if (isObject(visual)) { + each$3(visual, function (v, cate) { + var index = categoryMap[cate]; + visualArr_1[index != null ? index : CATEGORY_DEFAULT_VISUAL_INDEX] = v; + }); + } else { + // Is primary type, represents default visual. + visualArr_1[CATEGORY_DEFAULT_VISUAL_INDEX] = visual; + } + visual = setVisualToOption(thisOption, visualArr_1); + } + // Remove categories that has no visual, + // then we can mapping them to CATEGORY_DEFAULT_VISUAL_INDEX. + for (var i = categories.length - 1; i >= 0; i--) { + if (visual[i] == null) { + delete categoryMap[categories[i]]; + categories.pop(); + } + } + } + function normalizeVisualRange(thisOption, isCategory) { + var visual = thisOption.visual; + var visualArr = []; + if (isObject(visual)) { + each$3(visual, function (v) { + visualArr.push(v); + }); + } else if (visual != null) { + visualArr.push(visual); + } + var doNotNeedPair = { + color: 1, + symbol: 1 + }; + if (!isCategory && visualArr.length === 1 && !doNotNeedPair.hasOwnProperty(thisOption.type)) { + // Do not care visualArr.length === 0, which is illegal. + visualArr[1] = visualArr[0]; + } + setVisualToOption(thisOption, visualArr); + } + function makePartialColorVisualHandler(applyValue) { + return { + applyVisual: function (value, getter, setter) { + // Only used in HSL + var colorChannel = this.mapValueToVisual(value); + // Must not be array value + setter('color', applyValue(getter('color'), colorChannel)); + }, + _normalizedToVisual: createNormalizedToNumericVisual([0, 1]) + }; + } + function doMapToArray(normalized) { + var visual = this.option.visual; + return visual[Math.round(linearMap(normalized, [0, 1], [0, visual.length - 1], true))] || {}; // TODO {}? + } + + function makeApplyVisual(visualType) { + return function (value, getter, setter) { + setter(visualType, this.mapValueToVisual(value)); + }; + } + function doMapCategory(normalized) { + var visual = this.option.visual; + return visual[this.option.loop && normalized !== CATEGORY_DEFAULT_VISUAL_INDEX ? normalized % visual.length : normalized]; + } + function doMapFixed() { + // visual will be convert to array. + return this.option.visual[0]; + } + /** + * Create mapped to numeric visual + */ + function createNormalizedToNumericVisual(sourceExtent) { + return { + linear: function (normalized) { + return linearMap(normalized, sourceExtent, this.option.visual, true); + }, + category: doMapCategory, + piecewise: function (normalized, value) { + var result = getSpecifiedVisual.call(this, value); + if (result == null) { + result = linearMap(normalized, sourceExtent, this.option.visual, true); + } + return result; + }, + fixed: doMapFixed + }; + } + function getSpecifiedVisual(value) { + var thisOption = this.option; + var pieceList = thisOption.pieceList; + if (thisOption.hasSpecialVisual) { + var pieceIndex = VisualMapping.findPieceIndex(value, pieceList); + var piece = pieceList[pieceIndex]; + if (piece && piece.visual) { + return piece.visual[this.type]; + } + } + } + function setVisualToOption(thisOption, visualArr) { + thisOption.visual = visualArr; + if (thisOption.type === 'color') { + thisOption.parsedVisual = map(visualArr, function (item) { + var color$1 = parse(item); + if (!color$1 && "development" !== 'production') { + warn("'" + item + "' is an illegal color, fallback to '#000000'", true); + } + return color$1 || [0, 0, 0, 1]; + }); + } + return visualArr; + } + /** + * Normalizers by mapping methods. + */ + var normalizers = { + linear: function (value) { + return linearMap(value, this.option.dataExtent, [0, 1], true); + }, + piecewise: function (value) { + var pieceList = this.option.pieceList; + var pieceIndex = VisualMapping.findPieceIndex(value, pieceList, true); + if (pieceIndex != null) { + return linearMap(pieceIndex, [0, pieceList.length - 1], [0, 1], true); + } + }, + category: function (value) { + var index = this.option.categories ? this.option.categoryMap[value] : value; // ordinal value + return index == null ? CATEGORY_DEFAULT_VISUAL_INDEX : index; + }, + fixed: noop + }; + function littleThan(close, a, b) { + return close ? a <= b : a < b; + } + + var ITEM_STYLE_NORMAL = 'itemStyle'; + var inner$9 = makeInner(); + var treemapVisual = { + seriesType: 'treemap', + reset: function (seriesModel) { + var tree = seriesModel.getData().tree; + var root = tree.root; + if (root.isRemoved()) { + return; + } + travelTree(root, + // Visual should calculate from tree root but not view root. + {}, seriesModel.getViewRoot().getAncestors(), seriesModel); + } + }; + function travelTree(node, designatedVisual, viewRootAncestors, seriesModel) { + var nodeModel = node.getModel(); + var nodeLayout = node.getLayout(); + var data = node.hostTree.data; + // Optimize + if (!nodeLayout || nodeLayout.invisible || !nodeLayout.isInView) { + return; + } + var nodeItemStyleModel = nodeModel.getModel(ITEM_STYLE_NORMAL); + var visuals = buildVisuals(nodeItemStyleModel, designatedVisual, seriesModel); + var existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style'); + // calculate border color + var borderColor = nodeItemStyleModel.get('borderColor'); + var borderColorSaturation = nodeItemStyleModel.get('borderColorSaturation'); + var thisNodeColor; + if (borderColorSaturation != null) { + // For performance, do not always execute 'calculateColor'. + thisNodeColor = calculateColor(visuals); + borderColor = calculateBorderColor(borderColorSaturation, thisNodeColor); + } + existsStyle.stroke = borderColor; + var viewChildren = node.viewChildren; + if (!viewChildren || !viewChildren.length) { + thisNodeColor = calculateColor(visuals); + // Apply visual to this node. + existsStyle.fill = thisNodeColor; + } else { + var mapping_1 = buildVisualMapping(node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren); + // Designate visual to children. + each(viewChildren, function (child, index) { + // If higher than viewRoot, only ancestors of viewRoot is needed to visit. + if (child.depth >= viewRootAncestors.length || child === viewRootAncestors[child.depth]) { + var childVisual = mapVisual(nodeModel, visuals, child, index, mapping_1, seriesModel); + travelTree(child, childVisual, viewRootAncestors, seriesModel); + } + }); + } + } + function buildVisuals(nodeItemStyleModel, designatedVisual, seriesModel) { + var visuals = extend({}, designatedVisual); + var designatedVisualItemStyle = seriesModel.designatedVisualItemStyle; + each(['color', 'colorAlpha', 'colorSaturation'], function (visualName) { + // Priority: thisNode > thisLevel > parentNodeDesignated > seriesModel + designatedVisualItemStyle[visualName] = designatedVisual[visualName]; + var val = nodeItemStyleModel.get(visualName); + designatedVisualItemStyle[visualName] = null; + val != null && (visuals[visualName] = val); + }); + return visuals; + } + function calculateColor(visuals) { + var color = getValueVisualDefine(visuals, 'color'); + if (color) { + var colorAlpha = getValueVisualDefine(visuals, 'colorAlpha'); + var colorSaturation = getValueVisualDefine(visuals, 'colorSaturation'); + if (colorSaturation) { + color = modifyHSL(color, null, null, colorSaturation); + } + if (colorAlpha) { + color = modifyAlpha(color, colorAlpha); + } + return color; + } + } + function calculateBorderColor(borderColorSaturation, thisNodeColor) { + return thisNodeColor != null + // Can only be string + ? modifyHSL(thisNodeColor, null, null, borderColorSaturation) : null; + } + function getValueVisualDefine(visuals, name) { + var value = visuals[name]; + if (value != null && value !== 'none') { + return value; + } + } + function buildVisualMapping(node, nodeModel, nodeLayout, nodeItemStyleModel, visuals, viewChildren) { + if (!viewChildren || !viewChildren.length) { + return; + } + var rangeVisual = getRangeVisual(nodeModel, 'color') || visuals.color != null && visuals.color !== 'none' && (getRangeVisual(nodeModel, 'colorAlpha') || getRangeVisual(nodeModel, 'colorSaturation')); + if (!rangeVisual) { + return; + } + var visualMin = nodeModel.get('visualMin'); + var visualMax = nodeModel.get('visualMax'); + var dataExtent = nodeLayout.dataExtent.slice(); + visualMin != null && visualMin < dataExtent[0] && (dataExtent[0] = visualMin); + visualMax != null && visualMax > dataExtent[1] && (dataExtent[1] = visualMax); + var colorMappingBy = nodeModel.get('colorMappingBy'); + var opt = { + type: rangeVisual.name, + dataExtent: dataExtent, + visual: rangeVisual.range + }; + if (opt.type === 'color' && (colorMappingBy === 'index' || colorMappingBy === 'id')) { + opt.mappingMethod = 'category'; + opt.loop = true; + // categories is ordinal, so do not set opt.categories. + } else { + opt.mappingMethod = 'linear'; + } + var mapping = new VisualMapping(opt); + inner$9(mapping).drColorMappingBy = colorMappingBy; + return mapping; + } + // Notice: If we don't have the attribute 'colorRange', but only use + // attribute 'color' to represent both concepts of 'colorRange' and 'color', + // (It means 'colorRange' when 'color' is Array, means 'color' when not array), + // this problem will be encountered: + // If a level-1 node doesn't have children, and its siblings have children, + // and colorRange is set on level-1, then the node cannot be colored. + // So we separate 'colorRange' and 'color' to different attributes. + function getRangeVisual(nodeModel, name) { + // 'colorRange', 'colorARange', 'colorSRange'. + // If not exists on this node, fetch from levels and series. + var range = nodeModel.get(name); + return isArray(range) && range.length ? { + name: name, + range: range + } : null; + } + function mapVisual(nodeModel, visuals, child, index, mapping, seriesModel) { + var childVisuals = extend({}, visuals); + if (mapping) { + // Only support color, colorAlpha, colorSaturation. + var mappingType = mapping.type; + var colorMappingBy = mappingType === 'color' && inner$9(mapping).drColorMappingBy; + var value = colorMappingBy === 'index' ? index : colorMappingBy === 'id' ? seriesModel.mapIdToIndex(child.getId()) : child.getValue(nodeModel.get('visualDimension')); + childVisuals[mappingType] = mapping.mapValueToVisual(value); + } + return childVisuals; + } + + var mathMax$7 = Math.max; + var mathMin$7 = Math.min; + var retrieveValue = retrieve; + var each$4 = each; + var PATH_BORDER_WIDTH = ['itemStyle', 'borderWidth']; + var PATH_GAP_WIDTH = ['itemStyle', 'gapWidth']; + var PATH_UPPER_LABEL_SHOW = ['upperLabel', 'show']; + var PATH_UPPER_LABEL_HEIGHT = ['upperLabel', 'height']; + /** + * @public + */ + var treemapLayout = { + seriesType: 'treemap', + reset: function (seriesModel, ecModel, api, payload) { + // Layout result in each node: + // {x, y, width, height, area, borderWidth} + var ecWidth = api.getWidth(); + var ecHeight = api.getHeight(); + var seriesOption = seriesModel.option; + var layoutInfo = getLayoutRect(seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }); + var size = seriesOption.size || []; // Compatible with ec2. + var containerWidth = parsePercent$1(retrieveValue(layoutInfo.width, size[0]), ecWidth); + var containerHeight = parsePercent$1(retrieveValue(layoutInfo.height, size[1]), ecHeight); + // Fetch payload info. + var payloadType = payload && payload.type; + var types = ['treemapZoomToNode', 'treemapRootToNode']; + var targetInfo = retrieveTargetInfo(payload, types, seriesModel); + var rootRect = payloadType === 'treemapRender' || payloadType === 'treemapMove' ? payload.rootRect : null; + var viewRoot = seriesModel.getViewRoot(); + var viewAbovePath = getPathToRoot(viewRoot); + if (payloadType !== 'treemapMove') { + var rootSize = payloadType === 'treemapZoomToNode' ? estimateRootSize(seriesModel, targetInfo, viewRoot, containerWidth, containerHeight) : rootRect ? [rootRect.width, rootRect.height] : [containerWidth, containerHeight]; + var sort_1 = seriesOption.sort; + if (sort_1 && sort_1 !== 'asc' && sort_1 !== 'desc') { + // Default to be desc order. + sort_1 = 'desc'; + } + var options = { + squareRatio: seriesOption.squareRatio, + sort: sort_1, + leafDepth: seriesOption.leafDepth + }; + // layout should be cleared because using updateView but not update. + viewRoot.hostTree.clearLayouts(); + // TODO + // optimize: if out of view clip, do not layout. + // But take care that if do not render node out of view clip, + // how to calculate start po + var viewRootLayout_1 = { + x: 0, + y: 0, + width: rootSize[0], + height: rootSize[1], + area: rootSize[0] * rootSize[1] + }; + viewRoot.setLayout(viewRootLayout_1); + squarify(viewRoot, options, false, 0); + // Supplement layout. + viewRootLayout_1 = viewRoot.getLayout(); + each$4(viewAbovePath, function (node, index) { + var childValue = (viewAbovePath[index + 1] || viewRoot).getValue(); + node.setLayout(extend({ + dataExtent: [childValue, childValue], + borderWidth: 0, + upperHeight: 0 + }, viewRootLayout_1)); + }); + } + var treeRoot = seriesModel.getData().tree.root; + treeRoot.setLayout(calculateRootPosition(layoutInfo, rootRect, targetInfo), true); + seriesModel.setLayoutInfo(layoutInfo); + // FIXME + // 现在没有clip功能,暂时取ec高宽。 + prunning(treeRoot, + // Transform to base element coordinate system. + new BoundingRect(-layoutInfo.x, -layoutInfo.y, ecWidth, ecHeight), viewAbovePath, viewRoot, 0); + } + }; + /** + * Layout treemap with squarify algorithm. + * The original presentation of this algorithm + * was made by Mark Bruls, Kees Huizing, and Jarke J. van Wijk + * . + * The implementation of this algorithm was originally copied from "d3.js" + * + * with some modifications made for this program. + * See the license statement at the head of this file. + * + * @protected + * @param {module:echarts/data/Tree~TreeNode} node + * @param {Object} options + * @param {string} options.sort 'asc' or 'desc' + * @param {number} options.squareRatio + * @param {boolean} hideChildren + * @param {number} depth + */ + function squarify(node, options, hideChildren, depth) { + var width; + var height; + if (node.isRemoved()) { + return; + } + var thisLayout = node.getLayout(); + width = thisLayout.width; + height = thisLayout.height; + // Considering border and gap + var nodeModel = node.getModel(); + var borderWidth = nodeModel.get(PATH_BORDER_WIDTH); + var halfGapWidth = nodeModel.get(PATH_GAP_WIDTH) / 2; + var upperLabelHeight = getUpperLabelHeight(nodeModel); + var upperHeight = Math.max(borderWidth, upperLabelHeight); + var layoutOffset = borderWidth - halfGapWidth; + var layoutOffsetUpper = upperHeight - halfGapWidth; + node.setLayout({ + borderWidth: borderWidth, + upperHeight: upperHeight, + upperLabelHeight: upperLabelHeight + }, true); + width = mathMax$7(width - 2 * layoutOffset, 0); + height = mathMax$7(height - layoutOffset - layoutOffsetUpper, 0); + var totalArea = width * height; + var viewChildren = initChildren(node, nodeModel, totalArea, options, hideChildren, depth); + if (!viewChildren.length) { + return; + } + var rect = { + x: layoutOffset, + y: layoutOffsetUpper, + width: width, + height: height + }; + var rowFixedLength = mathMin$7(width, height); + var best = Infinity; // the best row score so far + var row = []; + row.area = 0; + for (var i = 0, len = viewChildren.length; i < len;) { + var child = viewChildren[i]; + row.push(child); + row.area += child.getLayout().area; + var score = worst(row, rowFixedLength, options.squareRatio); + // continue with this orientation + if (score <= best) { + i++; + best = score; + } + // abort, and try a different orientation + else { + row.area -= row.pop().getLayout().area; + position(row, rowFixedLength, rect, halfGapWidth, false); + rowFixedLength = mathMin$7(rect.width, rect.height); + row.length = row.area = 0; + best = Infinity; + } + } + if (row.length) { + position(row, rowFixedLength, rect, halfGapWidth, true); + } + if (!hideChildren) { + var childrenVisibleMin = nodeModel.get('childrenVisibleMin'); + if (childrenVisibleMin != null && totalArea < childrenVisibleMin) { + hideChildren = true; + } + } + for (var i = 0, len = viewChildren.length; i < len; i++) { + squarify(viewChildren[i], options, hideChildren, depth + 1); + } + } + /** + * Set area to each child, and calculate data extent for visual coding. + */ + function initChildren(node, nodeModel, totalArea, options, hideChildren, depth) { + var viewChildren = node.children || []; + var orderBy = options.sort; + orderBy !== 'asc' && orderBy !== 'desc' && (orderBy = null); + var overLeafDepth = options.leafDepth != null && options.leafDepth <= depth; + // leafDepth has higher priority. + if (hideChildren && !overLeafDepth) { + return node.viewChildren = []; + } + // Sort children, order by desc. + viewChildren = filter(viewChildren, function (child) { + return !child.isRemoved(); + }); + sort$1(viewChildren, orderBy); + var info = statistic(nodeModel, viewChildren, orderBy); + if (info.sum === 0) { + return node.viewChildren = []; + } + info.sum = filterByThreshold(nodeModel, totalArea, info.sum, orderBy, viewChildren); + if (info.sum === 0) { + return node.viewChildren = []; + } + // Set area to each child. + for (var i = 0, len = viewChildren.length; i < len; i++) { + var area = viewChildren[i].getValue() / info.sum * totalArea; + // Do not use setLayout({...}, true), because it is needed to clear last layout. + viewChildren[i].setLayout({ + area: area + }); + } + if (overLeafDepth) { + viewChildren.length && node.setLayout({ + isLeafRoot: true + }, true); + viewChildren.length = 0; + } + node.viewChildren = viewChildren; + node.setLayout({ + dataExtent: info.dataExtent + }, true); + return viewChildren; + } + /** + * Consider 'visibleMin'. Modify viewChildren and get new sum. + */ + function filterByThreshold(nodeModel, totalArea, sum, orderBy, orderedChildren) { + // visibleMin is not supported yet when no option.sort. + if (!orderBy) { + return sum; + } + var visibleMin = nodeModel.get('visibleMin'); + var len = orderedChildren.length; + var deletePoint = len; + // Always travel from little value to big value. + for (var i = len - 1; i >= 0; i--) { + var value = orderedChildren[orderBy === 'asc' ? len - i - 1 : i].getValue(); + if (value / sum * totalArea < visibleMin) { + deletePoint = i; + sum -= value; + } + } + orderBy === 'asc' ? orderedChildren.splice(0, len - deletePoint) : orderedChildren.splice(deletePoint, len - deletePoint); + return sum; + } + /** + * Sort + */ + function sort$1(viewChildren, orderBy) { + if (orderBy) { + viewChildren.sort(function (a, b) { + var diff = orderBy === 'asc' ? a.getValue() - b.getValue() : b.getValue() - a.getValue(); + return diff === 0 ? orderBy === 'asc' ? a.dataIndex - b.dataIndex : b.dataIndex - a.dataIndex : diff; + }); + } + return viewChildren; + } + /** + * Statistic + */ + function statistic(nodeModel, children, orderBy) { + // Calculate sum. + var sum = 0; + for (var i = 0, len = children.length; i < len; i++) { + sum += children[i].getValue(); + } + // Statistic data extent for latter visual coding. + // Notice: data extent should be calculate based on raw children + // but not filtered view children, otherwise visual mapping will not + // be stable when zoom (where children is filtered by visibleMin). + var dimension = nodeModel.get('visualDimension'); + var dataExtent; + // The same as area dimension. + if (!children || !children.length) { + dataExtent = [NaN, NaN]; + } else if (dimension === 'value' && orderBy) { + dataExtent = [children[children.length - 1].getValue(), children[0].getValue()]; + orderBy === 'asc' && dataExtent.reverse(); + } + // Other dimension. + else { + dataExtent = [Infinity, -Infinity]; + each$4(children, function (child) { + var value = child.getValue(dimension); + value < dataExtent[0] && (dataExtent[0] = value); + value > dataExtent[1] && (dataExtent[1] = value); + }); + } + return { + sum: sum, + dataExtent: dataExtent + }; + } + /** + * Computes the score for the specified row, + * as the worst aspect ratio. + */ + function worst(row, rowFixedLength, ratio) { + var areaMax = 0; + var areaMin = Infinity; + for (var i = 0, area = void 0, len = row.length; i < len; i++) { + area = row[i].getLayout().area; + if (area) { + area < areaMin && (areaMin = area); + area > areaMax && (areaMax = area); + } + } + var squareArea = row.area * row.area; + var f = rowFixedLength * rowFixedLength * ratio; + return squareArea ? mathMax$7(f * areaMax / squareArea, squareArea / (f * areaMin)) : Infinity; + } + /** + * Positions the specified row of nodes. Modifies `rect`. + */ + function position(row, rowFixedLength, rect, halfGapWidth, flush) { + // When rowFixedLength === rect.width, + // it is horizontal subdivision, + // rowFixedLength is the width of the subdivision, + // rowOtherLength is the height of the subdivision, + // and nodes will be positioned from left to right. + // wh[idx0WhenH] means: when horizontal, + // wh[idx0WhenH] => wh[0] => 'width'. + // xy[idx1WhenH] => xy[1] => 'y'. + var idx0WhenH = rowFixedLength === rect.width ? 0 : 1; + var idx1WhenH = 1 - idx0WhenH; + var xy = ['x', 'y']; + var wh = ['width', 'height']; + var last = rect[xy[idx0WhenH]]; + var rowOtherLength = rowFixedLength ? row.area / rowFixedLength : 0; + if (flush || rowOtherLength > rect[wh[idx1WhenH]]) { + rowOtherLength = rect[wh[idx1WhenH]]; // over+underflow + } + + for (var i = 0, rowLen = row.length; i < rowLen; i++) { + var node = row[i]; + var nodeLayout = {}; + var step = rowOtherLength ? node.getLayout().area / rowOtherLength : 0; + var wh1 = nodeLayout[wh[idx1WhenH]] = mathMax$7(rowOtherLength - 2 * halfGapWidth, 0); + // We use Math.max/min to avoid negative width/height when considering gap width. + var remain = rect[xy[idx0WhenH]] + rect[wh[idx0WhenH]] - last; + var modWH = i === rowLen - 1 || remain < step ? remain : step; + var wh0 = nodeLayout[wh[idx0WhenH]] = mathMax$7(modWH - 2 * halfGapWidth, 0); + nodeLayout[xy[idx1WhenH]] = rect[xy[idx1WhenH]] + mathMin$7(halfGapWidth, wh1 / 2); + nodeLayout[xy[idx0WhenH]] = last + mathMin$7(halfGapWidth, wh0 / 2); + last += modWH; + node.setLayout(nodeLayout, true); + } + rect[xy[idx1WhenH]] += rowOtherLength; + rect[wh[idx1WhenH]] -= rowOtherLength; + } + // Return [containerWidth, containerHeight] as default. + function estimateRootSize(seriesModel, targetInfo, viewRoot, containerWidth, containerHeight) { + // If targetInfo.node exists, we zoom to the node, + // so estimate whole width and height by target node. + var currNode = (targetInfo || {}).node; + var defaultSize = [containerWidth, containerHeight]; + if (!currNode || currNode === viewRoot) { + return defaultSize; + } + var parent; + var viewArea = containerWidth * containerHeight; + var area = viewArea * seriesModel.option.zoomToNodeRatio; + while (parent = currNode.parentNode) { + // jshint ignore:line + var sum = 0; + var siblings = parent.children; + for (var i = 0, len = siblings.length; i < len; i++) { + sum += siblings[i].getValue(); + } + var currNodeValue = currNode.getValue(); + if (currNodeValue === 0) { + return defaultSize; + } + area *= sum / currNodeValue; + // Considering border, suppose aspect ratio is 1. + var parentModel = parent.getModel(); + var borderWidth = parentModel.get(PATH_BORDER_WIDTH); + var upperHeight = Math.max(borderWidth, getUpperLabelHeight(parentModel)); + area += 4 * borderWidth * borderWidth + (3 * borderWidth + upperHeight) * Math.pow(area, 0.5); + area > MAX_SAFE_INTEGER && (area = MAX_SAFE_INTEGER); + currNode = parent; + } + area < viewArea && (area = viewArea); + var scale = Math.pow(area / viewArea, 0.5); + return [containerWidth * scale, containerHeight * scale]; + } + // Root position based on coord of containerGroup + function calculateRootPosition(layoutInfo, rootRect, targetInfo) { + if (rootRect) { + return { + x: rootRect.x, + y: rootRect.y + }; + } + var defaultPosition = { + x: 0, + y: 0 + }; + if (!targetInfo) { + return defaultPosition; + } + // If targetInfo is fetched by 'retrieveTargetInfo', + // old tree and new tree are the same tree, + // so the node still exists and we can visit it. + var targetNode = targetInfo.node; + var layout = targetNode.getLayout(); + if (!layout) { + return defaultPosition; + } + // Transform coord from local to container. + var targetCenter = [layout.width / 2, layout.height / 2]; + var node = targetNode; + while (node) { + var nodeLayout = node.getLayout(); + targetCenter[0] += nodeLayout.x; + targetCenter[1] += nodeLayout.y; + node = node.parentNode; + } + return { + x: layoutInfo.width / 2 - targetCenter[0], + y: layoutInfo.height / 2 - targetCenter[1] + }; + } + // Mark nodes visible for prunning when visual coding and rendering. + // Prunning depends on layout and root position, so we have to do it after layout. + function prunning(node, clipRect, viewAbovePath, viewRoot, depth) { + var nodeLayout = node.getLayout(); + var nodeInViewAbovePath = viewAbovePath[depth]; + var isAboveViewRoot = nodeInViewAbovePath && nodeInViewAbovePath === node; + if (nodeInViewAbovePath && !isAboveViewRoot || depth === viewAbovePath.length && node !== viewRoot) { + return; + } + node.setLayout({ + // isInView means: viewRoot sub tree + viewAbovePath + isInView: true, + // invisible only means: outside view clip so that the node can not + // see but still layout for animation preparation but not render. + invisible: !isAboveViewRoot && !clipRect.intersect(nodeLayout), + isAboveViewRoot: isAboveViewRoot + }, true); + // Transform to child coordinate. + var childClipRect = new BoundingRect(clipRect.x - nodeLayout.x, clipRect.y - nodeLayout.y, clipRect.width, clipRect.height); + each$4(node.viewChildren || [], function (child) { + prunning(child, childClipRect, viewAbovePath, viewRoot, depth + 1); + }); + } + function getUpperLabelHeight(model) { + return model.get(PATH_UPPER_LABEL_SHOW) ? model.get(PATH_UPPER_LABEL_HEIGHT) : 0; + } + + function install$c(registers) { + registers.registerSeriesModel(TreemapSeriesModel); + registers.registerChartView(TreemapView); + registers.registerVisual(treemapVisual); + registers.registerLayout(treemapLayout); + installTreemapAction(registers); + } + + function categoryFilter(ecModel) { + var legendModels = ecModel.findComponents({ + mainType: 'legend' + }); + if (!legendModels || !legendModels.length) { + return; + } + ecModel.eachSeriesByType('graph', function (graphSeries) { + var categoriesData = graphSeries.getCategoriesData(); + var graph = graphSeries.getGraph(); + var data = graph.data; + var categoryNames = categoriesData.mapArray(categoriesData.getName); + data.filterSelf(function (idx) { + var model = data.getItemModel(idx); + var category = model.getShallow('category'); + if (category != null) { + if (isNumber(category)) { + category = categoryNames[category]; + } + // If in any legend component the status is not selected. + for (var i = 0; i < legendModels.length; i++) { + if (!legendModels[i].isSelected(category)) { + return false; + } + } + } + return true; + }); + }); + } + + function categoryVisual(ecModel) { + var paletteScope = {}; + ecModel.eachSeriesByType('graph', function (seriesModel) { + var categoriesData = seriesModel.getCategoriesData(); + var data = seriesModel.getData(); + var categoryNameIdxMap = {}; + categoriesData.each(function (idx) { + var name = categoriesData.getName(idx); + // Add prefix to avoid conflict with Object.prototype. + categoryNameIdxMap['ec-' + name] = idx; + var itemModel = categoriesData.getItemModel(idx); + var style = itemModel.getModel('itemStyle').getItemStyle(); + if (!style.fill) { + // Get color from palette. + style.fill = seriesModel.getColorFromPalette(name, paletteScope); + } + categoriesData.setItemVisual(idx, 'style', style); + var symbolVisualList = ['symbol', 'symbolSize', 'symbolKeepAspect']; + for (var i = 0; i < symbolVisualList.length; i++) { + var symbolVisual = itemModel.getShallow(symbolVisualList[i], true); + if (symbolVisual != null) { + categoriesData.setItemVisual(idx, symbolVisualList[i], symbolVisual); + } + } + }); + // Assign category color to visual + if (categoriesData.count()) { + data.each(function (idx) { + var model = data.getItemModel(idx); + var categoryIdx = model.getShallow('category'); + if (categoryIdx != null) { + if (isString(categoryIdx)) { + categoryIdx = categoryNameIdxMap['ec-' + categoryIdx]; + } + var categoryStyle = categoriesData.getItemVisual(categoryIdx, 'style'); + var style = data.ensureUniqueItemVisual(idx, 'style'); + extend(style, categoryStyle); + var visualList = ['symbol', 'symbolSize', 'symbolKeepAspect']; + for (var i = 0; i < visualList.length; i++) { + data.setItemVisual(idx, visualList[i], categoriesData.getItemVisual(categoryIdx, visualList[i])); + } + } + }); + } + }); + } + + function normalize$2(a) { + if (!(a instanceof Array)) { + a = [a, a]; + } + return a; + } + function graphEdgeVisual(ecModel) { + ecModel.eachSeriesByType('graph', function (seriesModel) { + var graph = seriesModel.getGraph(); + var edgeData = seriesModel.getEdgeData(); + var symbolType = normalize$2(seriesModel.get('edgeSymbol')); + var symbolSize = normalize$2(seriesModel.get('edgeSymbolSize')); + // const colorQuery = ['lineStyle', 'color'] as const; + // const opacityQuery = ['lineStyle', 'opacity'] as const; + edgeData.setVisual('fromSymbol', symbolType && symbolType[0]); + edgeData.setVisual('toSymbol', symbolType && symbolType[1]); + edgeData.setVisual('fromSymbolSize', symbolSize && symbolSize[0]); + edgeData.setVisual('toSymbolSize', symbolSize && symbolSize[1]); + edgeData.setVisual('style', seriesModel.getModel('lineStyle').getLineStyle()); + edgeData.each(function (idx) { + var itemModel = edgeData.getItemModel(idx); + var edge = graph.getEdgeByIndex(idx); + var symbolType = normalize$2(itemModel.getShallow('symbol', true)); + var symbolSize = normalize$2(itemModel.getShallow('symbolSize', true)); + // Edge visual must after node visual + var style = itemModel.getModel('lineStyle').getLineStyle(); + var existsStyle = edgeData.ensureUniqueItemVisual(idx, 'style'); + extend(existsStyle, style); + switch (existsStyle.stroke) { + case 'source': + { + var nodeStyle = edge.node1.getVisual('style'); + existsStyle.stroke = nodeStyle && nodeStyle.fill; + break; + } + case 'target': + { + var nodeStyle = edge.node2.getVisual('style'); + existsStyle.stroke = nodeStyle && nodeStyle.fill; + break; + } + } + symbolType[0] && edge.setVisual('fromSymbol', symbolType[0]); + symbolType[1] && edge.setVisual('toSymbol', symbolType[1]); + symbolSize[0] && edge.setVisual('fromSymbolSize', symbolSize[0]); + symbolSize[1] && edge.setVisual('toSymbolSize', symbolSize[1]); + }); + }); + } + + var KEY_DELIMITER = '-->'; + /** + * params handler + * @param {module:echarts/model/SeriesModel} seriesModel + * @returns {*} + */ + var getAutoCurvenessParams = function (seriesModel) { + return seriesModel.get('autoCurveness') || null; + }; + /** + * Generate a list of edge curvatures, 20 is the default + * @param {module:echarts/model/SeriesModel} seriesModel + * @param {number} appendLength + * @return 20 => [0, -0.2, 0.2, -0.4, 0.4, -0.6, 0.6, -0.8, 0.8, -1, 1, -1.2, 1.2, -1.4, 1.4, -1.6, 1.6, -1.8, 1.8, -2] + */ + var createCurveness = function (seriesModel, appendLength) { + var autoCurvenessParmas = getAutoCurvenessParams(seriesModel); + var length = 20; + var curvenessList = []; + // handler the function set + if (isNumber(autoCurvenessParmas)) { + length = autoCurvenessParmas; + } else if (isArray(autoCurvenessParmas)) { + seriesModel.__curvenessList = autoCurvenessParmas; + return; + } + // append length + if (appendLength > length) { + length = appendLength; + } + // make sure the length is even + var len = length % 2 ? length + 2 : length + 3; + curvenessList = []; + for (var i = 0; i < len; i++) { + curvenessList.push((i % 2 ? i + 1 : i) / 10 * (i % 2 ? -1 : 1)); + } + seriesModel.__curvenessList = curvenessList; + }; + /** + * Create different cache key data in the positive and negative directions, in order to set the curvature later + * @param {number|string|module:echarts/data/Graph.Node} n1 + * @param {number|string|module:echarts/data/Graph.Node} n2 + * @param {module:echarts/model/SeriesModel} seriesModel + * @returns {string} key + */ + var getKeyOfEdges = function (n1, n2, seriesModel) { + var source = [n1.id, n1.dataIndex].join('.'); + var target = [n2.id, n2.dataIndex].join('.'); + return [seriesModel.uid, source, target].join(KEY_DELIMITER); + }; + /** + * get opposite key + * @param {string} key + * @returns {string} + */ + var getOppositeKey = function (key) { + var keys = key.split(KEY_DELIMITER); + return [keys[0], keys[2], keys[1]].join(KEY_DELIMITER); + }; + /** + * get edgeMap with key + * @param edge + * @param {module:echarts/model/SeriesModel} seriesModel + */ + var getEdgeFromMap = function (edge, seriesModel) { + var key = getKeyOfEdges(edge.node1, edge.node2, seriesModel); + return seriesModel.__edgeMap[key]; + }; + /** + * calculate all cases total length + * @param edge + * @param seriesModel + * @returns {number} + */ + var getTotalLengthBetweenNodes = function (edge, seriesModel) { + var len = getEdgeMapLengthWithKey(getKeyOfEdges(edge.node1, edge.node2, seriesModel), seriesModel); + var lenV = getEdgeMapLengthWithKey(getKeyOfEdges(edge.node2, edge.node1, seriesModel), seriesModel); + return len + lenV; + }; + /** + * + * @param key + */ + var getEdgeMapLengthWithKey = function (key, seriesModel) { + var edgeMap = seriesModel.__edgeMap; + return edgeMap[key] ? edgeMap[key].length : 0; + }; + /** + * Count the number of edges between the same two points, used to obtain the curvature table and the parity of the edge + * @see /graph/GraphSeries.js@getInitialData + * @param {module:echarts/model/SeriesModel} seriesModel + */ + function initCurvenessList(seriesModel) { + if (!getAutoCurvenessParams(seriesModel)) { + return; + } + seriesModel.__curvenessList = []; + seriesModel.__edgeMap = {}; + // calc the array of curveness List + createCurveness(seriesModel); + } + /** + * set edgeMap with key + * @param {number|string|module:echarts/data/Graph.Node} n1 + * @param {number|string|module:echarts/data/Graph.Node} n2 + * @param {module:echarts/model/SeriesModel} seriesModel + * @param {number} index + */ + function createEdgeMapForCurveness(n1, n2, seriesModel, index) { + if (!getAutoCurvenessParams(seriesModel)) { + return; + } + var key = getKeyOfEdges(n1, n2, seriesModel); + var edgeMap = seriesModel.__edgeMap; + var oppositeEdges = edgeMap[getOppositeKey(key)]; + // set direction + if (edgeMap[key] && !oppositeEdges) { + edgeMap[key].isForward = true; + } else if (oppositeEdges && edgeMap[key]) { + oppositeEdges.isForward = true; + edgeMap[key].isForward = false; + } + edgeMap[key] = edgeMap[key] || []; + edgeMap[key].push(index); + } + /** + * get curvature for edge + * @param edge + * @param {module:echarts/model/SeriesModel} seriesModel + * @param index + */ + function getCurvenessForEdge(edge, seriesModel, index, needReverse) { + var autoCurvenessParams = getAutoCurvenessParams(seriesModel); + var isArrayParam = isArray(autoCurvenessParams); + if (!autoCurvenessParams) { + return null; + } + var edgeArray = getEdgeFromMap(edge, seriesModel); + if (!edgeArray) { + return null; + } + var edgeIndex = -1; + for (var i = 0; i < edgeArray.length; i++) { + if (edgeArray[i] === index) { + edgeIndex = i; + break; + } + } + // if totalLen is Longer createCurveness + var totalLen = getTotalLengthBetweenNodes(edge, seriesModel); + createCurveness(seriesModel, totalLen); + edge.lineStyle = edge.lineStyle || {}; + // if is opposite edge, must set curvenss to opposite number + var curKey = getKeyOfEdges(edge.node1, edge.node2, seriesModel); + var curvenessList = seriesModel.__curvenessList; + // if pass array no need parity + var parityCorrection = isArrayParam ? 0 : totalLen % 2 ? 0 : 1; + if (!edgeArray.isForward) { + // the opposite edge show outside + var oppositeKey = getOppositeKey(curKey); + var len = getEdgeMapLengthWithKey(oppositeKey, seriesModel); + var resValue = curvenessList[edgeIndex + len + parityCorrection]; + // isNeedReverse, simple, force type need reverse the curveness in the junction of the forword and the opposite + if (needReverse) { + // set as array may make the parity handle with the len of opposite + if (isArrayParam) { + if (autoCurvenessParams && autoCurvenessParams[0] === 0) { + return (len + parityCorrection) % 2 ? resValue : -resValue; + } else { + return ((len % 2 ? 0 : 1) + parityCorrection) % 2 ? resValue : -resValue; + } + } else { + return (len + parityCorrection) % 2 ? resValue : -resValue; + } + } else { + return curvenessList[edgeIndex + len + parityCorrection]; + } + } else { + return curvenessList[parityCorrection + edgeIndex]; + } + } + + function simpleLayout(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.type !== 'view') { + return; + } + var graph = seriesModel.getGraph(); + graph.eachNode(function (node) { + var model = node.getModel(); + node.setLayout([+model.get('x'), +model.get('y')]); + }); + simpleLayoutEdge(graph, seriesModel); + } + function simpleLayoutEdge(graph, seriesModel) { + graph.eachEdge(function (edge, index) { + var curveness = retrieve3(edge.getModel().get(['lineStyle', 'curveness']), -getCurvenessForEdge(edge, seriesModel, index, true), 0); + var p1 = clone$1(edge.node1.getLayout()); + var p2 = clone$1(edge.node2.getLayout()); + var points = [p1, p2]; + if (+curveness) { + points.push([(p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * curveness, (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * curveness]); + } + edge.setLayout(points); + }); + } + + function graphSimpleLayout(ecModel, api) { + ecModel.eachSeriesByType('graph', function (seriesModel) { + var layout = seriesModel.get('layout'); + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.type !== 'view') { + var data_1 = seriesModel.getData(); + var dimensions_1 = []; + each(coordSys.dimensions, function (coordDim) { + dimensions_1 = dimensions_1.concat(data_1.mapDimensionsAll(coordDim)); + }); + for (var dataIndex = 0; dataIndex < data_1.count(); dataIndex++) { + var value = []; + var hasValue = false; + for (var i = 0; i < dimensions_1.length; i++) { + var val = data_1.get(dimensions_1[i], dataIndex); + if (!isNaN(val)) { + hasValue = true; + } + value.push(val); + } + if (hasValue) { + data_1.setItemLayout(dataIndex, coordSys.dataToPoint(value)); + } else { + // Also {Array.}, not undefined to avoid if...else... statement + data_1.setItemLayout(dataIndex, [NaN, NaN]); + } + } + simpleLayoutEdge(data_1.graph, seriesModel); + } else if (!layout || layout === 'none') { + simpleLayout(seriesModel); + } + }); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function getNodeGlobalScale(seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys.type !== 'view') { + return 1; + } + var nodeScaleRatio = seriesModel.option.nodeScaleRatio; + var groupZoom = coordSys.scaleX; + // Scale node when zoom changes + var roamZoom = coordSys.getZoom(); + var nodeScale = (roamZoom - 1) * nodeScaleRatio + 1; + return nodeScale / groupZoom; + } + function getSymbolSize(node) { + var symbolSize = node.getVisual('symbolSize'); + if (symbolSize instanceof Array) { + symbolSize = (symbolSize[0] + symbolSize[1]) / 2; + } + return +symbolSize; + } + + var PI$6 = Math.PI; + var _symbolRadiansHalf = []; + /** + * `basedOn` can be: + * 'value': + * This layout is not accurate and have same bad case. For example, + * if the min value is very smaller than the max value, the nodes + * with the min value probably overlap even though there is enough + * space to layout them. So we only use this approach in the as the + * init layout of the force layout. + * FIXME + * Probably we do not need this method any more but use + * `basedOn: 'symbolSize'` in force layout if + * delay its init operations to GraphView. + * 'symbolSize': + * This approach work only if all of the symbol size calculated. + * That is, the progressive rendering is not applied to graph. + * FIXME + * If progressive rendering is applied to graph some day, + * probably we have to use `basedOn: 'value'`. + */ + function circularLayout(seriesModel, basedOn, draggingNode, pointer) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.type !== 'view') { + return; + } + var rect = coordSys.getBoundingRect(); + var nodeData = seriesModel.getData(); + var graph = nodeData.graph; + var cx = rect.width / 2 + rect.x; + var cy = rect.height / 2 + rect.y; + var r = Math.min(rect.width, rect.height) / 2; + var count = nodeData.count(); + nodeData.setLayout({ + cx: cx, + cy: cy + }); + if (!count) { + return; + } + if (draggingNode) { + var _a = coordSys.pointToData(pointer), + tempX = _a[0], + tempY = _a[1]; + var v = [tempX - cx, tempY - cy]; + normalize(v, v); + scale(v, v, r); + draggingNode.setLayout([cx + v[0], cy + v[1]], true); + var circularRotateLabel = seriesModel.get(['circular', 'rotateLabel']); + rotateNodeLabel(draggingNode, circularRotateLabel, cx, cy); + } + _layoutNodesBasedOn[basedOn](seriesModel, graph, nodeData, r, cx, cy, count); + graph.eachEdge(function (edge, index) { + var curveness = retrieve3(edge.getModel().get(['lineStyle', 'curveness']), getCurvenessForEdge(edge, seriesModel, index), 0); + var p1 = clone$1(edge.node1.getLayout()); + var p2 = clone$1(edge.node2.getLayout()); + var cp1; + var x12 = (p1[0] + p2[0]) / 2; + var y12 = (p1[1] + p2[1]) / 2; + if (+curveness) { + curveness *= 3; + cp1 = [cx * curveness + x12 * (1 - curveness), cy * curveness + y12 * (1 - curveness)]; + } + edge.setLayout([p1, p2, cp1]); + }); + } + var _layoutNodesBasedOn = { + value: function (seriesModel, graph, nodeData, r, cx, cy, count) { + var angle = 0; + var sum = nodeData.getSum('value'); + var unitAngle = Math.PI * 2 / (sum || count); + graph.eachNode(function (node) { + var value = node.getValue('value'); + var radianHalf = unitAngle * (sum ? value : 1) / 2; + angle += radianHalf; + node.setLayout([r * Math.cos(angle) + cx, r * Math.sin(angle) + cy]); + angle += radianHalf; + }); + }, + symbolSize: function (seriesModel, graph, nodeData, r, cx, cy, count) { + var sumRadian = 0; + _symbolRadiansHalf.length = count; + var nodeScale = getNodeGlobalScale(seriesModel); + graph.eachNode(function (node) { + var symbolSize = getSymbolSize(node); + // Normally this case will not happen, but we still add + // some the defensive code (2px is an arbitrary value). + isNaN(symbolSize) && (symbolSize = 2); + symbolSize < 0 && (symbolSize = 0); + symbolSize *= nodeScale; + var symbolRadianHalf = Math.asin(symbolSize / 2 / r); + // when `symbolSize / 2` is bigger than `r`. + isNaN(symbolRadianHalf) && (symbolRadianHalf = PI$6 / 2); + _symbolRadiansHalf[node.dataIndex] = symbolRadianHalf; + sumRadian += symbolRadianHalf * 2; + }); + var halfRemainRadian = (2 * PI$6 - sumRadian) / count / 2; + var angle = 0; + graph.eachNode(function (node) { + var radianHalf = halfRemainRadian + _symbolRadiansHalf[node.dataIndex]; + angle += radianHalf; + // init circular layout for + // 1. layout undefined node + // 2. not fixed node + (!node.getLayout() || !node.getLayout().fixed) && node.setLayout([r * Math.cos(angle) + cx, r * Math.sin(angle) + cy]); + angle += radianHalf; + }); + } + }; + function rotateNodeLabel(node, circularRotateLabel, cx, cy) { + var el = node.getGraphicEl(); + // need to check if el exists. '-' value may not create node element. + if (!el) { + return; + } + var nodeModel = node.getModel(); + var labelRotate = nodeModel.get(['label', 'rotate']) || 0; + var symbolPath = el.getSymbolPath(); + if (circularRotateLabel) { + var pos = node.getLayout(); + var rad = Math.atan2(pos[1] - cy, pos[0] - cx); + if (rad < 0) { + rad = Math.PI * 2 + rad; + } + var isLeft = pos[0] < cx; + if (isLeft) { + rad = rad - Math.PI; + } + var textPosition = isLeft ? 'left' : 'right'; + symbolPath.setTextConfig({ + rotation: -rad, + position: textPosition, + origin: 'center' + }); + var emphasisState = symbolPath.ensureState('emphasis'); + extend(emphasisState.textConfig || (emphasisState.textConfig = {}), { + position: textPosition + }); + } else { + symbolPath.setTextConfig({ + rotation: labelRotate *= Math.PI / 180 + }); + } + } + + function graphCircularLayout(ecModel) { + ecModel.eachSeriesByType('graph', function (seriesModel) { + if (seriesModel.get('layout') === 'circular') { + circularLayout(seriesModel, 'symbolSize'); + } + }); + } + + var scaleAndAdd$1 = scaleAndAdd; + // function adjacentNode(n, e) { + // return e.n1 === n ? e.n2 : e.n1; + // } + function forceLayout(inNodes, inEdges, opts) { + var nodes = inNodes; + var edges = inEdges; + var rect = opts.rect; + var width = rect.width; + var height = rect.height; + var center = [rect.x + width / 2, rect.y + height / 2]; + // let scale = opts.scale || 1; + var gravity = opts.gravity == null ? 0.1 : opts.gravity; + // for (let i = 0; i < edges.length; i++) { + // let e = edges[i]; + // let n1 = e.n1; + // let n2 = e.n2; + // n1.edges = n1.edges || []; + // n2.edges = n2.edges || []; + // n1.edges.push(e); + // n2.edges.push(e); + // } + // Init position + for (var i = 0; i < nodes.length; i++) { + var n = nodes[i]; + if (!n.p) { + n.p = create(width * (Math.random() - 0.5) + center[0], height * (Math.random() - 0.5) + center[1]); + } + n.pp = clone$1(n.p); + n.edges = null; + } + // Formula in 'Graph Drawing by Force-directed Placement' + // let k = scale * Math.sqrt(width * height / nodes.length); + // let k2 = k * k; + var initialFriction = opts.friction == null ? 0.6 : opts.friction; + var friction = initialFriction; + var beforeStepCallback; + var afterStepCallback; + return { + warmUp: function () { + friction = initialFriction * 0.8; + }, + setFixed: function (idx) { + nodes[idx].fixed = true; + }, + setUnfixed: function (idx) { + nodes[idx].fixed = false; + }, + /** + * Before step hook + */ + beforeStep: function (cb) { + beforeStepCallback = cb; + }, + /** + * After step hook + */ + afterStep: function (cb) { + afterStepCallback = cb; + }, + /** + * Some formulas were originally copied from "d3.js" + * https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/layout/force.js + * with some modifications made for this project. + * See the license statement at the head of this file. + */ + step: function (cb) { + beforeStepCallback && beforeStepCallback(nodes, edges); + var v12 = []; + var nLen = nodes.length; + for (var i = 0; i < edges.length; i++) { + var e = edges[i]; + if (e.ignoreForceLayout) { + continue; + } + var n1 = e.n1; + var n2 = e.n2; + sub(v12, n2.p, n1.p); + var d = len(v12) - e.d; + var w = n2.w / (n1.w + n2.w); + if (isNaN(w)) { + w = 0; + } + normalize(v12, v12); + !n1.fixed && scaleAndAdd$1(n1.p, n1.p, v12, w * d * friction); + !n2.fixed && scaleAndAdd$1(n2.p, n2.p, v12, -(1 - w) * d * friction); + } + // Gravity + for (var i = 0; i < nLen; i++) { + var n = nodes[i]; + if (!n.fixed) { + sub(v12, center, n.p); + // let d = vec2.len(v12); + // vec2.scale(v12, v12, 1 / d); + // let gravityFactor = gravity; + scaleAndAdd$1(n.p, n.p, v12, gravity * friction); + } + } + // Repulsive + // PENDING + for (var i = 0; i < nLen; i++) { + var n1 = nodes[i]; + for (var j = i + 1; j < nLen; j++) { + var n2 = nodes[j]; + sub(v12, n2.p, n1.p); + var d = len(v12); + if (d === 0) { + // Random repulse + set(v12, Math.random() - 0.5, Math.random() - 0.5); + d = 1; + } + var repFact = (n1.rep + n2.rep) / d / d; + !n1.fixed && scaleAndAdd$1(n1.pp, n1.pp, v12, repFact); + !n2.fixed && scaleAndAdd$1(n2.pp, n2.pp, v12, -repFact); + } + } + var v = []; + for (var i = 0; i < nLen; i++) { + var n = nodes[i]; + if (!n.fixed) { + sub(v, n.p, n.pp); + scaleAndAdd$1(n.p, n.p, v, friction); + copy(n.pp, n.p); + } + } + friction = friction * 0.992; + var finished = friction < 0.01; + afterStepCallback && afterStepCallback(nodes, edges, finished); + cb && cb(finished); + } + }; + } + + function graphForceLayout(ecModel) { + ecModel.eachSeriesByType('graph', function (graphSeries) { + var coordSys = graphSeries.coordinateSystem; + if (coordSys && coordSys.type !== 'view') { + return; + } + if (graphSeries.get('layout') === 'force') { + var preservedPoints_1 = graphSeries.preservedPoints || {}; + var graph_1 = graphSeries.getGraph(); + var nodeData_1 = graph_1.data; + var edgeData = graph_1.edgeData; + var forceModel = graphSeries.getModel('force'); + var initLayout = forceModel.get('initLayout'); + if (graphSeries.preservedPoints) { + nodeData_1.each(function (idx) { + var id = nodeData_1.getId(idx); + nodeData_1.setItemLayout(idx, preservedPoints_1[id] || [NaN, NaN]); + }); + } else if (!initLayout || initLayout === 'none') { + simpleLayout(graphSeries); + } else if (initLayout === 'circular') { + circularLayout(graphSeries, 'value'); + } + var nodeDataExtent_1 = nodeData_1.getDataExtent('value'); + var edgeDataExtent_1 = edgeData.getDataExtent('value'); + // let edgeDataExtent = edgeData.getDataExtent('value'); + var repulsion = forceModel.get('repulsion'); + var edgeLength = forceModel.get('edgeLength'); + var repulsionArr_1 = isArray(repulsion) ? repulsion : [repulsion, repulsion]; + var edgeLengthArr_1 = isArray(edgeLength) ? edgeLength : [edgeLength, edgeLength]; + // Larger value has smaller length + edgeLengthArr_1 = [edgeLengthArr_1[1], edgeLengthArr_1[0]]; + var nodes_1 = nodeData_1.mapArray('value', function (value, idx) { + var point = nodeData_1.getItemLayout(idx); + var rep = linearMap(value, nodeDataExtent_1, repulsionArr_1); + if (isNaN(rep)) { + rep = (repulsionArr_1[0] + repulsionArr_1[1]) / 2; + } + return { + w: rep, + rep: rep, + fixed: nodeData_1.getItemModel(idx).get('fixed'), + p: !point || isNaN(point[0]) || isNaN(point[1]) ? null : point + }; + }); + var edges = edgeData.mapArray('value', function (value, idx) { + var edge = graph_1.getEdgeByIndex(idx); + var d = linearMap(value, edgeDataExtent_1, edgeLengthArr_1); + if (isNaN(d)) { + d = (edgeLengthArr_1[0] + edgeLengthArr_1[1]) / 2; + } + var edgeModel = edge.getModel(); + var curveness = retrieve3(edge.getModel().get(['lineStyle', 'curveness']), -getCurvenessForEdge(edge, graphSeries, idx, true), 0); + return { + n1: nodes_1[edge.node1.dataIndex], + n2: nodes_1[edge.node2.dataIndex], + d: d, + curveness: curveness, + ignoreForceLayout: edgeModel.get('ignoreForceLayout') + }; + }); + // let coordSys = graphSeries.coordinateSystem; + var rect = coordSys.getBoundingRect(); + var forceInstance = forceLayout(nodes_1, edges, { + rect: rect, + gravity: forceModel.get('gravity'), + friction: forceModel.get('friction') + }); + forceInstance.beforeStep(function (nodes, edges) { + for (var i = 0, l = nodes.length; i < l; i++) { + if (nodes[i].fixed) { + // Write back to layout instance + copy(nodes[i].p, graph_1.getNodeByIndex(i).getLayout()); + } + } + }); + forceInstance.afterStep(function (nodes, edges, stopped) { + for (var i = 0, l = nodes.length; i < l; i++) { + if (!nodes[i].fixed) { + graph_1.getNodeByIndex(i).setLayout(nodes[i].p); + } + preservedPoints_1[nodeData_1.getId(i)] = nodes[i].p; + } + for (var i = 0, l = edges.length; i < l; i++) { + var e = edges[i]; + var edge = graph_1.getEdgeByIndex(i); + var p1 = e.n1.p; + var p2 = e.n2.p; + var points = edge.getLayout(); + points = points ? points.slice() : []; + points[0] = points[0] || []; + points[1] = points[1] || []; + copy(points[0], p1); + copy(points[1], p2); + if (+e.curveness) { + points[2] = [(p1[0] + p2[0]) / 2 - (p1[1] - p2[1]) * e.curveness, (p1[1] + p2[1]) / 2 - (p2[0] - p1[0]) * e.curveness]; + } + edge.setLayout(points); + } + }); + graphSeries.forceLayout = forceInstance; + graphSeries.preservedPoints = preservedPoints_1; + // Step to get the layout + forceInstance.step(); + } else { + // Remove prev injected forceLayout instance + graphSeries.forceLayout = null; + } + }); + } + + function getViewRect$2(seriesModel, api, aspect) { + var option = extend(seriesModel.getBoxLayoutParams(), { + aspect: aspect + }); + return getLayoutRect(option, { + width: api.getWidth(), + height: api.getHeight() + }); + } + function createViewCoordSys(ecModel, api) { + var viewList = []; + ecModel.eachSeriesByType('graph', function (seriesModel) { + var coordSysType = seriesModel.get('coordinateSystem'); + if (!coordSysType || coordSysType === 'view') { + var data_1 = seriesModel.getData(); + var positions = data_1.mapArray(function (idx) { + var itemModel = data_1.getItemModel(idx); + return [+itemModel.get('x'), +itemModel.get('y')]; + }); + var min = []; + var max = []; + fromPoints(positions, min, max); + // If width or height is 0 + if (max[0] - min[0] === 0) { + max[0] += 1; + min[0] -= 1; + } + if (max[1] - min[1] === 0) { + max[1] += 1; + min[1] -= 1; + } + var aspect = (max[0] - min[0]) / (max[1] - min[1]); + // FIXME If get view rect after data processed? + var viewRect = getViewRect$2(seriesModel, api, aspect); + // Position may be NaN, use view rect instead + if (isNaN(aspect)) { + min = [viewRect.x, viewRect.y]; + max = [viewRect.x + viewRect.width, viewRect.y + viewRect.height]; + } + var bbWidth = max[0] - min[0]; + var bbHeight = max[1] - min[1]; + var viewWidth = viewRect.width; + var viewHeight = viewRect.height; + var viewCoordSys = seriesModel.coordinateSystem = new View(); + viewCoordSys.zoomLimit = seriesModel.get('scaleLimit'); + viewCoordSys.setBoundingRect(min[0], min[1], bbWidth, bbHeight); + viewCoordSys.setViewRect(viewRect.x, viewRect.y, viewWidth, viewHeight); + // Update roam info + viewCoordSys.setCenter(seriesModel.get('center'), api); + viewCoordSys.setZoom(seriesModel.get('zoom')); + viewList.push(viewCoordSys); + } + }); + return viewList; + } + + var straightLineProto = Line.prototype; + var bezierCurveProto = BezierCurve.prototype; + var StraightLineShape = /** @class */function () { + function StraightLineShape() { + // Start point + this.x1 = 0; + this.y1 = 0; + // End point + this.x2 = 0; + this.y2 = 0; + this.percent = 1; + } + return StraightLineShape; + }(); + var CurveShape = /** @class */function (_super) { + __extends(CurveShape, _super); + function CurveShape() { + return _super !== null && _super.apply(this, arguments) || this; + } + return CurveShape; + }(StraightLineShape); + function isStraightLine(shape) { + return isNaN(+shape.cpx1) || isNaN(+shape.cpy1); + } + var ECLinePath = /** @class */function (_super) { + __extends(ECLinePath, _super); + function ECLinePath(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'ec-line'; + return _this; + } + ECLinePath.prototype.getDefaultStyle = function () { + return { + stroke: '#000', + fill: null + }; + }; + ECLinePath.prototype.getDefaultShape = function () { + return new StraightLineShape(); + }; + ECLinePath.prototype.buildPath = function (ctx, shape) { + if (isStraightLine(shape)) { + straightLineProto.buildPath.call(this, ctx, shape); + } else { + bezierCurveProto.buildPath.call(this, ctx, shape); + } + }; + ECLinePath.prototype.pointAt = function (t) { + if (isStraightLine(this.shape)) { + return straightLineProto.pointAt.call(this, t); + } else { + return bezierCurveProto.pointAt.call(this, t); + } + }; + ECLinePath.prototype.tangentAt = function (t) { + var shape = this.shape; + var p = isStraightLine(shape) ? [shape.x2 - shape.x1, shape.y2 - shape.y1] : bezierCurveProto.tangentAt.call(this, t); + return normalize(p, p); + }; + return ECLinePath; + }(Path); + + var SYMBOL_CATEGORIES = ['fromSymbol', 'toSymbol']; + function makeSymbolTypeKey(symbolCategory) { + return '_' + symbolCategory + 'Type'; + } + function makeSymbolTypeValue(name, lineData, idx) { + var symbolType = lineData.getItemVisual(idx, name); + if (!symbolType || symbolType === 'none') { + return symbolType; + } + var symbolSize = lineData.getItemVisual(idx, name + 'Size'); + var symbolRotate = lineData.getItemVisual(idx, name + 'Rotate'); + var symbolOffset = lineData.getItemVisual(idx, name + 'Offset'); + var symbolKeepAspect = lineData.getItemVisual(idx, name + 'KeepAspect'); + var symbolSizeArr = normalizeSymbolSize(symbolSize); + var symbolOffsetArr = normalizeSymbolOffset(symbolOffset || 0, symbolSizeArr); + return symbolType + symbolSizeArr + symbolOffsetArr + (symbolRotate || '') + (symbolKeepAspect || ''); + } + /** + * @inner + */ + function createSymbol$1(name, lineData, idx) { + var symbolType = lineData.getItemVisual(idx, name); + if (!symbolType || symbolType === 'none') { + return; + } + var symbolSize = lineData.getItemVisual(idx, name + 'Size'); + var symbolRotate = lineData.getItemVisual(idx, name + 'Rotate'); + var symbolOffset = lineData.getItemVisual(idx, name + 'Offset'); + var symbolKeepAspect = lineData.getItemVisual(idx, name + 'KeepAspect'); + var symbolSizeArr = normalizeSymbolSize(symbolSize); + var symbolOffsetArr = normalizeSymbolOffset(symbolOffset || 0, symbolSizeArr); + var symbolPath = createSymbol(symbolType, -symbolSizeArr[0] / 2 + symbolOffsetArr[0], -symbolSizeArr[1] / 2 + symbolOffsetArr[1], symbolSizeArr[0], symbolSizeArr[1], null, symbolKeepAspect); + symbolPath.__specifiedRotation = symbolRotate == null || isNaN(symbolRotate) ? void 0 : +symbolRotate * Math.PI / 180 || 0; + symbolPath.name = name; + return symbolPath; + } + function createLine(points) { + var line = new ECLinePath({ + name: 'line', + subPixelOptimize: true + }); + setLinePoints(line.shape, points); + return line; + } + function setLinePoints(targetShape, points) { + targetShape.x1 = points[0][0]; + targetShape.y1 = points[0][1]; + targetShape.x2 = points[1][0]; + targetShape.y2 = points[1][1]; + targetShape.percent = 1; + var cp1 = points[2]; + if (cp1) { + targetShape.cpx1 = cp1[0]; + targetShape.cpy1 = cp1[1]; + } else { + targetShape.cpx1 = NaN; + targetShape.cpy1 = NaN; + } + } + var Line$1 = /** @class */function (_super) { + __extends(Line, _super); + function Line(lineData, idx, seriesScope) { + var _this = _super.call(this) || this; + _this._createLine(lineData, idx, seriesScope); + return _this; + } + Line.prototype._createLine = function (lineData, idx, seriesScope) { + var seriesModel = lineData.hostModel; + var linePoints = lineData.getItemLayout(idx); + var line = createLine(linePoints); + line.shape.percent = 0; + initProps(line, { + shape: { + percent: 1 + } + }, seriesModel, idx); + this.add(line); + each(SYMBOL_CATEGORIES, function (symbolCategory) { + var symbol = createSymbol$1(symbolCategory, lineData, idx); + // symbols must added after line to make sure + // it will be updated after line#update. + // Or symbol position and rotation update in line#beforeUpdate will be one frame slow + this.add(symbol); + this[makeSymbolTypeKey(symbolCategory)] = makeSymbolTypeValue(symbolCategory, lineData, idx); + }, this); + this._updateCommonStl(lineData, idx, seriesScope); + }; + // TODO More strict on the List type in parameters? + Line.prototype.updateData = function (lineData, idx, seriesScope) { + var seriesModel = lineData.hostModel; + var line = this.childOfName('line'); + var linePoints = lineData.getItemLayout(idx); + var target = { + shape: {} + }; + setLinePoints(target.shape, linePoints); + updateProps(line, target, seriesModel, idx); + each(SYMBOL_CATEGORIES, function (symbolCategory) { + var symbolType = makeSymbolTypeValue(symbolCategory, lineData, idx); + var key = makeSymbolTypeKey(symbolCategory); + // Symbol changed + if (this[key] !== symbolType) { + this.remove(this.childOfName(symbolCategory)); + var symbol = createSymbol$1(symbolCategory, lineData, idx); + this.add(symbol); + } + this[key] = symbolType; + }, this); + this._updateCommonStl(lineData, idx, seriesScope); + }; + Line.prototype.getLinePath = function () { + return this.childAt(0); + }; + Line.prototype._updateCommonStl = function (lineData, idx, seriesScope) { + var seriesModel = lineData.hostModel; + var line = this.childOfName('line'); + var emphasisLineStyle = seriesScope && seriesScope.emphasisLineStyle; + var blurLineStyle = seriesScope && seriesScope.blurLineStyle; + var selectLineStyle = seriesScope && seriesScope.selectLineStyle; + var labelStatesModels = seriesScope && seriesScope.labelStatesModels; + var emphasisDisabled = seriesScope && seriesScope.emphasisDisabled; + var focus = seriesScope && seriesScope.focus; + var blurScope = seriesScope && seriesScope.blurScope; + // Optimization for large dataset + if (!seriesScope || lineData.hasItemOption) { + var itemModel = lineData.getItemModel(idx); + var emphasisModel = itemModel.getModel('emphasis'); + emphasisLineStyle = emphasisModel.getModel('lineStyle').getLineStyle(); + blurLineStyle = itemModel.getModel(['blur', 'lineStyle']).getLineStyle(); + selectLineStyle = itemModel.getModel(['select', 'lineStyle']).getLineStyle(); + emphasisDisabled = emphasisModel.get('disabled'); + focus = emphasisModel.get('focus'); + blurScope = emphasisModel.get('blurScope'); + labelStatesModels = getLabelStatesModels(itemModel); + } + var lineStyle = lineData.getItemVisual(idx, 'style'); + var visualColor = lineStyle.stroke; + line.useStyle(lineStyle); + line.style.fill = null; + line.style.strokeNoScale = true; + line.ensureState('emphasis').style = emphasisLineStyle; + line.ensureState('blur').style = blurLineStyle; + line.ensureState('select').style = selectLineStyle; + // Update symbol + each(SYMBOL_CATEGORIES, function (symbolCategory) { + var symbol = this.childOfName(symbolCategory); + if (symbol) { + // Share opacity and color with line. + symbol.setColor(visualColor); + symbol.style.opacity = lineStyle.opacity; + for (var i = 0; i < SPECIAL_STATES.length; i++) { + var stateName = SPECIAL_STATES[i]; + var lineState = line.getState(stateName); + if (lineState) { + var lineStateStyle = lineState.style || {}; + var state = symbol.ensureState(stateName); + var stateStyle = state.style || (state.style = {}); + if (lineStateStyle.stroke != null) { + stateStyle[symbol.__isEmptyBrush ? 'stroke' : 'fill'] = lineStateStyle.stroke; + } + if (lineStateStyle.opacity != null) { + stateStyle.opacity = lineStateStyle.opacity; + } + } + } + symbol.markRedraw(); + } + }, this); + var rawVal = seriesModel.getRawValue(idx); + setLabelStyle(this, labelStatesModels, { + labelDataIndex: idx, + labelFetcher: { + getFormattedLabel: function (dataIndex, stateName) { + return seriesModel.getFormattedLabel(dataIndex, stateName, lineData.dataType); + } + }, + inheritColor: visualColor || '#000', + defaultOpacity: lineStyle.opacity, + defaultText: (rawVal == null ? lineData.getName(idx) : isFinite(rawVal) ? round(rawVal) : rawVal) + '' + }); + var label = this.getTextContent(); + // Always set `textStyle` even if `normalStyle.text` is null, because default + // values have to be set on `normalStyle`. + if (label) { + var labelNormalModel = labelStatesModels.normal; + label.__align = label.style.align; + label.__verticalAlign = label.style.verticalAlign; + // 'start', 'middle', 'end' + label.__position = labelNormalModel.get('position') || 'middle'; + var distance = labelNormalModel.get('distance'); + if (!isArray(distance)) { + distance = [distance, distance]; + } + label.__labelDistance = distance; + } + this.setTextConfig({ + position: null, + local: true, + inside: false // Can't be inside for stroke element. + }); + + toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled); + }; + Line.prototype.highlight = function () { + enterEmphasis(this); + }; + Line.prototype.downplay = function () { + leaveEmphasis(this); + }; + Line.prototype.updateLayout = function (lineData, idx) { + this.setLinePoints(lineData.getItemLayout(idx)); + }; + Line.prototype.setLinePoints = function (points) { + var linePath = this.childOfName('line'); + setLinePoints(linePath.shape, points); + linePath.dirty(); + }; + Line.prototype.beforeUpdate = function () { + var lineGroup = this; + var symbolFrom = lineGroup.childOfName('fromSymbol'); + var symbolTo = lineGroup.childOfName('toSymbol'); + var label = lineGroup.getTextContent(); + // Quick reject + if (!symbolFrom && !symbolTo && (!label || label.ignore)) { + return; + } + var invScale = 1; + var parentNode = this.parent; + while (parentNode) { + if (parentNode.scaleX) { + invScale /= parentNode.scaleX; + } + parentNode = parentNode.parent; + } + var line = lineGroup.childOfName('line'); + // If line not changed + // FIXME Parent scale changed + if (!this.__dirty && !line.__dirty) { + return; + } + var percent = line.shape.percent; + var fromPos = line.pointAt(0); + var toPos = line.pointAt(percent); + var d = sub([], toPos, fromPos); + normalize(d, d); + function setSymbolRotation(symbol, percent) { + // Fix #12388 + // when symbol is set to be 'arrow' in markLine, + // symbolRotate value will be ignored, and compulsively use tangent angle. + // rotate by default if symbol rotation is not specified + var specifiedRotation = symbol.__specifiedRotation; + if (specifiedRotation == null) { + var tangent = line.tangentAt(percent); + symbol.attr('rotation', (percent === 1 ? -1 : 1) * Math.PI / 2 - Math.atan2(tangent[1], tangent[0])); + } else { + symbol.attr('rotation', specifiedRotation); + } + } + if (symbolFrom) { + symbolFrom.setPosition(fromPos); + setSymbolRotation(symbolFrom, 0); + symbolFrom.scaleX = symbolFrom.scaleY = invScale * percent; + symbolFrom.markRedraw(); + } + if (symbolTo) { + symbolTo.setPosition(toPos); + setSymbolRotation(symbolTo, 1); + symbolTo.scaleX = symbolTo.scaleY = invScale * percent; + symbolTo.markRedraw(); + } + if (label && !label.ignore) { + label.x = label.y = 0; + label.originX = label.originY = 0; + var textAlign = void 0; + var textVerticalAlign = void 0; + var distance = label.__labelDistance; + var distanceX = distance[0] * invScale; + var distanceY = distance[1] * invScale; + var halfPercent = percent / 2; + var tangent = line.tangentAt(halfPercent); + var n = [tangent[1], -tangent[0]]; + var cp = line.pointAt(halfPercent); + if (n[1] > 0) { + n[0] = -n[0]; + n[1] = -n[1]; + } + var dir = tangent[0] < 0 ? -1 : 1; + if (label.__position !== 'start' && label.__position !== 'end') { + var rotation = -Math.atan2(tangent[1], tangent[0]); + if (toPos[0] < fromPos[0]) { + rotation = Math.PI + rotation; + } + label.rotation = rotation; + } + var dy = void 0; + switch (label.__position) { + case 'insideStartTop': + case 'insideMiddleTop': + case 'insideEndTop': + case 'middle': + dy = -distanceY; + textVerticalAlign = 'bottom'; + break; + case 'insideStartBottom': + case 'insideMiddleBottom': + case 'insideEndBottom': + dy = distanceY; + textVerticalAlign = 'top'; + break; + default: + dy = 0; + textVerticalAlign = 'middle'; + } + switch (label.__position) { + case 'end': + label.x = d[0] * distanceX + toPos[0]; + label.y = d[1] * distanceY + toPos[1]; + textAlign = d[0] > 0.8 ? 'left' : d[0] < -0.8 ? 'right' : 'center'; + textVerticalAlign = d[1] > 0.8 ? 'top' : d[1] < -0.8 ? 'bottom' : 'middle'; + break; + case 'start': + label.x = -d[0] * distanceX + fromPos[0]; + label.y = -d[1] * distanceY + fromPos[1]; + textAlign = d[0] > 0.8 ? 'right' : d[0] < -0.8 ? 'left' : 'center'; + textVerticalAlign = d[1] > 0.8 ? 'bottom' : d[1] < -0.8 ? 'top' : 'middle'; + break; + case 'insideStartTop': + case 'insideStart': + case 'insideStartBottom': + label.x = distanceX * dir + fromPos[0]; + label.y = fromPos[1] + dy; + textAlign = tangent[0] < 0 ? 'right' : 'left'; + label.originX = -distanceX * dir; + label.originY = -dy; + break; + case 'insideMiddleTop': + case 'insideMiddle': + case 'insideMiddleBottom': + case 'middle': + label.x = cp[0]; + label.y = cp[1] + dy; + textAlign = 'center'; + label.originY = -dy; + break; + case 'insideEndTop': + case 'insideEnd': + case 'insideEndBottom': + label.x = -distanceX * dir + toPos[0]; + label.y = toPos[1] + dy; + textAlign = tangent[0] >= 0 ? 'right' : 'left'; + label.originX = distanceX * dir; + label.originY = -dy; + break; + } + label.scaleX = label.scaleY = invScale; + label.setStyle({ + // Use the user specified text align and baseline first + verticalAlign: label.__verticalAlign || textVerticalAlign, + align: label.__align || textAlign + }); + } + }; + return Line; + }(Group); + + var LineDraw = /** @class */function () { + function LineDraw(LineCtor) { + this.group = new Group(); + this._LineCtor = LineCtor || Line$1; + } + LineDraw.prototype.updateData = function (lineData) { + var _this = this; + // Remove progressive els. + this._progressiveEls = null; + var lineDraw = this; + var group = lineDraw.group; + var oldLineData = lineDraw._lineData; + lineDraw._lineData = lineData; + // There is no oldLineData only when first rendering or switching from + // stream mode to normal mode, where previous elements should be removed. + if (!oldLineData) { + group.removeAll(); + } + var seriesScope = makeSeriesScope$1(lineData); + lineData.diff(oldLineData).add(function (idx) { + _this._doAdd(lineData, idx, seriesScope); + }).update(function (newIdx, oldIdx) { + _this._doUpdate(oldLineData, lineData, oldIdx, newIdx, seriesScope); + }).remove(function (idx) { + group.remove(oldLineData.getItemGraphicEl(idx)); + }).execute(); + }; + LineDraw.prototype.updateLayout = function () { + var lineData = this._lineData; + // Do not support update layout in incremental mode. + if (!lineData) { + return; + } + lineData.eachItemGraphicEl(function (el, idx) { + el.updateLayout(lineData, idx); + }, this); + }; + LineDraw.prototype.incrementalPrepareUpdate = function (lineData) { + this._seriesScope = makeSeriesScope$1(lineData); + this._lineData = null; + this.group.removeAll(); + }; + LineDraw.prototype.incrementalUpdate = function (taskParams, lineData) { + this._progressiveEls = []; + function updateIncrementalAndHover(el) { + if (!el.isGroup && !isEffectObject(el)) { + el.incremental = true; + el.ensureState('emphasis').hoverLayer = true; + } + } + for (var idx = taskParams.start; idx < taskParams.end; idx++) { + var itemLayout = lineData.getItemLayout(idx); + if (lineNeedsDraw(itemLayout)) { + var el = new this._LineCtor(lineData, idx, this._seriesScope); + el.traverse(updateIncrementalAndHover); + this.group.add(el); + lineData.setItemGraphicEl(idx, el); + this._progressiveEls.push(el); + } + } + }; + LineDraw.prototype.remove = function () { + this.group.removeAll(); + }; + LineDraw.prototype.eachRendered = function (cb) { + traverseElements(this._progressiveEls || this.group, cb); + }; + LineDraw.prototype._doAdd = function (lineData, idx, seriesScope) { + var itemLayout = lineData.getItemLayout(idx); + if (!lineNeedsDraw(itemLayout)) { + return; + } + var el = new this._LineCtor(lineData, idx, seriesScope); + lineData.setItemGraphicEl(idx, el); + this.group.add(el); + }; + LineDraw.prototype._doUpdate = function (oldLineData, newLineData, oldIdx, newIdx, seriesScope) { + var itemEl = oldLineData.getItemGraphicEl(oldIdx); + if (!lineNeedsDraw(newLineData.getItemLayout(newIdx))) { + this.group.remove(itemEl); + return; + } + if (!itemEl) { + itemEl = new this._LineCtor(newLineData, newIdx, seriesScope); + } else { + itemEl.updateData(newLineData, newIdx, seriesScope); + } + newLineData.setItemGraphicEl(newIdx, itemEl); + this.group.add(itemEl); + }; + return LineDraw; + }(); + function isEffectObject(el) { + return el.animators && el.animators.length > 0; + } + function makeSeriesScope$1(lineData) { + var hostModel = lineData.hostModel; + var emphasisModel = hostModel.getModel('emphasis'); + return { + lineStyle: hostModel.getModel('lineStyle').getLineStyle(), + emphasisLineStyle: emphasisModel.getModel(['lineStyle']).getLineStyle(), + blurLineStyle: hostModel.getModel(['blur', 'lineStyle']).getLineStyle(), + selectLineStyle: hostModel.getModel(['select', 'lineStyle']).getLineStyle(), + emphasisDisabled: emphasisModel.get('disabled'), + blurScope: emphasisModel.get('blurScope'), + focus: emphasisModel.get('focus'), + labelStatesModels: getLabelStatesModels(hostModel) + }; + } + function isPointNaN(pt) { + return isNaN(pt[0]) || isNaN(pt[1]); + } + function lineNeedsDraw(pts) { + return pts && !isPointNaN(pts[0]) && !isPointNaN(pts[1]); + } + + var v1 = []; + var v2 = []; + var v3 = []; + var quadraticAt$1 = quadraticAt; + var v2DistSquare = distSquare; + var mathAbs$2 = Math.abs; + function intersectCurveCircle(curvePoints, center, radius) { + var p0 = curvePoints[0]; + var p1 = curvePoints[1]; + var p2 = curvePoints[2]; + var d = Infinity; + var t; + var radiusSquare = radius * radius; + var interval = 0.1; + for (var _t = 0.1; _t <= 0.9; _t += 0.1) { + v1[0] = quadraticAt$1(p0[0], p1[0], p2[0], _t); + v1[1] = quadraticAt$1(p0[1], p1[1], p2[1], _t); + var diff = mathAbs$2(v2DistSquare(v1, center) - radiusSquare); + if (diff < d) { + d = diff; + t = _t; + } + } + // Assume the segment is monotone,Find root through Bisection method + // At most 32 iteration + for (var i = 0; i < 32; i++) { + // let prev = t - interval; + var next = t + interval; + // v1[0] = quadraticAt(p0[0], p1[0], p2[0], prev); + // v1[1] = quadraticAt(p0[1], p1[1], p2[1], prev); + v2[0] = quadraticAt$1(p0[0], p1[0], p2[0], t); + v2[1] = quadraticAt$1(p0[1], p1[1], p2[1], t); + v3[0] = quadraticAt$1(p0[0], p1[0], p2[0], next); + v3[1] = quadraticAt$1(p0[1], p1[1], p2[1], next); + var diff = v2DistSquare(v2, center) - radiusSquare; + if (mathAbs$2(diff) < 1e-2) { + break; + } + // let prevDiff = v2DistSquare(v1, center) - radiusSquare; + var nextDiff = v2DistSquare(v3, center) - radiusSquare; + interval /= 2; + if (diff < 0) { + if (nextDiff >= 0) { + t = t + interval; + } else { + t = t - interval; + } + } else { + if (nextDiff >= 0) { + t = t - interval; + } else { + t = t + interval; + } + } + } + return t; + } + // Adjust edge to avoid + function adjustEdge(graph, scale) { + var tmp0 = []; + var quadraticSubdivide$1 = quadraticSubdivide; + var pts = [[], [], []]; + var pts2 = [[], []]; + var v = []; + scale /= 2; + graph.eachEdge(function (edge, idx) { + var linePoints = edge.getLayout(); + var fromSymbol = edge.getVisual('fromSymbol'); + var toSymbol = edge.getVisual('toSymbol'); + if (!linePoints.__original) { + linePoints.__original = [clone$1(linePoints[0]), clone$1(linePoints[1])]; + if (linePoints[2]) { + linePoints.__original.push(clone$1(linePoints[2])); + } + } + var originalPoints = linePoints.__original; + // Quadratic curve + if (linePoints[2] != null) { + copy(pts[0], originalPoints[0]); + copy(pts[1], originalPoints[2]); + copy(pts[2], originalPoints[1]); + if (fromSymbol && fromSymbol !== 'none') { + var symbolSize = getSymbolSize(edge.node1); + var t = intersectCurveCircle(pts, originalPoints[0], symbolSize * scale); + // Subdivide and get the second + quadraticSubdivide$1(pts[0][0], pts[1][0], pts[2][0], t, tmp0); + pts[0][0] = tmp0[3]; + pts[1][0] = tmp0[4]; + quadraticSubdivide$1(pts[0][1], pts[1][1], pts[2][1], t, tmp0); + pts[0][1] = tmp0[3]; + pts[1][1] = tmp0[4]; + } + if (toSymbol && toSymbol !== 'none') { + var symbolSize = getSymbolSize(edge.node2); + var t = intersectCurveCircle(pts, originalPoints[1], symbolSize * scale); + // Subdivide and get the first + quadraticSubdivide$1(pts[0][0], pts[1][0], pts[2][0], t, tmp0); + pts[1][0] = tmp0[1]; + pts[2][0] = tmp0[2]; + quadraticSubdivide$1(pts[0][1], pts[1][1], pts[2][1], t, tmp0); + pts[1][1] = tmp0[1]; + pts[2][1] = tmp0[2]; + } + // Copy back to layout + copy(linePoints[0], pts[0]); + copy(linePoints[1], pts[2]); + copy(linePoints[2], pts[1]); + } + // Line + else { + copy(pts2[0], originalPoints[0]); + copy(pts2[1], originalPoints[1]); + sub(v, pts2[1], pts2[0]); + normalize(v, v); + if (fromSymbol && fromSymbol !== 'none') { + var symbolSize = getSymbolSize(edge.node1); + scaleAndAdd(pts2[0], pts2[0], v, symbolSize * scale); + } + if (toSymbol && toSymbol !== 'none') { + var symbolSize = getSymbolSize(edge.node2); + scaleAndAdd(pts2[1], pts2[1], v, -symbolSize * scale); + } + copy(linePoints[0], pts2[0]); + copy(linePoints[1], pts2[1]); + } + }); + } + + function isViewCoordSys(coordSys) { + return coordSys.type === 'view'; + } + var GraphView = /** @class */function (_super) { + __extends(GraphView, _super); + function GraphView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = GraphView.type; + return _this; + } + GraphView.prototype.init = function (ecModel, api) { + var symbolDraw = new SymbolDraw(); + var lineDraw = new LineDraw(); + var group = this.group; + this._controller = new RoamController(api.getZr()); + this._controllerHost = { + target: group + }; + group.add(symbolDraw.group); + group.add(lineDraw.group); + this._symbolDraw = symbolDraw; + this._lineDraw = lineDraw; + this._firstRender = true; + }; + GraphView.prototype.render = function (seriesModel, ecModel, api) { + var _this = this; + var coordSys = seriesModel.coordinateSystem; + this._model = seriesModel; + var symbolDraw = this._symbolDraw; + var lineDraw = this._lineDraw; + var group = this.group; + if (isViewCoordSys(coordSys)) { + var groupNewProp = { + x: coordSys.x, + y: coordSys.y, + scaleX: coordSys.scaleX, + scaleY: coordSys.scaleY + }; + if (this._firstRender) { + group.attr(groupNewProp); + } else { + updateProps(group, groupNewProp, seriesModel); + } + } + // Fix edge contact point with node + adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel)); + var data = seriesModel.getData(); + symbolDraw.updateData(data); + var edgeData = seriesModel.getEdgeData(); + // TODO: TYPE + lineDraw.updateData(edgeData); + this._updateNodeAndLinkScale(); + this._updateController(seriesModel, ecModel, api); + clearTimeout(this._layoutTimeout); + var forceLayout = seriesModel.forceLayout; + var layoutAnimation = seriesModel.get(['force', 'layoutAnimation']); + if (forceLayout) { + this._startForceLayoutIteration(forceLayout, layoutAnimation); + } + var layout = seriesModel.get('layout'); + data.graph.eachNode(function (node) { + var idx = node.dataIndex; + var el = node.getGraphicEl(); + var itemModel = node.getModel(); + if (!el) { + return; + } + // Update draggable + el.off('drag').off('dragend'); + var draggable = itemModel.get('draggable'); + if (draggable) { + el.on('drag', function (e) { + switch (layout) { + case 'force': + forceLayout.warmUp(); + !_this._layouting && _this._startForceLayoutIteration(forceLayout, layoutAnimation); + forceLayout.setFixed(idx); + // Write position back to layout + data.setItemLayout(idx, [el.x, el.y]); + break; + case 'circular': + data.setItemLayout(idx, [el.x, el.y]); + // mark node fixed + node.setLayout({ + fixed: true + }, true); + // recalculate circular layout + circularLayout(seriesModel, 'symbolSize', node, [e.offsetX, e.offsetY]); + _this.updateLayout(seriesModel); + break; + case 'none': + default: + data.setItemLayout(idx, [el.x, el.y]); + // update edge + simpleLayoutEdge(seriesModel.getGraph(), seriesModel); + _this.updateLayout(seriesModel); + break; + } + }).on('dragend', function () { + if (forceLayout) { + forceLayout.setUnfixed(idx); + } + }); + } + el.setDraggable(draggable, !!itemModel.get('cursor')); + var focus = itemModel.get(['emphasis', 'focus']); + if (focus === 'adjacency') { + getECData(el).focus = node.getAdjacentDataIndices(); + } + }); + data.graph.eachEdge(function (edge) { + var el = edge.getGraphicEl(); + var focus = edge.getModel().get(['emphasis', 'focus']); + if (!el) { + return; + } + if (focus === 'adjacency') { + getECData(el).focus = { + edge: [edge.dataIndex], + node: [edge.node1.dataIndex, edge.node2.dataIndex] + }; + } + }); + var circularRotateLabel = seriesModel.get('layout') === 'circular' && seriesModel.get(['circular', 'rotateLabel']); + var cx = data.getLayout('cx'); + var cy = data.getLayout('cy'); + data.graph.eachNode(function (node) { + rotateNodeLabel(node, circularRotateLabel, cx, cy); + }); + this._firstRender = false; + }; + GraphView.prototype.dispose = function () { + this.remove(); + this._controller && this._controller.dispose(); + this._controllerHost = null; + }; + GraphView.prototype._startForceLayoutIteration = function (forceLayout, layoutAnimation) { + var self = this; + (function step() { + forceLayout.step(function (stopped) { + self.updateLayout(self._model); + (self._layouting = !stopped) && (layoutAnimation ? self._layoutTimeout = setTimeout(step, 16) : step()); + }); + })(); + }; + GraphView.prototype._updateController = function (seriesModel, ecModel, api) { + var _this = this; + var controller = this._controller; + var controllerHost = this._controllerHost; + var group = this.group; + controller.setPointerChecker(function (e, x, y) { + var rect = group.getBoundingRect(); + rect.applyTransform(group.transform); + return rect.contain(x, y) && !onIrrelevantElement(e, api, seriesModel); + }); + if (!isViewCoordSys(seriesModel.coordinateSystem)) { + controller.disable(); + return; + } + controller.enable(seriesModel.get('roam')); + controllerHost.zoomLimit = seriesModel.get('scaleLimit'); + controllerHost.zoom = seriesModel.coordinateSystem.getZoom(); + controller.off('pan').off('zoom').on('pan', function (e) { + updateViewOnPan(controllerHost, e.dx, e.dy); + api.dispatchAction({ + seriesId: seriesModel.id, + type: 'graphRoam', + dx: e.dx, + dy: e.dy + }); + }).on('zoom', function (e) { + updateViewOnZoom(controllerHost, e.scale, e.originX, e.originY); + api.dispatchAction({ + seriesId: seriesModel.id, + type: 'graphRoam', + zoom: e.scale, + originX: e.originX, + originY: e.originY + }); + _this._updateNodeAndLinkScale(); + adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel)); + _this._lineDraw.updateLayout(); + // Only update label layout on zoom + api.updateLabelLayout(); + }); + }; + GraphView.prototype._updateNodeAndLinkScale = function () { + var seriesModel = this._model; + var data = seriesModel.getData(); + var nodeScale = getNodeGlobalScale(seriesModel); + data.eachItemGraphicEl(function (el, idx) { + el && el.setSymbolScale(nodeScale); + }); + }; + GraphView.prototype.updateLayout = function (seriesModel) { + adjustEdge(seriesModel.getGraph(), getNodeGlobalScale(seriesModel)); + this._symbolDraw.updateLayout(); + this._lineDraw.updateLayout(); + }; + GraphView.prototype.remove = function () { + clearTimeout(this._layoutTimeout); + this._layouting = false; + this._layoutTimeout = null; + this._symbolDraw && this._symbolDraw.remove(); + this._lineDraw && this._lineDraw.remove(); + }; + GraphView.type = 'graph'; + return GraphView; + }(ChartView); + + // id may be function name of Object, add a prefix to avoid this problem. + function generateNodeKey(id) { + return '_EC_' + id; + } + var Graph = /** @class */function () { + function Graph(directed) { + this.type = 'graph'; + this.nodes = []; + this.edges = []; + this._nodesMap = {}; + /** + * @type {Object.} + * @private + */ + this._edgesMap = {}; + this._directed = directed || false; + } + /** + * If is directed graph + */ + Graph.prototype.isDirected = function () { + return this._directed; + }; + /** + * Add a new node + */ + Graph.prototype.addNode = function (id, dataIndex) { + id = id == null ? '' + dataIndex : '' + id; + var nodesMap = this._nodesMap; + if (nodesMap[generateNodeKey(id)]) { + if ("development" !== 'production') { + console.error('Graph nodes have duplicate name or id'); + } + return; + } + var node = new GraphNode(id, dataIndex); + node.hostGraph = this; + this.nodes.push(node); + nodesMap[generateNodeKey(id)] = node; + return node; + }; + /** + * Get node by data index + */ + Graph.prototype.getNodeByIndex = function (dataIndex) { + var rawIdx = this.data.getRawIndex(dataIndex); + return this.nodes[rawIdx]; + }; + /** + * Get node by id + */ + Graph.prototype.getNodeById = function (id) { + return this._nodesMap[generateNodeKey(id)]; + }; + /** + * Add a new edge + */ + Graph.prototype.addEdge = function (n1, n2, dataIndex) { + var nodesMap = this._nodesMap; + var edgesMap = this._edgesMap; + // PENDING + if (isNumber(n1)) { + n1 = this.nodes[n1]; + } + if (isNumber(n2)) { + n2 = this.nodes[n2]; + } + if (!(n1 instanceof GraphNode)) { + n1 = nodesMap[generateNodeKey(n1)]; + } + if (!(n2 instanceof GraphNode)) { + n2 = nodesMap[generateNodeKey(n2)]; + } + if (!n1 || !n2) { + return; + } + var key = n1.id + '-' + n2.id; + var edge = new GraphEdge(n1, n2, dataIndex); + edge.hostGraph = this; + if (this._directed) { + n1.outEdges.push(edge); + n2.inEdges.push(edge); + } + n1.edges.push(edge); + if (n1 !== n2) { + n2.edges.push(edge); + } + this.edges.push(edge); + edgesMap[key] = edge; + return edge; + }; + /** + * Get edge by data index + */ + Graph.prototype.getEdgeByIndex = function (dataIndex) { + var rawIdx = this.edgeData.getRawIndex(dataIndex); + return this.edges[rawIdx]; + }; + /** + * Get edge by two linked nodes + */ + Graph.prototype.getEdge = function (n1, n2) { + if (n1 instanceof GraphNode) { + n1 = n1.id; + } + if (n2 instanceof GraphNode) { + n2 = n2.id; + } + var edgesMap = this._edgesMap; + if (this._directed) { + return edgesMap[n1 + '-' + n2]; + } else { + return edgesMap[n1 + '-' + n2] || edgesMap[n2 + '-' + n1]; + } + }; + /** + * Iterate all nodes + */ + Graph.prototype.eachNode = function (cb, context) { + var nodes = this.nodes; + var len = nodes.length; + for (var i = 0; i < len; i++) { + if (nodes[i].dataIndex >= 0) { + cb.call(context, nodes[i], i); + } + } + }; + /** + * Iterate all edges + */ + Graph.prototype.eachEdge = function (cb, context) { + var edges = this.edges; + var len = edges.length; + for (var i = 0; i < len; i++) { + if (edges[i].dataIndex >= 0 && edges[i].node1.dataIndex >= 0 && edges[i].node2.dataIndex >= 0) { + cb.call(context, edges[i], i); + } + } + }; + /** + * Breadth first traverse + * Return true to stop traversing + */ + Graph.prototype.breadthFirstTraverse = function (cb, startNode, direction, context) { + if (!(startNode instanceof GraphNode)) { + startNode = this._nodesMap[generateNodeKey(startNode)]; + } + if (!startNode) { + return; + } + var edgeType = direction === 'out' ? 'outEdges' : direction === 'in' ? 'inEdges' : 'edges'; + for (var i = 0; i < this.nodes.length; i++) { + this.nodes[i].__visited = false; + } + if (cb.call(context, startNode, null)) { + return; + } + var queue = [startNode]; + while (queue.length) { + var currentNode = queue.shift(); + var edges = currentNode[edgeType]; + for (var i = 0; i < edges.length; i++) { + var e = edges[i]; + var otherNode = e.node1 === currentNode ? e.node2 : e.node1; + if (!otherNode.__visited) { + if (cb.call(context, otherNode, currentNode)) { + // Stop traversing + return; + } + queue.push(otherNode); + otherNode.__visited = true; + } + } + } + }; + // TODO + // depthFirstTraverse( + // cb, startNode, direction, context + // ) { + // }; + // Filter update + Graph.prototype.update = function () { + var data = this.data; + var edgeData = this.edgeData; + var nodes = this.nodes; + var edges = this.edges; + for (var i = 0, len = nodes.length; i < len; i++) { + nodes[i].dataIndex = -1; + } + for (var i = 0, len = data.count(); i < len; i++) { + nodes[data.getRawIndex(i)].dataIndex = i; + } + edgeData.filterSelf(function (idx) { + var edge = edges[edgeData.getRawIndex(idx)]; + return edge.node1.dataIndex >= 0 && edge.node2.dataIndex >= 0; + }); + // Update edge + for (var i = 0, len = edges.length; i < len; i++) { + edges[i].dataIndex = -1; + } + for (var i = 0, len = edgeData.count(); i < len; i++) { + edges[edgeData.getRawIndex(i)].dataIndex = i; + } + }; + /** + * @return {module:echarts/data/Graph} + */ + Graph.prototype.clone = function () { + var graph = new Graph(this._directed); + var nodes = this.nodes; + var edges = this.edges; + for (var i = 0; i < nodes.length; i++) { + graph.addNode(nodes[i].id, nodes[i].dataIndex); + } + for (var i = 0; i < edges.length; i++) { + var e = edges[i]; + graph.addEdge(e.node1.id, e.node2.id, e.dataIndex); + } + return graph; + }; + return Graph; + }(); + var GraphNode = /** @class */function () { + function GraphNode(id, dataIndex) { + this.inEdges = []; + this.outEdges = []; + this.edges = []; + this.dataIndex = -1; + this.id = id == null ? '' : id; + this.dataIndex = dataIndex == null ? -1 : dataIndex; + } + /** + * @return {number} + */ + GraphNode.prototype.degree = function () { + return this.edges.length; + }; + /** + * @return {number} + */ + GraphNode.prototype.inDegree = function () { + return this.inEdges.length; + }; + /** + * @return {number} + */ + GraphNode.prototype.outDegree = function () { + return this.outEdges.length; + }; + GraphNode.prototype.getModel = function (path) { + if (this.dataIndex < 0) { + return; + } + var graph = this.hostGraph; + var itemModel = graph.data.getItemModel(this.dataIndex); + return itemModel.getModel(path); + }; + GraphNode.prototype.getAdjacentDataIndices = function () { + var dataIndices = { + edge: [], + node: [] + }; + for (var i = 0; i < this.edges.length; i++) { + var adjacentEdge = this.edges[i]; + if (adjacentEdge.dataIndex < 0) { + continue; + } + dataIndices.edge.push(adjacentEdge.dataIndex); + dataIndices.node.push(adjacentEdge.node1.dataIndex, adjacentEdge.node2.dataIndex); + } + return dataIndices; + }; + GraphNode.prototype.getTrajectoryDataIndices = function () { + var connectedEdgesMap = createHashMap(); + var connectedNodesMap = createHashMap(); + for (var i = 0; i < this.edges.length; i++) { + var adjacentEdge = this.edges[i]; + if (adjacentEdge.dataIndex < 0) { + continue; + } + connectedEdgesMap.set(adjacentEdge.dataIndex, true); + var sourceNodesQueue = [adjacentEdge.node1]; + var targetNodesQueue = [adjacentEdge.node2]; + var nodeIteratorIndex = 0; + while (nodeIteratorIndex < sourceNodesQueue.length) { + var sourceNode = sourceNodesQueue[nodeIteratorIndex]; + nodeIteratorIndex++; + connectedNodesMap.set(sourceNode.dataIndex, true); + for (var j = 0; j < sourceNode.inEdges.length; j++) { + connectedEdgesMap.set(sourceNode.inEdges[j].dataIndex, true); + sourceNodesQueue.push(sourceNode.inEdges[j].node1); + } + } + nodeIteratorIndex = 0; + while (nodeIteratorIndex < targetNodesQueue.length) { + var targetNode = targetNodesQueue[nodeIteratorIndex]; + nodeIteratorIndex++; + connectedNodesMap.set(targetNode.dataIndex, true); + for (var j = 0; j < targetNode.outEdges.length; j++) { + connectedEdgesMap.set(targetNode.outEdges[j].dataIndex, true); + targetNodesQueue.push(targetNode.outEdges[j].node2); + } + } + } + return { + edge: connectedEdgesMap.keys(), + node: connectedNodesMap.keys() + }; + }; + return GraphNode; + }(); + var GraphEdge = /** @class */function () { + function GraphEdge(n1, n2, dataIndex) { + this.dataIndex = -1; + this.node1 = n1; + this.node2 = n2; + this.dataIndex = dataIndex == null ? -1 : dataIndex; + } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + GraphEdge.prototype.getModel = function (path) { + if (this.dataIndex < 0) { + return; + } + var graph = this.hostGraph; + var itemModel = graph.edgeData.getItemModel(this.dataIndex); + return itemModel.getModel(path); + }; + GraphEdge.prototype.getAdjacentDataIndices = function () { + return { + edge: [this.dataIndex], + node: [this.node1.dataIndex, this.node2.dataIndex] + }; + }; + GraphEdge.prototype.getTrajectoryDataIndices = function () { + var connectedEdgesMap = createHashMap(); + var connectedNodesMap = createHashMap(); + connectedEdgesMap.set(this.dataIndex, true); + var sourceNodes = [this.node1]; + var targetNodes = [this.node2]; + var nodeIteratorIndex = 0; + while (nodeIteratorIndex < sourceNodes.length) { + var sourceNode = sourceNodes[nodeIteratorIndex]; + nodeIteratorIndex++; + connectedNodesMap.set(sourceNode.dataIndex, true); + for (var j = 0; j < sourceNode.inEdges.length; j++) { + connectedEdgesMap.set(sourceNode.inEdges[j].dataIndex, true); + sourceNodes.push(sourceNode.inEdges[j].node1); + } + } + nodeIteratorIndex = 0; + while (nodeIteratorIndex < targetNodes.length) { + var targetNode = targetNodes[nodeIteratorIndex]; + nodeIteratorIndex++; + connectedNodesMap.set(targetNode.dataIndex, true); + for (var j = 0; j < targetNode.outEdges.length; j++) { + connectedEdgesMap.set(targetNode.outEdges[j].dataIndex, true); + targetNodes.push(targetNode.outEdges[j].node2); + } + } + return { + edge: connectedEdgesMap.keys(), + node: connectedNodesMap.keys() + }; + }; + return GraphEdge; + }(); + function createGraphDataProxyMixin(hostName, dataName) { + return { + /** + * @param Default 'value'. can be 'a', 'b', 'c', 'd', 'e'. + */ + getValue: function (dimension) { + var data = this[hostName][dataName]; + return data.getStore().get(data.getDimensionIndex(dimension || 'value'), this.dataIndex); + }, + // TODO: TYPE stricter type. + setVisual: function (key, value) { + this.dataIndex >= 0 && this[hostName][dataName].setItemVisual(this.dataIndex, key, value); + }, + getVisual: function (key) { + return this[hostName][dataName].getItemVisual(this.dataIndex, key); + }, + setLayout: function (layout, merge) { + this.dataIndex >= 0 && this[hostName][dataName].setItemLayout(this.dataIndex, layout, merge); + }, + getLayout: function () { + return this[hostName][dataName].getItemLayout(this.dataIndex); + }, + getGraphicEl: function () { + return this[hostName][dataName].getItemGraphicEl(this.dataIndex); + }, + getRawIndex: function () { + return this[hostName][dataName].getRawIndex(this.dataIndex); + } + }; + } + mixin(GraphNode, createGraphDataProxyMixin('hostGraph', 'data')); + mixin(GraphEdge, createGraphDataProxyMixin('hostGraph', 'edgeData')); + + function createGraphFromNodeEdge(nodes, edges, seriesModel, directed, beforeLink) { + // ??? TODO + // support dataset? + var graph = new Graph(directed); + for (var i = 0; i < nodes.length; i++) { + graph.addNode(retrieve( + // Id, name, dataIndex + nodes[i].id, nodes[i].name, i), i); + } + var linkNameList = []; + var validEdges = []; + var linkCount = 0; + for (var i = 0; i < edges.length; i++) { + var link = edges[i]; + var source = link.source; + var target = link.target; + // addEdge may fail when source or target not exists + if (graph.addEdge(source, target, linkCount)) { + validEdges.push(link); + linkNameList.push(retrieve(convertOptionIdName(link.id, null), source + ' > ' + target)); + linkCount++; + } + } + var coordSys = seriesModel.get('coordinateSystem'); + var nodeData; + if (coordSys === 'cartesian2d' || coordSys === 'polar') { + nodeData = createSeriesData(nodes, seriesModel); + } else { + var coordSysCtor = CoordinateSystemManager.get(coordSys); + var coordDimensions = coordSysCtor ? coordSysCtor.dimensions || [] : []; + // FIXME: Some geo do not need `value` dimenson, whereas `calendar` needs + // `value` dimension, but graph need `value` dimension. It's better to + // uniform this behavior. + if (indexOf(coordDimensions, 'value') < 0) { + coordDimensions.concat(['value']); + } + var dimensions = prepareSeriesDataSchema(nodes, { + coordDimensions: coordDimensions, + encodeDefine: seriesModel.getEncode() + }).dimensions; + nodeData = new SeriesData(dimensions, seriesModel); + nodeData.initData(nodes); + } + var edgeData = new SeriesData(['value'], seriesModel); + edgeData.initData(validEdges, linkNameList); + beforeLink && beforeLink(nodeData, edgeData); + linkSeriesData({ + mainData: nodeData, + struct: graph, + structAttr: 'graph', + datas: { + node: nodeData, + edge: edgeData + }, + datasAttr: { + node: 'data', + edge: 'edgeData' + } + }); + // Update dataIndex of nodes and edges because invalid edge may be removed + graph.update(); + return graph; + } + + var GraphSeriesModel = /** @class */function (_super) { + __extends(GraphSeriesModel, _super); + function GraphSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = GraphSeriesModel.type; + _this.hasSymbolVisual = true; + return _this; + } + GraphSeriesModel.prototype.init = function (option) { + _super.prototype.init.apply(this, arguments); + var self = this; + function getCategoriesData() { + return self._categoriesData; + } + // Provide data for legend select + this.legendVisualProvider = new LegendVisualProvider(getCategoriesData, getCategoriesData); + this.fillDataTextStyle(option.edges || option.links); + this._updateCategoriesData(); + }; + GraphSeriesModel.prototype.mergeOption = function (option) { + _super.prototype.mergeOption.apply(this, arguments); + this.fillDataTextStyle(option.edges || option.links); + this._updateCategoriesData(); + }; + GraphSeriesModel.prototype.mergeDefaultAndTheme = function (option) { + _super.prototype.mergeDefaultAndTheme.apply(this, arguments); + defaultEmphasis(option, 'edgeLabel', ['show']); + }; + GraphSeriesModel.prototype.getInitialData = function (option, ecModel) { + var edges = option.edges || option.links || []; + var nodes = option.data || option.nodes || []; + var self = this; + if (nodes && edges) { + // auto curveness + initCurvenessList(this); + var graph = createGraphFromNodeEdge(nodes, edges, this, true, beforeLink); + each(graph.edges, function (edge) { + createEdgeMapForCurveness(edge.node1, edge.node2, this, edge.dataIndex); + }, this); + return graph.data; + } + function beforeLink(nodeData, edgeData) { + // Overwrite nodeData.getItemModel to + nodeData.wrapMethod('getItemModel', function (model) { + var categoriesModels = self._categoriesModels; + var categoryIdx = model.getShallow('category'); + var categoryModel = categoriesModels[categoryIdx]; + if (categoryModel) { + categoryModel.parentModel = model.parentModel; + model.parentModel = categoryModel; + } + return model; + }); + // TODO Inherit resolveParentPath by default in Model#getModel? + var oldGetModel = Model.prototype.getModel; + function newGetModel(path, parentModel) { + var model = oldGetModel.call(this, path, parentModel); + model.resolveParentPath = resolveParentPath; + return model; + } + edgeData.wrapMethod('getItemModel', function (model) { + model.resolveParentPath = resolveParentPath; + model.getModel = newGetModel; + return model; + }); + function resolveParentPath(pathArr) { + if (pathArr && (pathArr[0] === 'label' || pathArr[1] === 'label')) { + var newPathArr = pathArr.slice(); + if (pathArr[0] === 'label') { + newPathArr[0] = 'edgeLabel'; + } else if (pathArr[1] === 'label') { + newPathArr[1] = 'edgeLabel'; + } + return newPathArr; + } + return pathArr; + } + } + }; + GraphSeriesModel.prototype.getGraph = function () { + return this.getData().graph; + }; + GraphSeriesModel.prototype.getEdgeData = function () { + return this.getGraph().edgeData; + }; + GraphSeriesModel.prototype.getCategoriesData = function () { + return this._categoriesData; + }; + GraphSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + if (dataType === 'edge') { + var nodeData = this.getData(); + var params = this.getDataParams(dataIndex, dataType); + var edge = nodeData.graph.getEdgeByIndex(dataIndex); + var sourceName = nodeData.getName(edge.node1.dataIndex); + var targetName = nodeData.getName(edge.node2.dataIndex); + var nameArr = []; + sourceName != null && nameArr.push(sourceName); + targetName != null && nameArr.push(targetName); + return createTooltipMarkup('nameValue', { + name: nameArr.join(' > '), + value: params.value, + noValue: params.value == null + }); + } + // dataType === 'node' or empty + var nodeMarkup = defaultSeriesFormatTooltip({ + series: this, + dataIndex: dataIndex, + multipleSeries: multipleSeries + }); + return nodeMarkup; + }; + GraphSeriesModel.prototype._updateCategoriesData = function () { + var categories = map(this.option.categories || [], function (category) { + // Data must has value + return category.value != null ? category : extend({ + value: 0 + }, category); + }); + var categoriesData = new SeriesData(['value'], this); + categoriesData.initData(categories); + this._categoriesData = categoriesData; + this._categoriesModels = categoriesData.mapArray(function (idx) { + return categoriesData.getItemModel(idx); + }); + }; + GraphSeriesModel.prototype.setZoom = function (zoom) { + this.option.zoom = zoom; + }; + GraphSeriesModel.prototype.setCenter = function (center) { + this.option.center = center; + }; + GraphSeriesModel.prototype.isAnimationEnabled = function () { + return _super.prototype.isAnimationEnabled.call(this) + // Not enable animation when do force layout + && !(this.get('layout') === 'force' && this.get(['force', 'layoutAnimation'])); + }; + GraphSeriesModel.type = 'series.graph'; + GraphSeriesModel.dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar']; + GraphSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + coordinateSystem: 'view', + // Default option for all coordinate systems + // xAxisIndex: 0, + // yAxisIndex: 0, + // polarIndex: 0, + // geoIndex: 0, + legendHoverLink: true, + layout: null, + // Configuration of circular layout + circular: { + rotateLabel: false + }, + // Configuration of force directed layout + force: { + initLayout: null, + // Node repulsion. Can be an array to represent range. + repulsion: [0, 50], + gravity: 0.1, + // Initial friction + friction: 0.6, + // Edge length. Can be an array to represent range. + edgeLength: 30, + layoutAnimation: true + }, + left: 'center', + top: 'center', + // right: null, + // bottom: null, + // width: '80%', + // height: '80%', + symbol: 'circle', + symbolSize: 10, + edgeSymbol: ['none', 'none'], + edgeSymbolSize: 10, + edgeLabel: { + position: 'middle', + distance: 5 + }, + draggable: false, + roam: false, + // Default on center of graph + center: null, + zoom: 1, + // Symbol size scale ratio in roam + nodeScaleRatio: 0.6, + // cursor: null, + // categories: [], + // data: [] + // Or + // nodes: [] + // + // links: [] + // Or + // edges: [] + label: { + show: false, + formatter: '{b}' + }, + itemStyle: {}, + lineStyle: { + color: '#aaa', + width: 1, + opacity: 0.5 + }, + emphasis: { + scale: true, + label: { + show: true + } + }, + select: { + itemStyle: { + borderColor: '#212121' + } + } + }; + return GraphSeriesModel; + }(SeriesModel); + + var actionInfo = { + type: 'graphRoam', + event: 'graphRoam', + update: 'none' + }; + function install$d(registers) { + registers.registerChartView(GraphView); + registers.registerSeriesModel(GraphSeriesModel); + registers.registerProcessor(categoryFilter); + registers.registerVisual(categoryVisual); + registers.registerVisual(graphEdgeVisual); + registers.registerLayout(graphSimpleLayout); + registers.registerLayout(registers.PRIORITY.VISUAL.POST_CHART_LAYOUT, graphCircularLayout); + registers.registerLayout(graphForceLayout); + registers.registerCoordinateSystem('graphView', { + dimensions: View.dimensions, + create: createViewCoordSys + }); + // Register legacy focus actions + registers.registerAction({ + type: 'focusNodeAdjacency', + event: 'focusNodeAdjacency', + update: 'series:focusNodeAdjacency' + }, noop); + registers.registerAction({ + type: 'unfocusNodeAdjacency', + event: 'unfocusNodeAdjacency', + update: 'series:unfocusNodeAdjacency' + }, noop); + // Register roam action. + registers.registerAction(actionInfo, function (payload, ecModel, api) { + ecModel.eachComponent({ + mainType: 'series', + query: payload + }, function (seriesModel) { + var coordSys = seriesModel.coordinateSystem; + var res = updateCenterAndZoom(coordSys, payload, undefined, api); + seriesModel.setCenter && seriesModel.setCenter(res.center); + seriesModel.setZoom && seriesModel.setZoom(res.zoom); + }); + }); + } + + var PointerShape = /** @class */function () { + function PointerShape() { + this.angle = 0; + this.width = 10; + this.r = 10; + this.x = 0; + this.y = 0; + } + return PointerShape; + }(); + var PointerPath = /** @class */function (_super) { + __extends(PointerPath, _super); + function PointerPath(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'pointer'; + return _this; + } + PointerPath.prototype.getDefaultShape = function () { + return new PointerShape(); + }; + PointerPath.prototype.buildPath = function (ctx, shape) { + var mathCos = Math.cos; + var mathSin = Math.sin; + var r = shape.r; + var width = shape.width; + var angle = shape.angle; + var x = shape.x - mathCos(angle) * width * (width >= r / 3 ? 1 : 2); + var y = shape.y - mathSin(angle) * width * (width >= r / 3 ? 1 : 2); + angle = shape.angle - Math.PI / 2; + ctx.moveTo(x, y); + ctx.lineTo(shape.x + mathCos(angle) * width, shape.y + mathSin(angle) * width); + ctx.lineTo(shape.x + mathCos(shape.angle) * r, shape.y + mathSin(shape.angle) * r); + ctx.lineTo(shape.x - mathCos(angle) * width, shape.y - mathSin(angle) * width); + ctx.lineTo(x, y); + }; + return PointerPath; + }(Path); + + function parsePosition(seriesModel, api) { + var center = seriesModel.get('center'); + var width = api.getWidth(); + var height = api.getHeight(); + var size = Math.min(width, height); + var cx = parsePercent$1(center[0], api.getWidth()); + var cy = parsePercent$1(center[1], api.getHeight()); + var r = parsePercent$1(seriesModel.get('radius'), size / 2); + return { + cx: cx, + cy: cy, + r: r + }; + } + function formatLabel(value, labelFormatter) { + var label = value == null ? '' : value + ''; + if (labelFormatter) { + if (isString(labelFormatter)) { + label = labelFormatter.replace('{value}', label); + } else if (isFunction(labelFormatter)) { + label = labelFormatter(value); + } + } + return label; + } + var GaugeView = /** @class */function (_super) { + __extends(GaugeView, _super); + function GaugeView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = GaugeView.type; + return _this; + } + GaugeView.prototype.render = function (seriesModel, ecModel, api) { + this.group.removeAll(); + var colorList = seriesModel.get(['axisLine', 'lineStyle', 'color']); + var posInfo = parsePosition(seriesModel, api); + this._renderMain(seriesModel, ecModel, api, colorList, posInfo); + this._data = seriesModel.getData(); + }; + GaugeView.prototype.dispose = function () {}; + GaugeView.prototype._renderMain = function (seriesModel, ecModel, api, colorList, posInfo) { + var group = this.group; + var clockwise = seriesModel.get('clockwise'); + var startAngle = -seriesModel.get('startAngle') / 180 * Math.PI; + var endAngle = -seriesModel.get('endAngle') / 180 * Math.PI; + var axisLineModel = seriesModel.getModel('axisLine'); + var roundCap = axisLineModel.get('roundCap'); + var MainPath = roundCap ? SausagePath : Sector; + var showAxis = axisLineModel.get('show'); + var lineStyleModel = axisLineModel.getModel('lineStyle'); + var axisLineWidth = lineStyleModel.get('width'); + var angles = [startAngle, endAngle]; + normalizeArcAngles(angles, !clockwise); + startAngle = angles[0]; + endAngle = angles[1]; + var angleRangeSpan = endAngle - startAngle; + var prevEndAngle = startAngle; + var sectors = []; + for (var i = 0; showAxis && i < colorList.length; i++) { + // Clamp + var percent = Math.min(Math.max(colorList[i][0], 0), 1); + endAngle = startAngle + angleRangeSpan * percent; + var sector = new MainPath({ + shape: { + startAngle: prevEndAngle, + endAngle: endAngle, + cx: posInfo.cx, + cy: posInfo.cy, + clockwise: clockwise, + r0: posInfo.r - axisLineWidth, + r: posInfo.r + }, + silent: true + }); + sector.setStyle({ + fill: colorList[i][1] + }); + sector.setStyle(lineStyleModel.getLineStyle( + // Because we use sector to simulate arc + // so the properties for stroking are useless + ['color', 'width'])); + sectors.push(sector); + prevEndAngle = endAngle; + } + sectors.reverse(); + each(sectors, function (sector) { + return group.add(sector); + }); + var getColor = function (percent) { + // Less than 0 + if (percent <= 0) { + return colorList[0][1]; + } + var i; + for (i = 0; i < colorList.length; i++) { + if (colorList[i][0] >= percent && (i === 0 ? 0 : colorList[i - 1][0]) < percent) { + return colorList[i][1]; + } + } + // More than 1 + return colorList[i - 1][1]; + }; + this._renderTicks(seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise, axisLineWidth); + this._renderTitleAndDetail(seriesModel, ecModel, api, getColor, posInfo); + this._renderAnchor(seriesModel, posInfo); + this._renderPointer(seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise, axisLineWidth); + }; + GaugeView.prototype._renderTicks = function (seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise, axisLineWidth) { + var group = this.group; + var cx = posInfo.cx; + var cy = posInfo.cy; + var r = posInfo.r; + var minVal = +seriesModel.get('min'); + var maxVal = +seriesModel.get('max'); + var splitLineModel = seriesModel.getModel('splitLine'); + var tickModel = seriesModel.getModel('axisTick'); + var labelModel = seriesModel.getModel('axisLabel'); + var splitNumber = seriesModel.get('splitNumber'); + var subSplitNumber = tickModel.get('splitNumber'); + var splitLineLen = parsePercent$1(splitLineModel.get('length'), r); + var tickLen = parsePercent$1(tickModel.get('length'), r); + var angle = startAngle; + var step = (endAngle - startAngle) / splitNumber; + var subStep = step / subSplitNumber; + var splitLineStyle = splitLineModel.getModel('lineStyle').getLineStyle(); + var tickLineStyle = tickModel.getModel('lineStyle').getLineStyle(); + var splitLineDistance = splitLineModel.get('distance'); + var unitX; + var unitY; + for (var i = 0; i <= splitNumber; i++) { + unitX = Math.cos(angle); + unitY = Math.sin(angle); + // Split line + if (splitLineModel.get('show')) { + var distance = splitLineDistance ? splitLineDistance + axisLineWidth : axisLineWidth; + var splitLine = new Line({ + shape: { + x1: unitX * (r - distance) + cx, + y1: unitY * (r - distance) + cy, + x2: unitX * (r - splitLineLen - distance) + cx, + y2: unitY * (r - splitLineLen - distance) + cy + }, + style: splitLineStyle, + silent: true + }); + if (splitLineStyle.stroke === 'auto') { + splitLine.setStyle({ + stroke: getColor(i / splitNumber) + }); + } + group.add(splitLine); + } + // Label + if (labelModel.get('show')) { + var distance = labelModel.get('distance') + splitLineDistance; + var label = formatLabel(round(i / splitNumber * (maxVal - minVal) + minVal), labelModel.get('formatter')); + var autoColor = getColor(i / splitNumber); + var textStyleX = unitX * (r - splitLineLen - distance) + cx; + var textStyleY = unitY * (r - splitLineLen - distance) + cy; + var rotateType = labelModel.get('rotate'); + var rotate = 0; + if (rotateType === 'radial') { + rotate = -angle + 2 * Math.PI; + if (rotate > Math.PI / 2) { + rotate += Math.PI; + } + } else if (rotateType === 'tangential') { + rotate = -angle - Math.PI / 2; + } else if (isNumber(rotateType)) { + rotate = rotateType * Math.PI / 180; + } + if (rotate === 0) { + group.add(new ZRText({ + style: createTextStyle(labelModel, { + text: label, + x: textStyleX, + y: textStyleY, + verticalAlign: unitY < -0.8 ? 'top' : unitY > 0.8 ? 'bottom' : 'middle', + align: unitX < -0.4 ? 'left' : unitX > 0.4 ? 'right' : 'center' + }, { + inheritColor: autoColor + }), + silent: true + })); + } else { + group.add(new ZRText({ + style: createTextStyle(labelModel, { + text: label, + x: textStyleX, + y: textStyleY, + verticalAlign: 'middle', + align: 'center' + }, { + inheritColor: autoColor + }), + silent: true, + originX: textStyleX, + originY: textStyleY, + rotation: rotate + })); + } + } + // Axis tick + if (tickModel.get('show') && i !== splitNumber) { + var distance = tickModel.get('distance'); + distance = distance ? distance + axisLineWidth : axisLineWidth; + for (var j = 0; j <= subSplitNumber; j++) { + unitX = Math.cos(angle); + unitY = Math.sin(angle); + var tickLine = new Line({ + shape: { + x1: unitX * (r - distance) + cx, + y1: unitY * (r - distance) + cy, + x2: unitX * (r - tickLen - distance) + cx, + y2: unitY * (r - tickLen - distance) + cy + }, + silent: true, + style: tickLineStyle + }); + if (tickLineStyle.stroke === 'auto') { + tickLine.setStyle({ + stroke: getColor((i + j / subSplitNumber) / splitNumber) + }); + } + group.add(tickLine); + angle += subStep; + } + angle -= subStep; + } else { + angle += step; + } + } + }; + GaugeView.prototype._renderPointer = function (seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise, axisLineWidth) { + var group = this.group; + var oldData = this._data; + var oldProgressData = this._progressEls; + var progressList = []; + var showPointer = seriesModel.get(['pointer', 'show']); + var progressModel = seriesModel.getModel('progress'); + var showProgress = progressModel.get('show'); + var data = seriesModel.getData(); + var valueDim = data.mapDimension('value'); + var minVal = +seriesModel.get('min'); + var maxVal = +seriesModel.get('max'); + var valueExtent = [minVal, maxVal]; + var angleExtent = [startAngle, endAngle]; + function createPointer(idx, angle) { + var itemModel = data.getItemModel(idx); + var pointerModel = itemModel.getModel('pointer'); + var pointerWidth = parsePercent$1(pointerModel.get('width'), posInfo.r); + var pointerLength = parsePercent$1(pointerModel.get('length'), posInfo.r); + var pointerStr = seriesModel.get(['pointer', 'icon']); + var pointerOffset = pointerModel.get('offsetCenter'); + var pointerOffsetX = parsePercent$1(pointerOffset[0], posInfo.r); + var pointerOffsetY = parsePercent$1(pointerOffset[1], posInfo.r); + var pointerKeepAspect = pointerModel.get('keepAspect'); + var pointer; + // not exist icon type will be set 'rect' + if (pointerStr) { + pointer = createSymbol(pointerStr, pointerOffsetX - pointerWidth / 2, pointerOffsetY - pointerLength, pointerWidth, pointerLength, null, pointerKeepAspect); + } else { + pointer = new PointerPath({ + shape: { + angle: -Math.PI / 2, + width: pointerWidth, + r: pointerLength, + x: pointerOffsetX, + y: pointerOffsetY + } + }); + } + pointer.rotation = -(angle + Math.PI / 2); + pointer.x = posInfo.cx; + pointer.y = posInfo.cy; + return pointer; + } + function createProgress(idx, endAngle) { + var roundCap = progressModel.get('roundCap'); + var ProgressPath = roundCap ? SausagePath : Sector; + var isOverlap = progressModel.get('overlap'); + var progressWidth = isOverlap ? progressModel.get('width') : axisLineWidth / data.count(); + var r0 = isOverlap ? posInfo.r - progressWidth : posInfo.r - (idx + 1) * progressWidth; + var r = isOverlap ? posInfo.r : posInfo.r - idx * progressWidth; + var progress = new ProgressPath({ + shape: { + startAngle: startAngle, + endAngle: endAngle, + cx: posInfo.cx, + cy: posInfo.cy, + clockwise: clockwise, + r0: r0, + r: r + } + }); + isOverlap && (progress.z2 = maxVal - data.get(valueDim, idx) % maxVal); + return progress; + } + if (showProgress || showPointer) { + data.diff(oldData).add(function (idx) { + var val = data.get(valueDim, idx); + if (showPointer) { + var pointer = createPointer(idx, startAngle); + // TODO hide pointer on NaN value? + initProps(pointer, { + rotation: -((isNaN(+val) ? angleExtent[0] : linearMap(val, valueExtent, angleExtent, true)) + Math.PI / 2) + }, seriesModel); + group.add(pointer); + data.setItemGraphicEl(idx, pointer); + } + if (showProgress) { + var progress = createProgress(idx, startAngle); + var isClip = progressModel.get('clip'); + initProps(progress, { + shape: { + endAngle: linearMap(val, valueExtent, angleExtent, isClip) + } + }, seriesModel); + group.add(progress); + // Add data index and series index for indexing the data by element + // Useful in tooltip + setCommonECData(seriesModel.seriesIndex, data.dataType, idx, progress); + progressList[idx] = progress; + } + }).update(function (newIdx, oldIdx) { + var val = data.get(valueDim, newIdx); + if (showPointer) { + var previousPointer = oldData.getItemGraphicEl(oldIdx); + var previousRotate = previousPointer ? previousPointer.rotation : startAngle; + var pointer = createPointer(newIdx, previousRotate); + pointer.rotation = previousRotate; + updateProps(pointer, { + rotation: -((isNaN(+val) ? angleExtent[0] : linearMap(val, valueExtent, angleExtent, true)) + Math.PI / 2) + }, seriesModel); + group.add(pointer); + data.setItemGraphicEl(newIdx, pointer); + } + if (showProgress) { + var previousProgress = oldProgressData[oldIdx]; + var previousEndAngle = previousProgress ? previousProgress.shape.endAngle : startAngle; + var progress = createProgress(newIdx, previousEndAngle); + var isClip = progressModel.get('clip'); + updateProps(progress, { + shape: { + endAngle: linearMap(val, valueExtent, angleExtent, isClip) + } + }, seriesModel); + group.add(progress); + // Add data index and series index for indexing the data by element + // Useful in tooltip + setCommonECData(seriesModel.seriesIndex, data.dataType, newIdx, progress); + progressList[newIdx] = progress; + } + }).execute(); + data.each(function (idx) { + var itemModel = data.getItemModel(idx); + var emphasisModel = itemModel.getModel('emphasis'); + var focus = emphasisModel.get('focus'); + var blurScope = emphasisModel.get('blurScope'); + var emphasisDisabled = emphasisModel.get('disabled'); + if (showPointer) { + var pointer = data.getItemGraphicEl(idx); + var symbolStyle = data.getItemVisual(idx, 'style'); + var visualColor = symbolStyle.fill; + if (pointer instanceof ZRImage) { + var pathStyle = pointer.style; + pointer.useStyle(extend({ + image: pathStyle.image, + x: pathStyle.x, + y: pathStyle.y, + width: pathStyle.width, + height: pathStyle.height + }, symbolStyle)); + } else { + pointer.useStyle(symbolStyle); + pointer.type !== 'pointer' && pointer.setColor(visualColor); + } + pointer.setStyle(itemModel.getModel(['pointer', 'itemStyle']).getItemStyle()); + if (pointer.style.fill === 'auto') { + pointer.setStyle('fill', getColor(linearMap(data.get(valueDim, idx), valueExtent, [0, 1], true))); + } + pointer.z2EmphasisLift = 0; + setStatesStylesFromModel(pointer, itemModel); + toggleHoverEmphasis(pointer, focus, blurScope, emphasisDisabled); + } + if (showProgress) { + var progress = progressList[idx]; + progress.useStyle(data.getItemVisual(idx, 'style')); + progress.setStyle(itemModel.getModel(['progress', 'itemStyle']).getItemStyle()); + progress.z2EmphasisLift = 0; + setStatesStylesFromModel(progress, itemModel); + toggleHoverEmphasis(progress, focus, blurScope, emphasisDisabled); + } + }); + this._progressEls = progressList; + } + }; + GaugeView.prototype._renderAnchor = function (seriesModel, posInfo) { + var anchorModel = seriesModel.getModel('anchor'); + var showAnchor = anchorModel.get('show'); + if (showAnchor) { + var anchorSize = anchorModel.get('size'); + var anchorType = anchorModel.get('icon'); + var offsetCenter = anchorModel.get('offsetCenter'); + var anchorKeepAspect = anchorModel.get('keepAspect'); + var anchor = createSymbol(anchorType, posInfo.cx - anchorSize / 2 + parsePercent$1(offsetCenter[0], posInfo.r), posInfo.cy - anchorSize / 2 + parsePercent$1(offsetCenter[1], posInfo.r), anchorSize, anchorSize, null, anchorKeepAspect); + anchor.z2 = anchorModel.get('showAbove') ? 1 : 0; + anchor.setStyle(anchorModel.getModel('itemStyle').getItemStyle()); + this.group.add(anchor); + } + }; + GaugeView.prototype._renderTitleAndDetail = function (seriesModel, ecModel, api, getColor, posInfo) { + var _this = this; + var data = seriesModel.getData(); + var valueDim = data.mapDimension('value'); + var minVal = +seriesModel.get('min'); + var maxVal = +seriesModel.get('max'); + var contentGroup = new Group(); + var newTitleEls = []; + var newDetailEls = []; + var hasAnimation = seriesModel.isAnimationEnabled(); + var showPointerAbove = seriesModel.get(['pointer', 'showAbove']); + data.diff(this._data).add(function (idx) { + newTitleEls[idx] = new ZRText({ + silent: true + }); + newDetailEls[idx] = new ZRText({ + silent: true + }); + }).update(function (idx, oldIdx) { + newTitleEls[idx] = _this._titleEls[oldIdx]; + newDetailEls[idx] = _this._detailEls[oldIdx]; + }).execute(); + data.each(function (idx) { + var itemModel = data.getItemModel(idx); + var value = data.get(valueDim, idx); + var itemGroup = new Group(); + var autoColor = getColor(linearMap(value, [minVal, maxVal], [0, 1], true)); + var itemTitleModel = itemModel.getModel('title'); + if (itemTitleModel.get('show')) { + var titleOffsetCenter = itemTitleModel.get('offsetCenter'); + var titleX = posInfo.cx + parsePercent$1(titleOffsetCenter[0], posInfo.r); + var titleY = posInfo.cy + parsePercent$1(titleOffsetCenter[1], posInfo.r); + var labelEl = newTitleEls[idx]; + labelEl.attr({ + z2: showPointerAbove ? 0 : 2, + style: createTextStyle(itemTitleModel, { + x: titleX, + y: titleY, + text: data.getName(idx), + align: 'center', + verticalAlign: 'middle' + }, { + inheritColor: autoColor + }) + }); + itemGroup.add(labelEl); + } + var itemDetailModel = itemModel.getModel('detail'); + if (itemDetailModel.get('show')) { + var detailOffsetCenter = itemDetailModel.get('offsetCenter'); + var detailX = posInfo.cx + parsePercent$1(detailOffsetCenter[0], posInfo.r); + var detailY = posInfo.cy + parsePercent$1(detailOffsetCenter[1], posInfo.r); + var width = parsePercent$1(itemDetailModel.get('width'), posInfo.r); + var height = parsePercent$1(itemDetailModel.get('height'), posInfo.r); + var detailColor = seriesModel.get(['progress', 'show']) ? data.getItemVisual(idx, 'style').fill : autoColor; + var labelEl = newDetailEls[idx]; + var formatter_1 = itemDetailModel.get('formatter'); + labelEl.attr({ + z2: showPointerAbove ? 0 : 2, + style: createTextStyle(itemDetailModel, { + x: detailX, + y: detailY, + text: formatLabel(value, formatter_1), + width: isNaN(width) ? null : width, + height: isNaN(height) ? null : height, + align: 'center', + verticalAlign: 'middle' + }, { + inheritColor: detailColor + }) + }); + setLabelValueAnimation(labelEl, { + normal: itemDetailModel + }, value, function (value) { + return formatLabel(value, formatter_1); + }); + hasAnimation && animateLabelValue(labelEl, idx, data, seriesModel, { + getFormattedLabel: function (labelDataIndex, status, dataType, labelDimIndex, fmt, extendParams) { + return formatLabel(extendParams ? extendParams.interpolatedValue : value, formatter_1); + } + }); + itemGroup.add(labelEl); + } + contentGroup.add(itemGroup); + }); + this.group.add(contentGroup); + this._titleEls = newTitleEls; + this._detailEls = newDetailEls; + }; + GaugeView.type = 'gauge'; + return GaugeView; + }(ChartView); + + var GaugeSeriesModel = /** @class */function (_super) { + __extends(GaugeSeriesModel, _super); + function GaugeSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = GaugeSeriesModel.type; + _this.visualStyleAccessPath = 'itemStyle'; + return _this; + } + GaugeSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesDataSimply(this, ['value']); + }; + GaugeSeriesModel.type = 'series.gauge'; + GaugeSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + colorBy: 'data', + // 默认全局居中 + center: ['50%', '50%'], + legendHoverLink: true, + radius: '75%', + startAngle: 225, + endAngle: -45, + clockwise: true, + // 最小值 + min: 0, + // 最大值 + max: 100, + // 分割段数,默认为10 + splitNumber: 10, + // 坐标轴线 + axisLine: { + // 默认显示,属性show控制显示与否 + show: true, + roundCap: false, + lineStyle: { + color: [[1, '#E6EBF8']], + width: 10 + } + }, + // 坐标轴线 + progress: { + // 默认显示,属性show控制显示与否 + show: false, + overlap: true, + width: 10, + roundCap: false, + clip: true + }, + // 分隔线 + splitLine: { + // 默认显示,属性show控制显示与否 + show: true, + // 属性length控制线长 + length: 10, + distance: 10, + // 属性lineStyle(详见lineStyle)控制线条样式 + lineStyle: { + color: '#63677A', + width: 3, + type: 'solid' + } + }, + // 坐标轴小标记 + axisTick: { + // 属性show控制显示与否,默认不显示 + show: true, + // 每份split细分多少段 + splitNumber: 5, + // 属性length控制线长 + length: 6, + distance: 10, + // 属性lineStyle控制线条样式 + lineStyle: { + color: '#63677A', + width: 1, + type: 'solid' + } + }, + axisLabel: { + show: true, + distance: 15, + // formatter: null, + color: '#464646', + fontSize: 12, + rotate: 0 + }, + pointer: { + icon: null, + offsetCenter: [0, 0], + show: true, + showAbove: true, + length: '60%', + width: 6, + keepAspect: false + }, + anchor: { + show: false, + showAbove: false, + size: 6, + icon: 'circle', + offsetCenter: [0, 0], + keepAspect: false, + itemStyle: { + color: '#fff', + borderWidth: 0, + borderColor: '#5470c6' + } + }, + title: { + show: true, + // x, y,单位px + offsetCenter: [0, '20%'], + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#464646', + fontSize: 16, + valueAnimation: false + }, + detail: { + show: true, + backgroundColor: 'rgba(0,0,0,0)', + borderWidth: 0, + borderColor: '#ccc', + width: 100, + height: null, + padding: [5, 10], + // x, y,单位px + offsetCenter: [0, '40%'], + // formatter: null, + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#464646', + fontSize: 30, + fontWeight: 'bold', + lineHeight: 30, + valueAnimation: false + } + }; + return GaugeSeriesModel; + }(SeriesModel); + + function install$e(registers) { + registers.registerChartView(GaugeView); + registers.registerSeriesModel(GaugeSeriesModel); + } + + var opacityAccessPath = ['itemStyle', 'opacity']; + /** + * Piece of pie including Sector, Label, LabelLine + */ + var FunnelPiece = /** @class */function (_super) { + __extends(FunnelPiece, _super); + function FunnelPiece(data, idx) { + var _this = _super.call(this) || this; + var polygon = _this; + var labelLine = new Polyline(); + var text = new ZRText(); + polygon.setTextContent(text); + _this.setTextGuideLine(labelLine); + _this.updateData(data, idx, true); + return _this; + } + FunnelPiece.prototype.updateData = function (data, idx, firstCreate) { + var polygon = this; + var seriesModel = data.hostModel; + var itemModel = data.getItemModel(idx); + var layout = data.getItemLayout(idx); + var emphasisModel = itemModel.getModel('emphasis'); + var opacity = itemModel.get(opacityAccessPath); + opacity = opacity == null ? 1 : opacity; + if (!firstCreate) { + saveOldStyle(polygon); + } + // Update common style + polygon.useStyle(data.getItemVisual(idx, 'style')); + polygon.style.lineJoin = 'round'; + if (firstCreate) { + polygon.setShape({ + points: layout.points + }); + polygon.style.opacity = 0; + initProps(polygon, { + style: { + opacity: opacity + } + }, seriesModel, idx); + } else { + updateProps(polygon, { + style: { + opacity: opacity + }, + shape: { + points: layout.points + } + }, seriesModel, idx); + } + setStatesStylesFromModel(polygon, itemModel); + this._updateLabel(data, idx); + toggleHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + }; + FunnelPiece.prototype._updateLabel = function (data, idx) { + var polygon = this; + var labelLine = this.getTextGuideLine(); + var labelText = polygon.getTextContent(); + var seriesModel = data.hostModel; + var itemModel = data.getItemModel(idx); + var layout = data.getItemLayout(idx); + var labelLayout = layout.label; + var style = data.getItemVisual(idx, 'style'); + var visualColor = style.fill; + setLabelStyle( + // position will not be used in setLabelStyle + labelText, getLabelStatesModels(itemModel), { + labelFetcher: data.hostModel, + labelDataIndex: idx, + defaultOpacity: style.opacity, + defaultText: data.getName(idx) + }, { + normal: { + align: labelLayout.textAlign, + verticalAlign: labelLayout.verticalAlign + } + }); + polygon.setTextConfig({ + local: true, + inside: !!labelLayout.inside, + insideStroke: visualColor, + // insideFill: 'auto', + outsideFill: visualColor + }); + var linePoints = labelLayout.linePoints; + labelLine.setShape({ + points: linePoints + }); + polygon.textGuideLineConfig = { + anchor: linePoints ? new Point(linePoints[0][0], linePoints[0][1]) : null + }; + // Make sure update style on labelText after setLabelStyle. + // Because setLabelStyle will replace a new style on it. + updateProps(labelText, { + style: { + x: labelLayout.x, + y: labelLayout.y + } + }, seriesModel, idx); + labelText.attr({ + rotation: labelLayout.rotation, + originX: labelLayout.x, + originY: labelLayout.y, + z2: 10 + }); + setLabelLineStyle(polygon, getLabelLineStatesModels(itemModel), { + // Default use item visual color + stroke: visualColor + }); + }; + return FunnelPiece; + }(Polygon); + var FunnelView = /** @class */function (_super) { + __extends(FunnelView, _super); + function FunnelView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = FunnelView.type; + _this.ignoreLabelLineUpdate = true; + return _this; + } + FunnelView.prototype.render = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var oldData = this._data; + var group = this.group; + data.diff(oldData).add(function (idx) { + var funnelPiece = new FunnelPiece(data, idx); + data.setItemGraphicEl(idx, funnelPiece); + group.add(funnelPiece); + }).update(function (newIdx, oldIdx) { + var piece = oldData.getItemGraphicEl(oldIdx); + piece.updateData(data, newIdx); + group.add(piece); + data.setItemGraphicEl(newIdx, piece); + }).remove(function (idx) { + var piece = oldData.getItemGraphicEl(idx); + removeElementWithFadeOut(piece, seriesModel, idx); + }).execute(); + this._data = data; + }; + FunnelView.prototype.remove = function () { + this.group.removeAll(); + this._data = null; + }; + FunnelView.prototype.dispose = function () {}; + FunnelView.type = 'funnel'; + return FunnelView; + }(ChartView); + + var FunnelSeriesModel = /** @class */function (_super) { + __extends(FunnelSeriesModel, _super); + function FunnelSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = FunnelSeriesModel.type; + return _this; + } + FunnelSeriesModel.prototype.init = function (option) { + _super.prototype.init.apply(this, arguments); + // Enable legend selection for each data item + // Use a function instead of direct access because data reference may changed + this.legendVisualProvider = new LegendVisualProvider(bind(this.getData, this), bind(this.getRawData, this)); + // Extend labelLine emphasis + this._defaultLabelLine(option); + }; + FunnelSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesDataSimply(this, { + coordDimensions: ['value'], + encodeDefaulter: curry(makeSeriesEncodeForNameBased, this) + }); + }; + FunnelSeriesModel.prototype._defaultLabelLine = function (option) { + // Extend labelLine emphasis + defaultEmphasis(option, 'labelLine', ['show']); + var labelLineNormalOpt = option.labelLine; + var labelLineEmphasisOpt = option.emphasis.labelLine; + // Not show label line if `label.normal.show = false` + labelLineNormalOpt.show = labelLineNormalOpt.show && option.label.show; + labelLineEmphasisOpt.show = labelLineEmphasisOpt.show && option.emphasis.label.show; + }; + // Overwrite + FunnelSeriesModel.prototype.getDataParams = function (dataIndex) { + var data = this.getData(); + var params = _super.prototype.getDataParams.call(this, dataIndex); + var valueDim = data.mapDimension('value'); + var sum = data.getSum(valueDim); + // Percent is 0 if sum is 0 + params.percent = !sum ? 0 : +(data.get(valueDim, dataIndex) / sum * 100).toFixed(2); + params.$vars.push('percent'); + return params; + }; + FunnelSeriesModel.type = 'series.funnel'; + FunnelSeriesModel.defaultOption = { + // zlevel: 0, // 一级层叠 + z: 2, + legendHoverLink: true, + colorBy: 'data', + left: 80, + top: 60, + right: 80, + bottom: 60, + // width: {totalWidth} - left - right, + // height: {totalHeight} - top - bottom, + // 默认取数据最小最大值 + // min: 0, + // max: 100, + minSize: '0%', + maxSize: '100%', + sort: 'descending', + orient: 'vertical', + gap: 0, + funnelAlign: 'center', + label: { + show: true, + position: 'outer' + // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 + }, + + labelLine: { + show: true, + length: 20, + lineStyle: { + // color: 各异, + width: 1 + } + }, + itemStyle: { + // color: 各异, + borderColor: '#fff', + borderWidth: 1 + }, + emphasis: { + label: { + show: true + } + }, + select: { + itemStyle: { + borderColor: '#212121' + } + } + }; + return FunnelSeriesModel; + }(SeriesModel); + + function getViewRect$3(seriesModel, api) { + return getLayoutRect(seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }); + } + function getSortedIndices(data, sort) { + var valueDim = data.mapDimension('value'); + var valueArr = data.mapArray(valueDim, function (val) { + return val; + }); + var indices = []; + var isAscending = sort === 'ascending'; + for (var i = 0, len = data.count(); i < len; i++) { + indices[i] = i; + } + // Add custom sortable function & none sortable opetion by "options.sort" + if (isFunction(sort)) { + indices.sort(sort); + } else if (sort !== 'none') { + indices.sort(function (a, b) { + return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a]; + }); + } + return indices; + } + function labelLayout(data) { + var seriesModel = data.hostModel; + var orient = seriesModel.get('orient'); + data.each(function (idx) { + var itemModel = data.getItemModel(idx); + var labelModel = itemModel.getModel('label'); + var labelPosition = labelModel.get('position'); + var labelLineModel = itemModel.getModel('labelLine'); + var layout = data.getItemLayout(idx); + var points = layout.points; + var isLabelInside = labelPosition === 'inner' || labelPosition === 'inside' || labelPosition === 'center' || labelPosition === 'insideLeft' || labelPosition === 'insideRight'; + var textAlign; + var textX; + var textY; + var linePoints; + if (isLabelInside) { + if (labelPosition === 'insideLeft') { + textX = (points[0][0] + points[3][0]) / 2 + 5; + textY = (points[0][1] + points[3][1]) / 2; + textAlign = 'left'; + } else if (labelPosition === 'insideRight') { + textX = (points[1][0] + points[2][0]) / 2 - 5; + textY = (points[1][1] + points[2][1]) / 2; + textAlign = 'right'; + } else { + textX = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4; + textY = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4; + textAlign = 'center'; + } + linePoints = [[textX, textY], [textX, textY]]; + } else { + var x1 = void 0; + var y1 = void 0; + var x2 = void 0; + var y2 = void 0; + var labelLineLen = labelLineModel.get('length'); + if ("development" !== 'production') { + if (orient === 'vertical' && ['top', 'bottom'].indexOf(labelPosition) > -1) { + labelPosition = 'left'; + console.warn('Position error: Funnel chart on vertical orient dose not support top and bottom.'); + } + if (orient === 'horizontal' && ['left', 'right'].indexOf(labelPosition) > -1) { + labelPosition = 'bottom'; + console.warn('Position error: Funnel chart on horizontal orient dose not support left and right.'); + } + } + if (labelPosition === 'left') { + // Left side + x1 = (points[3][0] + points[0][0]) / 2; + y1 = (points[3][1] + points[0][1]) / 2; + x2 = x1 - labelLineLen; + textX = x2 - 5; + textAlign = 'right'; + } else if (labelPosition === 'right') { + // Right side + x1 = (points[1][0] + points[2][0]) / 2; + y1 = (points[1][1] + points[2][1]) / 2; + x2 = x1 + labelLineLen; + textX = x2 + 5; + textAlign = 'left'; + } else if (labelPosition === 'top') { + // Top side + x1 = (points[3][0] + points[0][0]) / 2; + y1 = (points[3][1] + points[0][1]) / 2; + y2 = y1 - labelLineLen; + textY = y2 - 5; + textAlign = 'center'; + } else if (labelPosition === 'bottom') { + // Bottom side + x1 = (points[1][0] + points[2][0]) / 2; + y1 = (points[1][1] + points[2][1]) / 2; + y2 = y1 + labelLineLen; + textY = y2 + 5; + textAlign = 'center'; + } else if (labelPosition === 'rightTop') { + // RightTop side + x1 = orient === 'horizontal' ? points[3][0] : points[1][0]; + y1 = orient === 'horizontal' ? points[3][1] : points[1][1]; + if (orient === 'horizontal') { + y2 = y1 - labelLineLen; + textY = y2 - 5; + textAlign = 'center'; + } else { + x2 = x1 + labelLineLen; + textX = x2 + 5; + textAlign = 'top'; + } + } else if (labelPosition === 'rightBottom') { + // RightBottom side + x1 = points[2][0]; + y1 = points[2][1]; + if (orient === 'horizontal') { + y2 = y1 + labelLineLen; + textY = y2 + 5; + textAlign = 'center'; + } else { + x2 = x1 + labelLineLen; + textX = x2 + 5; + textAlign = 'bottom'; + } + } else if (labelPosition === 'leftTop') { + // LeftTop side + x1 = points[0][0]; + y1 = orient === 'horizontal' ? points[0][1] : points[1][1]; + if (orient === 'horizontal') { + y2 = y1 - labelLineLen; + textY = y2 - 5; + textAlign = 'center'; + } else { + x2 = x1 - labelLineLen; + textX = x2 - 5; + textAlign = 'right'; + } + } else if (labelPosition === 'leftBottom') { + // LeftBottom side + x1 = orient === 'horizontal' ? points[1][0] : points[3][0]; + y1 = orient === 'horizontal' ? points[1][1] : points[2][1]; + if (orient === 'horizontal') { + y2 = y1 + labelLineLen; + textY = y2 + 5; + textAlign = 'center'; + } else { + x2 = x1 - labelLineLen; + textX = x2 - 5; + textAlign = 'right'; + } + } else { + // Right side or Bottom side + x1 = (points[1][0] + points[2][0]) / 2; + y1 = (points[1][1] + points[2][1]) / 2; + if (orient === 'horizontal') { + y2 = y1 + labelLineLen; + textY = y2 + 5; + textAlign = 'center'; + } else { + x2 = x1 + labelLineLen; + textX = x2 + 5; + textAlign = 'left'; + } + } + if (orient === 'horizontal') { + x2 = x1; + textX = x2; + } else { + y2 = y1; + textY = y2; + } + linePoints = [[x1, y1], [x2, y2]]; + } + layout.label = { + linePoints: linePoints, + x: textX, + y: textY, + verticalAlign: 'middle', + textAlign: textAlign, + inside: isLabelInside + }; + }); + } + function funnelLayout(ecModel, api) { + ecModel.eachSeriesByType('funnel', function (seriesModel) { + var data = seriesModel.getData(); + var valueDim = data.mapDimension('value'); + var sort = seriesModel.get('sort'); + var viewRect = getViewRect$3(seriesModel, api); + var orient = seriesModel.get('orient'); + var viewWidth = viewRect.width; + var viewHeight = viewRect.height; + var indices = getSortedIndices(data, sort); + var x = viewRect.x; + var y = viewRect.y; + var sizeExtent = orient === 'horizontal' ? [parsePercent$1(seriesModel.get('minSize'), viewHeight), parsePercent$1(seriesModel.get('maxSize'), viewHeight)] : [parsePercent$1(seriesModel.get('minSize'), viewWidth), parsePercent$1(seriesModel.get('maxSize'), viewWidth)]; + var dataExtent = data.getDataExtent(valueDim); + var min = seriesModel.get('min'); + var max = seriesModel.get('max'); + if (min == null) { + min = Math.min(dataExtent[0], 0); + } + if (max == null) { + max = dataExtent[1]; + } + var funnelAlign = seriesModel.get('funnelAlign'); + var gap = seriesModel.get('gap'); + var viewSize = orient === 'horizontal' ? viewWidth : viewHeight; + var itemSize = (viewSize - gap * (data.count() - 1)) / data.count(); + var getLinePoints = function (idx, offset) { + // End point index is data.count() and we assign it 0 + if (orient === 'horizontal') { + var val_1 = data.get(valueDim, idx) || 0; + var itemHeight = linearMap(val_1, [min, max], sizeExtent, true); + var y0 = void 0; + switch (funnelAlign) { + case 'top': + y0 = y; + break; + case 'center': + y0 = y + (viewHeight - itemHeight) / 2; + break; + case 'bottom': + y0 = y + (viewHeight - itemHeight); + break; + } + return [[offset, y0], [offset, y0 + itemHeight]]; + } + var val = data.get(valueDim, idx) || 0; + var itemWidth = linearMap(val, [min, max], sizeExtent, true); + var x0; + switch (funnelAlign) { + case 'left': + x0 = x; + break; + case 'center': + x0 = x + (viewWidth - itemWidth) / 2; + break; + case 'right': + x0 = x + viewWidth - itemWidth; + break; + } + return [[x0, offset], [x0 + itemWidth, offset]]; + }; + if (sort === 'ascending') { + // From bottom to top + itemSize = -itemSize; + gap = -gap; + if (orient === 'horizontal') { + x += viewWidth; + } else { + y += viewHeight; + } + indices = indices.reverse(); + } + for (var i = 0; i < indices.length; i++) { + var idx = indices[i]; + var nextIdx = indices[i + 1]; + var itemModel = data.getItemModel(idx); + if (orient === 'horizontal') { + var width = itemModel.get(['itemStyle', 'width']); + if (width == null) { + width = itemSize; + } else { + width = parsePercent$1(width, viewWidth); + if (sort === 'ascending') { + width = -width; + } + } + var start = getLinePoints(idx, x); + var end = getLinePoints(nextIdx, x + width); + x += width + gap; + data.setItemLayout(idx, { + points: start.concat(end.slice().reverse()) + }); + } else { + var height = itemModel.get(['itemStyle', 'height']); + if (height == null) { + height = itemSize; + } else { + height = parsePercent$1(height, viewHeight); + if (sort === 'ascending') { + height = -height; + } + } + var start = getLinePoints(idx, y); + var end = getLinePoints(nextIdx, y + height); + y += height + gap; + data.setItemLayout(idx, { + points: start.concat(end.slice().reverse()) + }); + } + } + labelLayout(data); + }); + } + + function install$f(registers) { + registers.registerChartView(FunnelView); + registers.registerSeriesModel(FunnelSeriesModel); + registers.registerLayout(funnelLayout); + registers.registerProcessor(dataFilter('funnel')); + } + + var DEFAULT_SMOOTH = 0.3; + var ParallelView = /** @class */function (_super) { + __extends(ParallelView, _super); + function ParallelView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ParallelView.type; + _this._dataGroup = new Group(); + _this._initialized = false; + return _this; + } + ParallelView.prototype.init = function () { + this.group.add(this._dataGroup); + }; + /** + * @override + */ + ParallelView.prototype.render = function (seriesModel, ecModel, api, payload) { + // Clear previously rendered progressive elements. + this._progressiveEls = null; + var dataGroup = this._dataGroup; + var data = seriesModel.getData(); + var oldData = this._data; + var coordSys = seriesModel.coordinateSystem; + var dimensions = coordSys.dimensions; + var seriesScope = makeSeriesScope$2(seriesModel); + data.diff(oldData).add(add).update(update).remove(remove).execute(); + function add(newDataIndex) { + var line = addEl(data, dataGroup, newDataIndex, dimensions, coordSys); + updateElCommon(line, data, newDataIndex, seriesScope); + } + function update(newDataIndex, oldDataIndex) { + var line = oldData.getItemGraphicEl(oldDataIndex); + var points = createLinePoints(data, newDataIndex, dimensions, coordSys); + data.setItemGraphicEl(newDataIndex, line); + updateProps(line, { + shape: { + points: points + } + }, seriesModel, newDataIndex); + saveOldStyle(line); + updateElCommon(line, data, newDataIndex, seriesScope); + } + function remove(oldDataIndex) { + var line = oldData.getItemGraphicEl(oldDataIndex); + dataGroup.remove(line); + } + // First create + if (!this._initialized) { + this._initialized = true; + var clipPath = createGridClipShape(coordSys, seriesModel, function () { + // Callback will be invoked immediately if there is no animation + setTimeout(function () { + dataGroup.removeClipPath(); + }); + }); + dataGroup.setClipPath(clipPath); + } + this._data = data; + }; + ParallelView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) { + this._initialized = true; + this._data = null; + this._dataGroup.removeAll(); + }; + ParallelView.prototype.incrementalRender = function (taskParams, seriesModel, ecModel) { + var data = seriesModel.getData(); + var coordSys = seriesModel.coordinateSystem; + var dimensions = coordSys.dimensions; + var seriesScope = makeSeriesScope$2(seriesModel); + var progressiveEls = this._progressiveEls = []; + for (var dataIndex = taskParams.start; dataIndex < taskParams.end; dataIndex++) { + var line = addEl(data, this._dataGroup, dataIndex, dimensions, coordSys); + line.incremental = true; + updateElCommon(line, data, dataIndex, seriesScope); + progressiveEls.push(line); + } + }; + ParallelView.prototype.remove = function () { + this._dataGroup && this._dataGroup.removeAll(); + this._data = null; + }; + ParallelView.type = 'parallel'; + return ParallelView; + }(ChartView); + function createGridClipShape(coordSys, seriesModel, cb) { + var parallelModel = coordSys.model; + var rect = coordSys.getRect(); + var rectEl = new Rect({ + shape: { + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + } + }); + var dim = parallelModel.get('layout') === 'horizontal' ? 'width' : 'height'; + rectEl.setShape(dim, 0); + initProps(rectEl, { + shape: { + width: rect.width, + height: rect.height + } + }, seriesModel, cb); + return rectEl; + } + function createLinePoints(data, dataIndex, dimensions, coordSys) { + var points = []; + for (var i = 0; i < dimensions.length; i++) { + var dimName = dimensions[i]; + var value = data.get(data.mapDimension(dimName), dataIndex); + if (!isEmptyValue(value, coordSys.getAxis(dimName).type)) { + points.push(coordSys.dataToPoint(value, dimName)); + } + } + return points; + } + function addEl(data, dataGroup, dataIndex, dimensions, coordSys) { + var points = createLinePoints(data, dataIndex, dimensions, coordSys); + var line = new Polyline({ + shape: { + points: points + }, + // silent: true, + z2: 10 + }); + dataGroup.add(line); + data.setItemGraphicEl(dataIndex, line); + return line; + } + function makeSeriesScope$2(seriesModel) { + var smooth = seriesModel.get('smooth', true); + smooth === true && (smooth = DEFAULT_SMOOTH); + smooth = numericToNumber(smooth); + eqNaN(smooth) && (smooth = 0); + return { + smooth: smooth + }; + } + function updateElCommon(el, data, dataIndex, seriesScope) { + el.useStyle(data.getItemVisual(dataIndex, 'style')); + el.style.fill = null; + el.setShape('smooth', seriesScope.smooth); + var itemModel = data.getItemModel(dataIndex); + var emphasisModel = itemModel.getModel('emphasis'); + setStatesStylesFromModel(el, itemModel, 'lineStyle'); + toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + } + // function simpleDiff(oldData, newData, dimensions) { + // let oldLen; + // if (!oldData + // || !oldData.__plProgressive + // || (oldLen = oldData.count()) !== newData.count() + // ) { + // return true; + // } + // let dimLen = dimensions.length; + // for (let i = 0; i < oldLen; i++) { + // for (let j = 0; j < dimLen; j++) { + // if (oldData.get(dimensions[j], i) !== newData.get(dimensions[j], i)) { + // return true; + // } + // } + // } + // return false; + // } + // FIXME put in common util? + function isEmptyValue(val, axisType) { + return axisType === 'category' ? val == null : val == null || isNaN(val); // axisType === 'value' + } + + var ParallelSeriesModel = /** @class */function (_super) { + __extends(ParallelSeriesModel, _super); + function ParallelSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ParallelSeriesModel.type; + _this.visualStyleAccessPath = 'lineStyle'; + _this.visualDrawType = 'stroke'; + return _this; + } + ParallelSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesData(null, this, { + useEncodeDefaulter: bind(makeDefaultEncode, null, this) + }); + }; + /** + * User can get data raw indices on 'axisAreaSelected' event received. + * + * @return Raw indices + */ + ParallelSeriesModel.prototype.getRawIndicesByActiveState = function (activeState) { + var coordSys = this.coordinateSystem; + var data = this.getData(); + var indices = []; + coordSys.eachActiveState(data, function (theActiveState, dataIndex) { + if (activeState === theActiveState) { + indices.push(data.getRawIndex(dataIndex)); + } + }); + return indices; + }; + ParallelSeriesModel.type = 'series.parallel'; + ParallelSeriesModel.dependencies = ['parallel']; + ParallelSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + coordinateSystem: 'parallel', + parallelIndex: 0, + label: { + show: false + }, + inactiveOpacity: 0.05, + activeOpacity: 1, + lineStyle: { + width: 1, + opacity: 0.45, + type: 'solid' + }, + emphasis: { + label: { + show: false + } + }, + progressive: 500, + smooth: false, + animationEasing: 'linear' + }; + return ParallelSeriesModel; + }(SeriesModel); + function makeDefaultEncode(seriesModel) { + // The mapping of parallelAxis dimension to data dimension can + // be specified in parallelAxis.option.dim. For example, if + // parallelAxis.option.dim is 'dim3', it mapping to the third + // dimension of data. But `data.encode` has higher priority. + // Moreover, parallelModel.dimension should not be regarded as data + // dimensions. Consider dimensions = ['dim4', 'dim2', 'dim6']; + var parallelModel = seriesModel.ecModel.getComponent('parallel', seriesModel.get('parallelIndex')); + if (!parallelModel) { + return; + } + var encodeDefine = {}; + each(parallelModel.dimensions, function (axisDim) { + var dataDimIndex = convertDimNameToNumber(axisDim); + encodeDefine[axisDim] = dataDimIndex; + }); + return encodeDefine; + } + function convertDimNameToNumber(dimName) { + return +dimName.replace('dim', ''); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var opacityAccessPath$1 = ['lineStyle', 'opacity']; + var parallelVisual = { + seriesType: 'parallel', + reset: function (seriesModel, ecModel) { + var coordSys = seriesModel.coordinateSystem; + var opacityMap = { + normal: seriesModel.get(['lineStyle', 'opacity']), + active: seriesModel.get('activeOpacity'), + inactive: seriesModel.get('inactiveOpacity') + }; + return { + progress: function (params, data) { + coordSys.eachActiveState(data, function (activeState, dataIndex) { + var opacity = opacityMap[activeState]; + if (activeState === 'normal' && data.hasItemOption) { + var itemOpacity = data.getItemModel(dataIndex).get(opacityAccessPath$1, true); + itemOpacity != null && (opacity = itemOpacity); + } + var existsStyle = data.ensureUniqueItemVisual(dataIndex, 'style'); + existsStyle.opacity = opacity; + }, params.start, params.end); + } + }; + } + }; + + function parallelPreprocessor(option) { + createParallelIfNeeded(option); + mergeAxisOptionFromParallel(option); + } + /** + * Create a parallel coordinate if not exists. + * @inner + */ + function createParallelIfNeeded(option) { + if (option.parallel) { + return; + } + var hasParallelSeries = false; + each(option.series, function (seriesOpt) { + if (seriesOpt && seriesOpt.type === 'parallel') { + hasParallelSeries = true; + } + }); + if (hasParallelSeries) { + option.parallel = [{}]; + } + } + /** + * Merge aixs definition from parallel option (if exists) to axis option. + * @inner + */ + function mergeAxisOptionFromParallel(option) { + var axes = normalizeToArray(option.parallelAxis); + each(axes, function (axisOption) { + if (!isObject(axisOption)) { + return; + } + var parallelIndex = axisOption.parallelIndex || 0; + var parallelOption = normalizeToArray(option.parallel)[parallelIndex]; + if (parallelOption && parallelOption.parallelAxisDefault) { + merge(axisOption, parallelOption.parallelAxisDefault, false); + } + }); + } + + var CLICK_THRESHOLD = 5; // > 4 + var ParallelView$1 = /** @class */function (_super) { + __extends(ParallelView, _super); + function ParallelView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ParallelView.type; + return _this; + } + ParallelView.prototype.render = function (parallelModel, ecModel, api) { + this._model = parallelModel; + this._api = api; + if (!this._handlers) { + this._handlers = {}; + each(handlers, function (handler, eventName) { + api.getZr().on(eventName, this._handlers[eventName] = bind(handler, this)); + }, this); + } + createOrUpdate(this, '_throttledDispatchExpand', parallelModel.get('axisExpandRate'), 'fixRate'); + }; + ParallelView.prototype.dispose = function (ecModel, api) { + clear(this, '_throttledDispatchExpand'); + each(this._handlers, function (handler, eventName) { + api.getZr().off(eventName, handler); + }); + this._handlers = null; + }; + /** + * @internal + * @param {Object} [opt] If null, cancel the last action triggering for debounce. + */ + ParallelView.prototype._throttledDispatchExpand = function (opt) { + this._dispatchExpand(opt); + }; + /** + * @internal + */ + ParallelView.prototype._dispatchExpand = function (opt) { + opt && this._api.dispatchAction(extend({ + type: 'parallelAxisExpand' + }, opt)); + }; + ParallelView.type = 'parallel'; + return ParallelView; + }(ComponentView); + var handlers = { + mousedown: function (e) { + if (checkTrigger(this, 'click')) { + this._mouseDownPoint = [e.offsetX, e.offsetY]; + } + }, + mouseup: function (e) { + var mouseDownPoint = this._mouseDownPoint; + if (checkTrigger(this, 'click') && mouseDownPoint) { + var point = [e.offsetX, e.offsetY]; + var dist = Math.pow(mouseDownPoint[0] - point[0], 2) + Math.pow(mouseDownPoint[1] - point[1], 2); + if (dist > CLICK_THRESHOLD) { + return; + } + var result = this._model.coordinateSystem.getSlidedAxisExpandWindow([e.offsetX, e.offsetY]); + result.behavior !== 'none' && this._dispatchExpand({ + axisExpandWindow: result.axisExpandWindow + }); + } + this._mouseDownPoint = null; + }, + mousemove: function (e) { + // Should do nothing when brushing. + if (this._mouseDownPoint || !checkTrigger(this, 'mousemove')) { + return; + } + var model = this._model; + var result = model.coordinateSystem.getSlidedAxisExpandWindow([e.offsetX, e.offsetY]); + var behavior = result.behavior; + behavior === 'jump' && this._throttledDispatchExpand.debounceNextCall(model.get('axisExpandDebounce')); + this._throttledDispatchExpand(behavior === 'none' ? null // Cancel the last trigger, in case that mouse slide out of the area quickly. + : { + axisExpandWindow: result.axisExpandWindow, + // Jumping uses animation, and sliding suppresses animation. + animation: behavior === 'jump' ? null : { + duration: 0 // Disable animation. + } + }); + } + }; + + function checkTrigger(view, triggerOn) { + var model = view._model; + return model.get('axisExpandable') && model.get('axisExpandTriggerOn') === triggerOn; + } + + var ParallelModel = /** @class */function (_super) { + __extends(ParallelModel, _super); + function ParallelModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ParallelModel.type; + return _this; + } + ParallelModel.prototype.init = function () { + _super.prototype.init.apply(this, arguments); + this.mergeOption({}); + }; + ParallelModel.prototype.mergeOption = function (newOption) { + var thisOption = this.option; + newOption && merge(thisOption, newOption, true); + this._initDimensions(); + }; + /** + * Whether series or axis is in this coordinate system. + */ + ParallelModel.prototype.contains = function (model, ecModel) { + var parallelIndex = model.get('parallelIndex'); + return parallelIndex != null && ecModel.getComponent('parallel', parallelIndex) === this; + }; + ParallelModel.prototype.setAxisExpand = function (opt) { + each(['axisExpandable', 'axisExpandCenter', 'axisExpandCount', 'axisExpandWidth', 'axisExpandWindow'], function (name) { + if (opt.hasOwnProperty(name)) { + // @ts-ignore FIXME: why "never" inferred in this.option[name]? + this.option[name] = opt[name]; + } + }, this); + }; + ParallelModel.prototype._initDimensions = function () { + var dimensions = this.dimensions = []; + var parallelAxisIndex = this.parallelAxisIndex = []; + var axisModels = filter(this.ecModel.queryComponents({ + mainType: 'parallelAxis' + }), function (axisModel) { + // Can not use this.contains here, because + // initialization has not been completed yet. + return (axisModel.get('parallelIndex') || 0) === this.componentIndex; + }, this); + each(axisModels, function (axisModel) { + dimensions.push('dim' + axisModel.get('dim')); + parallelAxisIndex.push(axisModel.componentIndex); + }); + }; + ParallelModel.type = 'parallel'; + ParallelModel.dependencies = ['parallelAxis']; + ParallelModel.layoutMode = 'box'; + ParallelModel.defaultOption = { + // zlevel: 0, + z: 0, + left: 80, + top: 60, + right: 80, + bottom: 60, + // width: {totalWidth} - left - right, + // height: {totalHeight} - top - bottom, + layout: 'horizontal', + // FIXME + // naming? + axisExpandable: false, + axisExpandCenter: null, + axisExpandCount: 0, + axisExpandWidth: 50, + axisExpandRate: 17, + axisExpandDebounce: 50, + // [out, in, jumpTarget]. In percentage. If use [null, 0.05], null means full. + // Do not doc to user until necessary. + axisExpandSlideTriggerArea: [-0.15, 0.05, 0.4], + axisExpandTriggerOn: 'click', + parallelAxisDefault: null + }; + return ParallelModel; + }(ComponentModel); + + var ParallelAxis = /** @class */function (_super) { + __extends(ParallelAxis, _super); + function ParallelAxis(dim, scale, coordExtent, axisType, axisIndex) { + var _this = _super.call(this, dim, scale, coordExtent) || this; + _this.type = axisType || 'value'; + _this.axisIndex = axisIndex; + return _this; + } + ParallelAxis.prototype.isHorizontal = function () { + return this.coordinateSystem.getModel().get('layout') !== 'horizontal'; + }; + return ParallelAxis; + }(Axis); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + /** + * Calculate slider move result. + * Usage: + * (1) If both handle0 and handle1 are needed to be moved, set minSpan the same as + * maxSpan and the same as `Math.abs(handleEnd[1] - handleEnds[0])`. + * (2) If handle0 is forbidden to cross handle1, set minSpan as `0`. + * + * @param delta Move length. + * @param handleEnds handleEnds[0] can be bigger then handleEnds[1]. + * handleEnds will be modified in this method. + * @param extent handleEnds is restricted by extent. + * extent[0] should less or equals than extent[1]. + * @param handleIndex Can be 'all', means that both move the two handleEnds. + * @param minSpan The range of dataZoom can not be smaller than that. + * If not set, handle0 and cross handle1. If set as a non-negative + * number (including `0`), handles will push each other when reaching + * the minSpan. + * @param maxSpan The range of dataZoom can not be larger than that. + * @return The input handleEnds. + */ + function sliderMove(delta, handleEnds, extent, handleIndex, minSpan, maxSpan) { + delta = delta || 0; + var extentSpan = extent[1] - extent[0]; + // Notice maxSpan and minSpan can be null/undefined. + if (minSpan != null) { + minSpan = restrict(minSpan, [0, extentSpan]); + } + if (maxSpan != null) { + maxSpan = Math.max(maxSpan, minSpan != null ? minSpan : 0); + } + if (handleIndex === 'all') { + var handleSpan = Math.abs(handleEnds[1] - handleEnds[0]); + handleSpan = restrict(handleSpan, [0, extentSpan]); + minSpan = maxSpan = restrict(handleSpan, [minSpan, maxSpan]); + handleIndex = 0; + } + handleEnds[0] = restrict(handleEnds[0], extent); + handleEnds[1] = restrict(handleEnds[1], extent); + var originalDistSign = getSpanSign(handleEnds, handleIndex); + handleEnds[handleIndex] += delta; + // Restrict in extent. + var extentMinSpan = minSpan || 0; + var realExtent = extent.slice(); + originalDistSign.sign < 0 ? realExtent[0] += extentMinSpan : realExtent[1] -= extentMinSpan; + handleEnds[handleIndex] = restrict(handleEnds[handleIndex], realExtent); + // Expand span. + var currDistSign; + currDistSign = getSpanSign(handleEnds, handleIndex); + if (minSpan != null && (currDistSign.sign !== originalDistSign.sign || currDistSign.span < minSpan)) { + // If minSpan exists, 'cross' is forbidden. + handleEnds[1 - handleIndex] = handleEnds[handleIndex] + originalDistSign.sign * minSpan; + } + // Shrink span. + currDistSign = getSpanSign(handleEnds, handleIndex); + if (maxSpan != null && currDistSign.span > maxSpan) { + handleEnds[1 - handleIndex] = handleEnds[handleIndex] + currDistSign.sign * maxSpan; + } + return handleEnds; + } + function getSpanSign(handleEnds, handleIndex) { + var dist = handleEnds[handleIndex] - handleEnds[1 - handleIndex]; + // If `handleEnds[0] === handleEnds[1]`, always believe that handleEnd[0] + // is at left of handleEnds[1] for non-cross case. + return { + span: Math.abs(dist), + sign: dist > 0 ? -1 : dist < 0 ? 1 : handleIndex ? -1 : 1 + }; + } + function restrict(value, extend) { + return Math.min(extend[1] != null ? extend[1] : Infinity, Math.max(extend[0] != null ? extend[0] : -Infinity, value)); + } + + var each$5 = each; + var mathMin$8 = Math.min; + var mathMax$8 = Math.max; + var mathFloor$1 = Math.floor; + var mathCeil$1 = Math.ceil; + var round$3 = round; + var PI$7 = Math.PI; + var Parallel = /** @class */function () { + function Parallel(parallelModel, ecModel, api) { + this.type = 'parallel'; + /** + * key: dimension + */ + this._axesMap = createHashMap(); + /** + * key: dimension + * value: {position: [], rotation, } + */ + this._axesLayout = {}; + this.dimensions = parallelModel.dimensions; + this._model = parallelModel; + this._init(parallelModel, ecModel, api); + } + Parallel.prototype._init = function (parallelModel, ecModel, api) { + var dimensions = parallelModel.dimensions; + var parallelAxisIndex = parallelModel.parallelAxisIndex; + each$5(dimensions, function (dim, idx) { + var axisIndex = parallelAxisIndex[idx]; + var axisModel = ecModel.getComponent('parallelAxis', axisIndex); + var axis = this._axesMap.set(dim, new ParallelAxis(dim, createScaleByModel(axisModel), [0, 0], axisModel.get('type'), axisIndex)); + var isCategory = axis.type === 'category'; + axis.onBand = isCategory && axisModel.get('boundaryGap'); + axis.inverse = axisModel.get('inverse'); + // Injection + axisModel.axis = axis; + axis.model = axisModel; + axis.coordinateSystem = axisModel.coordinateSystem = this; + }, this); + }; + /** + * Update axis scale after data processed + */ + Parallel.prototype.update = function (ecModel, api) { + this._updateAxesFromSeries(this._model, ecModel); + }; + Parallel.prototype.containPoint = function (point) { + var layoutInfo = this._makeLayoutInfo(); + var axisBase = layoutInfo.axisBase; + var layoutBase = layoutInfo.layoutBase; + var pixelDimIndex = layoutInfo.pixelDimIndex; + var pAxis = point[1 - pixelDimIndex]; + var pLayout = point[pixelDimIndex]; + return pAxis >= axisBase && pAxis <= axisBase + layoutInfo.axisLength && pLayout >= layoutBase && pLayout <= layoutBase + layoutInfo.layoutLength; + }; + Parallel.prototype.getModel = function () { + return this._model; + }; + /** + * Update properties from series + */ + Parallel.prototype._updateAxesFromSeries = function (parallelModel, ecModel) { + ecModel.eachSeries(function (seriesModel) { + if (!parallelModel.contains(seriesModel, ecModel)) { + return; + } + var data = seriesModel.getData(); + each$5(this.dimensions, function (dim) { + var axis = this._axesMap.get(dim); + axis.scale.unionExtentFromData(data, data.mapDimension(dim)); + niceScaleExtent(axis.scale, axis.model); + }, this); + }, this); + }; + /** + * Resize the parallel coordinate system. + */ + Parallel.prototype.resize = function (parallelModel, api) { + this._rect = getLayoutRect(parallelModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }); + this._layoutAxes(); + }; + Parallel.prototype.getRect = function () { + return this._rect; + }; + Parallel.prototype._makeLayoutInfo = function () { + var parallelModel = this._model; + var rect = this._rect; + var xy = ['x', 'y']; + var wh = ['width', 'height']; + var layout = parallelModel.get('layout'); + var pixelDimIndex = layout === 'horizontal' ? 0 : 1; + var layoutLength = rect[wh[pixelDimIndex]]; + var layoutExtent = [0, layoutLength]; + var axisCount = this.dimensions.length; + var axisExpandWidth = restrict$1(parallelModel.get('axisExpandWidth'), layoutExtent); + var axisExpandCount = restrict$1(parallelModel.get('axisExpandCount') || 0, [0, axisCount]); + var axisExpandable = parallelModel.get('axisExpandable') && axisCount > 3 && axisCount > axisExpandCount && axisExpandCount > 1 && axisExpandWidth > 0 && layoutLength > 0; + // `axisExpandWindow` is According to the coordinates of [0, axisExpandLength], + // for sake of consider the case that axisCollapseWidth is 0 (when screen is narrow), + // where collapsed axes should be overlapped. + var axisExpandWindow = parallelModel.get('axisExpandWindow'); + var winSize; + if (!axisExpandWindow) { + winSize = restrict$1(axisExpandWidth * (axisExpandCount - 1), layoutExtent); + var axisExpandCenter = parallelModel.get('axisExpandCenter') || mathFloor$1(axisCount / 2); + axisExpandWindow = [axisExpandWidth * axisExpandCenter - winSize / 2]; + axisExpandWindow[1] = axisExpandWindow[0] + winSize; + } else { + winSize = restrict$1(axisExpandWindow[1] - axisExpandWindow[0], layoutExtent); + axisExpandWindow[1] = axisExpandWindow[0] + winSize; + } + var axisCollapseWidth = (layoutLength - winSize) / (axisCount - axisExpandCount); + // Avoid axisCollapseWidth is too small. + axisCollapseWidth < 3 && (axisCollapseWidth = 0); + // Find the first and last indices > ewin[0] and < ewin[1]. + var winInnerIndices = [mathFloor$1(round$3(axisExpandWindow[0] / axisExpandWidth, 1)) + 1, mathCeil$1(round$3(axisExpandWindow[1] / axisExpandWidth, 1)) - 1]; + // Pos in ec coordinates. + var axisExpandWindow0Pos = axisCollapseWidth / axisExpandWidth * axisExpandWindow[0]; + return { + layout: layout, + pixelDimIndex: pixelDimIndex, + layoutBase: rect[xy[pixelDimIndex]], + layoutLength: layoutLength, + axisBase: rect[xy[1 - pixelDimIndex]], + axisLength: rect[wh[1 - pixelDimIndex]], + axisExpandable: axisExpandable, + axisExpandWidth: axisExpandWidth, + axisCollapseWidth: axisCollapseWidth, + axisExpandWindow: axisExpandWindow, + axisCount: axisCount, + winInnerIndices: winInnerIndices, + axisExpandWindow0Pos: axisExpandWindow0Pos + }; + }; + Parallel.prototype._layoutAxes = function () { + var rect = this._rect; + var axes = this._axesMap; + var dimensions = this.dimensions; + var layoutInfo = this._makeLayoutInfo(); + var layout = layoutInfo.layout; + axes.each(function (axis) { + var axisExtent = [0, layoutInfo.axisLength]; + var idx = axis.inverse ? 1 : 0; + axis.setExtent(axisExtent[idx], axisExtent[1 - idx]); + }); + each$5(dimensions, function (dim, idx) { + var posInfo = (layoutInfo.axisExpandable ? layoutAxisWithExpand : layoutAxisWithoutExpand)(idx, layoutInfo); + var positionTable = { + horizontal: { + x: posInfo.position, + y: layoutInfo.axisLength + }, + vertical: { + x: 0, + y: posInfo.position + } + }; + var rotationTable = { + horizontal: PI$7 / 2, + vertical: 0 + }; + var position = [positionTable[layout].x + rect.x, positionTable[layout].y + rect.y]; + var rotation = rotationTable[layout]; + var transform = create$1(); + rotate(transform, transform, rotation); + translate(transform, transform, position); + // TODO + // tick layout info + // TODO + // update dimensions info based on axis order. + this._axesLayout[dim] = { + position: position, + rotation: rotation, + transform: transform, + axisNameAvailableWidth: posInfo.axisNameAvailableWidth, + axisLabelShow: posInfo.axisLabelShow, + nameTruncateMaxWidth: posInfo.nameTruncateMaxWidth, + tickDirection: 1, + labelDirection: 1 + }; + }, this); + }; + /** + * Get axis by dim. + */ + Parallel.prototype.getAxis = function (dim) { + return this._axesMap.get(dim); + }; + /** + * Convert a dim value of a single item of series data to Point. + */ + Parallel.prototype.dataToPoint = function (value, dim) { + return this.axisCoordToPoint(this._axesMap.get(dim).dataToCoord(value), dim); + }; + /** + * Travel data for one time, get activeState of each data item. + * @param start the start dataIndex that travel from. + * @param end the next dataIndex of the last dataIndex will be travel. + */ + Parallel.prototype.eachActiveState = function (data, callback, start, end) { + start == null && (start = 0); + end == null && (end = data.count()); + var axesMap = this._axesMap; + var dimensions = this.dimensions; + var dataDimensions = []; + var axisModels = []; + each(dimensions, function (axisDim) { + dataDimensions.push(data.mapDimension(axisDim)); + axisModels.push(axesMap.get(axisDim).model); + }); + var hasActiveSet = this.hasAxisBrushed(); + for (var dataIndex = start; dataIndex < end; dataIndex++) { + var activeState = void 0; + if (!hasActiveSet) { + activeState = 'normal'; + } else { + activeState = 'active'; + var values = data.getValues(dataDimensions, dataIndex); + for (var j = 0, lenj = dimensions.length; j < lenj; j++) { + var state = axisModels[j].getActiveState(values[j]); + if (state === 'inactive') { + activeState = 'inactive'; + break; + } + } + } + callback(activeState, dataIndex); + } + }; + /** + * Whether has any activeSet. + */ + Parallel.prototype.hasAxisBrushed = function () { + var dimensions = this.dimensions; + var axesMap = this._axesMap; + var hasActiveSet = false; + for (var j = 0, lenj = dimensions.length; j < lenj; j++) { + if (axesMap.get(dimensions[j]).model.getActiveState() !== 'normal') { + hasActiveSet = true; + } + } + return hasActiveSet; + }; + /** + * Convert coords of each axis to Point. + * Return point. For example: [10, 20] + */ + Parallel.prototype.axisCoordToPoint = function (coord, dim) { + var axisLayout = this._axesLayout[dim]; + return applyTransform$1([coord, 0], axisLayout.transform); + }; + /** + * Get axis layout. + */ + Parallel.prototype.getAxisLayout = function (dim) { + return clone(this._axesLayout[dim]); + }; + /** + * @return {Object} {axisExpandWindow, delta, behavior: 'jump' | 'slide' | 'none'}. + */ + Parallel.prototype.getSlidedAxisExpandWindow = function (point) { + var layoutInfo = this._makeLayoutInfo(); + var pixelDimIndex = layoutInfo.pixelDimIndex; + var axisExpandWindow = layoutInfo.axisExpandWindow.slice(); + var winSize = axisExpandWindow[1] - axisExpandWindow[0]; + var extent = [0, layoutInfo.axisExpandWidth * (layoutInfo.axisCount - 1)]; + // Out of the area of coordinate system. + if (!this.containPoint(point)) { + return { + behavior: 'none', + axisExpandWindow: axisExpandWindow + }; + } + // Convert the point from global to expand coordinates. + var pointCoord = point[pixelDimIndex] - layoutInfo.layoutBase - layoutInfo.axisExpandWindow0Pos; + // For dragging operation convenience, the window should not be + // slided when mouse is the center area of the window. + var delta; + var behavior = 'slide'; + var axisCollapseWidth = layoutInfo.axisCollapseWidth; + var triggerArea = this._model.get('axisExpandSlideTriggerArea'); + // But consider touch device, jump is necessary. + var useJump = triggerArea[0] != null; + if (axisCollapseWidth) { + if (useJump && axisCollapseWidth && pointCoord < winSize * triggerArea[0]) { + behavior = 'jump'; + delta = pointCoord - winSize * triggerArea[2]; + } else if (useJump && axisCollapseWidth && pointCoord > winSize * (1 - triggerArea[0])) { + behavior = 'jump'; + delta = pointCoord - winSize * (1 - triggerArea[2]); + } else { + (delta = pointCoord - winSize * triggerArea[1]) >= 0 && (delta = pointCoord - winSize * (1 - triggerArea[1])) <= 0 && (delta = 0); + } + delta *= layoutInfo.axisExpandWidth / axisCollapseWidth; + delta ? sliderMove(delta, axisExpandWindow, extent, 'all') + // Avoid nonsense triger on mousemove. + : behavior = 'none'; + } + // When screen is too narrow, make it visible and slidable, although it is hard to interact. + else { + var winSize2 = axisExpandWindow[1] - axisExpandWindow[0]; + var pos = extent[1] * pointCoord / winSize2; + axisExpandWindow = [mathMax$8(0, pos - winSize2 / 2)]; + axisExpandWindow[1] = mathMin$8(extent[1], axisExpandWindow[0] + winSize2); + axisExpandWindow[0] = axisExpandWindow[1] - winSize2; + } + return { + axisExpandWindow: axisExpandWindow, + behavior: behavior + }; + }; + return Parallel; + }(); + function restrict$1(len, extent) { + return mathMin$8(mathMax$8(len, extent[0]), extent[1]); + } + function layoutAxisWithoutExpand(axisIndex, layoutInfo) { + var step = layoutInfo.layoutLength / (layoutInfo.axisCount - 1); + return { + position: step * axisIndex, + axisNameAvailableWidth: step, + axisLabelShow: true + }; + } + function layoutAxisWithExpand(axisIndex, layoutInfo) { + var layoutLength = layoutInfo.layoutLength; + var axisExpandWidth = layoutInfo.axisExpandWidth; + var axisCount = layoutInfo.axisCount; + var axisCollapseWidth = layoutInfo.axisCollapseWidth; + var winInnerIndices = layoutInfo.winInnerIndices; + var position; + var axisNameAvailableWidth = axisCollapseWidth; + var axisLabelShow = false; + var nameTruncateMaxWidth; + if (axisIndex < winInnerIndices[0]) { + position = axisIndex * axisCollapseWidth; + nameTruncateMaxWidth = axisCollapseWidth; + } else if (axisIndex <= winInnerIndices[1]) { + position = layoutInfo.axisExpandWindow0Pos + axisIndex * axisExpandWidth - layoutInfo.axisExpandWindow[0]; + axisNameAvailableWidth = axisExpandWidth; + axisLabelShow = true; + } else { + position = layoutLength - (axisCount - 1 - axisIndex) * axisCollapseWidth; + nameTruncateMaxWidth = axisCollapseWidth; + } + return { + position: position, + axisNameAvailableWidth: axisNameAvailableWidth, + axisLabelShow: axisLabelShow, + nameTruncateMaxWidth: nameTruncateMaxWidth + }; + } + + function createParallelCoordSys(ecModel, api) { + var coordSysList = []; + ecModel.eachComponent('parallel', function (parallelModel, idx) { + var coordSys = new Parallel(parallelModel, ecModel, api); + coordSys.name = 'parallel_' + idx; + coordSys.resize(parallelModel, api); + parallelModel.coordinateSystem = coordSys; + coordSys.model = parallelModel; + coordSysList.push(coordSys); + }); + // Inject the coordinateSystems into seriesModel + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.get('coordinateSystem') === 'parallel') { + var parallelModel = seriesModel.getReferringComponents('parallel', SINGLE_REFERRING).models[0]; + seriesModel.coordinateSystem = parallelModel.coordinateSystem; + } + }); + return coordSysList; + } + var parallelCoordSysCreator = { + create: createParallelCoordSys + }; + + var ParallelAxisModel = /** @class */function (_super) { + __extends(ParallelAxisModel, _super); + function ParallelAxisModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ParallelAxisModel.type; + /** + * @readOnly + */ + _this.activeIntervals = []; + return _this; + } + ParallelAxisModel.prototype.getAreaSelectStyle = function () { + return makeStyleMapper([['fill', 'color'], ['lineWidth', 'borderWidth'], ['stroke', 'borderColor'], ['width', 'width'], ['opacity', 'opacity'] + // Option decal is in `DecalObject` but style.decal is in `PatternObject`. + // So do not transfer decal directly. + ])(this.getModel('areaSelectStyle')); + }; + /** + * The code of this feature is put on AxisModel but not ParallelAxis, + * because axisModel can be alive after echarts updating but instance of + * ParallelAxis having been disposed. this._activeInterval should be kept + * when action dispatched (i.e. legend click). + * + * @param intervals `interval.length === 0` means set all active. + */ + ParallelAxisModel.prototype.setActiveIntervals = function (intervals) { + var activeIntervals = this.activeIntervals = clone(intervals); + // Normalize + if (activeIntervals) { + for (var i = activeIntervals.length - 1; i >= 0; i--) { + asc(activeIntervals[i]); + } + } + }; + /** + * @param value When only attempting detect whether 'no activeIntervals set', + * `value` is not needed to be input. + */ + ParallelAxisModel.prototype.getActiveState = function (value) { + var activeIntervals = this.activeIntervals; + if (!activeIntervals.length) { + return 'normal'; + } + if (value == null || isNaN(+value)) { + return 'inactive'; + } + // Simple optimization + if (activeIntervals.length === 1) { + var interval = activeIntervals[0]; + if (interval[0] <= value && value <= interval[1]) { + return 'active'; + } + } else { + for (var i = 0, len = activeIntervals.length; i < len; i++) { + if (activeIntervals[i][0] <= value && value <= activeIntervals[i][1]) { + return 'active'; + } + } + } + return 'inactive'; + }; + return ParallelAxisModel; + }(ComponentModel); + mixin(ParallelAxisModel, AxisModelCommonMixin); + + var BRUSH_PANEL_GLOBAL = true; + var mathMin$9 = Math.min; + var mathMax$9 = Math.max; + var mathPow$2 = Math.pow; + var COVER_Z = 10000; + var UNSELECT_THRESHOLD = 6; + var MIN_RESIZE_LINE_WIDTH = 6; + var MUTEX_RESOURCE_KEY = 'globalPan'; + var DIRECTION_MAP = { + w: [0, 0], + e: [0, 1], + n: [1, 0], + s: [1, 1] + }; + var CURSOR_MAP = { + w: 'ew', + e: 'ew', + n: 'ns', + s: 'ns', + ne: 'nesw', + sw: 'nesw', + nw: 'nwse', + se: 'nwse' + }; + var DEFAULT_BRUSH_OPT = { + brushStyle: { + lineWidth: 2, + stroke: 'rgba(210,219,238,0.3)', + fill: '#D2DBEE' + }, + transformable: true, + brushMode: 'single', + removeOnClick: false + }; + var baseUID = 0; + /** + * params: + * areas: Array., coord relates to container group, + * If no container specified, to global. + * opt { + * isEnd: boolean, + * removeOnClick: boolean + * } + */ + var BrushController = /** @class */function (_super) { + __extends(BrushController, _super); + function BrushController(zr) { + var _this = _super.call(this) || this; + /** + * @internal + */ + _this._track = []; + /** + * @internal + */ + _this._covers = []; + _this._handlers = {}; + if ("development" !== 'production') { + assert(zr); + } + _this._zr = zr; + _this.group = new Group(); + _this._uid = 'brushController_' + baseUID++; + each(pointerHandlers, function (handler, eventName) { + this._handlers[eventName] = bind(handler, this); + }, _this); + return _this; + } + /** + * If set to `false`, select disabled. + */ + BrushController.prototype.enableBrush = function (brushOption) { + if ("development" !== 'production') { + assert(this._mounted); + } + this._brushType && this._doDisableBrush(); + brushOption.brushType && this._doEnableBrush(brushOption); + return this; + }; + BrushController.prototype._doEnableBrush = function (brushOption) { + var zr = this._zr; + // Consider roam, which takes globalPan too. + if (!this._enableGlobalPan) { + take(zr, MUTEX_RESOURCE_KEY, this._uid); + } + each(this._handlers, function (handler, eventName) { + zr.on(eventName, handler); + }); + this._brushType = brushOption.brushType; + this._brushOption = merge(clone(DEFAULT_BRUSH_OPT), brushOption, true); + }; + BrushController.prototype._doDisableBrush = function () { + var zr = this._zr; + release(zr, MUTEX_RESOURCE_KEY, this._uid); + each(this._handlers, function (handler, eventName) { + zr.off(eventName, handler); + }); + this._brushType = this._brushOption = null; + }; + /** + * @param panelOpts If not pass, it is global brush. + */ + BrushController.prototype.setPanels = function (panelOpts) { + if (panelOpts && panelOpts.length) { + var panels_1 = this._panels = {}; + each(panelOpts, function (panelOpts) { + panels_1[panelOpts.panelId] = clone(panelOpts); + }); + } else { + this._panels = null; + } + return this; + }; + BrushController.prototype.mount = function (opt) { + opt = opt || {}; + if ("development" !== 'production') { + this._mounted = true; // should be at first. + } + + this._enableGlobalPan = opt.enableGlobalPan; + var thisGroup = this.group; + this._zr.add(thisGroup); + thisGroup.attr({ + x: opt.x || 0, + y: opt.y || 0, + rotation: opt.rotation || 0, + scaleX: opt.scaleX || 1, + scaleY: opt.scaleY || 1 + }); + this._transform = thisGroup.getLocalTransform(); + return this; + }; + // eachCover(cb, context): void { + // each(this._covers, cb, context); + // } + /** + * Update covers. + * @param coverConfigList + * If coverConfigList is null/undefined, all covers removed. + */ + BrushController.prototype.updateCovers = function (coverConfigList) { + if ("development" !== 'production') { + assert(this._mounted); + } + coverConfigList = map(coverConfigList, function (coverConfig) { + return merge(clone(DEFAULT_BRUSH_OPT), coverConfig, true); + }); + var tmpIdPrefix = '\0-brush-index-'; + var oldCovers = this._covers; + var newCovers = this._covers = []; + var controller = this; + var creatingCover = this._creatingCover; + new DataDiffer(oldCovers, coverConfigList, oldGetKey, getKey).add(addOrUpdate).update(addOrUpdate).remove(remove).execute(); + return this; + function getKey(brushOption, index) { + return (brushOption.id != null ? brushOption.id : tmpIdPrefix + index) + '-' + brushOption.brushType; + } + function oldGetKey(cover, index) { + return getKey(cover.__brushOption, index); + } + function addOrUpdate(newIndex, oldIndex) { + var newBrushInternal = coverConfigList[newIndex]; + // Consider setOption in event listener of brushSelect, + // where updating cover when creating should be forbidden. + if (oldIndex != null && oldCovers[oldIndex] === creatingCover) { + newCovers[newIndex] = oldCovers[oldIndex]; + } else { + var cover = newCovers[newIndex] = oldIndex != null ? (oldCovers[oldIndex].__brushOption = newBrushInternal, oldCovers[oldIndex]) : endCreating(controller, createCover(controller, newBrushInternal)); + updateCoverAfterCreation(controller, cover); + } + } + function remove(oldIndex) { + if (oldCovers[oldIndex] !== creatingCover) { + controller.group.remove(oldCovers[oldIndex]); + } + } + }; + BrushController.prototype.unmount = function () { + if ("development" !== 'production') { + if (!this._mounted) { + return; + } + } + this.enableBrush(false); + // container may 'removeAll' outside. + clearCovers(this); + this._zr.remove(this.group); + if ("development" !== 'production') { + this._mounted = false; // should be at last. + } + + return this; + }; + BrushController.prototype.dispose = function () { + this.unmount(); + this.off(); + }; + return BrushController; + }(Eventful); + function createCover(controller, brushOption) { + var cover = coverRenderers[brushOption.brushType].createCover(controller, brushOption); + cover.__brushOption = brushOption; + updateZ(cover, brushOption); + controller.group.add(cover); + return cover; + } + function endCreating(controller, creatingCover) { + var coverRenderer = getCoverRenderer(creatingCover); + if (coverRenderer.endCreating) { + coverRenderer.endCreating(controller, creatingCover); + updateZ(creatingCover, creatingCover.__brushOption); + } + return creatingCover; + } + function updateCoverShape(controller, cover) { + var brushOption = cover.__brushOption; + getCoverRenderer(cover).updateCoverShape(controller, cover, brushOption.range, brushOption); + } + function updateZ(cover, brushOption) { + var z = brushOption.z; + z == null && (z = COVER_Z); + cover.traverse(function (el) { + el.z = z; + el.z2 = z; // Consider in given container. + }); + } + + function updateCoverAfterCreation(controller, cover) { + getCoverRenderer(cover).updateCommon(controller, cover); + updateCoverShape(controller, cover); + } + function getCoverRenderer(cover) { + return coverRenderers[cover.__brushOption.brushType]; + } + // return target panel or `true` (means global panel) + function getPanelByPoint(controller, e, localCursorPoint) { + var panels = controller._panels; + if (!panels) { + return BRUSH_PANEL_GLOBAL; // Global panel + } + + var panel; + var transform = controller._transform; + each(panels, function (pn) { + pn.isTargetByCursor(e, localCursorPoint, transform) && (panel = pn); + }); + return panel; + } + // Return a panel or true + function getPanelByCover(controller, cover) { + var panels = controller._panels; + if (!panels) { + return BRUSH_PANEL_GLOBAL; // Global panel + } + + var panelId = cover.__brushOption.panelId; + // User may give cover without coord sys info, + // which is then treated as global panel. + return panelId != null ? panels[panelId] : BRUSH_PANEL_GLOBAL; + } + function clearCovers(controller) { + var covers = controller._covers; + var originalLength = covers.length; + each(covers, function (cover) { + controller.group.remove(cover); + }, controller); + covers.length = 0; + return !!originalLength; + } + function trigger$1(controller, opt) { + var areas = map(controller._covers, function (cover) { + var brushOption = cover.__brushOption; + var range = clone(brushOption.range); + return { + brushType: brushOption.brushType, + panelId: brushOption.panelId, + range: range + }; + }); + controller.trigger('brush', { + areas: areas, + isEnd: !!opt.isEnd, + removeOnClick: !!opt.removeOnClick + }); + } + function shouldShowCover(controller) { + var track = controller._track; + if (!track.length) { + return false; + } + var p2 = track[track.length - 1]; + var p1 = track[0]; + var dx = p2[0] - p1[0]; + var dy = p2[1] - p1[1]; + var dist = mathPow$2(dx * dx + dy * dy, 0.5); + return dist > UNSELECT_THRESHOLD; + } + function getTrackEnds(track) { + var tail = track.length - 1; + tail < 0 && (tail = 0); + return [track[0], track[tail]]; + } + function createBaseRectCover(rectRangeConverter, controller, brushOption, edgeNameSequences) { + var cover = new Group(); + cover.add(new Rect({ + name: 'main', + style: makeStyle(brushOption), + silent: true, + draggable: true, + cursor: 'move', + drift: curry(driftRect, rectRangeConverter, controller, cover, ['n', 's', 'w', 'e']), + ondragend: curry(trigger$1, controller, { + isEnd: true + }) + })); + each(edgeNameSequences, function (nameSequence) { + cover.add(new Rect({ + name: nameSequence.join(''), + style: { + opacity: 0 + }, + draggable: true, + silent: true, + invisible: true, + drift: curry(driftRect, rectRangeConverter, controller, cover, nameSequence), + ondragend: curry(trigger$1, controller, { + isEnd: true + }) + })); + }); + return cover; + } + function updateBaseRect(controller, cover, localRange, brushOption) { + var lineWidth = brushOption.brushStyle.lineWidth || 0; + var handleSize = mathMax$9(lineWidth, MIN_RESIZE_LINE_WIDTH); + var x = localRange[0][0]; + var y = localRange[1][0]; + var xa = x - lineWidth / 2; + var ya = y - lineWidth / 2; + var x2 = localRange[0][1]; + var y2 = localRange[1][1]; + var x2a = x2 - handleSize + lineWidth / 2; + var y2a = y2 - handleSize + lineWidth / 2; + var width = x2 - x; + var height = y2 - y; + var widtha = width + lineWidth; + var heighta = height + lineWidth; + updateRectShape(controller, cover, 'main', x, y, width, height); + if (brushOption.transformable) { + updateRectShape(controller, cover, 'w', xa, ya, handleSize, heighta); + updateRectShape(controller, cover, 'e', x2a, ya, handleSize, heighta); + updateRectShape(controller, cover, 'n', xa, ya, widtha, handleSize); + updateRectShape(controller, cover, 's', xa, y2a, widtha, handleSize); + updateRectShape(controller, cover, 'nw', xa, ya, handleSize, handleSize); + updateRectShape(controller, cover, 'ne', x2a, ya, handleSize, handleSize); + updateRectShape(controller, cover, 'sw', xa, y2a, handleSize, handleSize); + updateRectShape(controller, cover, 'se', x2a, y2a, handleSize, handleSize); + } + } + function updateCommon(controller, cover) { + var brushOption = cover.__brushOption; + var transformable = brushOption.transformable; + var mainEl = cover.childAt(0); + mainEl.useStyle(makeStyle(brushOption)); + mainEl.attr({ + silent: !transformable, + cursor: transformable ? 'move' : 'default' + }); + each([['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']], function (nameSequence) { + var el = cover.childOfName(nameSequence.join('')); + var globalDir = nameSequence.length === 1 ? getGlobalDirection1(controller, nameSequence[0]) : getGlobalDirection2(controller, nameSequence); + el && el.attr({ + silent: !transformable, + invisible: !transformable, + cursor: transformable ? CURSOR_MAP[globalDir] + '-resize' : null + }); + }); + } + function updateRectShape(controller, cover, name, x, y, w, h) { + var el = cover.childOfName(name); + el && el.setShape(pointsToRect(clipByPanel(controller, cover, [[x, y], [x + w, y + h]]))); + } + function makeStyle(brushOption) { + return defaults({ + strokeNoScale: true + }, brushOption.brushStyle); + } + function formatRectRange(x, y, x2, y2) { + var min = [mathMin$9(x, x2), mathMin$9(y, y2)]; + var max = [mathMax$9(x, x2), mathMax$9(y, y2)]; + return [[min[0], max[0]], [min[1], max[1]] // y range + ]; + } + + function getTransform$1(controller) { + return getTransform(controller.group); + } + function getGlobalDirection1(controller, localDirName) { + var map = { + w: 'left', + e: 'right', + n: 'top', + s: 'bottom' + }; + var inverseMap = { + left: 'w', + right: 'e', + top: 'n', + bottom: 's' + }; + var dir = transformDirection(map[localDirName], getTransform$1(controller)); + return inverseMap[dir]; + } + function getGlobalDirection2(controller, localDirNameSeq) { + var globalDir = [getGlobalDirection1(controller, localDirNameSeq[0]), getGlobalDirection1(controller, localDirNameSeq[1])]; + (globalDir[0] === 'e' || globalDir[0] === 'w') && globalDir.reverse(); + return globalDir.join(''); + } + function driftRect(rectRangeConverter, controller, cover, dirNameSequence, dx, dy) { + var brushOption = cover.__brushOption; + var rectRange = rectRangeConverter.toRectRange(brushOption.range); + var localDelta = toLocalDelta(controller, dx, dy); + each(dirNameSequence, function (dirName) { + var ind = DIRECTION_MAP[dirName]; + rectRange[ind[0]][ind[1]] += localDelta[ind[0]]; + }); + brushOption.range = rectRangeConverter.fromRectRange(formatRectRange(rectRange[0][0], rectRange[1][0], rectRange[0][1], rectRange[1][1])); + updateCoverAfterCreation(controller, cover); + trigger$1(controller, { + isEnd: false + }); + } + function driftPolygon(controller, cover, dx, dy) { + var range = cover.__brushOption.range; + var localDelta = toLocalDelta(controller, dx, dy); + each(range, function (point) { + point[0] += localDelta[0]; + point[1] += localDelta[1]; + }); + updateCoverAfterCreation(controller, cover); + trigger$1(controller, { + isEnd: false + }); + } + function toLocalDelta(controller, dx, dy) { + var thisGroup = controller.group; + var localD = thisGroup.transformCoordToLocal(dx, dy); + var localZero = thisGroup.transformCoordToLocal(0, 0); + return [localD[0] - localZero[0], localD[1] - localZero[1]]; + } + function clipByPanel(controller, cover, data) { + var panel = getPanelByCover(controller, cover); + return panel && panel !== BRUSH_PANEL_GLOBAL ? panel.clipPath(data, controller._transform) : clone(data); + } + function pointsToRect(points) { + var xmin = mathMin$9(points[0][0], points[1][0]); + var ymin = mathMin$9(points[0][1], points[1][1]); + var xmax = mathMax$9(points[0][0], points[1][0]); + var ymax = mathMax$9(points[0][1], points[1][1]); + return { + x: xmin, + y: ymin, + width: xmax - xmin, + height: ymax - ymin + }; + } + function resetCursor(controller, e, localCursorPoint) { + if ( + // Check active + !controller._brushType + // resetCursor should be always called when mouse is in zr area, + // but not called when mouse is out of zr area to avoid bad influence + // if `mousemove`, `mouseup` are triggered from `document` event. + || isOutsideZrArea(controller, e.offsetX, e.offsetY)) { + return; + } + var zr = controller._zr; + var covers = controller._covers; + var currPanel = getPanelByPoint(controller, e, localCursorPoint); + // Check whether in covers. + if (!controller._dragging) { + for (var i = 0; i < covers.length; i++) { + var brushOption = covers[i].__brushOption; + if (currPanel && (currPanel === BRUSH_PANEL_GLOBAL || brushOption.panelId === currPanel.panelId) && coverRenderers[brushOption.brushType].contain(covers[i], localCursorPoint[0], localCursorPoint[1])) { + // Use cursor style set on cover. + return; + } + } + } + currPanel && zr.setCursorStyle('crosshair'); + } + function preventDefault(e) { + var rawE = e.event; + rawE.preventDefault && rawE.preventDefault(); + } + function mainShapeContain(cover, x, y) { + return cover.childOfName('main').contain(x, y); + } + function updateCoverByMouse(controller, e, localCursorPoint, isEnd) { + var creatingCover = controller._creatingCover; + var panel = controller._creatingPanel; + var thisBrushOption = controller._brushOption; + var eventParams; + controller._track.push(localCursorPoint.slice()); + if (shouldShowCover(controller) || creatingCover) { + if (panel && !creatingCover) { + thisBrushOption.brushMode === 'single' && clearCovers(controller); + var brushOption = clone(thisBrushOption); + brushOption.brushType = determineBrushType(brushOption.brushType, panel); + brushOption.panelId = panel === BRUSH_PANEL_GLOBAL ? null : panel.panelId; + creatingCover = controller._creatingCover = createCover(controller, brushOption); + controller._covers.push(creatingCover); + } + if (creatingCover) { + var coverRenderer = coverRenderers[determineBrushType(controller._brushType, panel)]; + var coverBrushOption = creatingCover.__brushOption; + coverBrushOption.range = coverRenderer.getCreatingRange(clipByPanel(controller, creatingCover, controller._track)); + if (isEnd) { + endCreating(controller, creatingCover); + coverRenderer.updateCommon(controller, creatingCover); + } + updateCoverShape(controller, creatingCover); + eventParams = { + isEnd: isEnd + }; + } + } else if (isEnd && thisBrushOption.brushMode === 'single' && thisBrushOption.removeOnClick) { + // Help user to remove covers easily, only by a tiny drag, in 'single' mode. + // But a single click do not clear covers, because user may have casual + // clicks (for example, click on other component and do not expect covers + // disappear). + // Only some cover removed, trigger action, but not every click trigger action. + if (getPanelByPoint(controller, e, localCursorPoint) && clearCovers(controller)) { + eventParams = { + isEnd: isEnd, + removeOnClick: true + }; + } + } + return eventParams; + } + function determineBrushType(brushType, panel) { + if (brushType === 'auto') { + if ("development" !== 'production') { + assert(panel && panel.defaultBrushType, 'MUST have defaultBrushType when brushType is "atuo"'); + } + return panel.defaultBrushType; + } + return brushType; + } + var pointerHandlers = { + mousedown: function (e) { + if (this._dragging) { + // In case some browser do not support globalOut, + // and release mouse out side the browser. + handleDragEnd(this, e); + } else if (!e.target || !e.target.draggable) { + preventDefault(e); + var localCursorPoint = this.group.transformCoordToLocal(e.offsetX, e.offsetY); + this._creatingCover = null; + var panel = this._creatingPanel = getPanelByPoint(this, e, localCursorPoint); + if (panel) { + this._dragging = true; + this._track = [localCursorPoint.slice()]; + } + } + }, + mousemove: function (e) { + var x = e.offsetX; + var y = e.offsetY; + var localCursorPoint = this.group.transformCoordToLocal(x, y); + resetCursor(this, e, localCursorPoint); + if (this._dragging) { + preventDefault(e); + var eventParams = updateCoverByMouse(this, e, localCursorPoint, false); + eventParams && trigger$1(this, eventParams); + } + }, + mouseup: function (e) { + handleDragEnd(this, e); + } + }; + function handleDragEnd(controller, e) { + if (controller._dragging) { + preventDefault(e); + var x = e.offsetX; + var y = e.offsetY; + var localCursorPoint = controller.group.transformCoordToLocal(x, y); + var eventParams = updateCoverByMouse(controller, e, localCursorPoint, true); + controller._dragging = false; + controller._track = []; + controller._creatingCover = null; + // trigger event should be at final, after procedure will be nested. + eventParams && trigger$1(controller, eventParams); + } + } + function isOutsideZrArea(controller, x, y) { + var zr = controller._zr; + return x < 0 || x > zr.getWidth() || y < 0 || y > zr.getHeight(); + } + /** + * key: brushType + */ + var coverRenderers = { + lineX: getLineRenderer(0), + lineY: getLineRenderer(1), + rect: { + createCover: function (controller, brushOption) { + function returnInput(range) { + return range; + } + return createBaseRectCover({ + toRectRange: returnInput, + fromRectRange: returnInput + }, controller, brushOption, [['w'], ['e'], ['n'], ['s'], ['s', 'e'], ['s', 'w'], ['n', 'e'], ['n', 'w']]); + }, + getCreatingRange: function (localTrack) { + var ends = getTrackEnds(localTrack); + return formatRectRange(ends[1][0], ends[1][1], ends[0][0], ends[0][1]); + }, + updateCoverShape: function (controller, cover, localRange, brushOption) { + updateBaseRect(controller, cover, localRange, brushOption); + }, + updateCommon: updateCommon, + contain: mainShapeContain + }, + polygon: { + createCover: function (controller, brushOption) { + var cover = new Group(); + // Do not use graphic.Polygon because graphic.Polyline do not close the + // border of the shape when drawing, which is a better experience for user. + cover.add(new Polyline({ + name: 'main', + style: makeStyle(brushOption), + silent: true + })); + return cover; + }, + getCreatingRange: function (localTrack) { + return localTrack; + }, + endCreating: function (controller, cover) { + cover.remove(cover.childAt(0)); + // Use graphic.Polygon close the shape. + cover.add(new Polygon({ + name: 'main', + draggable: true, + drift: curry(driftPolygon, controller, cover), + ondragend: curry(trigger$1, controller, { + isEnd: true + }) + })); + }, + updateCoverShape: function (controller, cover, localRange, brushOption) { + cover.childAt(0).setShape({ + points: clipByPanel(controller, cover, localRange) + }); + }, + updateCommon: updateCommon, + contain: mainShapeContain + } + }; + function getLineRenderer(xyIndex) { + return { + createCover: function (controller, brushOption) { + return createBaseRectCover({ + toRectRange: function (range) { + var rectRange = [range, [0, 100]]; + xyIndex && rectRange.reverse(); + return rectRange; + }, + fromRectRange: function (rectRange) { + return rectRange[xyIndex]; + } + }, controller, brushOption, [[['w'], ['e']], [['n'], ['s']]][xyIndex]); + }, + getCreatingRange: function (localTrack) { + var ends = getTrackEnds(localTrack); + var min = mathMin$9(ends[0][xyIndex], ends[1][xyIndex]); + var max = mathMax$9(ends[0][xyIndex], ends[1][xyIndex]); + return [min, max]; + }, + updateCoverShape: function (controller, cover, localRange, brushOption) { + var otherExtent; + // If brushWidth not specified, fit the panel. + var panel = getPanelByCover(controller, cover); + if (panel !== BRUSH_PANEL_GLOBAL && panel.getLinearBrushOtherExtent) { + otherExtent = panel.getLinearBrushOtherExtent(xyIndex); + } else { + var zr = controller._zr; + otherExtent = [0, [zr.getWidth(), zr.getHeight()][1 - xyIndex]]; + } + var rectRange = [localRange, otherExtent]; + xyIndex && rectRange.reverse(); + updateBaseRect(controller, cover, rectRange, brushOption); + }, + updateCommon: updateCommon, + contain: mainShapeContain + }; + } + + function makeRectPanelClipPath(rect) { + rect = normalizeRect(rect); + return function (localPoints) { + return clipPointsByRect(localPoints, rect); + }; + } + function makeLinearBrushOtherExtent(rect, specifiedXYIndex) { + rect = normalizeRect(rect); + return function (xyIndex) { + var idx = specifiedXYIndex != null ? specifiedXYIndex : xyIndex; + var brushWidth = idx ? rect.width : rect.height; + var base = idx ? rect.x : rect.y; + return [base, base + (brushWidth || 0)]; + }; + } + function makeRectIsTargetByCursor(rect, api, targetModel) { + var boundingRect = normalizeRect(rect); + return function (e, localCursorPoint) { + return boundingRect.contain(localCursorPoint[0], localCursorPoint[1]) && !onIrrelevantElement(e, api, targetModel); + }; + } + // Consider width/height is negative. + function normalizeRect(rect) { + return BoundingRect.create(rect); + } + + var elementList = ['axisLine', 'axisTickLabel', 'axisName']; + var ParallelAxisView = /** @class */function (_super) { + __extends(ParallelAxisView, _super); + function ParallelAxisView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ParallelAxisView.type; + return _this; + } + ParallelAxisView.prototype.init = function (ecModel, api) { + _super.prototype.init.apply(this, arguments); + (this._brushController = new BrushController(api.getZr())).on('brush', bind(this._onBrush, this)); + }; + ParallelAxisView.prototype.render = function (axisModel, ecModel, api, payload) { + if (fromAxisAreaSelect(axisModel, ecModel, payload)) { + return; + } + this.axisModel = axisModel; + this.api = api; + this.group.removeAll(); + var oldAxisGroup = this._axisGroup; + this._axisGroup = new Group(); + this.group.add(this._axisGroup); + if (!axisModel.get('show')) { + return; + } + var coordSysModel = getCoordSysModel(axisModel, ecModel); + var coordSys = coordSysModel.coordinateSystem; + var areaSelectStyle = axisModel.getAreaSelectStyle(); + var areaWidth = areaSelectStyle.width; + var dim = axisModel.axis.dim; + var axisLayout = coordSys.getAxisLayout(dim); + var builderOpt = extend({ + strokeContainThreshold: areaWidth + }, axisLayout); + var axisBuilder = new AxisBuilder(axisModel, builderOpt); + each(elementList, axisBuilder.add, axisBuilder); + this._axisGroup.add(axisBuilder.getGroup()); + this._refreshBrushController(builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api); + groupTransition(oldAxisGroup, this._axisGroup, axisModel); + }; + // /** + // * @override + // */ + // updateVisual(axisModel, ecModel, api, payload) { + // this._brushController && this._brushController + // .updateCovers(getCoverInfoList(axisModel)); + // } + ParallelAxisView.prototype._refreshBrushController = function (builderOpt, areaSelectStyle, axisModel, coordSysModel, areaWidth, api) { + // After filtering, axis may change, select area needs to be update. + var extent = axisModel.axis.getExtent(); + var extentLen = extent[1] - extent[0]; + var extra = Math.min(30, Math.abs(extentLen) * 0.1); // Arbitrary value. + // width/height might be negative, which will be + // normalized in BoundingRect. + var rect = BoundingRect.create({ + x: extent[0], + y: -areaWidth / 2, + width: extentLen, + height: areaWidth + }); + rect.x -= extra; + rect.width += 2 * extra; + this._brushController.mount({ + enableGlobalPan: true, + rotation: builderOpt.rotation, + x: builderOpt.position[0], + y: builderOpt.position[1] + }).setPanels([{ + panelId: 'pl', + clipPath: makeRectPanelClipPath(rect), + isTargetByCursor: makeRectIsTargetByCursor(rect, api, coordSysModel), + getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect, 0) + }]).enableBrush({ + brushType: 'lineX', + brushStyle: areaSelectStyle, + removeOnClick: true + }).updateCovers(getCoverInfoList(axisModel)); + }; + ParallelAxisView.prototype._onBrush = function (eventParam) { + var coverInfoList = eventParam.areas; + // Do not cache these object, because the mey be changed. + var axisModel = this.axisModel; + var axis = axisModel.axis; + var intervals = map(coverInfoList, function (coverInfo) { + return [axis.coordToData(coverInfo.range[0], true), axis.coordToData(coverInfo.range[1], true)]; + }); + // If realtime is true, action is not dispatched on drag end, because + // the drag end emits the same params with the last drag move event, + // and may have some delay when using touch pad. + if (!axisModel.option.realtime === eventParam.isEnd || eventParam.removeOnClick) { + // jshint ignore:line + this.api.dispatchAction({ + type: 'axisAreaSelect', + parallelAxisId: axisModel.id, + intervals: intervals + }); + } + }; + ParallelAxisView.prototype.dispose = function () { + this._brushController.dispose(); + }; + ParallelAxisView.type = 'parallelAxis'; + return ParallelAxisView; + }(ComponentView); + function fromAxisAreaSelect(axisModel, ecModel, payload) { + return payload && payload.type === 'axisAreaSelect' && ecModel.findComponents({ + mainType: 'parallelAxis', + query: payload + })[0] === axisModel; + } + function getCoverInfoList(axisModel) { + var axis = axisModel.axis; + return map(axisModel.activeIntervals, function (interval) { + return { + brushType: 'lineX', + panelId: 'pl', + range: [axis.dataToCoord(interval[0], true), axis.dataToCoord(interval[1], true)] + }; + }); + } + function getCoordSysModel(axisModel, ecModel) { + return ecModel.getComponent('parallel', axisModel.get('parallelIndex')); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var actionInfo$1 = { + type: 'axisAreaSelect', + event: 'axisAreaSelected' + // update: 'updateVisual' + }; + + function installParallelActions(registers) { + registers.registerAction(actionInfo$1, function (payload, ecModel) { + ecModel.eachComponent({ + mainType: 'parallelAxis', + query: payload + }, function (parallelAxisModel) { + parallelAxisModel.axis.model.setActiveIntervals(payload.intervals); + }); + }); + /** + * @payload + */ + registers.registerAction('parallelAxisExpand', function (payload, ecModel) { + ecModel.eachComponent({ + mainType: 'parallel', + query: payload + }, function (parallelModel) { + parallelModel.setAxisExpand(payload); + }); + }); + } + + var defaultAxisOption = { + type: 'value', + areaSelectStyle: { + width: 20, + borderWidth: 1, + borderColor: 'rgba(160,197,232)', + color: 'rgba(160,197,232)', + opacity: 0.3 + }, + realtime: true, + z: 10 + }; + function install$g(registers) { + registers.registerComponentView(ParallelView$1); + registers.registerComponentModel(ParallelModel); + registers.registerCoordinateSystem('parallel', parallelCoordSysCreator); + registers.registerPreprocessor(parallelPreprocessor); + registers.registerComponentModel(ParallelAxisModel); + registers.registerComponentView(ParallelAxisView); + axisModelCreator(registers, 'parallel', ParallelAxisModel, defaultAxisOption); + installParallelActions(registers); + } + + function install$h(registers) { + use(install$g); + registers.registerChartView(ParallelView); + registers.registerSeriesModel(ParallelSeriesModel); + registers.registerVisual(registers.PRIORITY.VISUAL.BRUSH, parallelVisual); + } + + var SankeyPathShape = /** @class */function () { + function SankeyPathShape() { + this.x1 = 0; + this.y1 = 0; + this.x2 = 0; + this.y2 = 0; + this.cpx1 = 0; + this.cpy1 = 0; + this.cpx2 = 0; + this.cpy2 = 0; + this.extent = 0; + } + return SankeyPathShape; + }(); + var SankeyPath = /** @class */function (_super) { + __extends(SankeyPath, _super); + function SankeyPath(opts) { + return _super.call(this, opts) || this; + } + SankeyPath.prototype.getDefaultShape = function () { + return new SankeyPathShape(); + }; + SankeyPath.prototype.buildPath = function (ctx, shape) { + var extent = shape.extent; + ctx.moveTo(shape.x1, shape.y1); + ctx.bezierCurveTo(shape.cpx1, shape.cpy1, shape.cpx2, shape.cpy2, shape.x2, shape.y2); + if (shape.orient === 'vertical') { + ctx.lineTo(shape.x2 + extent, shape.y2); + ctx.bezierCurveTo(shape.cpx2 + extent, shape.cpy2, shape.cpx1 + extent, shape.cpy1, shape.x1 + extent, shape.y1); + } else { + ctx.lineTo(shape.x2, shape.y2 + extent); + ctx.bezierCurveTo(shape.cpx2, shape.cpy2 + extent, shape.cpx1, shape.cpy1 + extent, shape.x1, shape.y1 + extent); + } + ctx.closePath(); + }; + SankeyPath.prototype.highlight = function () { + enterEmphasis(this); + }; + SankeyPath.prototype.downplay = function () { + leaveEmphasis(this); + }; + return SankeyPath; + }(Path); + var SankeyView = /** @class */function (_super) { + __extends(SankeyView, _super); + function SankeyView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SankeyView.type; + _this._focusAdjacencyDisabled = false; + return _this; + } + SankeyView.prototype.render = function (seriesModel, ecModel, api) { + var sankeyView = this; + var graph = seriesModel.getGraph(); + var group = this.group; + var layoutInfo = seriesModel.layoutInfo; + // view width + var width = layoutInfo.width; + // view height + var height = layoutInfo.height; + var nodeData = seriesModel.getData(); + var edgeData = seriesModel.getData('edge'); + var orient = seriesModel.get('orient'); + this._model = seriesModel; + group.removeAll(); + group.x = layoutInfo.x; + group.y = layoutInfo.y; + // generate a bezire Curve for each edge + graph.eachEdge(function (edge) { + var curve = new SankeyPath(); + var ecData = getECData(curve); + ecData.dataIndex = edge.dataIndex; + ecData.seriesIndex = seriesModel.seriesIndex; + ecData.dataType = 'edge'; + var edgeModel = edge.getModel(); + var lineStyleModel = edgeModel.getModel('lineStyle'); + var curvature = lineStyleModel.get('curveness'); + var n1Layout = edge.node1.getLayout(); + var node1Model = edge.node1.getModel(); + var dragX1 = node1Model.get('localX'); + var dragY1 = node1Model.get('localY'); + var n2Layout = edge.node2.getLayout(); + var node2Model = edge.node2.getModel(); + var dragX2 = node2Model.get('localX'); + var dragY2 = node2Model.get('localY'); + var edgeLayout = edge.getLayout(); + var x1; + var y1; + var x2; + var y2; + var cpx1; + var cpy1; + var cpx2; + var cpy2; + curve.shape.extent = Math.max(1, edgeLayout.dy); + curve.shape.orient = orient; + if (orient === 'vertical') { + x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + edgeLayout.sy; + y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + n1Layout.dy; + x2 = (dragX2 != null ? dragX2 * width : n2Layout.x) + edgeLayout.ty; + y2 = dragY2 != null ? dragY2 * height : n2Layout.y; + cpx1 = x1; + cpy1 = y1 * (1 - curvature) + y2 * curvature; + cpx2 = x2; + cpy2 = y1 * curvature + y2 * (1 - curvature); + } else { + x1 = (dragX1 != null ? dragX1 * width : n1Layout.x) + n1Layout.dx; + y1 = (dragY1 != null ? dragY1 * height : n1Layout.y) + edgeLayout.sy; + x2 = dragX2 != null ? dragX2 * width : n2Layout.x; + y2 = (dragY2 != null ? dragY2 * height : n2Layout.y) + edgeLayout.ty; + cpx1 = x1 * (1 - curvature) + x2 * curvature; + cpy1 = y1; + cpx2 = x1 * curvature + x2 * (1 - curvature); + cpy2 = y2; + } + curve.setShape({ + x1: x1, + y1: y1, + x2: x2, + y2: y2, + cpx1: cpx1, + cpy1: cpy1, + cpx2: cpx2, + cpy2: cpy2 + }); + curve.useStyle(lineStyleModel.getItemStyle()); + // Special color, use source node color or target node color + applyCurveStyle(curve.style, orient, edge); + var defaultEdgeLabelText = "" + edgeModel.get('value'); + var edgeLabelStateModels = getLabelStatesModels(edgeModel, 'edgeLabel'); + setLabelStyle(curve, edgeLabelStateModels, { + labelFetcher: { + getFormattedLabel: function (dataIndex, stateName, dataType, labelDimIndex, formatter, extendParams) { + return seriesModel.getFormattedLabel(dataIndex, stateName, 'edge', labelDimIndex, + // ensure edgeLabel formatter is provided + // to prevent the inheritance from `label.formatter` of the series + retrieve3(formatter, edgeLabelStateModels.normal && edgeLabelStateModels.normal.get('formatter'), defaultEdgeLabelText), extendParams); + } + }, + labelDataIndex: edge.dataIndex, + defaultText: defaultEdgeLabelText + }); + curve.setTextConfig({ + position: 'inside' + }); + var emphasisModel = edgeModel.getModel('emphasis'); + setStatesStylesFromModel(curve, edgeModel, 'lineStyle', function (model) { + var style = model.getItemStyle(); + applyCurveStyle(style, orient, edge); + return style; + }); + group.add(curve); + edgeData.setItemGraphicEl(edge.dataIndex, curve); + var focus = emphasisModel.get('focus'); + toggleHoverEmphasis(curve, focus === 'adjacency' ? edge.getAdjacentDataIndices() : focus === 'trajectory' ? edge.getTrajectoryDataIndices() : focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + }); + // Generate a rect for each node + graph.eachNode(function (node) { + var layout = node.getLayout(); + var itemModel = node.getModel(); + var dragX = itemModel.get('localX'); + var dragY = itemModel.get('localY'); + var emphasisModel = itemModel.getModel('emphasis'); + var rect = new Rect({ + shape: { + x: dragX != null ? dragX * width : layout.x, + y: dragY != null ? dragY * height : layout.y, + width: layout.dx, + height: layout.dy + }, + style: itemModel.getModel('itemStyle').getItemStyle(), + z2: 10 + }); + setLabelStyle(rect, getLabelStatesModels(itemModel), { + labelFetcher: { + getFormattedLabel: function (dataIndex, stateName) { + return seriesModel.getFormattedLabel(dataIndex, stateName, 'node'); + } + }, + labelDataIndex: node.dataIndex, + defaultText: node.id + }); + rect.disableLabelAnimation = true; + rect.setStyle('fill', node.getVisual('color')); + rect.setStyle('decal', node.getVisual('style').decal); + setStatesStylesFromModel(rect, itemModel); + group.add(rect); + nodeData.setItemGraphicEl(node.dataIndex, rect); + getECData(rect).dataType = 'node'; + var focus = emphasisModel.get('focus'); + toggleHoverEmphasis(rect, focus === 'adjacency' ? node.getAdjacentDataIndices() : focus === 'trajectory' ? node.getTrajectoryDataIndices() : focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + }); + nodeData.eachItemGraphicEl(function (el, dataIndex) { + var itemModel = nodeData.getItemModel(dataIndex); + if (itemModel.get('draggable')) { + el.drift = function (dx, dy) { + sankeyView._focusAdjacencyDisabled = true; + this.shape.x += dx; + this.shape.y += dy; + this.dirty(); + api.dispatchAction({ + type: 'dragNode', + seriesId: seriesModel.id, + dataIndex: nodeData.getRawIndex(dataIndex), + localX: this.shape.x / width, + localY: this.shape.y / height + }); + }; + el.ondragend = function () { + sankeyView._focusAdjacencyDisabled = false; + }; + el.draggable = true; + el.cursor = 'move'; + } + }); + if (!this._data && seriesModel.isAnimationEnabled()) { + group.setClipPath(createGridClipShape$1(group.getBoundingRect(), seriesModel, function () { + group.removeClipPath(); + })); + } + this._data = seriesModel.getData(); + }; + SankeyView.prototype.dispose = function () {}; + SankeyView.type = 'sankey'; + return SankeyView; + }(ChartView); + /** + * Special color, use source node color or target node color + * @param curveProps curve's style to parse + * @param orient direction + * @param edge current curve data + */ + function applyCurveStyle(curveProps, orient, edge) { + switch (curveProps.fill) { + case 'source': + curveProps.fill = edge.node1.getVisual('color'); + curveProps.decal = edge.node1.getVisual('style').decal; + break; + case 'target': + curveProps.fill = edge.node2.getVisual('color'); + curveProps.decal = edge.node2.getVisual('style').decal; + break; + case 'gradient': + var sourceColor = edge.node1.getVisual('color'); + var targetColor = edge.node2.getVisual('color'); + if (isString(sourceColor) && isString(targetColor)) { + curveProps.fill = new LinearGradient(0, 0, +(orient === 'horizontal'), +(orient === 'vertical'), [{ + color: sourceColor, + offset: 0 + }, { + color: targetColor, + offset: 1 + }]); + } + } + } + // Add animation to the view + function createGridClipShape$1(rect, seriesModel, cb) { + var rectEl = new Rect({ + shape: { + x: rect.x - 10, + y: rect.y - 10, + width: 0, + height: rect.height + 20 + } + }); + initProps(rectEl, { + shape: { + width: rect.width + 20 + } + }, seriesModel, cb); + return rectEl; + } + + var SankeySeriesModel = /** @class */function (_super) { + __extends(SankeySeriesModel, _super); + function SankeySeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SankeySeriesModel.type; + return _this; + } + /** + * Init a graph data structure from data in option series + */ + SankeySeriesModel.prototype.getInitialData = function (option, ecModel) { + var links = option.edges || option.links; + var nodes = option.data || option.nodes; + var levels = option.levels; + this.levelModels = []; + var levelModels = this.levelModels; + for (var i = 0; i < levels.length; i++) { + if (levels[i].depth != null && levels[i].depth >= 0) { + levelModels[levels[i].depth] = new Model(levels[i], this, ecModel); + } else { + if ("development" !== 'production') { + throw new Error('levels[i].depth is mandatory and should be natural number'); + } + } + } + if (nodes && links) { + var graph = createGraphFromNodeEdge(nodes, links, this, true, beforeLink); + return graph.data; + } + function beforeLink(nodeData, edgeData) { + nodeData.wrapMethod('getItemModel', function (model, idx) { + var seriesModel = model.parentModel; + var layout = seriesModel.getData().getItemLayout(idx); + if (layout) { + var nodeDepth = layout.depth; + var levelModel = seriesModel.levelModels[nodeDepth]; + if (levelModel) { + model.parentModel = levelModel; + } + } + return model; + }); + edgeData.wrapMethod('getItemModel', function (model, idx) { + var seriesModel = model.parentModel; + var edge = seriesModel.getGraph().getEdgeByIndex(idx); + var layout = edge.node1.getLayout(); + if (layout) { + var depth = layout.depth; + var levelModel = seriesModel.levelModels[depth]; + if (levelModel) { + model.parentModel = levelModel; + } + } + return model; + }); + } + }; + SankeySeriesModel.prototype.setNodePosition = function (dataIndex, localPosition) { + var nodes = this.option.data || this.option.nodes; + var dataItem = nodes[dataIndex]; + dataItem.localX = localPosition[0]; + dataItem.localY = localPosition[1]; + }; + /** + * Return the graphic data structure + * + * @return graphic data structure + */ + SankeySeriesModel.prototype.getGraph = function () { + return this.getData().graph; + }; + /** + * Get edge data of graphic data structure + * + * @return data structure of list + */ + SankeySeriesModel.prototype.getEdgeData = function () { + return this.getGraph().edgeData; + }; + SankeySeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + function noValue(val) { + return isNaN(val) || val == null; + } + // dataType === 'node' or empty do not show tooltip by default + if (dataType === 'edge') { + var params = this.getDataParams(dataIndex, dataType); + var rawDataOpt = params.data; + var edgeValue = params.value; + var edgeName = rawDataOpt.source + ' -- ' + rawDataOpt.target; + return createTooltipMarkup('nameValue', { + name: edgeName, + value: edgeValue, + noValue: noValue(edgeValue) + }); + } + // dataType === 'node' + else { + var node = this.getGraph().getNodeByIndex(dataIndex); + var value = node.getLayout().value; + var name_1 = this.getDataParams(dataIndex, dataType).data.name; + return createTooltipMarkup('nameValue', { + name: name_1 != null ? name_1 + '' : null, + value: value, + noValue: noValue(value) + }); + } + }; + SankeySeriesModel.prototype.optionUpdated = function () {}; + // Override Series.getDataParams() + SankeySeriesModel.prototype.getDataParams = function (dataIndex, dataType) { + var params = _super.prototype.getDataParams.call(this, dataIndex, dataType); + if (params.value == null && dataType === 'node') { + var node = this.getGraph().getNodeByIndex(dataIndex); + var nodeValue = node.getLayout().value; + params.value = nodeValue; + } + return params; + }; + SankeySeriesModel.type = 'series.sankey'; + SankeySeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + coordinateSystem: 'view', + left: '5%', + top: '5%', + right: '20%', + bottom: '5%', + orient: 'horizontal', + nodeWidth: 20, + nodeGap: 8, + draggable: true, + layoutIterations: 32, + label: { + show: true, + position: 'right', + fontSize: 12 + }, + edgeLabel: { + show: false, + fontSize: 12 + }, + levels: [], + nodeAlign: 'justify', + lineStyle: { + color: '#314656', + opacity: 0.2, + curveness: 0.5 + }, + emphasis: { + label: { + show: true + }, + lineStyle: { + opacity: 0.5 + } + }, + select: { + itemStyle: { + borderColor: '#212121' + } + }, + animationEasing: 'linear', + animationDuration: 1000 + }; + return SankeySeriesModel; + }(SeriesModel); + + function sankeyLayout(ecModel, api) { + ecModel.eachSeriesByType('sankey', function (seriesModel) { + var nodeWidth = seriesModel.get('nodeWidth'); + var nodeGap = seriesModel.get('nodeGap'); + var layoutInfo = getViewRect$4(seriesModel, api); + seriesModel.layoutInfo = layoutInfo; + var width = layoutInfo.width; + var height = layoutInfo.height; + var graph = seriesModel.getGraph(); + var nodes = graph.nodes; + var edges = graph.edges; + computeNodeValues(nodes); + var filteredNodes = filter(nodes, function (node) { + return node.getLayout().value === 0; + }); + var iterations = filteredNodes.length !== 0 ? 0 : seriesModel.get('layoutIterations'); + var orient = seriesModel.get('orient'); + var nodeAlign = seriesModel.get('nodeAlign'); + layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations, orient, nodeAlign); + }); + } + /** + * Get the layout position of the whole view + */ + function getViewRect$4(seriesModel, api) { + return getLayoutRect(seriesModel.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }); + } + function layoutSankey(nodes, edges, nodeWidth, nodeGap, width, height, iterations, orient, nodeAlign) { + computeNodeBreadths(nodes, edges, nodeWidth, width, height, orient, nodeAlign); + computeNodeDepths(nodes, edges, height, width, nodeGap, iterations, orient); + computeEdgeDepths(nodes, orient); + } + /** + * Compute the value of each node by summing the associated edge's value + */ + function computeNodeValues(nodes) { + each(nodes, function (node) { + var value1 = sum(node.outEdges, getEdgeValue); + var value2 = sum(node.inEdges, getEdgeValue); + var nodeRawValue = node.getValue() || 0; + var value = Math.max(value1, value2, nodeRawValue); + node.setLayout({ + value: value + }, true); + }); + } + /** + * Compute the x-position for each node. + * + * Here we use Kahn algorithm to detect cycle when we traverse + * the node to computer the initial x position. + */ + function computeNodeBreadths(nodes, edges, nodeWidth, width, height, orient, nodeAlign) { + // Used to mark whether the edge is deleted. if it is deleted, + // the value is 0, otherwise it is 1. + var remainEdges = []; + // Storage each node's indegree. + var indegreeArr = []; + // Used to storage the node with indegree is equal to 0. + var zeroIndegrees = []; + var nextTargetNode = []; + var x = 0; + // let kx = 0; + for (var i = 0; i < edges.length; i++) { + remainEdges[i] = 1; + } + for (var i = 0; i < nodes.length; i++) { + indegreeArr[i] = nodes[i].inEdges.length; + if (indegreeArr[i] === 0) { + zeroIndegrees.push(nodes[i]); + } + } + var maxNodeDepth = -1; + // Traversing nodes using topological sorting to calculate the + // horizontal(if orient === 'horizontal') or vertical(if orient === 'vertical') + // position of the nodes. + while (zeroIndegrees.length) { + for (var idx = 0; idx < zeroIndegrees.length; idx++) { + var node = zeroIndegrees[idx]; + var item = node.hostGraph.data.getRawDataItem(node.dataIndex); + var isItemDepth = item.depth != null && item.depth >= 0; + if (isItemDepth && item.depth > maxNodeDepth) { + maxNodeDepth = item.depth; + } + node.setLayout({ + depth: isItemDepth ? item.depth : x + }, true); + orient === 'vertical' ? node.setLayout({ + dy: nodeWidth + }, true) : node.setLayout({ + dx: nodeWidth + }, true); + for (var edgeIdx = 0; edgeIdx < node.outEdges.length; edgeIdx++) { + var edge = node.outEdges[edgeIdx]; + var indexEdge = edges.indexOf(edge); + remainEdges[indexEdge] = 0; + var targetNode = edge.node2; + var nodeIndex = nodes.indexOf(targetNode); + if (--indegreeArr[nodeIndex] === 0 && nextTargetNode.indexOf(targetNode) < 0) { + nextTargetNode.push(targetNode); + } + } + } + ++x; + zeroIndegrees = nextTargetNode; + nextTargetNode = []; + } + for (var i = 0; i < remainEdges.length; i++) { + if (remainEdges[i] === 1) { + throw new Error('Sankey is a DAG, the original data has cycle!'); + } + } + var maxDepth = maxNodeDepth > x - 1 ? maxNodeDepth : x - 1; + if (nodeAlign && nodeAlign !== 'left') { + adjustNodeWithNodeAlign(nodes, nodeAlign, orient, maxDepth); + } + var kx = orient === 'vertical' ? (height - nodeWidth) / maxDepth : (width - nodeWidth) / maxDepth; + scaleNodeBreadths(nodes, kx, orient); + } + function isNodeDepth(node) { + var item = node.hostGraph.data.getRawDataItem(node.dataIndex); + return item.depth != null && item.depth >= 0; + } + function adjustNodeWithNodeAlign(nodes, nodeAlign, orient, maxDepth) { + if (nodeAlign === 'right') { + var nextSourceNode = []; + var remainNodes = nodes; + var nodeHeight = 0; + while (remainNodes.length) { + for (var i = 0; i < remainNodes.length; i++) { + var node = remainNodes[i]; + node.setLayout({ + skNodeHeight: nodeHeight + }, true); + for (var j = 0; j < node.inEdges.length; j++) { + var edge = node.inEdges[j]; + if (nextSourceNode.indexOf(edge.node1) < 0) { + nextSourceNode.push(edge.node1); + } + } + } + remainNodes = nextSourceNode; + nextSourceNode = []; + ++nodeHeight; + } + each(nodes, function (node) { + if (!isNodeDepth(node)) { + node.setLayout({ + depth: Math.max(0, maxDepth - node.getLayout().skNodeHeight) + }, true); + } + }); + } else if (nodeAlign === 'justify') { + moveSinksRight(nodes, maxDepth); + } + } + /** + * All the node without outEgdes are assigned maximum x-position and + * be aligned in the last column. + * + * @param nodes. node of sankey view. + * @param maxDepth. use to assign to node without outEdges as x-position. + */ + function moveSinksRight(nodes, maxDepth) { + each(nodes, function (node) { + if (!isNodeDepth(node) && !node.outEdges.length) { + node.setLayout({ + depth: maxDepth + }, true); + } + }); + } + /** + * Scale node x-position to the width + * + * @param nodes node of sankey view + * @param kx multiple used to scale nodes + */ + function scaleNodeBreadths(nodes, kx, orient) { + each(nodes, function (node) { + var nodeDepth = node.getLayout().depth * kx; + orient === 'vertical' ? node.setLayout({ + y: nodeDepth + }, true) : node.setLayout({ + x: nodeDepth + }, true); + }); + } + /** + * Using Gauss-Seidel iterations method to compute the node depth(y-position) + * + * @param nodes node of sankey view + * @param edges edge of sankey view + * @param height the whole height of the area to draw the view + * @param nodeGap the vertical distance between two nodes + * in the same column. + * @param iterations the number of iterations for the algorithm + */ + function computeNodeDepths(nodes, edges, height, width, nodeGap, iterations, orient) { + var nodesByBreadth = prepareNodesByBreadth(nodes, orient); + initializeNodeDepth(nodesByBreadth, edges, height, width, nodeGap, orient); + resolveCollisions(nodesByBreadth, nodeGap, height, width, orient); + for (var alpha = 1; iterations > 0; iterations--) { + // 0.99 is a experience parameter, ensure that each iterations of + // changes as small as possible. + alpha *= 0.99; + relaxRightToLeft(nodesByBreadth, alpha, orient); + resolveCollisions(nodesByBreadth, nodeGap, height, width, orient); + relaxLeftToRight(nodesByBreadth, alpha, orient); + resolveCollisions(nodesByBreadth, nodeGap, height, width, orient); + } + } + function prepareNodesByBreadth(nodes, orient) { + var nodesByBreadth = []; + var keyAttr = orient === 'vertical' ? 'y' : 'x'; + var groupResult = groupData(nodes, function (node) { + return node.getLayout()[keyAttr]; + }); + groupResult.keys.sort(function (a, b) { + return a - b; + }); + each(groupResult.keys, function (key) { + nodesByBreadth.push(groupResult.buckets.get(key)); + }); + return nodesByBreadth; + } + /** + * Compute the original y-position for each node + */ + function initializeNodeDepth(nodesByBreadth, edges, height, width, nodeGap, orient) { + var minKy = Infinity; + each(nodesByBreadth, function (nodes) { + var n = nodes.length; + var sum = 0; + each(nodes, function (node) { + sum += node.getLayout().value; + }); + var ky = orient === 'vertical' ? (width - (n - 1) * nodeGap) / sum : (height - (n - 1) * nodeGap) / sum; + if (ky < minKy) { + minKy = ky; + } + }); + each(nodesByBreadth, function (nodes) { + each(nodes, function (node, i) { + var nodeDy = node.getLayout().value * minKy; + if (orient === 'vertical') { + node.setLayout({ + x: i + }, true); + node.setLayout({ + dx: nodeDy + }, true); + } else { + node.setLayout({ + y: i + }, true); + node.setLayout({ + dy: nodeDy + }, true); + } + }); + }); + each(edges, function (edge) { + var edgeDy = +edge.getValue() * minKy; + edge.setLayout({ + dy: edgeDy + }, true); + }); + } + /** + * Resolve the collision of initialized depth (y-position) + */ + function resolveCollisions(nodesByBreadth, nodeGap, height, width, orient) { + var keyAttr = orient === 'vertical' ? 'x' : 'y'; + each(nodesByBreadth, function (nodes) { + nodes.sort(function (a, b) { + return a.getLayout()[keyAttr] - b.getLayout()[keyAttr]; + }); + var nodeX; + var node; + var dy; + var y0 = 0; + var n = nodes.length; + var nodeDyAttr = orient === 'vertical' ? 'dx' : 'dy'; + for (var i = 0; i < n; i++) { + node = nodes[i]; + dy = y0 - node.getLayout()[keyAttr]; + if (dy > 0) { + nodeX = node.getLayout()[keyAttr] + dy; + orient === 'vertical' ? node.setLayout({ + x: nodeX + }, true) : node.setLayout({ + y: nodeX + }, true); + } + y0 = node.getLayout()[keyAttr] + node.getLayout()[nodeDyAttr] + nodeGap; + } + var viewWidth = orient === 'vertical' ? width : height; + // If the bottommost node goes outside the bounds, push it back up + dy = y0 - nodeGap - viewWidth; + if (dy > 0) { + nodeX = node.getLayout()[keyAttr] - dy; + orient === 'vertical' ? node.setLayout({ + x: nodeX + }, true) : node.setLayout({ + y: nodeX + }, true); + y0 = nodeX; + for (var i = n - 2; i >= 0; --i) { + node = nodes[i]; + dy = node.getLayout()[keyAttr] + node.getLayout()[nodeDyAttr] + nodeGap - y0; + if (dy > 0) { + nodeX = node.getLayout()[keyAttr] - dy; + orient === 'vertical' ? node.setLayout({ + x: nodeX + }, true) : node.setLayout({ + y: nodeX + }, true); + } + y0 = node.getLayout()[keyAttr]; + } + } + }); + } + /** + * Change the y-position of the nodes, except most the right side nodes + * @param nodesByBreadth + * @param alpha parameter used to adjust the nodes y-position + */ + function relaxRightToLeft(nodesByBreadth, alpha, orient) { + each(nodesByBreadth.slice().reverse(), function (nodes) { + each(nodes, function (node) { + if (node.outEdges.length) { + var y = sum(node.outEdges, weightedTarget, orient) / sum(node.outEdges, getEdgeValue); + if (isNaN(y)) { + var len = node.outEdges.length; + y = len ? sum(node.outEdges, centerTarget, orient) / len : 0; + } + if (orient === 'vertical') { + var nodeX = node.getLayout().x + (y - center$1(node, orient)) * alpha; + node.setLayout({ + x: nodeX + }, true); + } else { + var nodeY = node.getLayout().y + (y - center$1(node, orient)) * alpha; + node.setLayout({ + y: nodeY + }, true); + } + } + }); + }); + } + function weightedTarget(edge, orient) { + return center$1(edge.node2, orient) * edge.getValue(); + } + function centerTarget(edge, orient) { + return center$1(edge.node2, orient); + } + function weightedSource(edge, orient) { + return center$1(edge.node1, orient) * edge.getValue(); + } + function centerSource(edge, orient) { + return center$1(edge.node1, orient); + } + function center$1(node, orient) { + return orient === 'vertical' ? node.getLayout().x + node.getLayout().dx / 2 : node.getLayout().y + node.getLayout().dy / 2; + } + function getEdgeValue(edge) { + return edge.getValue(); + } + function sum(array, cb, orient) { + var sum = 0; + var len = array.length; + var i = -1; + while (++i < len) { + var value = +cb(array[i], orient); + if (!isNaN(value)) { + sum += value; + } + } + return sum; + } + /** + * Change the y-position of the nodes, except most the left side nodes + */ + function relaxLeftToRight(nodesByBreadth, alpha, orient) { + each(nodesByBreadth, function (nodes) { + each(nodes, function (node) { + if (node.inEdges.length) { + var y = sum(node.inEdges, weightedSource, orient) / sum(node.inEdges, getEdgeValue); + if (isNaN(y)) { + var len = node.inEdges.length; + y = len ? sum(node.inEdges, centerSource, orient) / len : 0; + } + if (orient === 'vertical') { + var nodeX = node.getLayout().x + (y - center$1(node, orient)) * alpha; + node.setLayout({ + x: nodeX + }, true); + } else { + var nodeY = node.getLayout().y + (y - center$1(node, orient)) * alpha; + node.setLayout({ + y: nodeY + }, true); + } + } + }); + }); + } + /** + * Compute the depth(y-position) of each edge + */ + function computeEdgeDepths(nodes, orient) { + var keyAttr = orient === 'vertical' ? 'x' : 'y'; + each(nodes, function (node) { + node.outEdges.sort(function (a, b) { + return a.node2.getLayout()[keyAttr] - b.node2.getLayout()[keyAttr]; + }); + node.inEdges.sort(function (a, b) { + return a.node1.getLayout()[keyAttr] - b.node1.getLayout()[keyAttr]; + }); + }); + each(nodes, function (node) { + var sy = 0; + var ty = 0; + each(node.outEdges, function (edge) { + edge.setLayout({ + sy: sy + }, true); + sy += edge.getLayout().dy; + }); + each(node.inEdges, function (edge) { + edge.setLayout({ + ty: ty + }, true); + ty += edge.getLayout().dy; + }); + }); + } + + function sankeyVisual(ecModel) { + ecModel.eachSeriesByType('sankey', function (seriesModel) { + var graph = seriesModel.getGraph(); + var nodes = graph.nodes; + var edges = graph.edges; + if (nodes.length) { + var minValue_1 = Infinity; + var maxValue_1 = -Infinity; + each(nodes, function (node) { + var nodeValue = node.getLayout().value; + if (nodeValue < minValue_1) { + minValue_1 = nodeValue; + } + if (nodeValue > maxValue_1) { + maxValue_1 = nodeValue; + } + }); + each(nodes, function (node) { + var mapping = new VisualMapping({ + type: 'color', + mappingMethod: 'linear', + dataExtent: [minValue_1, maxValue_1], + visual: seriesModel.get('color') + }); + var mapValueToColor = mapping.mapValueToVisual(node.getLayout().value); + var customColor = node.getModel().get(['itemStyle', 'color']); + if (customColor != null) { + node.setVisual('color', customColor); + node.setVisual('style', { + fill: customColor + }); + } else { + node.setVisual('color', mapValueToColor); + node.setVisual('style', { + fill: mapValueToColor + }); + } + }); + } + if (edges.length) { + each(edges, function (edge) { + var edgeStyle = edge.getModel().get('lineStyle'); + edge.setVisual('style', edgeStyle); + }); + } + }); + } + + function install$i(registers) { + registers.registerChartView(SankeyView); + registers.registerSeriesModel(SankeySeriesModel); + registers.registerLayout(sankeyLayout); + registers.registerVisual(sankeyVisual); + registers.registerAction({ + type: 'dragNode', + event: 'dragnode', + // here can only use 'update' now, other value is not support in echarts. + update: 'update' + }, function (payload, ecModel) { + ecModel.eachComponent({ + mainType: 'series', + subType: 'sankey', + query: payload + }, function (seriesModel) { + seriesModel.setNodePosition(payload.dataIndex, [payload.localX, payload.localY]); + }); + }); + } + + var WhiskerBoxCommonMixin = /** @class */function () { + function WhiskerBoxCommonMixin() {} + /** + * @override + */ + WhiskerBoxCommonMixin.prototype.getInitialData = function (option, ecModel) { + // When both types of xAxis and yAxis are 'value', layout is + // needed to be specified by user. Otherwise, layout can be + // judged by which axis is category. + var ordinalMeta; + var xAxisModel = ecModel.getComponent('xAxis', this.get('xAxisIndex')); + var yAxisModel = ecModel.getComponent('yAxis', this.get('yAxisIndex')); + var xAxisType = xAxisModel.get('type'); + var yAxisType = yAxisModel.get('type'); + var addOrdinal; + // FIXME + // Consider time axis. + if (xAxisType === 'category') { + option.layout = 'horizontal'; + ordinalMeta = xAxisModel.getOrdinalMeta(); + addOrdinal = true; + } else if (yAxisType === 'category') { + option.layout = 'vertical'; + ordinalMeta = yAxisModel.getOrdinalMeta(); + addOrdinal = true; + } else { + option.layout = option.layout || 'horizontal'; + } + var coordDims = ['x', 'y']; + var baseAxisDimIndex = option.layout === 'horizontal' ? 0 : 1; + var baseAxisDim = this._baseAxisDim = coordDims[baseAxisDimIndex]; + var otherAxisDim = coordDims[1 - baseAxisDimIndex]; + var axisModels = [xAxisModel, yAxisModel]; + var baseAxisType = axisModels[baseAxisDimIndex].get('type'); + var otherAxisType = axisModels[1 - baseAxisDimIndex].get('type'); + var data = option.data; + // Clone a new data for next setOption({}) usage. + // Avoid modifying current data will affect further update. + if (data && addOrdinal) { + var newOptionData_1 = []; + each(data, function (item, index) { + var newItem; + if (isArray(item)) { + newItem = item.slice(); + // Modify current using data. + item.unshift(index); + } else if (isArray(item.value)) { + newItem = extend({}, item); + newItem.value = newItem.value.slice(); + // Modify current using data. + item.value.unshift(index); + } else { + newItem = item; + } + newOptionData_1.push(newItem); + }); + option.data = newOptionData_1; + } + var defaultValueDimensions = this.defaultValueDimensions; + var coordDimensions = [{ + name: baseAxisDim, + type: getDimensionTypeByAxis(baseAxisType), + ordinalMeta: ordinalMeta, + otherDims: { + tooltip: false, + itemName: 0 + }, + dimsDef: ['base'] + }, { + name: otherAxisDim, + type: getDimensionTypeByAxis(otherAxisType), + dimsDef: defaultValueDimensions.slice() + }]; + return createSeriesDataSimply(this, { + coordDimensions: coordDimensions, + dimensionsCount: defaultValueDimensions.length + 1, + encodeDefaulter: curry(makeSeriesEncodeForAxisCoordSys, coordDimensions, this) + }); + }; + /** + * If horizontal, base axis is x, otherwise y. + * @override + */ + WhiskerBoxCommonMixin.prototype.getBaseAxis = function () { + var dim = this._baseAxisDim; + return this.ecModel.getComponent(dim + 'Axis', this.get(dim + 'AxisIndex')).axis; + }; + return WhiskerBoxCommonMixin; + }(); + + var BoxplotSeriesModel = /** @class */function (_super) { + __extends(BoxplotSeriesModel, _super); + function BoxplotSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = BoxplotSeriesModel.type; + // TODO + // box width represents group size, so dimension should have 'size'. + /** + * @see + * The meanings of 'min' and 'max' depend on user, + * and echarts do not need to know it. + * @readOnly + */ + _this.defaultValueDimensions = [{ + name: 'min', + defaultTooltip: true + }, { + name: 'Q1', + defaultTooltip: true + }, { + name: 'median', + defaultTooltip: true + }, { + name: 'Q3', + defaultTooltip: true + }, { + name: 'max', + defaultTooltip: true + }]; + _this.visualDrawType = 'stroke'; + return _this; + } + BoxplotSeriesModel.type = 'series.boxplot'; + BoxplotSeriesModel.dependencies = ['xAxis', 'yAxis', 'grid']; + BoxplotSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + coordinateSystem: 'cartesian2d', + legendHoverLink: true, + layout: null, + boxWidth: [7, 50], + itemStyle: { + color: '#fff', + borderWidth: 1 + }, + emphasis: { + scale: true, + itemStyle: { + borderWidth: 2, + shadowBlur: 5, + shadowOffsetX: 1, + shadowOffsetY: 1, + shadowColor: 'rgba(0,0,0,0.2)' + } + }, + animationDuration: 800 + }; + return BoxplotSeriesModel; + }(SeriesModel); + mixin(BoxplotSeriesModel, WhiskerBoxCommonMixin, true); + + var BoxplotView = /** @class */function (_super) { + __extends(BoxplotView, _super); + function BoxplotView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = BoxplotView.type; + return _this; + } + BoxplotView.prototype.render = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var group = this.group; + var oldData = this._data; + // There is no old data only when first rendering or switching from + // stream mode to normal mode, where previous elements should be removed. + if (!this._data) { + group.removeAll(); + } + var constDim = seriesModel.get('layout') === 'horizontal' ? 1 : 0; + data.diff(oldData).add(function (newIdx) { + if (data.hasValue(newIdx)) { + var itemLayout = data.getItemLayout(newIdx); + var symbolEl = createNormalBox(itemLayout, data, newIdx, constDim, true); + data.setItemGraphicEl(newIdx, symbolEl); + group.add(symbolEl); + } + }).update(function (newIdx, oldIdx) { + var symbolEl = oldData.getItemGraphicEl(oldIdx); + // Empty data + if (!data.hasValue(newIdx)) { + group.remove(symbolEl); + return; + } + var itemLayout = data.getItemLayout(newIdx); + if (!symbolEl) { + symbolEl = createNormalBox(itemLayout, data, newIdx, constDim); + } else { + saveOldStyle(symbolEl); + updateNormalBoxData(itemLayout, symbolEl, data, newIdx); + } + group.add(symbolEl); + data.setItemGraphicEl(newIdx, symbolEl); + }).remove(function (oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + el && group.remove(el); + }).execute(); + this._data = data; + }; + BoxplotView.prototype.remove = function (ecModel) { + var group = this.group; + var data = this._data; + this._data = null; + data && data.eachItemGraphicEl(function (el) { + el && group.remove(el); + }); + }; + BoxplotView.type = 'boxplot'; + return BoxplotView; + }(ChartView); + var BoxPathShape = /** @class */function () { + function BoxPathShape() {} + return BoxPathShape; + }(); + var BoxPath = /** @class */function (_super) { + __extends(BoxPath, _super); + function BoxPath(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'boxplotBoxPath'; + return _this; + } + BoxPath.prototype.getDefaultShape = function () { + return new BoxPathShape(); + }; + BoxPath.prototype.buildPath = function (ctx, shape) { + var ends = shape.points; + var i = 0; + ctx.moveTo(ends[i][0], ends[i][1]); + i++; + for (; i < 4; i++) { + ctx.lineTo(ends[i][0], ends[i][1]); + } + ctx.closePath(); + for (; i < ends.length; i++) { + ctx.moveTo(ends[i][0], ends[i][1]); + i++; + ctx.lineTo(ends[i][0], ends[i][1]); + } + }; + return BoxPath; + }(Path); + function createNormalBox(itemLayout, data, dataIndex, constDim, isInit) { + var ends = itemLayout.ends; + var el = new BoxPath({ + shape: { + points: isInit ? transInit(ends, constDim, itemLayout) : ends + } + }); + updateNormalBoxData(itemLayout, el, data, dataIndex, isInit); + return el; + } + function updateNormalBoxData(itemLayout, el, data, dataIndex, isInit) { + var seriesModel = data.hostModel; + var updateMethod = graphic[isInit ? 'initProps' : 'updateProps']; + updateMethod(el, { + shape: { + points: itemLayout.ends + } + }, seriesModel, dataIndex); + el.useStyle(data.getItemVisual(dataIndex, 'style')); + el.style.strokeNoScale = true; + el.z2 = 100; + var itemModel = data.getItemModel(dataIndex); + var emphasisModel = itemModel.getModel('emphasis'); + setStatesStylesFromModel(el, itemModel); + toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + } + function transInit(points, dim, itemLayout) { + return map(points, function (point) { + point = point.slice(); + point[dim] = itemLayout.initBaseline; + return point; + }); + } + + var each$6 = each; + function boxplotLayout(ecModel) { + var groupResult = groupSeriesByAxis(ecModel); + each$6(groupResult, function (groupItem) { + var seriesModels = groupItem.seriesModels; + if (!seriesModels.length) { + return; + } + calculateBase(groupItem); + each$6(seriesModels, function (seriesModel, idx) { + layoutSingleSeries(seriesModel, groupItem.boxOffsetList[idx], groupItem.boxWidthList[idx]); + }); + }); + } + /** + * Group series by axis. + */ + function groupSeriesByAxis(ecModel) { + var result = []; + var axisList = []; + ecModel.eachSeriesByType('boxplot', function (seriesModel) { + var baseAxis = seriesModel.getBaseAxis(); + var idx = indexOf(axisList, baseAxis); + if (idx < 0) { + idx = axisList.length; + axisList[idx] = baseAxis; + result[idx] = { + axis: baseAxis, + seriesModels: [] + }; + } + result[idx].seriesModels.push(seriesModel); + }); + return result; + } + /** + * Calculate offset and box width for each series. + */ + function calculateBase(groupItem) { + var baseAxis = groupItem.axis; + var seriesModels = groupItem.seriesModels; + var seriesCount = seriesModels.length; + var boxWidthList = groupItem.boxWidthList = []; + var boxOffsetList = groupItem.boxOffsetList = []; + var boundList = []; + var bandWidth; + if (baseAxis.type === 'category') { + bandWidth = baseAxis.getBandWidth(); + } else { + var maxDataCount_1 = 0; + each$6(seriesModels, function (seriesModel) { + maxDataCount_1 = Math.max(maxDataCount_1, seriesModel.getData().count()); + }); + var extent = baseAxis.getExtent(); + bandWidth = Math.abs(extent[1] - extent[0]) / maxDataCount_1; + } + each$6(seriesModels, function (seriesModel) { + var boxWidthBound = seriesModel.get('boxWidth'); + if (!isArray(boxWidthBound)) { + boxWidthBound = [boxWidthBound, boxWidthBound]; + } + boundList.push([parsePercent$1(boxWidthBound[0], bandWidth) || 0, parsePercent$1(boxWidthBound[1], bandWidth) || 0]); + }); + var availableWidth = bandWidth * 0.8 - 2; + var boxGap = availableWidth / seriesCount * 0.3; + var boxWidth = (availableWidth - boxGap * (seriesCount - 1)) / seriesCount; + var base = boxWidth / 2 - availableWidth / 2; + each$6(seriesModels, function (seriesModel, idx) { + boxOffsetList.push(base); + base += boxGap + boxWidth; + boxWidthList.push(Math.min(Math.max(boxWidth, boundList[idx][0]), boundList[idx][1])); + }); + } + /** + * Calculate points location for each series. + */ + function layoutSingleSeries(seriesModel, offset, boxWidth) { + var coordSys = seriesModel.coordinateSystem; + var data = seriesModel.getData(); + var halfWidth = boxWidth / 2; + var cDimIdx = seriesModel.get('layout') === 'horizontal' ? 0 : 1; + var vDimIdx = 1 - cDimIdx; + var coordDims = ['x', 'y']; + var cDim = data.mapDimension(coordDims[cDimIdx]); + var vDims = data.mapDimensionsAll(coordDims[vDimIdx]); + if (cDim == null || vDims.length < 5) { + return; + } + for (var dataIndex = 0; dataIndex < data.count(); dataIndex++) { + var axisDimVal = data.get(cDim, dataIndex); + var median = getPoint(axisDimVal, vDims[2], dataIndex); + var end1 = getPoint(axisDimVal, vDims[0], dataIndex); + var end2 = getPoint(axisDimVal, vDims[1], dataIndex); + var end4 = getPoint(axisDimVal, vDims[3], dataIndex); + var end5 = getPoint(axisDimVal, vDims[4], dataIndex); + var ends = []; + addBodyEnd(ends, end2, false); + addBodyEnd(ends, end4, true); + ends.push(end1, end2, end5, end4); + layEndLine(ends, end1); + layEndLine(ends, end5); + layEndLine(ends, median); + data.setItemLayout(dataIndex, { + initBaseline: median[vDimIdx], + ends: ends + }); + } + function getPoint(axisDimVal, dim, dataIndex) { + var val = data.get(dim, dataIndex); + var p = []; + p[cDimIdx] = axisDimVal; + p[vDimIdx] = val; + var point; + if (isNaN(axisDimVal) || isNaN(val)) { + point = [NaN, NaN]; + } else { + point = coordSys.dataToPoint(p); + point[cDimIdx] += offset; + } + return point; + } + function addBodyEnd(ends, point, start) { + var point1 = point.slice(); + var point2 = point.slice(); + point1[cDimIdx] += halfWidth; + point2[cDimIdx] -= halfWidth; + start ? ends.push(point1, point2) : ends.push(point2, point1); + } + function layEndLine(ends, endCenter) { + var from = endCenter.slice(); + var to = endCenter.slice(); + from[cDimIdx] -= halfWidth; + to[cDimIdx] += halfWidth; + ends.push(from, to); + } + } + + /** + * See: + * + * + * + * Helper method for preparing data. + * + * @param rawData like + * [ + * [12,232,443], (raw data set for the first box) + * [3843,5545,1232], (raw data set for the second box) + * ... + * ] + * @param opt.boundIQR=1.5 Data less than min bound is outlier. + * default 1.5, means Q1 - 1.5 * (Q3 - Q1). + * If 'none'/0 passed, min bound will not be used. + */ + function prepareBoxplotData(rawData, opt) { + opt = opt || {}; + var boxData = []; + var outliers = []; + var boundIQR = opt.boundIQR; + var useExtreme = boundIQR === 'none' || boundIQR === 0; + for (var i = 0; i < rawData.length; i++) { + var ascList = asc(rawData[i].slice()); + var Q1 = quantile(ascList, 0.25); + var Q2 = quantile(ascList, 0.5); + var Q3 = quantile(ascList, 0.75); + var min = ascList[0]; + var max = ascList[ascList.length - 1]; + var bound = (boundIQR == null ? 1.5 : boundIQR) * (Q3 - Q1); + var low = useExtreme ? min : Math.max(min, Q1 - bound); + var high = useExtreme ? max : Math.min(max, Q3 + bound); + var itemNameFormatter = opt.itemNameFormatter; + var itemName = isFunction(itemNameFormatter) ? itemNameFormatter({ + value: i + }) : isString(itemNameFormatter) ? itemNameFormatter.replace('{value}', i + '') : i + ''; + boxData.push([itemName, low, Q1, Q2, Q3, high]); + for (var j = 0; j < ascList.length; j++) { + var dataItem = ascList[j]; + if (dataItem < low || dataItem > high) { + var outlier = [itemName, dataItem]; + outliers.push(outlier); + } + } + } + return { + boxData: boxData, + outliers: outliers + }; + } + + var boxplotTransform = { + type: 'echarts:boxplot', + transform: function transform(params) { + var upstream = params.upstream; + if (upstream.sourceFormat !== SOURCE_FORMAT_ARRAY_ROWS) { + var errMsg = ''; + if ("development" !== 'production') { + errMsg = makePrintable('source data is not applicable for this boxplot transform. Expect number[][].'); + } + throwError(errMsg); + } + var result = prepareBoxplotData(upstream.getRawData(), params.config); + return [{ + dimensions: ['ItemName', 'Low', 'Q1', 'Q2', 'Q3', 'High'], + data: result.boxData + }, { + data: result.outliers + }]; + } + }; + + function install$j(registers) { + registers.registerSeriesModel(BoxplotSeriesModel); + registers.registerChartView(BoxplotView); + registers.registerLayout(boxplotLayout); + registers.registerTransform(boxplotTransform); + } + + var SKIP_PROPS = ['color', 'borderColor']; + var CandlestickView = /** @class */function (_super) { + __extends(CandlestickView, _super); + function CandlestickView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CandlestickView.type; + return _this; + } + CandlestickView.prototype.render = function (seriesModel, ecModel, api) { + // If there is clipPath created in large mode. Remove it. + this.group.removeClipPath(); + // Clear previously rendered progressive elements. + this._progressiveEls = null; + this._updateDrawMode(seriesModel); + this._isLargeDraw ? this._renderLarge(seriesModel) : this._renderNormal(seriesModel); + }; + CandlestickView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) { + this._clear(); + this._updateDrawMode(seriesModel); + }; + CandlestickView.prototype.incrementalRender = function (params, seriesModel, ecModel, api) { + this._progressiveEls = []; + this._isLargeDraw ? this._incrementalRenderLarge(params, seriesModel) : this._incrementalRenderNormal(params, seriesModel); + }; + CandlestickView.prototype.eachRendered = function (cb) { + traverseElements(this._progressiveEls || this.group, cb); + }; + CandlestickView.prototype._updateDrawMode = function (seriesModel) { + var isLargeDraw = seriesModel.pipelineContext.large; + if (this._isLargeDraw == null || isLargeDraw !== this._isLargeDraw) { + this._isLargeDraw = isLargeDraw; + this._clear(); + } + }; + CandlestickView.prototype._renderNormal = function (seriesModel) { + var data = seriesModel.getData(); + var oldData = this._data; + var group = this.group; + var isSimpleBox = data.getLayout('isSimpleBox'); + var needsClip = seriesModel.get('clip', true); + var coord = seriesModel.coordinateSystem; + var clipArea = coord.getArea && coord.getArea(); + // There is no old data only when first rendering or switching from + // stream mode to normal mode, where previous elements should be removed. + if (!this._data) { + group.removeAll(); + } + data.diff(oldData).add(function (newIdx) { + if (data.hasValue(newIdx)) { + var itemLayout = data.getItemLayout(newIdx); + if (needsClip && isNormalBoxClipped(clipArea, itemLayout)) { + return; + } + var el = createNormalBox$1(itemLayout, newIdx, true); + initProps(el, { + shape: { + points: itemLayout.ends + } + }, seriesModel, newIdx); + setBoxCommon(el, data, newIdx, isSimpleBox); + group.add(el); + data.setItemGraphicEl(newIdx, el); + } + }).update(function (newIdx, oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + // Empty data + if (!data.hasValue(newIdx)) { + group.remove(el); + return; + } + var itemLayout = data.getItemLayout(newIdx); + if (needsClip && isNormalBoxClipped(clipArea, itemLayout)) { + group.remove(el); + return; + } + if (!el) { + el = createNormalBox$1(itemLayout); + } else { + updateProps(el, { + shape: { + points: itemLayout.ends + } + }, seriesModel, newIdx); + saveOldStyle(el); + } + setBoxCommon(el, data, newIdx, isSimpleBox); + group.add(el); + data.setItemGraphicEl(newIdx, el); + }).remove(function (oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + el && group.remove(el); + }).execute(); + this._data = data; + }; + CandlestickView.prototype._renderLarge = function (seriesModel) { + this._clear(); + createLarge$1(seriesModel, this.group); + var clipPath = seriesModel.get('clip', true) ? createClipPath(seriesModel.coordinateSystem, false, seriesModel) : null; + if (clipPath) { + this.group.setClipPath(clipPath); + } else { + this.group.removeClipPath(); + } + }; + CandlestickView.prototype._incrementalRenderNormal = function (params, seriesModel) { + var data = seriesModel.getData(); + var isSimpleBox = data.getLayout('isSimpleBox'); + var dataIndex; + while ((dataIndex = params.next()) != null) { + var itemLayout = data.getItemLayout(dataIndex); + var el = createNormalBox$1(itemLayout); + setBoxCommon(el, data, dataIndex, isSimpleBox); + el.incremental = true; + this.group.add(el); + this._progressiveEls.push(el); + } + }; + CandlestickView.prototype._incrementalRenderLarge = function (params, seriesModel) { + createLarge$1(seriesModel, this.group, this._progressiveEls, true); + }; + CandlestickView.prototype.remove = function (ecModel) { + this._clear(); + }; + CandlestickView.prototype._clear = function () { + this.group.removeAll(); + this._data = null; + }; + CandlestickView.type = 'candlestick'; + return CandlestickView; + }(ChartView); + var NormalBoxPathShape = /** @class */function () { + function NormalBoxPathShape() {} + return NormalBoxPathShape; + }(); + var NormalBoxPath = /** @class */function (_super) { + __extends(NormalBoxPath, _super); + function NormalBoxPath(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'normalCandlestickBox'; + return _this; + } + NormalBoxPath.prototype.getDefaultShape = function () { + return new NormalBoxPathShape(); + }; + NormalBoxPath.prototype.buildPath = function (ctx, shape) { + var ends = shape.points; + if (this.__simpleBox) { + ctx.moveTo(ends[4][0], ends[4][1]); + ctx.lineTo(ends[6][0], ends[6][1]); + } else { + ctx.moveTo(ends[0][0], ends[0][1]); + ctx.lineTo(ends[1][0], ends[1][1]); + ctx.lineTo(ends[2][0], ends[2][1]); + ctx.lineTo(ends[3][0], ends[3][1]); + ctx.closePath(); + ctx.moveTo(ends[4][0], ends[4][1]); + ctx.lineTo(ends[5][0], ends[5][1]); + ctx.moveTo(ends[6][0], ends[6][1]); + ctx.lineTo(ends[7][0], ends[7][1]); + } + }; + return NormalBoxPath; + }(Path); + function createNormalBox$1(itemLayout, dataIndex, isInit) { + var ends = itemLayout.ends; + return new NormalBoxPath({ + shape: { + points: isInit ? transInit$1(ends, itemLayout) : ends + }, + z2: 100 + }); + } + function isNormalBoxClipped(clipArea, itemLayout) { + var clipped = true; + for (var i = 0; i < itemLayout.ends.length; i++) { + // If any point are in the region. + if (clipArea.contain(itemLayout.ends[i][0], itemLayout.ends[i][1])) { + clipped = false; + break; + } + } + return clipped; + } + function setBoxCommon(el, data, dataIndex, isSimpleBox) { + var itemModel = data.getItemModel(dataIndex); + el.useStyle(data.getItemVisual(dataIndex, 'style')); + el.style.strokeNoScale = true; + el.__simpleBox = isSimpleBox; + setStatesStylesFromModel(el, itemModel); + } + function transInit$1(points, itemLayout) { + return map(points, function (point) { + point = point.slice(); + point[1] = itemLayout.initBaseline; + return point; + }); + } + var LargeBoxPathShape = /** @class */function () { + function LargeBoxPathShape() {} + return LargeBoxPathShape; + }(); + var LargeBoxPath = /** @class */function (_super) { + __extends(LargeBoxPath, _super); + function LargeBoxPath(opts) { + var _this = _super.call(this, opts) || this; + _this.type = 'largeCandlestickBox'; + return _this; + } + LargeBoxPath.prototype.getDefaultShape = function () { + return new LargeBoxPathShape(); + }; + LargeBoxPath.prototype.buildPath = function (ctx, shape) { + // Drawing lines is more efficient than drawing + // a whole line or drawing rects. + var points = shape.points; + for (var i = 0; i < points.length;) { + if (this.__sign === points[i++]) { + var x = points[i++]; + ctx.moveTo(x, points[i++]); + ctx.lineTo(x, points[i++]); + } else { + i += 3; + } + } + }; + return LargeBoxPath; + }(Path); + function createLarge$1(seriesModel, group, progressiveEls, incremental) { + var data = seriesModel.getData(); + var largePoints = data.getLayout('largePoints'); + var elP = new LargeBoxPath({ + shape: { + points: largePoints + }, + __sign: 1, + ignoreCoarsePointer: true + }); + group.add(elP); + var elN = new LargeBoxPath({ + shape: { + points: largePoints + }, + __sign: -1, + ignoreCoarsePointer: true + }); + group.add(elN); + var elDoji = new LargeBoxPath({ + shape: { + points: largePoints + }, + __sign: 0, + ignoreCoarsePointer: true + }); + group.add(elDoji); + setLargeStyle(1, elP, seriesModel); + setLargeStyle(-1, elN, seriesModel); + setLargeStyle(0, elDoji, seriesModel); + if (incremental) { + elP.incremental = true; + elN.incremental = true; + } + if (progressiveEls) { + progressiveEls.push(elP, elN); + } + } + function setLargeStyle(sign, el, seriesModel, data) { + // TODO put in visual? + var borderColor = seriesModel.get(['itemStyle', sign > 0 ? 'borderColor' : 'borderColor0']) + // Use color for border color by default. + || seriesModel.get(['itemStyle', sign > 0 ? 'color' : 'color0']); + if (sign === 0) { + borderColor = seriesModel.get(['itemStyle', 'borderColorDoji']); + } + // Color must be excluded. + // Because symbol provide setColor individually to set fill and stroke + var itemStyle = seriesModel.getModel('itemStyle').getItemStyle(SKIP_PROPS); + el.useStyle(itemStyle); + el.style.fill = null; + el.style.stroke = borderColor; + } + + var CandlestickSeriesModel = /** @class */function (_super) { + __extends(CandlestickSeriesModel, _super); + function CandlestickSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CandlestickSeriesModel.type; + _this.defaultValueDimensions = [{ + name: 'open', + defaultTooltip: true + }, { + name: 'close', + defaultTooltip: true + }, { + name: 'lowest', + defaultTooltip: true + }, { + name: 'highest', + defaultTooltip: true + }]; + return _this; + } + /** + * Get dimension for shadow in dataZoom + * @return dimension name + */ + CandlestickSeriesModel.prototype.getShadowDim = function () { + return 'open'; + }; + CandlestickSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) { + var itemLayout = data.getItemLayout(dataIndex); + return itemLayout && selectors.rect(itemLayout.brushRect); + }; + CandlestickSeriesModel.type = 'series.candlestick'; + CandlestickSeriesModel.dependencies = ['xAxis', 'yAxis', 'grid']; + CandlestickSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + coordinateSystem: 'cartesian2d', + legendHoverLink: true, + // xAxisIndex: 0, + // yAxisIndex: 0, + layout: null, + clip: true, + itemStyle: { + color: '#eb5454', + color0: '#47b262', + borderColor: '#eb5454', + borderColor0: '#47b262', + borderColorDoji: null, + // borderColor: '#d24040', + // borderColor0: '#398f4f', + borderWidth: 1 + }, + emphasis: { + scale: true, + itemStyle: { + borderWidth: 2 + } + }, + barMaxWidth: null, + barMinWidth: null, + barWidth: null, + large: true, + largeThreshold: 600, + progressive: 3e3, + progressiveThreshold: 1e4, + progressiveChunkMode: 'mod', + animationEasing: 'linear', + animationDuration: 300 + }; + return CandlestickSeriesModel; + }(SeriesModel); + mixin(CandlestickSeriesModel, WhiskerBoxCommonMixin, true); + + function candlestickPreprocessor(option) { + if (!option || !isArray(option.series)) { + return; + } + // Translate 'k' to 'candlestick'. + each(option.series, function (seriesItem) { + if (isObject(seriesItem) && seriesItem.type === 'k') { + seriesItem.type = 'candlestick'; + } + }); + } + + var positiveBorderColorQuery = ['itemStyle', 'borderColor']; + var negativeBorderColorQuery = ['itemStyle', 'borderColor0']; + var dojiBorderColorQuery = ['itemStyle', 'borderColorDoji']; + var positiveColorQuery = ['itemStyle', 'color']; + var negativeColorQuery = ['itemStyle', 'color0']; + var candlestickVisual = { + seriesType: 'candlestick', + plan: createRenderPlanner(), + // For legend. + performRawSeries: true, + reset: function (seriesModel, ecModel) { + function getColor(sign, model) { + return model.get(sign > 0 ? positiveColorQuery : negativeColorQuery); + } + function getBorderColor(sign, model) { + return model.get(sign === 0 ? dojiBorderColorQuery : sign > 0 ? positiveBorderColorQuery : negativeBorderColorQuery); + } + // Only visible series has each data be visual encoded + if (ecModel.isSeriesFiltered(seriesModel)) { + return; + } + var isLargeRender = seriesModel.pipelineContext.large; + return !isLargeRender && { + progress: function (params, data) { + var dataIndex; + while ((dataIndex = params.next()) != null) { + var itemModel = data.getItemModel(dataIndex); + var sign = data.getItemLayout(dataIndex).sign; + var style = itemModel.getItemStyle(); + style.fill = getColor(sign, itemModel); + style.stroke = getBorderColor(sign, itemModel) || style.fill; + var existsStyle = data.ensureUniqueItemVisual(dataIndex, 'style'); + extend(existsStyle, style); + } + } + }; + } + }; + + var candlestickLayout = { + seriesType: 'candlestick', + plan: createRenderPlanner(), + reset: function (seriesModel) { + var coordSys = seriesModel.coordinateSystem; + var data = seriesModel.getData(); + var candleWidth = calculateCandleWidth(seriesModel, data); + var cDimIdx = 0; + var vDimIdx = 1; + var coordDims = ['x', 'y']; + var cDimI = data.getDimensionIndex(data.mapDimension(coordDims[cDimIdx])); + var vDimsI = map(data.mapDimensionsAll(coordDims[vDimIdx]), data.getDimensionIndex, data); + var openDimI = vDimsI[0]; + var closeDimI = vDimsI[1]; + var lowestDimI = vDimsI[2]; + var highestDimI = vDimsI[3]; + data.setLayout({ + candleWidth: candleWidth, + // The value is experimented visually. + isSimpleBox: candleWidth <= 1.3 + }); + if (cDimI < 0 || vDimsI.length < 4) { + return; + } + return { + progress: seriesModel.pipelineContext.large ? largeProgress : normalProgress + }; + function normalProgress(params, data) { + var dataIndex; + var store = data.getStore(); + while ((dataIndex = params.next()) != null) { + var axisDimVal = store.get(cDimI, dataIndex); + var openVal = store.get(openDimI, dataIndex); + var closeVal = store.get(closeDimI, dataIndex); + var lowestVal = store.get(lowestDimI, dataIndex); + var highestVal = store.get(highestDimI, dataIndex); + var ocLow = Math.min(openVal, closeVal); + var ocHigh = Math.max(openVal, closeVal); + var ocLowPoint = getPoint(ocLow, axisDimVal); + var ocHighPoint = getPoint(ocHigh, axisDimVal); + var lowestPoint = getPoint(lowestVal, axisDimVal); + var highestPoint = getPoint(highestVal, axisDimVal); + var ends = []; + addBodyEnd(ends, ocHighPoint, 0); + addBodyEnd(ends, ocLowPoint, 1); + ends.push(subPixelOptimizePoint(highestPoint), subPixelOptimizePoint(ocHighPoint), subPixelOptimizePoint(lowestPoint), subPixelOptimizePoint(ocLowPoint)); + var itemModel = data.getItemModel(dataIndex); + var hasDojiColor = !!itemModel.get(['itemStyle', 'borderColorDoji']); + data.setItemLayout(dataIndex, { + sign: getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor), + initBaseline: openVal > closeVal ? ocHighPoint[vDimIdx] : ocLowPoint[vDimIdx], + ends: ends, + brushRect: makeBrushRect(lowestVal, highestVal, axisDimVal) + }); + } + function getPoint(val, axisDimVal) { + var p = []; + p[cDimIdx] = axisDimVal; + p[vDimIdx] = val; + return isNaN(axisDimVal) || isNaN(val) ? [NaN, NaN] : coordSys.dataToPoint(p); + } + function addBodyEnd(ends, point, start) { + var point1 = point.slice(); + var point2 = point.slice(); + point1[cDimIdx] = subPixelOptimize$1(point1[cDimIdx] + candleWidth / 2, 1, false); + point2[cDimIdx] = subPixelOptimize$1(point2[cDimIdx] - candleWidth / 2, 1, true); + start ? ends.push(point1, point2) : ends.push(point2, point1); + } + function makeBrushRect(lowestVal, highestVal, axisDimVal) { + var pmin = getPoint(lowestVal, axisDimVal); + var pmax = getPoint(highestVal, axisDimVal); + pmin[cDimIdx] -= candleWidth / 2; + pmax[cDimIdx] -= candleWidth / 2; + return { + x: pmin[0], + y: pmin[1], + width: candleWidth , + height: pmax[1] - pmin[1] + }; + } + function subPixelOptimizePoint(point) { + point[cDimIdx] = subPixelOptimize$1(point[cDimIdx], 1); + return point; + } + } + function largeProgress(params, data) { + // Structure: [sign, x, yhigh, ylow, sign, x, yhigh, ylow, ...] + var points = createFloat32Array(params.count * 4); + var offset = 0; + var point; + var tmpIn = []; + var tmpOut = []; + var dataIndex; + var store = data.getStore(); + var hasDojiColor = !!seriesModel.get(['itemStyle', 'borderColorDoji']); + while ((dataIndex = params.next()) != null) { + var axisDimVal = store.get(cDimI, dataIndex); + var openVal = store.get(openDimI, dataIndex); + var closeVal = store.get(closeDimI, dataIndex); + var lowestVal = store.get(lowestDimI, dataIndex); + var highestVal = store.get(highestDimI, dataIndex); + if (isNaN(axisDimVal) || isNaN(lowestVal) || isNaN(highestVal)) { + points[offset++] = NaN; + offset += 3; + continue; + } + points[offset++] = getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor); + tmpIn[cDimIdx] = axisDimVal; + tmpIn[vDimIdx] = lowestVal; + point = coordSys.dataToPoint(tmpIn, null, tmpOut); + points[offset++] = point ? point[0] : NaN; + points[offset++] = point ? point[1] : NaN; + tmpIn[vDimIdx] = highestVal; + point = coordSys.dataToPoint(tmpIn, null, tmpOut); + points[offset++] = point ? point[1] : NaN; + } + data.setLayout('largePoints', points); + } + } + }; + /** + * Get the sign of a single data. + * + * @returns 0 for doji with hasDojiColor: true, + * 1 for positive, + * -1 for negative. + */ + function getSign(store, dataIndex, openVal, closeVal, closeDimI, hasDojiColor) { + var sign; + if (openVal > closeVal) { + sign = -1; + } else if (openVal < closeVal) { + sign = 1; + } else { + sign = hasDojiColor + // When doji color is set, use it instead of color/color0. + ? 0 : dataIndex > 0 + // If close === open, compare with close of last record + ? store.get(closeDimI, dataIndex - 1) <= closeVal ? 1 : -1 + // No record of previous, set to be positive + : 1; + } + return sign; + } + function calculateCandleWidth(seriesModel, data) { + var baseAxis = seriesModel.getBaseAxis(); + var extent; + var bandWidth = baseAxis.type === 'category' ? baseAxis.getBandWidth() : (extent = baseAxis.getExtent(), Math.abs(extent[1] - extent[0]) / data.count()); + var barMaxWidth = parsePercent$1(retrieve2(seriesModel.get('barMaxWidth'), bandWidth), bandWidth); + var barMinWidth = parsePercent$1(retrieve2(seriesModel.get('barMinWidth'), 1), bandWidth); + var barWidth = seriesModel.get('barWidth'); + return barWidth != null ? parsePercent$1(barWidth, bandWidth) + // Put max outer to ensure bar visible in spite of overlap. + : Math.max(Math.min(bandWidth / 2, barMaxWidth), barMinWidth); + } + + function install$k(registers) { + registers.registerChartView(CandlestickView); + registers.registerSeriesModel(CandlestickSeriesModel); + registers.registerPreprocessor(candlestickPreprocessor); + registers.registerVisual(candlestickVisual); + registers.registerLayout(candlestickLayout); + } + + function updateRipplePath(rippleGroup, effectCfg) { + var color = effectCfg.rippleEffectColor || effectCfg.color; + rippleGroup.eachChild(function (ripplePath) { + ripplePath.attr({ + z: effectCfg.z, + zlevel: effectCfg.zlevel, + style: { + stroke: effectCfg.brushType === 'stroke' ? color : null, + fill: effectCfg.brushType === 'fill' ? color : null + } + }); + }); + } + var EffectSymbol = /** @class */function (_super) { + __extends(EffectSymbol, _super); + function EffectSymbol(data, idx) { + var _this = _super.call(this) || this; + var symbol = new Symbol(data, idx); + var rippleGroup = new Group(); + _this.add(symbol); + _this.add(rippleGroup); + _this.updateData(data, idx); + return _this; + } + EffectSymbol.prototype.stopEffectAnimation = function () { + this.childAt(1).removeAll(); + }; + EffectSymbol.prototype.startEffectAnimation = function (effectCfg) { + var symbolType = effectCfg.symbolType; + var color = effectCfg.color; + var rippleNumber = effectCfg.rippleNumber; + var rippleGroup = this.childAt(1); + for (var i = 0; i < rippleNumber; i++) { + // If width/height are set too small (e.g., set to 1) on ios10 + // and macOS Sierra, a circle stroke become a rect, no matter what + // the scale is set. So we set width/height as 2. See #4136. + var ripplePath = createSymbol(symbolType, -1, -1, 2, 2, color); + ripplePath.attr({ + style: { + strokeNoScale: true + }, + z2: 99, + silent: true, + scaleX: 0.5, + scaleY: 0.5 + }); + var delay = -i / rippleNumber * effectCfg.period + effectCfg.effectOffset; + ripplePath.animate('', true).when(effectCfg.period, { + scaleX: effectCfg.rippleScale / 2, + scaleY: effectCfg.rippleScale / 2 + }).delay(delay).start(); + ripplePath.animateStyle(true).when(effectCfg.period, { + opacity: 0 + }).delay(delay).start(); + rippleGroup.add(ripplePath); + } + updateRipplePath(rippleGroup, effectCfg); + }; + /** + * Update effect symbol + */ + EffectSymbol.prototype.updateEffectAnimation = function (effectCfg) { + var oldEffectCfg = this._effectCfg; + var rippleGroup = this.childAt(1); + // Must reinitialize effect if following configuration changed + var DIFFICULT_PROPS = ['symbolType', 'period', 'rippleScale', 'rippleNumber']; + for (var i = 0; i < DIFFICULT_PROPS.length; i++) { + var propName = DIFFICULT_PROPS[i]; + if (oldEffectCfg[propName] !== effectCfg[propName]) { + this.stopEffectAnimation(); + this.startEffectAnimation(effectCfg); + return; + } + } + updateRipplePath(rippleGroup, effectCfg); + }; + /** + * Highlight symbol + */ + EffectSymbol.prototype.highlight = function () { + enterEmphasis(this); + }; + /** + * Downplay symbol + */ + EffectSymbol.prototype.downplay = function () { + leaveEmphasis(this); + }; + EffectSymbol.prototype.getSymbolType = function () { + var symbol = this.childAt(0); + return symbol && symbol.getSymbolType(); + }; + /** + * Update symbol properties + */ + EffectSymbol.prototype.updateData = function (data, idx) { + var _this = this; + var seriesModel = data.hostModel; + this.childAt(0).updateData(data, idx); + var rippleGroup = this.childAt(1); + var itemModel = data.getItemModel(idx); + var symbolType = data.getItemVisual(idx, 'symbol'); + var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize')); + var symbolStyle = data.getItemVisual(idx, 'style'); + var color = symbolStyle && symbolStyle.fill; + var emphasisModel = itemModel.getModel('emphasis'); + rippleGroup.setScale(symbolSize); + rippleGroup.traverse(function (ripplePath) { + ripplePath.setStyle('fill', color); + }); + var symbolOffset = normalizeSymbolOffset(data.getItemVisual(idx, 'symbolOffset'), symbolSize); + if (symbolOffset) { + rippleGroup.x = symbolOffset[0]; + rippleGroup.y = symbolOffset[1]; + } + var symbolRotate = data.getItemVisual(idx, 'symbolRotate'); + rippleGroup.rotation = (symbolRotate || 0) * Math.PI / 180 || 0; + var effectCfg = {}; + effectCfg.showEffectOn = seriesModel.get('showEffectOn'); + effectCfg.rippleScale = itemModel.get(['rippleEffect', 'scale']); + effectCfg.brushType = itemModel.get(['rippleEffect', 'brushType']); + effectCfg.period = itemModel.get(['rippleEffect', 'period']) * 1000; + effectCfg.effectOffset = idx / data.count(); + effectCfg.z = seriesModel.getShallow('z') || 0; + effectCfg.zlevel = seriesModel.getShallow('zlevel') || 0; + effectCfg.symbolType = symbolType; + effectCfg.color = color; + effectCfg.rippleEffectColor = itemModel.get(['rippleEffect', 'color']); + effectCfg.rippleNumber = itemModel.get(['rippleEffect', 'number']); + if (effectCfg.showEffectOn === 'render') { + this._effectCfg ? this.updateEffectAnimation(effectCfg) : this.startEffectAnimation(effectCfg); + this._effectCfg = effectCfg; + } else { + // Not keep old effect config + this._effectCfg = null; + this.stopEffectAnimation(); + this.onHoverStateChange = function (toState) { + if (toState === 'emphasis') { + if (effectCfg.showEffectOn !== 'render') { + _this.startEffectAnimation(effectCfg); + } + } else if (toState === 'normal') { + if (effectCfg.showEffectOn !== 'render') { + _this.stopEffectAnimation(); + } + } + }; + } + this._effectCfg = effectCfg; + toggleHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + }; + EffectSymbol.prototype.fadeOut = function (cb) { + cb && cb(); + }; + return EffectSymbol; + }(Group); + + var EffectScatterView = /** @class */function (_super) { + __extends(EffectScatterView, _super); + function EffectScatterView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = EffectScatterView.type; + return _this; + } + EffectScatterView.prototype.init = function () { + this._symbolDraw = new SymbolDraw(EffectSymbol); + }; + EffectScatterView.prototype.render = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var effectSymbolDraw = this._symbolDraw; + effectSymbolDraw.updateData(data, { + clipShape: this._getClipShape(seriesModel) + }); + this.group.add(effectSymbolDraw.group); + }; + EffectScatterView.prototype._getClipShape = function (seriesModel) { + var coordSys = seriesModel.coordinateSystem; + var clipArea = coordSys && coordSys.getArea && coordSys.getArea(); + return seriesModel.get('clip', true) ? clipArea : null; + }; + EffectScatterView.prototype.updateTransform = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + this.group.dirty(); + var res = pointsLayout('').reset(seriesModel, ecModel, api); + if (res.progress) { + res.progress({ + start: 0, + end: data.count(), + count: data.count() + }, data); + } + this._symbolDraw.updateLayout(); + }; + EffectScatterView.prototype._updateGroupTransform = function (seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.getRoamTransform) { + this.group.transform = clone$2(coordSys.getRoamTransform()); + this.group.decomposeTransform(); + } + }; + EffectScatterView.prototype.remove = function (ecModel, api) { + this._symbolDraw && this._symbolDraw.remove(true); + }; + EffectScatterView.type = 'effectScatter'; + return EffectScatterView; + }(ChartView); + + var EffectScatterSeriesModel = /** @class */function (_super) { + __extends(EffectScatterSeriesModel, _super); + function EffectScatterSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = EffectScatterSeriesModel.type; + _this.hasSymbolVisual = true; + return _this; + } + EffectScatterSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesData(null, this, { + useEncodeDefaulter: true + }); + }; + EffectScatterSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) { + return selectors.point(data.getItemLayout(dataIndex)); + }; + EffectScatterSeriesModel.type = 'series.effectScatter'; + EffectScatterSeriesModel.dependencies = ['grid', 'polar']; + EffectScatterSeriesModel.defaultOption = { + coordinateSystem: 'cartesian2d', + // zlevel: 0, + z: 2, + legendHoverLink: true, + effectType: 'ripple', + progressive: 0, + // When to show the effect, option: 'render'|'emphasis' + showEffectOn: 'render', + clip: true, + // Ripple effect config + rippleEffect: { + period: 4, + // Scale of ripple + scale: 2.5, + // Brush type can be fill or stroke + brushType: 'fill', + // Ripple number + number: 3 + }, + universalTransition: { + divideShape: 'clone' + }, + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + // Polar coordinate system + // polarIndex: 0, + // Geo coordinate system + // geoIndex: 0, + // symbol: null, // 图形类型 + symbolSize: 10 // 图形大小,半宽(半径)参数,当图形为方向或菱形则总宽度为symbolSize * 2 + // symbolRotate: null, // 图形旋转控制 + // itemStyle: { + // opacity: 1 + // } + }; + + return EffectScatterSeriesModel; + }(SeriesModel); + + function install$l(registers) { + registers.registerChartView(EffectScatterView); + registers.registerSeriesModel(EffectScatterSeriesModel); + registers.registerLayout(pointsLayout('effectScatter')); + } + + var EffectLine = /** @class */function (_super) { + __extends(EffectLine, _super); + function EffectLine(lineData, idx, seriesScope) { + var _this = _super.call(this) || this; + _this.add(_this.createLine(lineData, idx, seriesScope)); + _this._updateEffectSymbol(lineData, idx); + return _this; + } + EffectLine.prototype.createLine = function (lineData, idx, seriesScope) { + return new Line$1(lineData, idx, seriesScope); + }; + EffectLine.prototype._updateEffectSymbol = function (lineData, idx) { + var itemModel = lineData.getItemModel(idx); + var effectModel = itemModel.getModel('effect'); + var size = effectModel.get('symbolSize'); + var symbolType = effectModel.get('symbol'); + if (!isArray(size)) { + size = [size, size]; + } + var lineStyle = lineData.getItemVisual(idx, 'style'); + var color = effectModel.get('color') || lineStyle && lineStyle.stroke; + var symbol = this.childAt(1); + if (this._symbolType !== symbolType) { + // Remove previous + this.remove(symbol); + symbol = createSymbol(symbolType, -0.5, -0.5, 1, 1, color); + symbol.z2 = 100; + symbol.culling = true; + this.add(symbol); + } + // Symbol may be removed if loop is false + if (!symbol) { + return; + } + // Shadow color is same with color in default + symbol.setStyle('shadowColor', color); + symbol.setStyle(effectModel.getItemStyle(['color'])); + symbol.scaleX = size[0]; + symbol.scaleY = size[1]; + symbol.setColor(color); + this._symbolType = symbolType; + this._symbolScale = size; + this._updateEffectAnimation(lineData, effectModel, idx); + }; + EffectLine.prototype._updateEffectAnimation = function (lineData, effectModel, idx) { + var symbol = this.childAt(1); + if (!symbol) { + return; + } + var points = lineData.getItemLayout(idx); + var period = effectModel.get('period') * 1000; + var loop = effectModel.get('loop'); + var roundTrip = effectModel.get('roundTrip'); + var constantSpeed = effectModel.get('constantSpeed'); + var delayExpr = retrieve(effectModel.get('delay'), function (idx) { + return idx / lineData.count() * period / 3; + }); + // Ignore when updating + symbol.ignore = true; + this._updateAnimationPoints(symbol, points); + if (constantSpeed > 0) { + period = this._getLineLength(symbol) / constantSpeed * 1000; + } + if (period !== this._period || loop !== this._loop || roundTrip !== this._roundTrip) { + symbol.stopAnimation(); + var delayNum = void 0; + if (isFunction(delayExpr)) { + delayNum = delayExpr(idx); + } else { + delayNum = delayExpr; + } + if (symbol.__t > 0) { + delayNum = -period * symbol.__t; + } + this._animateSymbol(symbol, period, delayNum, loop, roundTrip); + } + this._period = period; + this._loop = loop; + this._roundTrip = roundTrip; + }; + EffectLine.prototype._animateSymbol = function (symbol, period, delayNum, loop, roundTrip) { + if (period > 0) { + symbol.__t = 0; + var self_1 = this; + var animator = symbol.animate('', loop).when(roundTrip ? period * 2 : period, { + __t: roundTrip ? 2 : 1 + }).delay(delayNum).during(function () { + self_1._updateSymbolPosition(symbol); + }); + if (!loop) { + animator.done(function () { + self_1.remove(symbol); + }); + } + animator.start(); + } + }; + EffectLine.prototype._getLineLength = function (symbol) { + // Not so accurate + return dist(symbol.__p1, symbol.__cp1) + dist(symbol.__cp1, symbol.__p2); + }; + EffectLine.prototype._updateAnimationPoints = function (symbol, points) { + symbol.__p1 = points[0]; + symbol.__p2 = points[1]; + symbol.__cp1 = points[2] || [(points[0][0] + points[1][0]) / 2, (points[0][1] + points[1][1]) / 2]; + }; + EffectLine.prototype.updateData = function (lineData, idx, seriesScope) { + this.childAt(0).updateData(lineData, idx, seriesScope); + this._updateEffectSymbol(lineData, idx); + }; + EffectLine.prototype._updateSymbolPosition = function (symbol) { + var p1 = symbol.__p1; + var p2 = symbol.__p2; + var cp1 = symbol.__cp1; + var t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t; + var pos = [symbol.x, symbol.y]; + var lastPos = pos.slice(); + var quadraticAt$1 = quadraticAt; + var quadraticDerivativeAt$1 = quadraticDerivativeAt; + pos[0] = quadraticAt$1(p1[0], cp1[0], p2[0], t); + pos[1] = quadraticAt$1(p1[1], cp1[1], p2[1], t); + // Tangent + var tx = symbol.__t < 1 ? quadraticDerivativeAt$1(p1[0], cp1[0], p2[0], t) : quadraticDerivativeAt$1(p2[0], cp1[0], p1[0], 1 - t); + var ty = symbol.__t < 1 ? quadraticDerivativeAt$1(p1[1], cp1[1], p2[1], t) : quadraticDerivativeAt$1(p2[1], cp1[1], p1[1], 1 - t); + symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2; + // enable continuity trail for 'line', 'rect', 'roundRect' symbolType + if (this._symbolType === 'line' || this._symbolType === 'rect' || this._symbolType === 'roundRect') { + if (symbol.__lastT !== undefined && symbol.__lastT < symbol.__t) { + symbol.scaleY = dist(lastPos, pos) * 1.05; + // make sure the last segment render within endPoint + if (t === 1) { + pos[0] = lastPos[0] + (pos[0] - lastPos[0]) / 2; + pos[1] = lastPos[1] + (pos[1] - lastPos[1]) / 2; + } + } else if (symbol.__lastT === 1) { + // After first loop, symbol.__t does NOT start with 0, so connect p1 to pos directly. + symbol.scaleY = 2 * dist(p1, pos); + } else { + symbol.scaleY = this._symbolScale[1]; + } + } + symbol.__lastT = symbol.__t; + symbol.ignore = false; + symbol.x = pos[0]; + symbol.y = pos[1]; + }; + EffectLine.prototype.updateLayout = function (lineData, idx) { + this.childAt(0).updateLayout(lineData, idx); + var effectModel = lineData.getItemModel(idx).getModel('effect'); + this._updateEffectAnimation(lineData, effectModel, idx); + }; + return EffectLine; + }(Group); + + var Polyline$1 = /** @class */function (_super) { + __extends(Polyline$1, _super); + function Polyline$1(lineData, idx, seriesScope) { + var _this = _super.call(this) || this; + _this._createPolyline(lineData, idx, seriesScope); + return _this; + } + Polyline$1.prototype._createPolyline = function (lineData, idx, seriesScope) { + // let seriesModel = lineData.hostModel; + var points = lineData.getItemLayout(idx); + var line = new Polyline({ + shape: { + points: points + } + }); + this.add(line); + this._updateCommonStl(lineData, idx, seriesScope); + }; + Polyline$1.prototype.updateData = function (lineData, idx, seriesScope) { + var seriesModel = lineData.hostModel; + var line = this.childAt(0); + var target = { + shape: { + points: lineData.getItemLayout(idx) + } + }; + updateProps(line, target, seriesModel, idx); + this._updateCommonStl(lineData, idx, seriesScope); + }; + Polyline$1.prototype._updateCommonStl = function (lineData, idx, seriesScope) { + var line = this.childAt(0); + var itemModel = lineData.getItemModel(idx); + var emphasisLineStyle = seriesScope && seriesScope.emphasisLineStyle; + var focus = seriesScope && seriesScope.focus; + var blurScope = seriesScope && seriesScope.blurScope; + var emphasisDisabled = seriesScope && seriesScope.emphasisDisabled; + if (!seriesScope || lineData.hasItemOption) { + var emphasisModel = itemModel.getModel('emphasis'); + emphasisLineStyle = emphasisModel.getModel('lineStyle').getLineStyle(); + emphasisDisabled = emphasisModel.get('disabled'); + focus = emphasisModel.get('focus'); + blurScope = emphasisModel.get('blurScope'); + } + line.useStyle(lineData.getItemVisual(idx, 'style')); + line.style.fill = null; + line.style.strokeNoScale = true; + var lineEmphasisState = line.ensureState('emphasis'); + lineEmphasisState.style = emphasisLineStyle; + toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled); + }; + Polyline$1.prototype.updateLayout = function (lineData, idx) { + var polyline = this.childAt(0); + polyline.setShape('points', lineData.getItemLayout(idx)); + }; + return Polyline$1; + }(Group); + + var EffectPolyline = /** @class */function (_super) { + __extends(EffectPolyline, _super); + function EffectPolyline() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._lastFrame = 0; + _this._lastFramePercent = 0; + return _this; + } + // Override + EffectPolyline.prototype.createLine = function (lineData, idx, seriesScope) { + return new Polyline$1(lineData, idx, seriesScope); + }; + // Override + EffectPolyline.prototype._updateAnimationPoints = function (symbol, points) { + this._points = points; + var accLenArr = [0]; + var len = 0; + for (var i = 1; i < points.length; i++) { + var p1 = points[i - 1]; + var p2 = points[i]; + len += dist(p1, p2); + accLenArr.push(len); + } + if (len === 0) { + this._length = 0; + return; + } + for (var i = 0; i < accLenArr.length; i++) { + accLenArr[i] /= len; + } + this._offsets = accLenArr; + this._length = len; + }; + // Override + EffectPolyline.prototype._getLineLength = function () { + return this._length; + }; + // Override + EffectPolyline.prototype._updateSymbolPosition = function (symbol) { + var t = symbol.__t < 1 ? symbol.__t : 2 - symbol.__t; + var points = this._points; + var offsets = this._offsets; + var len = points.length; + if (!offsets) { + // Has length 0 + return; + } + var lastFrame = this._lastFrame; + var frame; + if (t < this._lastFramePercent) { + // Start from the next frame + // PENDING start from lastFrame ? + var start = Math.min(lastFrame + 1, len - 1); + for (frame = start; frame >= 0; frame--) { + if (offsets[frame] <= t) { + break; + } + } + // PENDING really need to do this ? + frame = Math.min(frame, len - 2); + } else { + for (frame = lastFrame; frame < len; frame++) { + if (offsets[frame] > t) { + break; + } + } + frame = Math.min(frame - 1, len - 2); + } + var p = (t - offsets[frame]) / (offsets[frame + 1] - offsets[frame]); + var p0 = points[frame]; + var p1 = points[frame + 1]; + symbol.x = p0[0] * (1 - p) + p * p1[0]; + symbol.y = p0[1] * (1 - p) + p * p1[1]; + var tx = symbol.__t < 1 ? p1[0] - p0[0] : p0[0] - p1[0]; + var ty = symbol.__t < 1 ? p1[1] - p0[1] : p0[1] - p1[1]; + symbol.rotation = -Math.atan2(ty, tx) - Math.PI / 2; + this._lastFrame = frame; + this._lastFramePercent = t; + symbol.ignore = false; + }; + return EffectPolyline; + }(EffectLine); + + var LargeLinesPathShape = /** @class */function () { + function LargeLinesPathShape() { + this.polyline = false; + this.curveness = 0; + this.segs = []; + } + return LargeLinesPathShape; + }(); + var LargeLinesPath = /** @class */function (_super) { + __extends(LargeLinesPath, _super); + function LargeLinesPath(opts) { + var _this = _super.call(this, opts) || this; + _this._off = 0; + _this.hoverDataIdx = -1; + return _this; + } + LargeLinesPath.prototype.reset = function () { + this.notClear = false; + this._off = 0; + }; + LargeLinesPath.prototype.getDefaultStyle = function () { + return { + stroke: '#000', + fill: null + }; + }; + LargeLinesPath.prototype.getDefaultShape = function () { + return new LargeLinesPathShape(); + }; + LargeLinesPath.prototype.buildPath = function (ctx, shape) { + var segs = shape.segs; + var curveness = shape.curveness; + var i; + if (shape.polyline) { + for (i = this._off; i < segs.length;) { + var count = segs[i++]; + if (count > 0) { + ctx.moveTo(segs[i++], segs[i++]); + for (var k = 1; k < count; k++) { + ctx.lineTo(segs[i++], segs[i++]); + } + } + } + } else { + for (i = this._off; i < segs.length;) { + var x0 = segs[i++]; + var y0 = segs[i++]; + var x1 = segs[i++]; + var y1 = segs[i++]; + ctx.moveTo(x0, y0); + if (curveness > 0) { + var x2 = (x0 + x1) / 2 - (y0 - y1) * curveness; + var y2 = (y0 + y1) / 2 - (x1 - x0) * curveness; + ctx.quadraticCurveTo(x2, y2, x1, y1); + } else { + ctx.lineTo(x1, y1); + } + } + } + if (this.incremental) { + this._off = i; + this.notClear = true; + } + }; + LargeLinesPath.prototype.findDataIndex = function (x, y) { + var shape = this.shape; + var segs = shape.segs; + var curveness = shape.curveness; + var lineWidth = this.style.lineWidth; + if (shape.polyline) { + var dataIndex = 0; + for (var i = 0; i < segs.length;) { + var count = segs[i++]; + if (count > 0) { + var x0 = segs[i++]; + var y0 = segs[i++]; + for (var k = 1; k < count; k++) { + var x1 = segs[i++]; + var y1 = segs[i++]; + if (containStroke(x0, y0, x1, y1, lineWidth, x, y)) { + return dataIndex; + } + } + } + dataIndex++; + } + } else { + var dataIndex = 0; + for (var i = 0; i < segs.length;) { + var x0 = segs[i++]; + var y0 = segs[i++]; + var x1 = segs[i++]; + var y1 = segs[i++]; + if (curveness > 0) { + var x2 = (x0 + x1) / 2 - (y0 - y1) * curveness; + var y2 = (y0 + y1) / 2 - (x1 - x0) * curveness; + if (containStroke$2(x0, y0, x2, y2, x1, y1, lineWidth, x, y)) { + return dataIndex; + } + } else { + if (containStroke(x0, y0, x1, y1, lineWidth, x, y)) { + return dataIndex; + } + } + dataIndex++; + } + } + return -1; + }; + LargeLinesPath.prototype.contain = function (x, y) { + var localPos = this.transformCoordToLocal(x, y); + var rect = this.getBoundingRect(); + x = localPos[0]; + y = localPos[1]; + if (rect.contain(x, y)) { + // Cache found data index. + var dataIdx = this.hoverDataIdx = this.findDataIndex(x, y); + return dataIdx >= 0; + } + this.hoverDataIdx = -1; + return false; + }; + LargeLinesPath.prototype.getBoundingRect = function () { + // Ignore stroke for large symbol draw. + var rect = this._rect; + if (!rect) { + var shape = this.shape; + var points = shape.segs; + var minX = Infinity; + var minY = Infinity; + var maxX = -Infinity; + var maxY = -Infinity; + for (var i = 0; i < points.length;) { + var x = points[i++]; + var y = points[i++]; + minX = Math.min(x, minX); + maxX = Math.max(x, maxX); + minY = Math.min(y, minY); + maxY = Math.max(y, maxY); + } + rect = this._rect = new BoundingRect(minX, minY, maxX, maxY); + } + return rect; + }; + return LargeLinesPath; + }(Path); + var LargeLineDraw = /** @class */function () { + function LargeLineDraw() { + this.group = new Group(); + } + /** + * Update symbols draw by new data + */ + LargeLineDraw.prototype.updateData = function (data) { + this._clear(); + var lineEl = this._create(); + lineEl.setShape({ + segs: data.getLayout('linesPoints') + }); + this._setCommon(lineEl, data); + }; + /** + * @override + */ + LargeLineDraw.prototype.incrementalPrepareUpdate = function (data) { + this.group.removeAll(); + this._clear(); + }; + /** + * @override + */ + LargeLineDraw.prototype.incrementalUpdate = function (taskParams, data) { + var lastAdded = this._newAdded[0]; + var linePoints = data.getLayout('linesPoints'); + var oldSegs = lastAdded && lastAdded.shape.segs; + // Merging the exists. Each element has 1e4 points. + // Consider the performance balance between too much elements and too much points in one shape(may affect hover optimization) + if (oldSegs && oldSegs.length < 2e4) { + var oldLen = oldSegs.length; + var newSegs = new Float32Array(oldLen + linePoints.length); + // Concat two array + newSegs.set(oldSegs); + newSegs.set(linePoints, oldLen); + lastAdded.setShape({ + segs: newSegs + }); + } else { + // Clear + this._newAdded = []; + var lineEl = this._create(); + lineEl.incremental = true; + lineEl.setShape({ + segs: linePoints + }); + this._setCommon(lineEl, data); + lineEl.__startIndex = taskParams.start; + } + }; + /** + * @override + */ + LargeLineDraw.prototype.remove = function () { + this._clear(); + }; + LargeLineDraw.prototype.eachRendered = function (cb) { + this._newAdded[0] && cb(this._newAdded[0]); + }; + LargeLineDraw.prototype._create = function () { + var lineEl = new LargeLinesPath({ + cursor: 'default', + ignoreCoarsePointer: true + }); + this._newAdded.push(lineEl); + this.group.add(lineEl); + return lineEl; + }; + LargeLineDraw.prototype._setCommon = function (lineEl, data, isIncremental) { + var hostModel = data.hostModel; + lineEl.setShape({ + polyline: hostModel.get('polyline'), + curveness: hostModel.get(['lineStyle', 'curveness']) + }); + lineEl.useStyle(hostModel.getModel('lineStyle').getLineStyle()); + lineEl.style.strokeNoScale = true; + var style = data.getVisual('style'); + if (style && style.stroke) { + lineEl.setStyle('stroke', style.stroke); + } + lineEl.setStyle('fill', null); + var ecData = getECData(lineEl); + // Enable tooltip + // PENDING May have performance issue when path is extremely large + ecData.seriesIndex = hostModel.seriesIndex; + lineEl.on('mousemove', function (e) { + ecData.dataIndex = null; + var dataIndex = lineEl.hoverDataIdx; + if (dataIndex > 0) { + // Provide dataIndex for tooltip + ecData.dataIndex = dataIndex + lineEl.__startIndex; + } + }); + }; + LargeLineDraw.prototype._clear = function () { + this._newAdded = []; + this.group.removeAll(); + }; + return LargeLineDraw; + }(); + + var linesLayout = { + seriesType: 'lines', + plan: createRenderPlanner(), + reset: function (seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (!coordSys) { + if ("development" !== 'production') { + error('The lines series must have a coordinate system.'); + } + return; + } + var isPolyline = seriesModel.get('polyline'); + var isLarge = seriesModel.pipelineContext.large; + return { + progress: function (params, lineData) { + var lineCoords = []; + if (isLarge) { + var points = void 0; + var segCount = params.end - params.start; + if (isPolyline) { + var totalCoordsCount = 0; + for (var i = params.start; i < params.end; i++) { + totalCoordsCount += seriesModel.getLineCoordsCount(i); + } + points = new Float32Array(segCount + totalCoordsCount * 2); + } else { + points = new Float32Array(segCount * 4); + } + var offset = 0; + var pt = []; + for (var i = params.start; i < params.end; i++) { + var len = seriesModel.getLineCoords(i, lineCoords); + if (isPolyline) { + points[offset++] = len; + } + for (var k = 0; k < len; k++) { + pt = coordSys.dataToPoint(lineCoords[k], false, pt); + points[offset++] = pt[0]; + points[offset++] = pt[1]; + } + } + lineData.setLayout('linesPoints', points); + } else { + for (var i = params.start; i < params.end; i++) { + var itemModel = lineData.getItemModel(i); + var len = seriesModel.getLineCoords(i, lineCoords); + var pts = []; + if (isPolyline) { + for (var j = 0; j < len; j++) { + pts.push(coordSys.dataToPoint(lineCoords[j])); + } + } else { + pts[0] = coordSys.dataToPoint(lineCoords[0]); + pts[1] = coordSys.dataToPoint(lineCoords[1]); + var curveness = itemModel.get(['lineStyle', 'curveness']); + if (+curveness) { + pts[2] = [(pts[0][0] + pts[1][0]) / 2 - (pts[0][1] - pts[1][1]) * curveness, (pts[0][1] + pts[1][1]) / 2 - (pts[1][0] - pts[0][0]) * curveness]; + } + } + lineData.setItemLayout(i, pts); + } + } + } + }; + } + }; + + var LinesView = /** @class */function (_super) { + __extends(LinesView, _super); + function LinesView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = LinesView.type; + return _this; + } + LinesView.prototype.render = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var lineDraw = this._updateLineDraw(data, seriesModel); + var zlevel = seriesModel.get('zlevel'); + var trailLength = seriesModel.get(['effect', 'trailLength']); + var zr = api.getZr(); + // Avoid the drag cause ghost shadow + // FIXME Better way ? + // SVG doesn't support + var isSvg = zr.painter.getType() === 'svg'; + if (!isSvg) { + zr.painter.getLayer(zlevel).clear(true); + } + // Config layer with motion blur + if (this._lastZlevel != null && !isSvg) { + zr.configLayer(this._lastZlevel, { + motionBlur: false + }); + } + if (this._showEffect(seriesModel) && trailLength > 0) { + if (!isSvg) { + zr.configLayer(zlevel, { + motionBlur: true, + lastFrameAlpha: Math.max(Math.min(trailLength / 10 + 0.9, 1), 0) + }); + } else if ("development" !== 'production') { + console.warn('SVG render mode doesn\'t support lines with trail effect'); + } + } + lineDraw.updateData(data); + var clipPath = seriesModel.get('clip', true) && createClipPath(seriesModel.coordinateSystem, false, seriesModel); + if (clipPath) { + this.group.setClipPath(clipPath); + } else { + this.group.removeClipPath(); + } + this._lastZlevel = zlevel; + this._finished = true; + }; + LinesView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var lineDraw = this._updateLineDraw(data, seriesModel); + lineDraw.incrementalPrepareUpdate(data); + this._clearLayer(api); + this._finished = false; + }; + LinesView.prototype.incrementalRender = function (taskParams, seriesModel, ecModel) { + this._lineDraw.incrementalUpdate(taskParams, seriesModel.getData()); + this._finished = taskParams.end === seriesModel.getData().count(); + }; + LinesView.prototype.eachRendered = function (cb) { + this._lineDraw && this._lineDraw.eachRendered(cb); + }; + LinesView.prototype.updateTransform = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var pipelineContext = seriesModel.pipelineContext; + if (!this._finished || pipelineContext.large || pipelineContext.progressiveRender) { + // TODO Don't have to do update in large mode. Only do it when there are millions of data. + return { + update: true + }; + } else { + // TODO Use same logic with ScatterView. + // Manually update layout + var res = linesLayout.reset(seriesModel, ecModel, api); + if (res.progress) { + res.progress({ + start: 0, + end: data.count(), + count: data.count() + }, data); + } + // Not in large mode + this._lineDraw.updateLayout(); + this._clearLayer(api); + } + }; + LinesView.prototype._updateLineDraw = function (data, seriesModel) { + var lineDraw = this._lineDraw; + var hasEffect = this._showEffect(seriesModel); + var isPolyline = !!seriesModel.get('polyline'); + var pipelineContext = seriesModel.pipelineContext; + var isLargeDraw = pipelineContext.large; + if ("development" !== 'production') { + if (hasEffect && isLargeDraw) { + console.warn('Large lines not support effect'); + } + } + if (!lineDraw || hasEffect !== this._hasEffet || isPolyline !== this._isPolyline || isLargeDraw !== this._isLargeDraw) { + if (lineDraw) { + lineDraw.remove(); + } + lineDraw = this._lineDraw = isLargeDraw ? new LargeLineDraw() : new LineDraw(isPolyline ? hasEffect ? EffectPolyline : Polyline$1 : hasEffect ? EffectLine : Line$1); + this._hasEffet = hasEffect; + this._isPolyline = isPolyline; + this._isLargeDraw = isLargeDraw; + } + this.group.add(lineDraw.group); + return lineDraw; + }; + LinesView.prototype._showEffect = function (seriesModel) { + return !!seriesModel.get(['effect', 'show']); + }; + LinesView.prototype._clearLayer = function (api) { + // Not use motion when dragging or zooming + var zr = api.getZr(); + var isSvg = zr.painter.getType() === 'svg'; + if (!isSvg && this._lastZlevel != null) { + zr.painter.getLayer(this._lastZlevel).clear(true); + } + }; + LinesView.prototype.remove = function (ecModel, api) { + this._lineDraw && this._lineDraw.remove(); + this._lineDraw = null; + // Clear motion when lineDraw is removed + this._clearLayer(api); + }; + LinesView.prototype.dispose = function (ecModel, api) { + this.remove(ecModel, api); + }; + LinesView.type = 'lines'; + return LinesView; + }(ChartView); + + var Uint32Arr = typeof Uint32Array === 'undefined' ? Array : Uint32Array; + var Float64Arr = typeof Float64Array === 'undefined' ? Array : Float64Array; + function compatEc2(seriesOpt) { + var data = seriesOpt.data; + if (data && data[0] && data[0][0] && data[0][0].coord) { + if ("development" !== 'production') { + console.warn('Lines data configuration has been changed to' + ' { coords:[[1,2],[2,3]] }'); + } + seriesOpt.data = map(data, function (itemOpt) { + var coords = [itemOpt[0].coord, itemOpt[1].coord]; + var target = { + coords: coords + }; + if (itemOpt[0].name) { + target.fromName = itemOpt[0].name; + } + if (itemOpt[1].name) { + target.toName = itemOpt[1].name; + } + return mergeAll([target, itemOpt[0], itemOpt[1]]); + }); + } + } + var LinesSeriesModel = /** @class */function (_super) { + __extends(LinesSeriesModel, _super); + function LinesSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = LinesSeriesModel.type; + _this.visualStyleAccessPath = 'lineStyle'; + _this.visualDrawType = 'stroke'; + return _this; + } + LinesSeriesModel.prototype.init = function (option) { + // The input data may be null/undefined. + option.data = option.data || []; + // Not using preprocessor because mergeOption may not have series.type + compatEc2(option); + var result = this._processFlatCoordsArray(option.data); + this._flatCoords = result.flatCoords; + this._flatCoordsOffset = result.flatCoordsOffset; + if (result.flatCoords) { + option.data = new Float32Array(result.count); + } + _super.prototype.init.apply(this, arguments); + }; + LinesSeriesModel.prototype.mergeOption = function (option) { + compatEc2(option); + if (option.data) { + // Only update when have option data to merge. + var result = this._processFlatCoordsArray(option.data); + this._flatCoords = result.flatCoords; + this._flatCoordsOffset = result.flatCoordsOffset; + if (result.flatCoords) { + option.data = new Float32Array(result.count); + } + } + _super.prototype.mergeOption.apply(this, arguments); + }; + LinesSeriesModel.prototype.appendData = function (params) { + var result = this._processFlatCoordsArray(params.data); + if (result.flatCoords) { + if (!this._flatCoords) { + this._flatCoords = result.flatCoords; + this._flatCoordsOffset = result.flatCoordsOffset; + } else { + this._flatCoords = concatArray(this._flatCoords, result.flatCoords); + this._flatCoordsOffset = concatArray(this._flatCoordsOffset, result.flatCoordsOffset); + } + params.data = new Float32Array(result.count); + } + this.getRawData().appendData(params.data); + }; + LinesSeriesModel.prototype._getCoordsFromItemModel = function (idx) { + var itemModel = this.getData().getItemModel(idx); + var coords = itemModel.option instanceof Array ? itemModel.option : itemModel.getShallow('coords'); + if ("development" !== 'production') { + if (!(coords instanceof Array && coords.length > 0 && coords[0] instanceof Array)) { + throw new Error('Invalid coords ' + JSON.stringify(coords) + '. Lines must have 2d coords array in data item.'); + } + } + return coords; + }; + LinesSeriesModel.prototype.getLineCoordsCount = function (idx) { + if (this._flatCoordsOffset) { + return this._flatCoordsOffset[idx * 2 + 1]; + } else { + return this._getCoordsFromItemModel(idx).length; + } + }; + LinesSeriesModel.prototype.getLineCoords = function (idx, out) { + if (this._flatCoordsOffset) { + var offset = this._flatCoordsOffset[idx * 2]; + var len = this._flatCoordsOffset[idx * 2 + 1]; + for (var i = 0; i < len; i++) { + out[i] = out[i] || []; + out[i][0] = this._flatCoords[offset + i * 2]; + out[i][1] = this._flatCoords[offset + i * 2 + 1]; + } + return len; + } else { + var coords = this._getCoordsFromItemModel(idx); + for (var i = 0; i < coords.length; i++) { + out[i] = out[i] || []; + out[i][0] = coords[i][0]; + out[i][1] = coords[i][1]; + } + return coords.length; + } + }; + LinesSeriesModel.prototype._processFlatCoordsArray = function (data) { + var startOffset = 0; + if (this._flatCoords) { + startOffset = this._flatCoords.length; + } + // Stored as a typed array. In format + // Points Count(2) | x | y | x | y | Points Count(3) | x | y | x | y | x | y | + if (isNumber(data[0])) { + var len = data.length; + // Store offset and len of each segment + var coordsOffsetAndLenStorage = new Uint32Arr(len); + var coordsStorage = new Float64Arr(len); + var coordsCursor = 0; + var offsetCursor = 0; + var dataCount = 0; + for (var i = 0; i < len;) { + dataCount++; + var count = data[i++]; + // Offset + coordsOffsetAndLenStorage[offsetCursor++] = coordsCursor + startOffset; + // Len + coordsOffsetAndLenStorage[offsetCursor++] = count; + for (var k = 0; k < count; k++) { + var x = data[i++]; + var y = data[i++]; + coordsStorage[coordsCursor++] = x; + coordsStorage[coordsCursor++] = y; + if (i > len) { + if ("development" !== 'production') { + throw new Error('Invalid data format.'); + } + } + } + } + return { + flatCoordsOffset: new Uint32Array(coordsOffsetAndLenStorage.buffer, 0, offsetCursor), + flatCoords: coordsStorage, + count: dataCount + }; + } + return { + flatCoordsOffset: null, + flatCoords: null, + count: data.length + }; + }; + LinesSeriesModel.prototype.getInitialData = function (option, ecModel) { + if ("development" !== 'production') { + var CoordSys = CoordinateSystemManager.get(option.coordinateSystem); + if (!CoordSys) { + throw new Error('Unknown coordinate system ' + option.coordinateSystem); + } + } + var lineData = new SeriesData(['value'], this); + lineData.hasItemOption = false; + lineData.initData(option.data, [], function (dataItem, dimName, dataIndex, dimIndex) { + // dataItem is simply coords + if (dataItem instanceof Array) { + return NaN; + } else { + lineData.hasItemOption = true; + var value = dataItem.value; + if (value != null) { + return value instanceof Array ? value[dimIndex] : value; + } + } + }); + return lineData; + }; + LinesSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + var data = this.getData(); + var itemModel = data.getItemModel(dataIndex); + var name = itemModel.get('name'); + if (name) { + return name; + } + var fromName = itemModel.get('fromName'); + var toName = itemModel.get('toName'); + var nameArr = []; + fromName != null && nameArr.push(fromName); + toName != null && nameArr.push(toName); + return createTooltipMarkup('nameValue', { + name: nameArr.join(' > ') + }); + }; + LinesSeriesModel.prototype.preventIncremental = function () { + return !!this.get(['effect', 'show']); + }; + LinesSeriesModel.prototype.getProgressive = function () { + var progressive = this.option.progressive; + if (progressive == null) { + return this.option.large ? 1e4 : this.get('progressive'); + } + return progressive; + }; + LinesSeriesModel.prototype.getProgressiveThreshold = function () { + var progressiveThreshold = this.option.progressiveThreshold; + if (progressiveThreshold == null) { + return this.option.large ? 2e4 : this.get('progressiveThreshold'); + } + return progressiveThreshold; + }; + LinesSeriesModel.prototype.getZLevelKey = function () { + var effectModel = this.getModel('effect'); + var trailLength = effectModel.get('trailLength'); + return this.getData().count() > this.getProgressiveThreshold() + // Each progressive series has individual key. + ? this.id : effectModel.get('show') && trailLength > 0 ? trailLength + '' : ''; + }; + LinesSeriesModel.type = 'series.lines'; + LinesSeriesModel.dependencies = ['grid', 'polar', 'geo', 'calendar']; + LinesSeriesModel.defaultOption = { + coordinateSystem: 'geo', + // zlevel: 0, + z: 2, + legendHoverLink: true, + // Cartesian coordinate system + xAxisIndex: 0, + yAxisIndex: 0, + symbol: ['none', 'none'], + symbolSize: [10, 10], + // Geo coordinate system + geoIndex: 0, + effect: { + show: false, + period: 4, + constantSpeed: 0, + symbol: 'circle', + symbolSize: 3, + loop: true, + trailLength: 0.2 + }, + large: false, + // Available when large is true + largeThreshold: 2000, + polyline: false, + clip: true, + label: { + show: false, + position: 'end' + // distance: 5, + // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 + }, + + lineStyle: { + opacity: 0.5 + } + }; + return LinesSeriesModel; + }(SeriesModel); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function normalize$3(a) { + if (!(a instanceof Array)) { + a = [a, a]; + } + return a; + } + var linesVisual = { + seriesType: 'lines', + reset: function (seriesModel) { + var symbolType = normalize$3(seriesModel.get('symbol')); + var symbolSize = normalize$3(seriesModel.get('symbolSize')); + var data = seriesModel.getData(); + data.setVisual('fromSymbol', symbolType && symbolType[0]); + data.setVisual('toSymbol', symbolType && symbolType[1]); + data.setVisual('fromSymbolSize', symbolSize && symbolSize[0]); + data.setVisual('toSymbolSize', symbolSize && symbolSize[1]); + function dataEach(data, idx) { + var itemModel = data.getItemModel(idx); + var symbolType = normalize$3(itemModel.getShallow('symbol', true)); + var symbolSize = normalize$3(itemModel.getShallow('symbolSize', true)); + symbolType[0] && data.setItemVisual(idx, 'fromSymbol', symbolType[0]); + symbolType[1] && data.setItemVisual(idx, 'toSymbol', symbolType[1]); + symbolSize[0] && data.setItemVisual(idx, 'fromSymbolSize', symbolSize[0]); + symbolSize[1] && data.setItemVisual(idx, 'toSymbolSize', symbolSize[1]); + } + return { + dataEach: data.hasItemOption ? dataEach : null + }; + } + }; + + function install$m(registers) { + registers.registerChartView(LinesView); + registers.registerSeriesModel(LinesSeriesModel); + registers.registerLayout(linesLayout); + registers.registerVisual(linesVisual); + } + + var GRADIENT_LEVELS = 256; + var HeatmapLayer = /** @class */function () { + function HeatmapLayer() { + this.blurSize = 30; + this.pointSize = 20; + this.maxOpacity = 1; + this.minOpacity = 0; + this._gradientPixels = { + inRange: null, + outOfRange: null + }; + var canvas = platformApi.createCanvas(); + this.canvas = canvas; + } + /** + * Renders Heatmap and returns the rendered canvas + * @param data array of data, each has x, y, value + * @param width canvas width + * @param height canvas height + */ + HeatmapLayer.prototype.update = function (data, width, height, normalize, colorFunc, isInRange) { + var brush = this._getBrush(); + var gradientInRange = this._getGradient(colorFunc, 'inRange'); + var gradientOutOfRange = this._getGradient(colorFunc, 'outOfRange'); + var r = this.pointSize + this.blurSize; + var canvas = this.canvas; + var ctx = canvas.getContext('2d'); + var len = data.length; + canvas.width = width; + canvas.height = height; + for (var i = 0; i < len; ++i) { + var p = data[i]; + var x = p[0]; + var y = p[1]; + var value = p[2]; + // calculate alpha using value + var alpha = normalize(value); + // draw with the circle brush with alpha + ctx.globalAlpha = alpha; + ctx.drawImage(brush, x - r, y - r); + } + if (!canvas.width || !canvas.height) { + // Avoid "Uncaught DOMException: Failed to execute 'getImageData' on + // 'CanvasRenderingContext2D': The source height is 0." + return canvas; + } + // colorize the canvas using alpha value and set with gradient + var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + var pixels = imageData.data; + var offset = 0; + var pixelLen = pixels.length; + var minOpacity = this.minOpacity; + var maxOpacity = this.maxOpacity; + var diffOpacity = maxOpacity - minOpacity; + while (offset < pixelLen) { + var alpha = pixels[offset + 3] / 256; + var gradientOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1)) * 4; + // Simple optimize to ignore the empty data + if (alpha > 0) { + var gradient = isInRange(alpha) ? gradientInRange : gradientOutOfRange; + // Any alpha > 0 will be mapped to [minOpacity, maxOpacity] + alpha > 0 && (alpha = alpha * diffOpacity + minOpacity); + pixels[offset++] = gradient[gradientOffset]; + pixels[offset++] = gradient[gradientOffset + 1]; + pixels[offset++] = gradient[gradientOffset + 2]; + pixels[offset++] = gradient[gradientOffset + 3] * alpha * 256; + } else { + offset += 4; + } + } + ctx.putImageData(imageData, 0, 0); + return canvas; + }; + /** + * get canvas of a black circle brush used for canvas to draw later + */ + HeatmapLayer.prototype._getBrush = function () { + var brushCanvas = this._brushCanvas || (this._brushCanvas = platformApi.createCanvas()); + // set brush size + var r = this.pointSize + this.blurSize; + var d = r * 2; + brushCanvas.width = d; + brushCanvas.height = d; + var ctx = brushCanvas.getContext('2d'); + ctx.clearRect(0, 0, d, d); + // in order to render shadow without the distinct circle, + // draw the distinct circle in an invisible place, + // and use shadowOffset to draw shadow in the center of the canvas + ctx.shadowOffsetX = d; + ctx.shadowBlur = this.blurSize; + // draw the shadow in black, and use alpha and shadow blur to generate + // color in color map + ctx.shadowColor = '#000'; + // draw circle in the left to the canvas + ctx.beginPath(); + ctx.arc(-r, r, this.pointSize, 0, Math.PI * 2, true); + ctx.closePath(); + ctx.fill(); + return brushCanvas; + }; + /** + * get gradient color map + * @private + */ + HeatmapLayer.prototype._getGradient = function (colorFunc, state) { + var gradientPixels = this._gradientPixels; + var pixelsSingleState = gradientPixels[state] || (gradientPixels[state] = new Uint8ClampedArray(256 * 4)); + var color = [0, 0, 0, 0]; + var off = 0; + for (var i = 0; i < 256; i++) { + colorFunc[state](i / 255, true, color); + pixelsSingleState[off++] = color[0]; + pixelsSingleState[off++] = color[1]; + pixelsSingleState[off++] = color[2]; + pixelsSingleState[off++] = color[3]; + } + return pixelsSingleState; + }; + return HeatmapLayer; + }(); + + function getIsInPiecewiseRange(dataExtent, pieceList, selected) { + var dataSpan = dataExtent[1] - dataExtent[0]; + pieceList = map(pieceList, function (piece) { + return { + interval: [(piece.interval[0] - dataExtent[0]) / dataSpan, (piece.interval[1] - dataExtent[0]) / dataSpan] + }; + }); + var len = pieceList.length; + var lastIndex = 0; + return function (val) { + var i; + // Try to find in the location of the last found + for (i = lastIndex; i < len; i++) { + var interval = pieceList[i].interval; + if (interval[0] <= val && val <= interval[1]) { + lastIndex = i; + break; + } + } + if (i === len) { + // Not found, back interation + for (i = lastIndex - 1; i >= 0; i--) { + var interval = pieceList[i].interval; + if (interval[0] <= val && val <= interval[1]) { + lastIndex = i; + break; + } + } + } + return i >= 0 && i < len && selected[i]; + }; + } + function getIsInContinuousRange(dataExtent, range) { + var dataSpan = dataExtent[1] - dataExtent[0]; + range = [(range[0] - dataExtent[0]) / dataSpan, (range[1] - dataExtent[0]) / dataSpan]; + return function (val) { + return val >= range[0] && val <= range[1]; + }; + } + function isGeoCoordSys(coordSys) { + var dimensions = coordSys.dimensions; + // Not use coordSys.type === 'geo' because coordSys maybe extended + return dimensions[0] === 'lng' && dimensions[1] === 'lat'; + } + var HeatmapView = /** @class */function (_super) { + __extends(HeatmapView, _super); + function HeatmapView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = HeatmapView.type; + return _this; + } + HeatmapView.prototype.render = function (seriesModel, ecModel, api) { + var visualMapOfThisSeries; + ecModel.eachComponent('visualMap', function (visualMap) { + visualMap.eachTargetSeries(function (targetSeries) { + if (targetSeries === seriesModel) { + visualMapOfThisSeries = visualMap; + } + }); + }); + if ("development" !== 'production') { + if (!visualMapOfThisSeries) { + throw new Error('Heatmap must use with visualMap'); + } + } + // Clear previously rendered progressive elements. + this._progressiveEls = null; + this.group.removeAll(); + var coordSys = seriesModel.coordinateSystem; + if (coordSys.type === 'cartesian2d' || coordSys.type === 'calendar') { + this._renderOnCartesianAndCalendar(seriesModel, api, 0, seriesModel.getData().count()); + } else if (isGeoCoordSys(coordSys)) { + this._renderOnGeo(coordSys, seriesModel, visualMapOfThisSeries, api); + } + }; + HeatmapView.prototype.incrementalPrepareRender = function (seriesModel, ecModel, api) { + this.group.removeAll(); + }; + HeatmapView.prototype.incrementalRender = function (params, seriesModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys) { + // geo does not support incremental rendering? + if (isGeoCoordSys(coordSys)) { + this.render(seriesModel, ecModel, api); + } else { + this._progressiveEls = []; + this._renderOnCartesianAndCalendar(seriesModel, api, params.start, params.end, true); + } + } + }; + HeatmapView.prototype.eachRendered = function (cb) { + traverseElements(this._progressiveEls || this.group, cb); + }; + HeatmapView.prototype._renderOnCartesianAndCalendar = function (seriesModel, api, start, end, incremental) { + var coordSys = seriesModel.coordinateSystem; + var isCartesian2d = isCoordinateSystemType(coordSys, 'cartesian2d'); + var width; + var height; + var xAxisExtent; + var yAxisExtent; + if (isCartesian2d) { + var xAxis = coordSys.getAxis('x'); + var yAxis = coordSys.getAxis('y'); + if ("development" !== 'production') { + if (!(xAxis.type === 'category' && yAxis.type === 'category')) { + throw new Error('Heatmap on cartesian must have two category axes'); + } + if (!(xAxis.onBand && yAxis.onBand)) { + throw new Error('Heatmap on cartesian must have two axes with boundaryGap true'); + } + } + // add 0.5px to avoid the gaps + width = xAxis.getBandWidth() + .5; + height = yAxis.getBandWidth() + .5; + xAxisExtent = xAxis.scale.getExtent(); + yAxisExtent = yAxis.scale.getExtent(); + } + var group = this.group; + var data = seriesModel.getData(); + var emphasisStyle = seriesModel.getModel(['emphasis', 'itemStyle']).getItemStyle(); + var blurStyle = seriesModel.getModel(['blur', 'itemStyle']).getItemStyle(); + var selectStyle = seriesModel.getModel(['select', 'itemStyle']).getItemStyle(); + var borderRadius = seriesModel.get(['itemStyle', 'borderRadius']); + var labelStatesModels = getLabelStatesModels(seriesModel); + var emphasisModel = seriesModel.getModel('emphasis'); + var focus = emphasisModel.get('focus'); + var blurScope = emphasisModel.get('blurScope'); + var emphasisDisabled = emphasisModel.get('disabled'); + var dataDims = isCartesian2d ? [data.mapDimension('x'), data.mapDimension('y'), data.mapDimension('value')] : [data.mapDimension('time'), data.mapDimension('value')]; + for (var idx = start; idx < end; idx++) { + var rect = void 0; + var style = data.getItemVisual(idx, 'style'); + if (isCartesian2d) { + var dataDimX = data.get(dataDims[0], idx); + var dataDimY = data.get(dataDims[1], idx); + // Ignore empty data and out of extent data + if (isNaN(data.get(dataDims[2], idx)) || isNaN(dataDimX) || isNaN(dataDimY) || dataDimX < xAxisExtent[0] || dataDimX > xAxisExtent[1] || dataDimY < yAxisExtent[0] || dataDimY > yAxisExtent[1]) { + continue; + } + var point = coordSys.dataToPoint([dataDimX, dataDimY]); + rect = new Rect({ + shape: { + x: point[0] - width / 2, + y: point[1] - height / 2, + width: width, + height: height + }, + style: style + }); + } else { + // Ignore empty data + if (isNaN(data.get(dataDims[1], idx))) { + continue; + } + rect = new Rect({ + z2: 1, + shape: coordSys.dataToRect([data.get(dataDims[0], idx)]).contentShape, + style: style + }); + } + // Optimization for large dataset + if (data.hasItemOption) { + var itemModel = data.getItemModel(idx); + var emphasisModel_1 = itemModel.getModel('emphasis'); + emphasisStyle = emphasisModel_1.getModel('itemStyle').getItemStyle(); + blurStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle(); + selectStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle(); + // Each item value struct in the data would be firstly + // { + // itemStyle: { borderRadius: [30, 30] }, + // value: [2022, 02, 22] + // } + borderRadius = itemModel.get(['itemStyle', 'borderRadius']); + focus = emphasisModel_1.get('focus'); + blurScope = emphasisModel_1.get('blurScope'); + emphasisDisabled = emphasisModel_1.get('disabled'); + labelStatesModels = getLabelStatesModels(itemModel); + } + rect.shape.r = borderRadius; + var rawValue = seriesModel.getRawValue(idx); + var defaultText = '-'; + if (rawValue && rawValue[2] != null) { + defaultText = rawValue[2] + ''; + } + setLabelStyle(rect, labelStatesModels, { + labelFetcher: seriesModel, + labelDataIndex: idx, + defaultOpacity: style.opacity, + defaultText: defaultText + }); + rect.ensureState('emphasis').style = emphasisStyle; + rect.ensureState('blur').style = blurStyle; + rect.ensureState('select').style = selectStyle; + toggleHoverEmphasis(rect, focus, blurScope, emphasisDisabled); + rect.incremental = incremental; + // PENDING + if (incremental) { + // Rect must use hover layer if it's incremental. + rect.states.emphasis.hoverLayer = true; + } + group.add(rect); + data.setItemGraphicEl(idx, rect); + if (this._progressiveEls) { + this._progressiveEls.push(rect); + } + } + }; + HeatmapView.prototype._renderOnGeo = function (geo, seriesModel, visualMapModel, api) { + var inRangeVisuals = visualMapModel.targetVisuals.inRange; + var outOfRangeVisuals = visualMapModel.targetVisuals.outOfRange; + // if (!visualMapping) { + // throw new Error('Data range must have color visuals'); + // } + var data = seriesModel.getData(); + var hmLayer = this._hmLayer || this._hmLayer || new HeatmapLayer(); + hmLayer.blurSize = seriesModel.get('blurSize'); + hmLayer.pointSize = seriesModel.get('pointSize'); + hmLayer.minOpacity = seriesModel.get('minOpacity'); + hmLayer.maxOpacity = seriesModel.get('maxOpacity'); + var rect = geo.getViewRect().clone(); + var roamTransform = geo.getRoamTransform(); + rect.applyTransform(roamTransform); + // Clamp on viewport + var x = Math.max(rect.x, 0); + var y = Math.max(rect.y, 0); + var x2 = Math.min(rect.width + rect.x, api.getWidth()); + var y2 = Math.min(rect.height + rect.y, api.getHeight()); + var width = x2 - x; + var height = y2 - y; + var dims = [data.mapDimension('lng'), data.mapDimension('lat'), data.mapDimension('value')]; + var points = data.mapArray(dims, function (lng, lat, value) { + var pt = geo.dataToPoint([lng, lat]); + pt[0] -= x; + pt[1] -= y; + pt.push(value); + return pt; + }); + var dataExtent = visualMapModel.getExtent(); + var isInRange = visualMapModel.type === 'visualMap.continuous' ? getIsInContinuousRange(dataExtent, visualMapModel.option.range) : getIsInPiecewiseRange(dataExtent, visualMapModel.getPieceList(), visualMapModel.option.selected); + hmLayer.update(points, width, height, inRangeVisuals.color.getNormalizer(), { + inRange: inRangeVisuals.color.getColorMapper(), + outOfRange: outOfRangeVisuals.color.getColorMapper() + }, isInRange); + var img = new ZRImage({ + style: { + width: width, + height: height, + x: x, + y: y, + image: hmLayer.canvas + }, + silent: true + }); + this.group.add(img); + }; + HeatmapView.type = 'heatmap'; + return HeatmapView; + }(ChartView); + + var HeatmapSeriesModel = /** @class */function (_super) { + __extends(HeatmapSeriesModel, _super); + function HeatmapSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = HeatmapSeriesModel.type; + return _this; + } + HeatmapSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesData(null, this, { + generateCoord: 'value' + }); + }; + HeatmapSeriesModel.prototype.preventIncremental = function () { + var coordSysCreator = CoordinateSystemManager.get(this.get('coordinateSystem')); + if (coordSysCreator && coordSysCreator.dimensions) { + return coordSysCreator.dimensions[0] === 'lng' && coordSysCreator.dimensions[1] === 'lat'; + } + }; + HeatmapSeriesModel.type = 'series.heatmap'; + HeatmapSeriesModel.dependencies = ['grid', 'geo', 'calendar']; + HeatmapSeriesModel.defaultOption = { + coordinateSystem: 'cartesian2d', + // zlevel: 0, + z: 2, + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + // Geo coordinate system + geoIndex: 0, + blurSize: 30, + pointSize: 20, + maxOpacity: 1, + minOpacity: 0, + select: { + itemStyle: { + borderColor: '#212121' + } + } + }; + return HeatmapSeriesModel; + }(SeriesModel); + + function install$n(registers) { + registers.registerChartView(HeatmapView); + registers.registerSeriesModel(HeatmapSeriesModel); + } + + var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'borderWidth']; + // index: +isHorizontal + var LAYOUT_ATTRS = [{ + xy: 'x', + wh: 'width', + index: 0, + posDesc: ['left', 'right'] + }, { + xy: 'y', + wh: 'height', + index: 1, + posDesc: ['top', 'bottom'] + }]; + var pathForLineWidth = new Circle(); + var PictorialBarView = /** @class */function (_super) { + __extends(PictorialBarView, _super); + function PictorialBarView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = PictorialBarView.type; + return _this; + } + PictorialBarView.prototype.render = function (seriesModel, ecModel, api) { + var group = this.group; + var data = seriesModel.getData(); + var oldData = this._data; + var cartesian = seriesModel.coordinateSystem; + var baseAxis = cartesian.getBaseAxis(); + var isHorizontal = baseAxis.isHorizontal(); + var coordSysRect = cartesian.master.getRect(); + var opt = { + ecSize: { + width: api.getWidth(), + height: api.getHeight() + }, + seriesModel: seriesModel, + coordSys: cartesian, + coordSysExtent: [[coordSysRect.x, coordSysRect.x + coordSysRect.width], [coordSysRect.y, coordSysRect.y + coordSysRect.height]], + isHorizontal: isHorizontal, + valueDim: LAYOUT_ATTRS[+isHorizontal], + categoryDim: LAYOUT_ATTRS[1 - +isHorizontal] + }; + data.diff(oldData).add(function (dataIndex) { + if (!data.hasValue(dataIndex)) { + return; + } + var itemModel = getItemModel(data, dataIndex); + var symbolMeta = getSymbolMeta(data, dataIndex, itemModel, opt); + var bar = createBar(data, opt, symbolMeta); + data.setItemGraphicEl(dataIndex, bar); + group.add(bar); + updateCommon$1(bar, opt, symbolMeta); + }).update(function (newIndex, oldIndex) { + var bar = oldData.getItemGraphicEl(oldIndex); + if (!data.hasValue(newIndex)) { + group.remove(bar); + return; + } + var itemModel = getItemModel(data, newIndex); + var symbolMeta = getSymbolMeta(data, newIndex, itemModel, opt); + var pictorialShapeStr = getShapeStr(data, symbolMeta); + if (bar && pictorialShapeStr !== bar.__pictorialShapeStr) { + group.remove(bar); + data.setItemGraphicEl(newIndex, null); + bar = null; + } + if (bar) { + updateBar(bar, opt, symbolMeta); + } else { + bar = createBar(data, opt, symbolMeta, true); + } + data.setItemGraphicEl(newIndex, bar); + bar.__pictorialSymbolMeta = symbolMeta; + // Add back + group.add(bar); + updateCommon$1(bar, opt, symbolMeta); + }).remove(function (dataIndex) { + var bar = oldData.getItemGraphicEl(dataIndex); + bar && removeBar(oldData, dataIndex, bar.__pictorialSymbolMeta.animationModel, bar); + }).execute(); + // Do clipping + var clipPath = seriesModel.get('clip', true) ? createClipPath(seriesModel.coordinateSystem, false, seriesModel) : null; + if (clipPath) { + group.setClipPath(clipPath); + } else { + group.removeClipPath(); + } + this._data = data; + return this.group; + }; + PictorialBarView.prototype.remove = function (ecModel, api) { + var group = this.group; + var data = this._data; + if (ecModel.get('animation')) { + if (data) { + data.eachItemGraphicEl(function (bar) { + removeBar(data, getECData(bar).dataIndex, ecModel, bar); + }); + } + } else { + group.removeAll(); + } + }; + PictorialBarView.type = 'pictorialBar'; + return PictorialBarView; + }(ChartView); + // Set or calculate default value about symbol, and calculate layout info. + function getSymbolMeta(data, dataIndex, itemModel, opt) { + var layout = data.getItemLayout(dataIndex); + var symbolRepeat = itemModel.get('symbolRepeat'); + var symbolClip = itemModel.get('symbolClip'); + var symbolPosition = itemModel.get('symbolPosition') || 'start'; + var symbolRotate = itemModel.get('symbolRotate'); + var rotation = (symbolRotate || 0) * Math.PI / 180 || 0; + var symbolPatternSize = itemModel.get('symbolPatternSize') || 2; + var isAnimationEnabled = itemModel.isAnimationEnabled(); + var symbolMeta = { + dataIndex: dataIndex, + layout: layout, + itemModel: itemModel, + symbolType: data.getItemVisual(dataIndex, 'symbol') || 'circle', + style: data.getItemVisual(dataIndex, 'style'), + symbolClip: symbolClip, + symbolRepeat: symbolRepeat, + symbolRepeatDirection: itemModel.get('symbolRepeatDirection'), + symbolPatternSize: symbolPatternSize, + rotation: rotation, + animationModel: isAnimationEnabled ? itemModel : null, + hoverScale: isAnimationEnabled && itemModel.get(['emphasis', 'scale']), + z2: itemModel.getShallow('z', true) || 0 + }; + prepareBarLength(itemModel, symbolRepeat, layout, opt, symbolMeta); + prepareSymbolSize(data, dataIndex, layout, symbolRepeat, symbolClip, symbolMeta.boundingLength, symbolMeta.pxSign, symbolPatternSize, opt, symbolMeta); + prepareLineWidth(itemModel, symbolMeta.symbolScale, rotation, opt, symbolMeta); + var symbolSize = symbolMeta.symbolSize; + var symbolOffset = normalizeSymbolOffset(itemModel.get('symbolOffset'), symbolSize); + prepareLayoutInfo(itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, symbolPosition, symbolMeta.valueLineWidth, symbolMeta.boundingLength, symbolMeta.repeatCutLength, opt, symbolMeta); + return symbolMeta; + } + // bar length can be negative. + function prepareBarLength(itemModel, symbolRepeat, layout, opt, outputSymbolMeta) { + var valueDim = opt.valueDim; + var symbolBoundingData = itemModel.get('symbolBoundingData'); + var valueAxis = opt.coordSys.getOtherAxis(opt.coordSys.getBaseAxis()); + var zeroPx = valueAxis.toGlobalCoord(valueAxis.dataToCoord(0)); + var pxSignIdx = 1 - +(layout[valueDim.wh] <= 0); + var boundingLength; + if (isArray(symbolBoundingData)) { + var symbolBoundingExtent = [convertToCoordOnAxis(valueAxis, symbolBoundingData[0]) - zeroPx, convertToCoordOnAxis(valueAxis, symbolBoundingData[1]) - zeroPx]; + symbolBoundingExtent[1] < symbolBoundingExtent[0] && symbolBoundingExtent.reverse(); + boundingLength = symbolBoundingExtent[pxSignIdx]; + } else if (symbolBoundingData != null) { + boundingLength = convertToCoordOnAxis(valueAxis, symbolBoundingData) - zeroPx; + } else if (symbolRepeat) { + boundingLength = opt.coordSysExtent[valueDim.index][pxSignIdx] - zeroPx; + } else { + boundingLength = layout[valueDim.wh]; + } + outputSymbolMeta.boundingLength = boundingLength; + if (symbolRepeat) { + outputSymbolMeta.repeatCutLength = layout[valueDim.wh]; + } + // if 'pxSign' means sign of pixel, it can't be zero, or symbolScale will be zero + // and when borderWidth be settled, the actual linewidth will be NaN + outputSymbolMeta.pxSign = boundingLength > 0 ? 1 : -1; + } + function convertToCoordOnAxis(axis, value) { + return axis.toGlobalCoord(axis.dataToCoord(axis.scale.parse(value))); + } + // Support ['100%', '100%'] + function prepareSymbolSize(data, dataIndex, layout, symbolRepeat, symbolClip, boundingLength, pxSign, symbolPatternSize, opt, outputSymbolMeta) { + var valueDim = opt.valueDim; + var categoryDim = opt.categoryDim; + var categorySize = Math.abs(layout[categoryDim.wh]); + var symbolSize = data.getItemVisual(dataIndex, 'symbolSize'); + var parsedSymbolSize; + if (isArray(symbolSize)) { + parsedSymbolSize = symbolSize.slice(); + } else { + if (symbolSize == null) { + // will parse to number below + parsedSymbolSize = ['100%', '100%']; + } else { + parsedSymbolSize = [symbolSize, symbolSize]; + } + } + // Note: percentage symbolSize (like '100%') do not consider lineWidth, because it is + // to complicated to calculate real percent value if considering scaled lineWidth. + // So the actual size will bigger than layout size if lineWidth is bigger than zero, + // which can be tolerated in pictorial chart. + parsedSymbolSize[categoryDim.index] = parsePercent$1(parsedSymbolSize[categoryDim.index], categorySize); + parsedSymbolSize[valueDim.index] = parsePercent$1(parsedSymbolSize[valueDim.index], symbolRepeat ? categorySize : Math.abs(boundingLength)); + outputSymbolMeta.symbolSize = parsedSymbolSize; + // If x or y is less than zero, show reversed shape. + var symbolScale = outputSymbolMeta.symbolScale = [parsedSymbolSize[0] / symbolPatternSize, parsedSymbolSize[1] / symbolPatternSize]; + // Follow convention, 'right' and 'top' is the normal scale. + symbolScale[valueDim.index] *= (opt.isHorizontal ? -1 : 1) * pxSign; + } + function prepareLineWidth(itemModel, symbolScale, rotation, opt, outputSymbolMeta) { + // In symbols are drawn with scale, so do not need to care about the case that width + // or height are too small. But symbol use strokeNoScale, where acture lineWidth should + // be calculated. + var valueLineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0; + if (valueLineWidth) { + pathForLineWidth.attr({ + scaleX: symbolScale[0], + scaleY: symbolScale[1], + rotation: rotation + }); + pathForLineWidth.updateTransform(); + valueLineWidth /= pathForLineWidth.getLineScale(); + valueLineWidth *= symbolScale[opt.valueDim.index]; + } + outputSymbolMeta.valueLineWidth = valueLineWidth || 0; + } + function prepareLayoutInfo(itemModel, symbolSize, layout, symbolRepeat, symbolClip, symbolOffset, symbolPosition, valueLineWidth, boundingLength, repeatCutLength, opt, outputSymbolMeta) { + var categoryDim = opt.categoryDim; + var valueDim = opt.valueDim; + var pxSign = outputSymbolMeta.pxSign; + var unitLength = Math.max(symbolSize[valueDim.index] + valueLineWidth, 0); + var pathLen = unitLength; + // Note: rotation will not effect the layout of symbols, because user may + // want symbols to rotate on its center, which should not be translated + // when rotating. + if (symbolRepeat) { + var absBoundingLength = Math.abs(boundingLength); + var symbolMargin = retrieve(itemModel.get('symbolMargin'), '15%') + ''; + var hasEndGap = false; + if (symbolMargin.lastIndexOf('!') === symbolMargin.length - 1) { + hasEndGap = true; + symbolMargin = symbolMargin.slice(0, symbolMargin.length - 1); + } + var symbolMarginNumeric = parsePercent$1(symbolMargin, symbolSize[valueDim.index]); + var uLenWithMargin = Math.max(unitLength + symbolMarginNumeric * 2, 0); + // When symbol margin is less than 0, margin at both ends will be subtracted + // to ensure that all of the symbols will not be overflow the given area. + var endFix = hasEndGap ? 0 : symbolMarginNumeric * 2; + // Both final repeatTimes and final symbolMarginNumeric area calculated based on + // boundingLength. + var repeatSpecified = isNumeric(symbolRepeat); + var repeatTimes = repeatSpecified ? symbolRepeat : toIntTimes((absBoundingLength + endFix) / uLenWithMargin); + // Adjust calculate margin, to ensure each symbol is displayed + // entirely in the given layout area. + var mDiff = absBoundingLength - repeatTimes * unitLength; + symbolMarginNumeric = mDiff / 2 / (hasEndGap ? repeatTimes : Math.max(repeatTimes - 1, 1)); + uLenWithMargin = unitLength + symbolMarginNumeric * 2; + endFix = hasEndGap ? 0 : symbolMarginNumeric * 2; + // Update repeatTimes when not all symbol will be shown. + if (!repeatSpecified && symbolRepeat !== 'fixed') { + repeatTimes = repeatCutLength ? toIntTimes((Math.abs(repeatCutLength) + endFix) / uLenWithMargin) : 0; + } + pathLen = repeatTimes * uLenWithMargin - endFix; + outputSymbolMeta.repeatTimes = repeatTimes; + outputSymbolMeta.symbolMargin = symbolMarginNumeric; + } + var sizeFix = pxSign * (pathLen / 2); + var pathPosition = outputSymbolMeta.pathPosition = []; + pathPosition[categoryDim.index] = layout[categoryDim.wh] / 2; + pathPosition[valueDim.index] = symbolPosition === 'start' ? sizeFix : symbolPosition === 'end' ? boundingLength - sizeFix : boundingLength / 2; // 'center' + if (symbolOffset) { + pathPosition[0] += symbolOffset[0]; + pathPosition[1] += symbolOffset[1]; + } + var bundlePosition = outputSymbolMeta.bundlePosition = []; + bundlePosition[categoryDim.index] = layout[categoryDim.xy]; + bundlePosition[valueDim.index] = layout[valueDim.xy]; + var barRectShape = outputSymbolMeta.barRectShape = extend({}, layout); + barRectShape[valueDim.wh] = pxSign * Math.max(Math.abs(layout[valueDim.wh]), Math.abs(pathPosition[valueDim.index] + sizeFix)); + barRectShape[categoryDim.wh] = layout[categoryDim.wh]; + var clipShape = outputSymbolMeta.clipShape = {}; + // Consider that symbol may be overflow layout rect. + clipShape[categoryDim.xy] = -layout[categoryDim.xy]; + clipShape[categoryDim.wh] = opt.ecSize[categoryDim.wh]; + clipShape[valueDim.xy] = 0; + clipShape[valueDim.wh] = layout[valueDim.wh]; + } + function createPath(symbolMeta) { + var symbolPatternSize = symbolMeta.symbolPatternSize; + var path = createSymbol( + // Consider texture img, make a big size. + symbolMeta.symbolType, -symbolPatternSize / 2, -symbolPatternSize / 2, symbolPatternSize, symbolPatternSize); + path.attr({ + culling: true + }); + path.type !== 'image' && path.setStyle({ + strokeNoScale: true + }); + return path; + } + function createOrUpdateRepeatSymbols(bar, opt, symbolMeta, isUpdate) { + var bundle = bar.__pictorialBundle; + var symbolSize = symbolMeta.symbolSize; + var valueLineWidth = symbolMeta.valueLineWidth; + var pathPosition = symbolMeta.pathPosition; + var valueDim = opt.valueDim; + var repeatTimes = symbolMeta.repeatTimes || 0; + var index = 0; + var unit = symbolSize[opt.valueDim.index] + valueLineWidth + symbolMeta.symbolMargin * 2; + eachPath(bar, function (path) { + path.__pictorialAnimationIndex = index; + path.__pictorialRepeatTimes = repeatTimes; + if (index < repeatTimes) { + updateAttr(path, null, makeTarget(index), symbolMeta, isUpdate); + } else { + updateAttr(path, null, { + scaleX: 0, + scaleY: 0 + }, symbolMeta, isUpdate, function () { + bundle.remove(path); + }); + } + // updateHoverAnimation(path, symbolMeta); + index++; + }); + for (; index < repeatTimes; index++) { + var path = createPath(symbolMeta); + path.__pictorialAnimationIndex = index; + path.__pictorialRepeatTimes = repeatTimes; + bundle.add(path); + var target = makeTarget(index); + updateAttr(path, { + x: target.x, + y: target.y, + scaleX: 0, + scaleY: 0 + }, { + scaleX: target.scaleX, + scaleY: target.scaleY, + rotation: target.rotation + }, symbolMeta, isUpdate); + } + function makeTarget(index) { + var position = pathPosition.slice(); + // (start && pxSign > 0) || (end && pxSign < 0): i = repeatTimes - index + // Otherwise: i = index; + var pxSign = symbolMeta.pxSign; + var i = index; + if (symbolMeta.symbolRepeatDirection === 'start' ? pxSign > 0 : pxSign < 0) { + i = repeatTimes - 1 - index; + } + position[valueDim.index] = unit * (i - repeatTimes / 2 + 0.5) + pathPosition[valueDim.index]; + return { + x: position[0], + y: position[1], + scaleX: symbolMeta.symbolScale[0], + scaleY: symbolMeta.symbolScale[1], + rotation: symbolMeta.rotation + }; + } + } + function createOrUpdateSingleSymbol(bar, opt, symbolMeta, isUpdate) { + var bundle = bar.__pictorialBundle; + var mainPath = bar.__pictorialMainPath; + if (!mainPath) { + mainPath = bar.__pictorialMainPath = createPath(symbolMeta); + bundle.add(mainPath); + updateAttr(mainPath, { + x: symbolMeta.pathPosition[0], + y: symbolMeta.pathPosition[1], + scaleX: 0, + scaleY: 0, + rotation: symbolMeta.rotation + }, { + scaleX: symbolMeta.symbolScale[0], + scaleY: symbolMeta.symbolScale[1] + }, symbolMeta, isUpdate); + } else { + updateAttr(mainPath, null, { + x: symbolMeta.pathPosition[0], + y: symbolMeta.pathPosition[1], + scaleX: symbolMeta.symbolScale[0], + scaleY: symbolMeta.symbolScale[1], + rotation: symbolMeta.rotation + }, symbolMeta, isUpdate); + } + } + // bar rect is used for label. + function createOrUpdateBarRect(bar, symbolMeta, isUpdate) { + var rectShape = extend({}, symbolMeta.barRectShape); + var barRect = bar.__pictorialBarRect; + if (!barRect) { + barRect = bar.__pictorialBarRect = new Rect({ + z2: 2, + shape: rectShape, + silent: true, + style: { + stroke: 'transparent', + fill: 'transparent', + lineWidth: 0 + } + }); + barRect.disableMorphing = true; + bar.add(barRect); + } else { + updateAttr(barRect, null, { + shape: rectShape + }, symbolMeta, isUpdate); + } + } + function createOrUpdateClip(bar, opt, symbolMeta, isUpdate) { + // If not clip, symbol will be remove and rebuilt. + if (symbolMeta.symbolClip) { + var clipPath = bar.__pictorialClipPath; + var clipShape = extend({}, symbolMeta.clipShape); + var valueDim = opt.valueDim; + var animationModel = symbolMeta.animationModel; + var dataIndex = symbolMeta.dataIndex; + if (clipPath) { + updateProps(clipPath, { + shape: clipShape + }, animationModel, dataIndex); + } else { + clipShape[valueDim.wh] = 0; + clipPath = new Rect({ + shape: clipShape + }); + bar.__pictorialBundle.setClipPath(clipPath); + bar.__pictorialClipPath = clipPath; + var target = {}; + target[valueDim.wh] = symbolMeta.clipShape[valueDim.wh]; + graphic[isUpdate ? 'updateProps' : 'initProps'](clipPath, { + shape: target + }, animationModel, dataIndex); + } + } + } + function getItemModel(data, dataIndex) { + var itemModel = data.getItemModel(dataIndex); + itemModel.getAnimationDelayParams = getAnimationDelayParams; + itemModel.isAnimationEnabled = isAnimationEnabled; + return itemModel; + } + function getAnimationDelayParams(path) { + // The order is the same as the z-order, see `symbolRepeatDiretion`. + return { + index: path.__pictorialAnimationIndex, + count: path.__pictorialRepeatTimes + }; + } + function isAnimationEnabled() { + // `animation` prop can be set on itemModel in pictorial bar chart. + return this.parentModel.isAnimationEnabled() && !!this.getShallow('animation'); + } + function createBar(data, opt, symbolMeta, isUpdate) { + // bar is the main element for each data. + var bar = new Group(); + // bundle is used for location and clip. + var bundle = new Group(); + bar.add(bundle); + bar.__pictorialBundle = bundle; + bundle.x = symbolMeta.bundlePosition[0]; + bundle.y = symbolMeta.bundlePosition[1]; + if (symbolMeta.symbolRepeat) { + createOrUpdateRepeatSymbols(bar, opt, symbolMeta); + } else { + createOrUpdateSingleSymbol(bar, opt, symbolMeta); + } + createOrUpdateBarRect(bar, symbolMeta, isUpdate); + createOrUpdateClip(bar, opt, symbolMeta, isUpdate); + bar.__pictorialShapeStr = getShapeStr(data, symbolMeta); + bar.__pictorialSymbolMeta = symbolMeta; + return bar; + } + function updateBar(bar, opt, symbolMeta) { + var animationModel = symbolMeta.animationModel; + var dataIndex = symbolMeta.dataIndex; + var bundle = bar.__pictorialBundle; + updateProps(bundle, { + x: symbolMeta.bundlePosition[0], + y: symbolMeta.bundlePosition[1] + }, animationModel, dataIndex); + if (symbolMeta.symbolRepeat) { + createOrUpdateRepeatSymbols(bar, opt, symbolMeta, true); + } else { + createOrUpdateSingleSymbol(bar, opt, symbolMeta, true); + } + createOrUpdateBarRect(bar, symbolMeta, true); + createOrUpdateClip(bar, opt, symbolMeta, true); + } + function removeBar(data, dataIndex, animationModel, bar) { + // Not show text when animating + var labelRect = bar.__pictorialBarRect; + labelRect && labelRect.removeTextContent(); + var paths = []; + eachPath(bar, function (path) { + paths.push(path); + }); + bar.__pictorialMainPath && paths.push(bar.__pictorialMainPath); + // I do not find proper remove animation for clip yet. + bar.__pictorialClipPath && (animationModel = null); + each(paths, function (path) { + removeElement(path, { + scaleX: 0, + scaleY: 0 + }, animationModel, dataIndex, function () { + bar.parent && bar.parent.remove(bar); + }); + }); + data.setItemGraphicEl(dataIndex, null); + } + function getShapeStr(data, symbolMeta) { + return [data.getItemVisual(symbolMeta.dataIndex, 'symbol') || 'none', !!symbolMeta.symbolRepeat, !!symbolMeta.symbolClip].join(':'); + } + function eachPath(bar, cb, context) { + // Do not use Group#eachChild, because it do not support remove. + each(bar.__pictorialBundle.children(), function (el) { + el !== bar.__pictorialBarRect && cb.call(context, el); + }); + } + function updateAttr(el, immediateAttrs, animationAttrs, symbolMeta, isUpdate, cb) { + immediateAttrs && el.attr(immediateAttrs); + // when symbolCip used, only clip path has init animation, otherwise it would be weird effect. + if (symbolMeta.symbolClip && !isUpdate) { + animationAttrs && el.attr(animationAttrs); + } else { + animationAttrs && graphic[isUpdate ? 'updateProps' : 'initProps'](el, animationAttrs, symbolMeta.animationModel, symbolMeta.dataIndex, cb); + } + } + function updateCommon$1(bar, opt, symbolMeta) { + var dataIndex = symbolMeta.dataIndex; + var itemModel = symbolMeta.itemModel; + // Color must be excluded. + // Because symbol provide setColor individually to set fill and stroke + var emphasisModel = itemModel.getModel('emphasis'); + var emphasisStyle = emphasisModel.getModel('itemStyle').getItemStyle(); + var blurStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle(); + var selectStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle(); + var cursorStyle = itemModel.getShallow('cursor'); + var focus = emphasisModel.get('focus'); + var blurScope = emphasisModel.get('blurScope'); + var hoverScale = emphasisModel.get('scale'); + eachPath(bar, function (path) { + if (path instanceof ZRImage) { + var pathStyle = path.style; + path.useStyle(extend({ + // TODO other properties like dx, dy ? + image: pathStyle.image, + x: pathStyle.x, + y: pathStyle.y, + width: pathStyle.width, + height: pathStyle.height + }, symbolMeta.style)); + } else { + path.useStyle(symbolMeta.style); + } + var emphasisState = path.ensureState('emphasis'); + emphasisState.style = emphasisStyle; + if (hoverScale) { + // NOTE: Must after scale is set after updateAttr + emphasisState.scaleX = path.scaleX * 1.1; + emphasisState.scaleY = path.scaleY * 1.1; + } + path.ensureState('blur').style = blurStyle; + path.ensureState('select').style = selectStyle; + cursorStyle && (path.cursor = cursorStyle); + path.z2 = symbolMeta.z2; + }); + var barPositionOutside = opt.valueDim.posDesc[+(symbolMeta.boundingLength > 0)]; + var barRect = bar.__pictorialBarRect; + barRect.ignoreClip = true; + setLabelStyle(barRect, getLabelStatesModels(itemModel), { + labelFetcher: opt.seriesModel, + labelDataIndex: dataIndex, + defaultText: getDefaultLabel(opt.seriesModel.getData(), dataIndex), + inheritColor: symbolMeta.style.fill, + defaultOpacity: symbolMeta.style.opacity, + defaultOutsidePosition: barPositionOutside + }); + toggleHoverEmphasis(bar, focus, blurScope, emphasisModel.get('disabled')); + } + function toIntTimes(times) { + var roundedTimes = Math.round(times); + // Escapse accurate error + return Math.abs(times - roundedTimes) < 1e-4 ? roundedTimes : Math.ceil(times); + } + + var PictorialBarSeriesModel = /** @class */function (_super) { + __extends(PictorialBarSeriesModel, _super); + function PictorialBarSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = PictorialBarSeriesModel.type; + _this.hasSymbolVisual = true; + _this.defaultSymbol = 'roundRect'; + return _this; + } + PictorialBarSeriesModel.prototype.getInitialData = function (option) { + // Disable stack. + option.stack = null; + return _super.prototype.getInitialData.apply(this, arguments); + }; + PictorialBarSeriesModel.type = 'series.pictorialBar'; + PictorialBarSeriesModel.dependencies = ['grid']; + PictorialBarSeriesModel.defaultOption = inheritDefaultOption(BaseBarSeriesModel.defaultOption, { + symbol: 'circle', + symbolSize: null, + symbolRotate: null, + symbolPosition: null, + symbolOffset: null, + symbolMargin: null, + symbolRepeat: false, + symbolRepeatDirection: 'end', + symbolClip: false, + symbolBoundingData: null, + symbolPatternSize: 400, + barGap: '-100%', + // Pictorial bar do not clip by default because in many cases + // xAxis and yAxis are not displayed and it's expected not to clip + clip: false, + // z can be set in data item, which is z2 actually. + // Disable progressive + progressive: 0, + emphasis: { + // By default pictorialBar do not hover scale. Hover scale is not suitable + // for the case that both has foreground and background. + scale: false + }, + select: { + itemStyle: { + borderColor: '#212121' + } + } + }); + return PictorialBarSeriesModel; + }(BaseBarSeriesModel); + + function install$o(registers) { + registers.registerChartView(PictorialBarView); + registers.registerSeriesModel(PictorialBarSeriesModel); + registers.registerLayout(registers.PRIORITY.VISUAL.LAYOUT, curry(layout, 'pictorialBar')); + // Do layout after other overall layout, which can prepare some information. + registers.registerLayout(registers.PRIORITY.VISUAL.PROGRESSIVE_LAYOUT, createProgressiveLayout('pictorialBar')); + } + + var ThemeRiverView = /** @class */function (_super) { + __extends(ThemeRiverView, _super); + function ThemeRiverView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ThemeRiverView.type; + _this._layers = []; + return _this; + } + ThemeRiverView.prototype.render = function (seriesModel, ecModel, api) { + var data = seriesModel.getData(); + var self = this; + var group = this.group; + var layersSeries = seriesModel.getLayerSeries(); + var layoutInfo = data.getLayout('layoutInfo'); + var rect = layoutInfo.rect; + var boundaryGap = layoutInfo.boundaryGap; + group.x = 0; + group.y = rect.y + boundaryGap[0]; + function keyGetter(item) { + return item.name; + } + var dataDiffer = new DataDiffer(this._layersSeries || [], layersSeries, keyGetter, keyGetter); + var newLayersGroups = []; + dataDiffer.add(bind(process, this, 'add')).update(bind(process, this, 'update')).remove(bind(process, this, 'remove')).execute(); + function process(status, idx, oldIdx) { + var oldLayersGroups = self._layers; + if (status === 'remove') { + group.remove(oldLayersGroups[idx]); + return; + } + var points0 = []; + var points1 = []; + var style; + var indices = layersSeries[idx].indices; + var j = 0; + for (; j < indices.length; j++) { + var layout = data.getItemLayout(indices[j]); + var x = layout.x; + var y0 = layout.y0; + var y = layout.y; + points0.push(x, y0); + points1.push(x, y0 + y); + style = data.getItemVisual(indices[j], 'style'); + } + var polygon; + var textLayout = data.getItemLayout(indices[0]); + var labelModel = seriesModel.getModel('label'); + var margin = labelModel.get('margin'); + var emphasisModel = seriesModel.getModel('emphasis'); + if (status === 'add') { + var layerGroup = newLayersGroups[idx] = new Group(); + polygon = new ECPolygon({ + shape: { + points: points0, + stackedOnPoints: points1, + smooth: 0.4, + stackedOnSmooth: 0.4, + smoothConstraint: false + }, + z2: 0 + }); + layerGroup.add(polygon); + group.add(layerGroup); + if (seriesModel.isAnimationEnabled()) { + polygon.setClipPath(createGridClipShape$2(polygon.getBoundingRect(), seriesModel, function () { + polygon.removeClipPath(); + })); + } + } else { + var layerGroup = oldLayersGroups[oldIdx]; + polygon = layerGroup.childAt(0); + group.add(layerGroup); + newLayersGroups[idx] = layerGroup; + updateProps(polygon, { + shape: { + points: points0, + stackedOnPoints: points1 + } + }, seriesModel); + saveOldStyle(polygon); + } + setLabelStyle(polygon, getLabelStatesModels(seriesModel), { + labelDataIndex: indices[j - 1], + defaultText: data.getName(indices[j - 1]), + inheritColor: style.fill + }, { + normal: { + verticalAlign: 'middle' + // align: 'right' + } + }); + + polygon.setTextConfig({ + position: null, + local: true + }); + var labelEl = polygon.getTextContent(); + // TODO More label position options. + if (labelEl) { + labelEl.x = textLayout.x - margin; + labelEl.y = textLayout.y0 + textLayout.y / 2; + } + polygon.useStyle(style); + data.setItemGraphicEl(idx, polygon); + setStatesStylesFromModel(polygon, seriesModel); + toggleHoverEmphasis(polygon, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + } + this._layersSeries = layersSeries; + this._layers = newLayersGroups; + }; + ThemeRiverView.type = 'themeRiver'; + return ThemeRiverView; + }(ChartView); + // add animation to the view + function createGridClipShape$2(rect, seriesModel, cb) { + var rectEl = new Rect({ + shape: { + x: rect.x - 10, + y: rect.y - 10, + width: 0, + height: rect.height + 20 + } + }); + initProps(rectEl, { + shape: { + x: rect.x - 50, + width: rect.width + 100, + height: rect.height + 20 + } + }, seriesModel, cb); + return rectEl; + } + + var DATA_NAME_INDEX = 2; + var ThemeRiverSeriesModel = /** @class */function (_super) { + __extends(ThemeRiverSeriesModel, _super); + function ThemeRiverSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ThemeRiverSeriesModel.type; + return _this; + } + /** + * @override + */ + ThemeRiverSeriesModel.prototype.init = function (option) { + // eslint-disable-next-line + _super.prototype.init.apply(this, arguments); + // Put this function here is for the sake of consistency of code style. + // Enable legend selection for each data item + // Use a function instead of direct access because data reference may changed + this.legendVisualProvider = new LegendVisualProvider(bind(this.getData, this), bind(this.getRawData, this)); + }; + /** + * If there is no value of a certain point in the time for some event,set it value to 0. + * + * @param {Array} data initial data in the option + * @return {Array} + */ + ThemeRiverSeriesModel.prototype.fixData = function (data) { + var rawDataLength = data.length; + /** + * Make sure every layer data get the same keys. + * The value index tells which layer has visited. + * { + * 2014/01/01: -1 + * } + */ + var timeValueKeys = {}; + // grouped data by name + var groupResult = groupData(data, function (item) { + if (!timeValueKeys.hasOwnProperty(item[0] + '')) { + timeValueKeys[item[0] + ''] = -1; + } + return item[2]; + }); + var layerData = []; + groupResult.buckets.each(function (items, key) { + layerData.push({ + name: key, + dataList: items + }); + }); + var layerNum = layerData.length; + for (var k = 0; k < layerNum; ++k) { + var name_1 = layerData[k].name; + for (var j = 0; j < layerData[k].dataList.length; ++j) { + var timeValue = layerData[k].dataList[j][0] + ''; + timeValueKeys[timeValue] = k; + } + for (var timeValue in timeValueKeys) { + if (timeValueKeys.hasOwnProperty(timeValue) && timeValueKeys[timeValue] !== k) { + timeValueKeys[timeValue] = k; + data[rawDataLength] = [timeValue, 0, name_1]; + rawDataLength++; + } + } + } + return data; + }; + /** + * @override + * @param option the initial option that user gave + * @param ecModel the model object for themeRiver option + */ + ThemeRiverSeriesModel.prototype.getInitialData = function (option, ecModel) { + var singleAxisModel = this.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0]; + var axisType = singleAxisModel.get('type'); + // filter the data item with the value of label is undefined + var filterData = filter(option.data, function (dataItem) { + return dataItem[2] !== undefined; + }); + // ??? TODO design a stage to transfer data for themeRiver and lines? + var data = this.fixData(filterData || []); + var nameList = []; + var nameMap = this.nameMap = createHashMap(); + var count = 0; + for (var i = 0; i < data.length; ++i) { + nameList.push(data[i][DATA_NAME_INDEX]); + if (!nameMap.get(data[i][DATA_NAME_INDEX])) { + nameMap.set(data[i][DATA_NAME_INDEX], count); + count++; + } + } + var dimensions = prepareSeriesDataSchema(data, { + coordDimensions: ['single'], + dimensionsDefine: [{ + name: 'time', + type: getDimensionTypeByAxis(axisType) + }, { + name: 'value', + type: 'float' + }, { + name: 'name', + type: 'ordinal' + }], + encodeDefine: { + single: 0, + value: 1, + itemName: 2 + } + }).dimensions; + var list = new SeriesData(dimensions, this); + list.initData(data); + return list; + }; + /** + * The raw data is divided into multiple layers and each layer + * has same name. + */ + ThemeRiverSeriesModel.prototype.getLayerSeries = function () { + var data = this.getData(); + var lenCount = data.count(); + var indexArr = []; + for (var i = 0; i < lenCount; ++i) { + indexArr[i] = i; + } + var timeDim = data.mapDimension('single'); + // data group by name + var groupResult = groupData(indexArr, function (index) { + return data.get('name', index); + }); + var layerSeries = []; + groupResult.buckets.each(function (items, key) { + items.sort(function (index1, index2) { + return data.get(timeDim, index1) - data.get(timeDim, index2); + }); + layerSeries.push({ + name: key, + indices: items + }); + }); + return layerSeries; + }; + /** + * Get data indices for show tooltip content + */ + ThemeRiverSeriesModel.prototype.getAxisTooltipData = function (dim, value, baseAxis) { + if (!isArray(dim)) { + dim = dim ? [dim] : []; + } + var data = this.getData(); + var layerSeries = this.getLayerSeries(); + var indices = []; + var layerNum = layerSeries.length; + var nestestValue; + for (var i = 0; i < layerNum; ++i) { + var minDist = Number.MAX_VALUE; + var nearestIdx = -1; + var pointNum = layerSeries[i].indices.length; + for (var j = 0; j < pointNum; ++j) { + var theValue = data.get(dim[0], layerSeries[i].indices[j]); + var dist = Math.abs(theValue - value); + if (dist <= minDist) { + nestestValue = theValue; + minDist = dist; + nearestIdx = layerSeries[i].indices[j]; + } + } + indices.push(nearestIdx); + } + return { + dataIndices: indices, + nestestValue: nestestValue + }; + }; + ThemeRiverSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + var data = this.getData(); + var name = data.getName(dataIndex); + var value = data.get(data.mapDimension('value'), dataIndex); + return createTooltipMarkup('nameValue', { + name: name, + value: value + }); + }; + ThemeRiverSeriesModel.type = 'series.themeRiver'; + ThemeRiverSeriesModel.dependencies = ['singleAxis']; + ThemeRiverSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + colorBy: 'data', + coordinateSystem: 'singleAxis', + // gap in axis's orthogonal orientation + boundaryGap: ['10%', '10%'], + // legendHoverLink: true, + singleAxisIndex: 0, + animationEasing: 'linear', + label: { + margin: 4, + show: true, + position: 'left', + fontSize: 11 + }, + emphasis: { + label: { + show: true + } + } + }; + return ThemeRiverSeriesModel; + }(SeriesModel); + + function themeRiverLayout(ecModel, api) { + ecModel.eachSeriesByType('themeRiver', function (seriesModel) { + var data = seriesModel.getData(); + var single = seriesModel.coordinateSystem; + var layoutInfo = {}; + // use the axis boundingRect for view + var rect = single.getRect(); + layoutInfo.rect = rect; + var boundaryGap = seriesModel.get('boundaryGap'); + var axis = single.getAxis(); + layoutInfo.boundaryGap = boundaryGap; + if (axis.orient === 'horizontal') { + boundaryGap[0] = parsePercent$1(boundaryGap[0], rect.height); + boundaryGap[1] = parsePercent$1(boundaryGap[1], rect.height); + var height = rect.height - boundaryGap[0] - boundaryGap[1]; + doThemeRiverLayout(data, seriesModel, height); + } else { + boundaryGap[0] = parsePercent$1(boundaryGap[0], rect.width); + boundaryGap[1] = parsePercent$1(boundaryGap[1], rect.width); + var width = rect.width - boundaryGap[0] - boundaryGap[1]; + doThemeRiverLayout(data, seriesModel, width); + } + data.setLayout('layoutInfo', layoutInfo); + }); + } + /** + * The layout information about themeriver + * + * @param data data in the series + * @param seriesModel the model object of themeRiver series + * @param height value used to compute every series height + */ + function doThemeRiverLayout(data, seriesModel, height) { + if (!data.count()) { + return; + } + var coordSys = seriesModel.coordinateSystem; + // the data in each layer are organized into a series. + var layerSeries = seriesModel.getLayerSeries(); + // the points in each layer. + var timeDim = data.mapDimension('single'); + var valueDim = data.mapDimension('value'); + var layerPoints = map(layerSeries, function (singleLayer) { + return map(singleLayer.indices, function (idx) { + var pt = coordSys.dataToPoint(data.get(timeDim, idx)); + pt[1] = data.get(valueDim, idx); + return pt; + }); + }); + var base = computeBaseline(layerPoints); + var baseLine = base.y0; + var ky = height / base.max; + // set layout information for each item. + var n = layerSeries.length; + var m = layerSeries[0].indices.length; + var baseY0; + for (var j = 0; j < m; ++j) { + baseY0 = baseLine[j] * ky; + data.setItemLayout(layerSeries[0].indices[j], { + layerIndex: 0, + x: layerPoints[0][j][0], + y0: baseY0, + y: layerPoints[0][j][1] * ky + }); + for (var i = 1; i < n; ++i) { + baseY0 += layerPoints[i - 1][j][1] * ky; + data.setItemLayout(layerSeries[i].indices[j], { + layerIndex: i, + x: layerPoints[i][j][0], + y0: baseY0, + y: layerPoints[i][j][1] * ky + }); + } + } + } + /** + * Compute the baseLine of the rawdata + * Inspired by Lee Byron's paper Stacked Graphs - Geometry & Aesthetics + * + * @param data the points in each layer + */ + function computeBaseline(data) { + var layerNum = data.length; + var pointNum = data[0].length; + var sums = []; + var y0 = []; + var max = 0; + for (var i = 0; i < pointNum; ++i) { + var temp = 0; + for (var j = 0; j < layerNum; ++j) { + temp += data[j][i][1]; + } + if (temp > max) { + max = temp; + } + sums.push(temp); + } + for (var k = 0; k < pointNum; ++k) { + y0[k] = (max - sums[k]) / 2; + } + max = 0; + for (var l = 0; l < pointNum; ++l) { + var sum = sums[l] + y0[l]; + if (sum > max) { + max = sum; + } + } + return { + y0: y0, + max: max + }; + } + + function install$p(registers) { + registers.registerChartView(ThemeRiverView); + registers.registerSeriesModel(ThemeRiverSeriesModel); + registers.registerLayout(themeRiverLayout); + registers.registerProcessor(dataFilter('themeRiver')); + } + + var DEFAULT_SECTOR_Z = 2; + var DEFAULT_TEXT_Z = 4; + /** + * Sunburstce of Sunburst including Sector, Label, LabelLine + */ + var SunburstPiece = /** @class */function (_super) { + __extends(SunburstPiece, _super); + function SunburstPiece(node, seriesModel, ecModel, api) { + var _this = _super.call(this) || this; + _this.z2 = DEFAULT_SECTOR_Z; + _this.textConfig = { + inside: true + }; + getECData(_this).seriesIndex = seriesModel.seriesIndex; + var text = new ZRText({ + z2: DEFAULT_TEXT_Z, + silent: node.getModel().get(['label', 'silent']) + }); + _this.setTextContent(text); + _this.updateData(true, node, seriesModel, ecModel, api); + return _this; + } + SunburstPiece.prototype.updateData = function (firstCreate, node, + // state: 'emphasis' | 'normal' | 'highlight' | 'downplay', + seriesModel, ecModel, api) { + this.node = node; + node.piece = this; + seriesModel = seriesModel || this._seriesModel; + ecModel = ecModel || this._ecModel; + var sector = this; + getECData(sector).dataIndex = node.dataIndex; + var itemModel = node.getModel(); + var emphasisModel = itemModel.getModel('emphasis'); + var layout = node.getLayout(); + var sectorShape = extend({}, layout); + sectorShape.label = null; + var normalStyle = node.getVisual('style'); + normalStyle.lineJoin = 'bevel'; + var decal = node.getVisual('decal'); + if (decal) { + normalStyle.decal = createOrUpdatePatternFromDecal(decal, api); + } + var cornerRadius = getSectorCornerRadius(itemModel.getModel('itemStyle'), sectorShape, true); + extend(sectorShape, cornerRadius); + each(SPECIAL_STATES, function (stateName) { + var state = sector.ensureState(stateName); + var itemStyleModel = itemModel.getModel([stateName, 'itemStyle']); + state.style = itemStyleModel.getItemStyle(); + // border radius + var cornerRadius = getSectorCornerRadius(itemStyleModel, sectorShape); + if (cornerRadius) { + state.shape = cornerRadius; + } + }); + if (firstCreate) { + sector.setShape(sectorShape); + sector.shape.r = layout.r0; + initProps(sector, { + shape: { + r: layout.r + } + }, seriesModel, node.dataIndex); + } else { + // Disable animation for gradient since no interpolation method + // is supported for gradient + updateProps(sector, { + shape: sectorShape + }, seriesModel); + saveOldStyle(sector); + } + sector.useStyle(normalStyle); + this._updateLabel(seriesModel); + var cursorStyle = itemModel.getShallow('cursor'); + cursorStyle && sector.attr('cursor', cursorStyle); + this._seriesModel = seriesModel || this._seriesModel; + this._ecModel = ecModel || this._ecModel; + var focus = emphasisModel.get('focus'); + var focusOrIndices = focus === 'ancestor' ? node.getAncestorsIndices() : focus === 'descendant' ? node.getDescendantIndices() : focus; + toggleHoverEmphasis(this, focusOrIndices, emphasisModel.get('blurScope'), emphasisModel.get('disabled')); + }; + SunburstPiece.prototype._updateLabel = function (seriesModel) { + var _this = this; + var itemModel = this.node.getModel(); + var normalLabelModel = itemModel.getModel('label'); + var layout = this.node.getLayout(); + var angle = layout.endAngle - layout.startAngle; + var midAngle = (layout.startAngle + layout.endAngle) / 2; + var dx = Math.cos(midAngle); + var dy = Math.sin(midAngle); + var sector = this; + var label = sector.getTextContent(); + var dataIndex = this.node.dataIndex; + var labelMinAngle = normalLabelModel.get('minAngle') / 180 * Math.PI; + var isNormalShown = normalLabelModel.get('show') && !(labelMinAngle != null && Math.abs(angle) < labelMinAngle); + label.ignore = !isNormalShown; + // TODO use setLabelStyle + each(DISPLAY_STATES, function (stateName) { + var labelStateModel = stateName === 'normal' ? itemModel.getModel('label') : itemModel.getModel([stateName, 'label']); + var isNormal = stateName === 'normal'; + var state = isNormal ? label : label.ensureState(stateName); + var text = seriesModel.getFormattedLabel(dataIndex, stateName); + if (isNormal) { + text = text || _this.node.name; + } + state.style = createTextStyle(labelStateModel, {}, null, stateName !== 'normal', true); + if (text) { + state.style.text = text; + } + // Not displaying text when angle is too small + var isShown = labelStateModel.get('show'); + if (isShown != null && !isNormal) { + state.ignore = !isShown; + } + var labelPosition = getLabelAttr(labelStateModel, 'position'); + var sectorState = isNormal ? sector : sector.states[stateName]; + var labelColor = sectorState.style.fill; + sectorState.textConfig = { + outsideFill: labelStateModel.get('color') === 'inherit' ? labelColor : null, + inside: labelPosition !== 'outside' + }; + var r; + var labelPadding = getLabelAttr(labelStateModel, 'distance') || 0; + var textAlign = getLabelAttr(labelStateModel, 'align'); + var rotateType = getLabelAttr(labelStateModel, 'rotate'); + var flipStartAngle = Math.PI * 0.5; + var flipEndAngle = Math.PI * 1.5; + var midAngleNormal = normalizeRadian(rotateType === 'tangential' ? Math.PI / 2 - midAngle : midAngle); + // For text that is up-side down, rotate 180 degrees to make sure + // it's readable + var needsFlip = midAngleNormal > flipStartAngle && !isRadianAroundZero(midAngleNormal - flipStartAngle) && midAngleNormal < flipEndAngle; + if (labelPosition === 'outside') { + r = layout.r + labelPadding; + textAlign = needsFlip ? 'right' : 'left'; + } else { + if (!textAlign || textAlign === 'center') { + // Put label in the center if it's a circle + if (angle === 2 * Math.PI && layout.r0 === 0) { + r = 0; + } else { + r = (layout.r + layout.r0) / 2; + } + textAlign = 'center'; + } else if (textAlign === 'left') { + r = layout.r0 + labelPadding; + textAlign = needsFlip ? 'right' : 'left'; + } else if (textAlign === 'right') { + r = layout.r - labelPadding; + textAlign = needsFlip ? 'left' : 'right'; + } + } + state.style.align = textAlign; + state.style.verticalAlign = getLabelAttr(labelStateModel, 'verticalAlign') || 'middle'; + state.x = r * dx + layout.cx; + state.y = r * dy + layout.cy; + var rotate = 0; + if (rotateType === 'radial') { + rotate = normalizeRadian(-midAngle) + (needsFlip ? Math.PI : 0); + } else if (rotateType === 'tangential') { + rotate = normalizeRadian(Math.PI / 2 - midAngle) + (needsFlip ? Math.PI : 0); + } else if (isNumber(rotateType)) { + rotate = rotateType * Math.PI / 180; + } + state.rotation = normalizeRadian(rotate); + }); + function getLabelAttr(model, name) { + var stateAttr = model.get(name); + if (stateAttr == null) { + return normalLabelModel.get(name); + } + return stateAttr; + } + label.dirtyStyle(); + }; + return SunburstPiece; + }(Sector); + + var ROOT_TO_NODE_ACTION = 'sunburstRootToNode'; + var HIGHLIGHT_ACTION = 'sunburstHighlight'; + var UNHIGHLIGHT_ACTION = 'sunburstUnhighlight'; + function installSunburstAction(registers) { + registers.registerAction({ + type: ROOT_TO_NODE_ACTION, + update: 'updateView' + }, function (payload, ecModel) { + ecModel.eachComponent({ + mainType: 'series', + subType: 'sunburst', + query: payload + }, handleRootToNode); + function handleRootToNode(model, index) { + var targetInfo = retrieveTargetInfo(payload, [ROOT_TO_NODE_ACTION], model); + if (targetInfo) { + var originViewRoot = model.getViewRoot(); + if (originViewRoot) { + payload.direction = aboveViewRoot(originViewRoot, targetInfo.node) ? 'rollUp' : 'drillDown'; + } + model.resetViewRoot(targetInfo.node); + } + } + }); + registers.registerAction({ + type: HIGHLIGHT_ACTION, + update: 'none' + }, function (payload, ecModel, api) { + // Clone + payload = extend({}, payload); + ecModel.eachComponent({ + mainType: 'series', + subType: 'sunburst', + query: payload + }, handleHighlight); + function handleHighlight(model) { + var targetInfo = retrieveTargetInfo(payload, [HIGHLIGHT_ACTION], model); + if (targetInfo) { + payload.dataIndex = targetInfo.node.dataIndex; + } + } + if ("development" !== 'production') { + deprecateReplaceLog('sunburstHighlight', 'highlight'); + } + // Fast forward action + api.dispatchAction(extend(payload, { + type: 'highlight' + })); + }); + registers.registerAction({ + type: UNHIGHLIGHT_ACTION, + update: 'updateView' + }, function (payload, ecModel, api) { + payload = extend({}, payload); + if ("development" !== 'production') { + deprecateReplaceLog('sunburstUnhighlight', 'downplay'); + } + api.dispatchAction(extend(payload, { + type: 'downplay' + })); + }); + } + + var SunburstView = /** @class */function (_super) { + __extends(SunburstView, _super); + function SunburstView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SunburstView.type; + return _this; + } + SunburstView.prototype.render = function (seriesModel, ecModel, api, + // @ts-ignore + payload) { + var self = this; + this.seriesModel = seriesModel; + this.api = api; + this.ecModel = ecModel; + var data = seriesModel.getData(); + var virtualRoot = data.tree.root; + var newRoot = seriesModel.getViewRoot(); + var group = this.group; + var renderLabelForZeroData = seriesModel.get('renderLabelForZeroData'); + var newChildren = []; + newRoot.eachNode(function (node) { + newChildren.push(node); + }); + var oldChildren = this._oldChildren || []; + dualTravel(newChildren, oldChildren); + renderRollUp(virtualRoot, newRoot); + this._initEvents(); + this._oldChildren = newChildren; + function dualTravel(newChildren, oldChildren) { + if (newChildren.length === 0 && oldChildren.length === 0) { + return; + } + new DataDiffer(oldChildren, newChildren, getKey, getKey).add(processNode).update(processNode).remove(curry(processNode, null)).execute(); + function getKey(node) { + return node.getId(); + } + function processNode(newIdx, oldIdx) { + var newNode = newIdx == null ? null : newChildren[newIdx]; + var oldNode = oldIdx == null ? null : oldChildren[oldIdx]; + doRenderNode(newNode, oldNode); + } + } + function doRenderNode(newNode, oldNode) { + if (!renderLabelForZeroData && newNode && !newNode.getValue()) { + // Not render data with value 0 + newNode = null; + } + if (newNode !== virtualRoot && oldNode !== virtualRoot) { + if (oldNode && oldNode.piece) { + if (newNode) { + // Update + oldNode.piece.updateData(false, newNode, seriesModel, ecModel, api); + // For tooltip + data.setItemGraphicEl(newNode.dataIndex, oldNode.piece); + } else { + // Remove + removeNode(oldNode); + } + } else if (newNode) { + // Add + var piece = new SunburstPiece(newNode, seriesModel, ecModel, api); + group.add(piece); + // For tooltip + data.setItemGraphicEl(newNode.dataIndex, piece); + } + } + } + function removeNode(node) { + if (!node) { + return; + } + if (node.piece) { + group.remove(node.piece); + node.piece = null; + } + } + function renderRollUp(virtualRoot, viewRoot) { + if (viewRoot.depth > 0) { + // Render + if (self.virtualPiece) { + // Update + self.virtualPiece.updateData(false, virtualRoot, seriesModel, ecModel, api); + } else { + // Add + self.virtualPiece = new SunburstPiece(virtualRoot, seriesModel, ecModel, api); + group.add(self.virtualPiece); + } + // TODO event scope + viewRoot.piece.off('click'); + self.virtualPiece.on('click', function (e) { + self._rootToNode(viewRoot.parentNode); + }); + } else if (self.virtualPiece) { + // Remove + group.remove(self.virtualPiece); + self.virtualPiece = null; + } + } + }; + /** + * @private + */ + SunburstView.prototype._initEvents = function () { + var _this = this; + this.group.off('click'); + this.group.on('click', function (e) { + var targetFound = false; + var viewRoot = _this.seriesModel.getViewRoot(); + viewRoot.eachNode(function (node) { + if (!targetFound && node.piece && node.piece === e.target) { + var nodeClick = node.getModel().get('nodeClick'); + if (nodeClick === 'rootToNode') { + _this._rootToNode(node); + } else if (nodeClick === 'link') { + var itemModel = node.getModel(); + var link = itemModel.get('link'); + if (link) { + var linkTarget = itemModel.get('target', true) || '_blank'; + windowOpen(link, linkTarget); + } + } + targetFound = true; + } + }); + }); + }; + /** + * @private + */ + SunburstView.prototype._rootToNode = function (node) { + if (node !== this.seriesModel.getViewRoot()) { + this.api.dispatchAction({ + type: ROOT_TO_NODE_ACTION, + from: this.uid, + seriesId: this.seriesModel.id, + targetNode: node + }); + } + }; + /** + * @implement + */ + SunburstView.prototype.containPoint = function (point, seriesModel) { + var treeRoot = seriesModel.getData(); + var itemLayout = treeRoot.getItemLayout(0); + if (itemLayout) { + var dx = point[0] - itemLayout.cx; + var dy = point[1] - itemLayout.cy; + var radius = Math.sqrt(dx * dx + dy * dy); + return radius <= itemLayout.r && radius >= itemLayout.r0; + } + }; + SunburstView.type = 'sunburst'; + return SunburstView; + }(ChartView); + + var SunburstSeriesModel = /** @class */function (_super) { + __extends(SunburstSeriesModel, _super); + function SunburstSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SunburstSeriesModel.type; + _this.ignoreStyleOnData = true; + return _this; + } + SunburstSeriesModel.prototype.getInitialData = function (option, ecModel) { + // Create a virtual root. + var root = { + name: option.name, + children: option.data + }; + completeTreeValue$1(root); + var levelModels = this._levelModels = map(option.levels || [], function (levelDefine) { + return new Model(levelDefine, this, ecModel); + }, this); + // Make sure always a new tree is created when setOption, + // in TreemapView, we check whether oldTree === newTree + // to choose mappings approach among old shapes and new shapes. + var tree = Tree.createTree(root, this, beforeLink); + function beforeLink(nodeData) { + nodeData.wrapMethod('getItemModel', function (model, idx) { + var node = tree.getNodeByDataIndex(idx); + var levelModel = levelModels[node.depth]; + levelModel && (model.parentModel = levelModel); + return model; + }); + } + return tree.data; + }; + SunburstSeriesModel.prototype.optionUpdated = function () { + this.resetViewRoot(); + }; + /* + * @override + */ + SunburstSeriesModel.prototype.getDataParams = function (dataIndex) { + var params = _super.prototype.getDataParams.apply(this, arguments); + var node = this.getData().tree.getNodeByDataIndex(dataIndex); + params.treePathInfo = wrapTreePathInfo(node, this); + return params; + }; + SunburstSeriesModel.prototype.getLevelModel = function (node) { + return this._levelModels && this._levelModels[node.depth]; + }; + SunburstSeriesModel.prototype.getViewRoot = function () { + return this._viewRoot; + }; + SunburstSeriesModel.prototype.resetViewRoot = function (viewRoot) { + viewRoot ? this._viewRoot = viewRoot : viewRoot = this._viewRoot; + var root = this.getRawData().tree.root; + if (!viewRoot || viewRoot !== root && !root.contains(viewRoot)) { + this._viewRoot = root; + } + }; + SunburstSeriesModel.prototype.enableAriaDecal = function () { + enableAriaDecalForTree(this); + }; + SunburstSeriesModel.type = 'series.sunburst'; + SunburstSeriesModel.defaultOption = { + // zlevel: 0, + z: 2, + // 默认全局居中 + center: ['50%', '50%'], + radius: [0, '75%'], + // 默认顺时针 + clockwise: true, + startAngle: 90, + // 最小角度改为0 + minAngle: 0, + // If still show when all data zero. + stillShowZeroSum: true, + // 'rootToNode', 'link', or false + nodeClick: 'rootToNode', + renderLabelForZeroData: false, + label: { + // could be: 'radial', 'tangential', or 'none' + rotate: 'radial', + show: true, + opacity: 1, + // 'left' is for inner side of inside, and 'right' is for outer + // side for inside + align: 'center', + position: 'inside', + distance: 5, + silent: true + }, + itemStyle: { + borderWidth: 1, + borderColor: 'white', + borderType: 'solid', + shadowBlur: 0, + shadowColor: 'rgba(0, 0, 0, 0.2)', + shadowOffsetX: 0, + shadowOffsetY: 0, + opacity: 1 + }, + emphasis: { + focus: 'descendant' + }, + blur: { + itemStyle: { + opacity: 0.2 + }, + label: { + opacity: 0.1 + } + }, + // Animation type can be expansion, scale. + animationType: 'expansion', + animationDuration: 1000, + animationDurationUpdate: 500, + data: [], + /** + * Sort order. + * + * Valid values: 'desc', 'asc', null, or callback function. + * 'desc' and 'asc' for descend and ascendant order; + * null for not sorting; + * example of callback function: + * function(nodeA, nodeB) { + * return nodeA.getValue() - nodeB.getValue(); + * } + */ + sort: 'desc' + }; + return SunburstSeriesModel; + }(SeriesModel); + function completeTreeValue$1(dataNode) { + // Postorder travel tree. + // If value of none-leaf node is not set, + // calculate it by suming up the value of all children. + var sum = 0; + each(dataNode.children, function (child) { + completeTreeValue$1(child); + var childValue = child.value; + // TODO First value of array must be a number + isArray(childValue) && (childValue = childValue[0]); + sum += childValue; + }); + var thisValue = dataNode.value; + if (isArray(thisValue)) { + thisValue = thisValue[0]; + } + if (thisValue == null || isNaN(thisValue)) { + thisValue = sum; + } + // Value should not less than 0. + if (thisValue < 0) { + thisValue = 0; + } + isArray(dataNode.value) ? dataNode.value[0] = thisValue : dataNode.value = thisValue; + } + + // let PI2 = Math.PI * 2; + var RADIAN$2 = Math.PI / 180; + function sunburstLayout(seriesType, ecModel, api) { + ecModel.eachSeriesByType(seriesType, function (seriesModel) { + var center = seriesModel.get('center'); + var radius = seriesModel.get('radius'); + if (!isArray(radius)) { + radius = [0, radius]; + } + if (!isArray(center)) { + center = [center, center]; + } + var width = api.getWidth(); + var height = api.getHeight(); + var size = Math.min(width, height); + var cx = parsePercent$1(center[0], width); + var cy = parsePercent$1(center[1], height); + var r0 = parsePercent$1(radius[0], size / 2); + var r = parsePercent$1(radius[1], size / 2); + var startAngle = -seriesModel.get('startAngle') * RADIAN$2; + var minAngle = seriesModel.get('minAngle') * RADIAN$2; + var virtualRoot = seriesModel.getData().tree.root; + var treeRoot = seriesModel.getViewRoot(); + var rootDepth = treeRoot.depth; + var sort = seriesModel.get('sort'); + if (sort != null) { + initChildren$1(treeRoot, sort); + } + var validDataCount = 0; + each(treeRoot.children, function (child) { + !isNaN(child.getValue()) && validDataCount++; + }); + var sum = treeRoot.getValue(); + // Sum may be 0 + var unitRadian = Math.PI / (sum || validDataCount) * 2; + var renderRollupNode = treeRoot.depth > 0; + var levels = treeRoot.height - (renderRollupNode ? -1 : 1); + var rPerLevel = (r - r0) / (levels || 1); + var clockwise = seriesModel.get('clockwise'); + var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); + // In the case some sector angle is smaller than minAngle + // let restAngle = PI2; + // let valueSumLargerThanMinAngle = 0; + var dir = clockwise ? 1 : -1; + /** + * Render a tree + * @return increased angle + */ + var renderNode = function (node, startAngle) { + if (!node) { + return; + } + var endAngle = startAngle; + // Render self + if (node !== virtualRoot) { + // Tree node is virtual, so it doesn't need to be drawn + var value = node.getValue(); + var angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian; + if (angle < minAngle) { + angle = minAngle; + // restAngle -= minAngle; + } + // else { + // valueSumLargerThanMinAngle += value; + // } + endAngle = startAngle + dir * angle; + var depth = node.depth - rootDepth - (renderRollupNode ? -1 : 1); + var rStart = r0 + rPerLevel * depth; + var rEnd = r0 + rPerLevel * (depth + 1); + var levelModel = seriesModel.getLevelModel(node); + if (levelModel) { + var r0_1 = levelModel.get('r0', true); + var r_1 = levelModel.get('r', true); + var radius_1 = levelModel.get('radius', true); + if (radius_1 != null) { + r0_1 = radius_1[0]; + r_1 = radius_1[1]; + } + r0_1 != null && (rStart = parsePercent$1(r0_1, size / 2)); + r_1 != null && (rEnd = parsePercent$1(r_1, size / 2)); + } + node.setLayout({ + angle: angle, + startAngle: startAngle, + endAngle: endAngle, + clockwise: clockwise, + cx: cx, + cy: cy, + r0: rStart, + r: rEnd + }); + } + // Render children + if (node.children && node.children.length) { + // currentAngle = startAngle; + var siblingAngle_1 = 0; + each(node.children, function (node) { + siblingAngle_1 += renderNode(node, startAngle + siblingAngle_1); + }); + } + return endAngle - startAngle; + }; + // Virtual root node for roll up + if (renderRollupNode) { + var rStart = r0; + var rEnd = r0 + rPerLevel; + var angle = Math.PI * 2; + virtualRoot.setLayout({ + angle: angle, + startAngle: startAngle, + endAngle: startAngle + angle, + clockwise: clockwise, + cx: cx, + cy: cy, + r0: rStart, + r: rEnd + }); + } + renderNode(treeRoot, startAngle); + }); + } + /** + * Init node children by order and update visual + */ + function initChildren$1(node, sortOrder) { + var children = node.children || []; + node.children = sort$2(children, sortOrder); + // Init children recursively + if (children.length) { + each(node.children, function (child) { + initChildren$1(child, sortOrder); + }); + } + } + /** + * Sort children nodes + * + * @param {TreeNode[]} children children of node to be sorted + * @param {string | function | null} sort sort method + * See SunburstSeries.js for details. + */ + function sort$2(children, sortOrder) { + if (isFunction(sortOrder)) { + var sortTargets = map(children, function (child, idx) { + var value = child.getValue(); + return { + params: { + depth: child.depth, + height: child.height, + dataIndex: child.dataIndex, + getValue: function () { + return value; + } + }, + index: idx + }; + }); + sortTargets.sort(function (a, b) { + return sortOrder(a.params, b.params); + }); + return map(sortTargets, function (target) { + return children[target.index]; + }); + } else { + var isAsc_1 = sortOrder === 'asc'; + return children.sort(function (a, b) { + var diff = (a.getValue() - b.getValue()) * (isAsc_1 ? 1 : -1); + return diff === 0 ? (a.dataIndex - b.dataIndex) * (isAsc_1 ? -1 : 1) : diff; + }); + } + } + + function sunburstVisual(ecModel) { + var paletteScope = {}; + // Default color strategy + function pickColor(node, seriesModel, treeHeight) { + // Choose color from palette based on the first level. + var current = node; + while (current && current.depth > 1) { + current = current.parentNode; + } + var color = seriesModel.getColorFromPalette(current.name || current.dataIndex + '', paletteScope); + if (node.depth > 1 && isString(color)) { + // Lighter on the deeper level. + color = lift(color, (node.depth - 1) / (treeHeight - 1) * 0.5); + } + return color; + } + ecModel.eachSeriesByType('sunburst', function (seriesModel) { + var data = seriesModel.getData(); + var tree = data.tree; + tree.eachNode(function (node) { + var model = node.getModel(); + var style = model.getModel('itemStyle').getItemStyle(); + if (!style.fill) { + style.fill = pickColor(node, seriesModel, tree.root.height); + } + var existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style'); + extend(existsStyle, style); + }); + }); + } + + function install$q(registers) { + registers.registerChartView(SunburstView); + registers.registerSeriesModel(SunburstSeriesModel); + registers.registerLayout(curry(sunburstLayout, 'sunburst')); + registers.registerProcessor(curry(dataFilter, 'sunburst')); + registers.registerVisual(sunburstVisual); + installSunburstAction(registers); + } + + // Also compat with ec4, where + // `visual('color') visual('borderColor')` is supported. + var STYLE_VISUAL_TYPE = { + color: 'fill', + borderColor: 'stroke' + }; + var NON_STYLE_VISUAL_PROPS = { + symbol: 1, + symbolSize: 1, + symbolKeepAspect: 1, + legendIcon: 1, + visualMeta: 1, + liftZ: 1, + decal: 1 + }; + var customInnerStore = makeInner(); + var CustomSeriesModel = /** @class */function (_super) { + __extends(CustomSeriesModel, _super); + function CustomSeriesModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CustomSeriesModel.type; + return _this; + } + CustomSeriesModel.prototype.optionUpdated = function () { + this.currentZLevel = this.get('zlevel', true); + this.currentZ = this.get('z', true); + }; + CustomSeriesModel.prototype.getInitialData = function (option, ecModel) { + return createSeriesData(null, this); + }; + CustomSeriesModel.prototype.getDataParams = function (dataIndex, dataType, el) { + var params = _super.prototype.getDataParams.call(this, dataIndex, dataType); + el && (params.info = customInnerStore(el).info); + return params; + }; + CustomSeriesModel.type = 'series.custom'; + CustomSeriesModel.dependencies = ['grid', 'polar', 'geo', 'singleAxis', 'calendar']; + CustomSeriesModel.defaultOption = { + coordinateSystem: 'cartesian2d', + // zlevel: 0, + z: 2, + legendHoverLink: true, + // Custom series will not clip by default. + // Some case will use custom series to draw label + // For example https://echarts.apache.org/examples/en/editor.html?c=custom-gantt-flight + clip: false + // Cartesian coordinate system + // xAxisIndex: 0, + // yAxisIndex: 0, + // Polar coordinate system + // polarIndex: 0, + // Geo coordinate system + // geoIndex: 0, + }; + + return CustomSeriesModel; + }(SeriesModel); + + function dataToCoordSize(dataSize, dataItem) { + // dataItem is necessary in log axis. + dataItem = dataItem || [0, 0]; + return map(['x', 'y'], function (dim, dimIdx) { + var axis = this.getAxis(dim); + var val = dataItem[dimIdx]; + var halfSize = dataSize[dimIdx] / 2; + return axis.type === 'category' ? axis.getBandWidth() : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize)); + }, this); + } + function cartesianPrepareCustom(coordSys) { + var rect = coordSys.master.getRect(); + return { + coordSys: { + // The name exposed to user is always 'cartesian2d' but not 'grid'. + type: 'cartesian2d', + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + }, + api: { + coord: function (data) { + // do not provide "out" param + return coordSys.dataToPoint(data); + }, + size: bind(dataToCoordSize, coordSys) + } + }; + } + + function dataToCoordSize$1(dataSize, dataItem) { + dataItem = dataItem || [0, 0]; + return map([0, 1], function (dimIdx) { + var val = dataItem[dimIdx]; + var halfSize = dataSize[dimIdx] / 2; + var p1 = []; + var p2 = []; + p1[dimIdx] = val - halfSize; + p2[dimIdx] = val + halfSize; + p1[1 - dimIdx] = p2[1 - dimIdx] = dataItem[1 - dimIdx]; + return Math.abs(this.dataToPoint(p1)[dimIdx] - this.dataToPoint(p2)[dimIdx]); + }, this); + } + function geoPrepareCustom(coordSys) { + var rect = coordSys.getBoundingRect(); + return { + coordSys: { + type: 'geo', + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height, + zoom: coordSys.getZoom() + }, + api: { + coord: function (data) { + // do not provide "out" and noRoam param, + // Compatible with this usage: + // echarts.util.map(item.points, api.coord) + return coordSys.dataToPoint(data); + }, + size: bind(dataToCoordSize$1, coordSys) + } + }; + } + + function dataToCoordSize$2(dataSize, dataItem) { + // dataItem is necessary in log axis. + var axis = this.getAxis(); + var val = dataItem instanceof Array ? dataItem[0] : dataItem; + var halfSize = (dataSize instanceof Array ? dataSize[0] : dataSize) / 2; + return axis.type === 'category' ? axis.getBandWidth() : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize)); + } + function singlePrepareCustom(coordSys) { + var rect = coordSys.getRect(); + return { + coordSys: { + type: 'singleAxis', + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height + }, + api: { + coord: function (val) { + // do not provide "out" param + return coordSys.dataToPoint(val); + }, + size: bind(dataToCoordSize$2, coordSys) + } + }; + } + + // import AngleAxis from './AngleAxis.js'; + function dataToCoordSize$3(dataSize, dataItem) { + // dataItem is necessary in log axis. + dataItem = dataItem || [0, 0]; + return map(['Radius', 'Angle'], function (dim, dimIdx) { + var getterName = 'get' + dim + 'Axis'; + // TODO: TYPE Check Angle Axis + var axis = this[getterName](); + var val = dataItem[dimIdx]; + var halfSize = dataSize[dimIdx] / 2; + var result = axis.type === 'category' ? axis.getBandWidth() : Math.abs(axis.dataToCoord(val - halfSize) - axis.dataToCoord(val + halfSize)); + if (dim === 'Angle') { + result = result * Math.PI / 180; + } + return result; + }, this); + } + function polarPrepareCustom(coordSys) { + var radiusAxis = coordSys.getRadiusAxis(); + var angleAxis = coordSys.getAngleAxis(); + var radius = radiusAxis.getExtent(); + radius[0] > radius[1] && radius.reverse(); + return { + coordSys: { + type: 'polar', + cx: coordSys.cx, + cy: coordSys.cy, + r: radius[1], + r0: radius[0] + }, + api: { + coord: function (data) { + var radius = radiusAxis.dataToRadius(data[0]); + var angle = angleAxis.dataToAngle(data[1]); + var coord = coordSys.coordToPoint([radius, angle]); + coord.push(radius, angle * Math.PI / 180); + return coord; + }, + size: bind(dataToCoordSize$3, coordSys) + } + }; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function calendarPrepareCustom(coordSys) { + var rect = coordSys.getRect(); + var rangeInfo = coordSys.getRangeInfo(); + return { + coordSys: { + type: 'calendar', + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height, + cellWidth: coordSys.getCellWidth(), + cellHeight: coordSys.getCellHeight(), + rangeInfo: { + start: rangeInfo.start, + end: rangeInfo.end, + weeks: rangeInfo.weeks, + dayCount: rangeInfo.allDay + } + }, + api: { + coord: function (data, clamp) { + return coordSys.dataToPoint(data, clamp); + } + } + }; + } + + var deprecatedLogs = {}; + /** + * Whether need to call `convertEC4CompatibleStyle`. + */ + function isEC4CompatibleStyle(style, elType, hasOwnTextContentOption, hasOwnTextConfig) { + // Since echarts5, `RectText` is separated from its host element and style.text + // does not exist any more. The compat work brings some extra burden on performance. + // So we provide: + // `legacy: true` force make compat. + // `legacy: false`, force do not compat. + // `legacy` not set: auto detect whether legacy. + // But in this case we do not compat (difficult to detect and rare case): + // Becuse custom series and graphic component support "merge", users may firstly + // only set `textStrokeWidth` style or secondly only set `text`. + return style && (style.legacy || style.legacy !== false && !hasOwnTextContentOption && !hasOwnTextConfig && elType !== 'tspan' + // Difficult to detect whether legacy for a "text" el. + && (elType === 'text' || hasOwn(style, 'text'))); + } + /** + * `EC4CompatibleStyle` is style that might be in echarts4 format or echarts5 format. + * @param hostStyle The properties might be modified. + * @return If be text el, `textContentStyle` and `textConfig` will not be returned. + * Otherwise a `textContentStyle` and `textConfig` will be created, whose props area + * retried from the `hostStyle`. + */ + function convertFromEC4CompatibleStyle(hostStyle, elType, isNormal) { + var srcStyle = hostStyle; + var textConfig; + var textContent; + var textContentStyle; + if (elType === 'text') { + textContentStyle = srcStyle; + } else { + textContentStyle = {}; + hasOwn(srcStyle, 'text') && (textContentStyle.text = srcStyle.text); + hasOwn(srcStyle, 'rich') && (textContentStyle.rich = srcStyle.rich); + hasOwn(srcStyle, 'textFill') && (textContentStyle.fill = srcStyle.textFill); + hasOwn(srcStyle, 'textStroke') && (textContentStyle.stroke = srcStyle.textStroke); + hasOwn(srcStyle, 'fontFamily') && (textContentStyle.fontFamily = srcStyle.fontFamily); + hasOwn(srcStyle, 'fontSize') && (textContentStyle.fontSize = srcStyle.fontSize); + hasOwn(srcStyle, 'fontStyle') && (textContentStyle.fontStyle = srcStyle.fontStyle); + hasOwn(srcStyle, 'fontWeight') && (textContentStyle.fontWeight = srcStyle.fontWeight); + textContent = { + type: 'text', + style: textContentStyle, + // ec4 does not support rectText trigger. + // And when text position is different in normal and emphasis + // => hover text trigger emphasis; + // => text position changed, leave mouse pointer immediately; + // That might cause incorrect state. + silent: true + }; + textConfig = {}; + var hasOwnPos = hasOwn(srcStyle, 'textPosition'); + if (isNormal) { + textConfig.position = hasOwnPos ? srcStyle.textPosition : 'inside'; + } else { + hasOwnPos && (textConfig.position = srcStyle.textPosition); + } + hasOwn(srcStyle, 'textPosition') && (textConfig.position = srcStyle.textPosition); + hasOwn(srcStyle, 'textOffset') && (textConfig.offset = srcStyle.textOffset); + hasOwn(srcStyle, 'textRotation') && (textConfig.rotation = srcStyle.textRotation); + hasOwn(srcStyle, 'textDistance') && (textConfig.distance = srcStyle.textDistance); + } + convertEC4CompatibleRichItem(textContentStyle, hostStyle); + each(textContentStyle.rich, function (richItem) { + convertEC4CompatibleRichItem(richItem, richItem); + }); + return { + textConfig: textConfig, + textContent: textContent + }; + } + /** + * The result will be set to `out`. + */ + function convertEC4CompatibleRichItem(out, richItem) { + if (!richItem) { + return; + } + // (1) For simplicity, make textXXX properties (deprecated since ec5) has + // higher priority. For example, consider in ec4 `borderColor: 5, textBorderColor: 10` + // on a rect means `borderColor: 4` on the rect and `borderColor: 10` on an attached + // richText in ec5. + // (2) `out === richItem` if and only if `out` is text el or rich item. + // So we can overwrite existing props in `out` since textXXX has higher priority. + richItem.font = richItem.textFont || richItem.font; + hasOwn(richItem, 'textStrokeWidth') && (out.lineWidth = richItem.textStrokeWidth); + hasOwn(richItem, 'textAlign') && (out.align = richItem.textAlign); + hasOwn(richItem, 'textVerticalAlign') && (out.verticalAlign = richItem.textVerticalAlign); + hasOwn(richItem, 'textLineHeight') && (out.lineHeight = richItem.textLineHeight); + hasOwn(richItem, 'textWidth') && (out.width = richItem.textWidth); + hasOwn(richItem, 'textHeight') && (out.height = richItem.textHeight); + hasOwn(richItem, 'textBackgroundColor') && (out.backgroundColor = richItem.textBackgroundColor); + hasOwn(richItem, 'textPadding') && (out.padding = richItem.textPadding); + hasOwn(richItem, 'textBorderColor') && (out.borderColor = richItem.textBorderColor); + hasOwn(richItem, 'textBorderWidth') && (out.borderWidth = richItem.textBorderWidth); + hasOwn(richItem, 'textBorderRadius') && (out.borderRadius = richItem.textBorderRadius); + hasOwn(richItem, 'textBoxShadowColor') && (out.shadowColor = richItem.textBoxShadowColor); + hasOwn(richItem, 'textBoxShadowBlur') && (out.shadowBlur = richItem.textBoxShadowBlur); + hasOwn(richItem, 'textBoxShadowOffsetX') && (out.shadowOffsetX = richItem.textBoxShadowOffsetX); + hasOwn(richItem, 'textBoxShadowOffsetY') && (out.shadowOffsetY = richItem.textBoxShadowOffsetY); + } + /** + * Convert to pure echarts4 format style. + * `itemStyle` will be modified, added with ec4 style properties from + * `textStyle` and `textConfig`. + * + * [Caveat]: For simplicity, `insideRollback` in ec4 does not compat, where + * `styleEmphasis: {textFill: 'red'}` will remove the normal auto added stroke. + */ + function convertToEC4StyleForCustomSerise(itemStl, txStl, txCfg) { + var out = itemStl; + // See `custom.ts`, a trick to set extra `textPosition` firstly. + out.textPosition = out.textPosition || txCfg.position || 'inside'; + txCfg.offset != null && (out.textOffset = txCfg.offset); + txCfg.rotation != null && (out.textRotation = txCfg.rotation); + txCfg.distance != null && (out.textDistance = txCfg.distance); + var isInside = out.textPosition.indexOf('inside') >= 0; + var hostFill = itemStl.fill || '#000'; + convertToEC4RichItem(out, txStl); + var textFillNotSet = out.textFill == null; + if (isInside) { + if (textFillNotSet) { + out.textFill = txCfg.insideFill || '#fff'; + !out.textStroke && txCfg.insideStroke && (out.textStroke = txCfg.insideStroke); + !out.textStroke && (out.textStroke = hostFill); + out.textStrokeWidth == null && (out.textStrokeWidth = 2); + } + } else { + if (textFillNotSet) { + out.textFill = itemStl.fill || txCfg.outsideFill || '#000'; + } + !out.textStroke && txCfg.outsideStroke && (out.textStroke = txCfg.outsideStroke); + } + out.text = txStl.text; + out.rich = txStl.rich; + each(txStl.rich, function (richItem) { + convertToEC4RichItem(richItem, richItem); + }); + return out; + } + function convertToEC4RichItem(out, richItem) { + if (!richItem) { + return; + } + hasOwn(richItem, 'fill') && (out.textFill = richItem.fill); + hasOwn(richItem, 'stroke') && (out.textStroke = richItem.fill); + hasOwn(richItem, 'lineWidth') && (out.textStrokeWidth = richItem.lineWidth); + hasOwn(richItem, 'font') && (out.font = richItem.font); + hasOwn(richItem, 'fontStyle') && (out.fontStyle = richItem.fontStyle); + hasOwn(richItem, 'fontWeight') && (out.fontWeight = richItem.fontWeight); + hasOwn(richItem, 'fontSize') && (out.fontSize = richItem.fontSize); + hasOwn(richItem, 'fontFamily') && (out.fontFamily = richItem.fontFamily); + hasOwn(richItem, 'align') && (out.textAlign = richItem.align); + hasOwn(richItem, 'verticalAlign') && (out.textVerticalAlign = richItem.verticalAlign); + hasOwn(richItem, 'lineHeight') && (out.textLineHeight = richItem.lineHeight); + hasOwn(richItem, 'width') && (out.textWidth = richItem.width); + hasOwn(richItem, 'height') && (out.textHeight = richItem.height); + hasOwn(richItem, 'backgroundColor') && (out.textBackgroundColor = richItem.backgroundColor); + hasOwn(richItem, 'padding') && (out.textPadding = richItem.padding); + hasOwn(richItem, 'borderColor') && (out.textBorderColor = richItem.borderColor); + hasOwn(richItem, 'borderWidth') && (out.textBorderWidth = richItem.borderWidth); + hasOwn(richItem, 'borderRadius') && (out.textBorderRadius = richItem.borderRadius); + hasOwn(richItem, 'shadowColor') && (out.textBoxShadowColor = richItem.shadowColor); + hasOwn(richItem, 'shadowBlur') && (out.textBoxShadowBlur = richItem.shadowBlur); + hasOwn(richItem, 'shadowOffsetX') && (out.textBoxShadowOffsetX = richItem.shadowOffsetX); + hasOwn(richItem, 'shadowOffsetY') && (out.textBoxShadowOffsetY = richItem.shadowOffsetY); + hasOwn(richItem, 'textShadowColor') && (out.textShadowColor = richItem.textShadowColor); + hasOwn(richItem, 'textShadowBlur') && (out.textShadowBlur = richItem.textShadowBlur); + hasOwn(richItem, 'textShadowOffsetX') && (out.textShadowOffsetX = richItem.textShadowOffsetX); + hasOwn(richItem, 'textShadowOffsetY') && (out.textShadowOffsetY = richItem.textShadowOffsetY); + } + function warnDeprecated(deprecated, insteadApproach) { + if ("development" !== 'production') { + var key = deprecated + '^_^' + insteadApproach; + if (!deprecatedLogs[key]) { + console.warn("[ECharts] DEPRECATED: \"" + deprecated + "\" has been deprecated. " + insteadApproach); + deprecatedLogs[key] = true; + } + } + } + + var LEGACY_TRANSFORM_PROPS_MAP = { + position: ['x', 'y'], + scale: ['scaleX', 'scaleY'], + origin: ['originX', 'originY'] + }; + var LEGACY_TRANSFORM_PROPS = keys(LEGACY_TRANSFORM_PROPS_MAP); + var TRANSFORM_PROPS_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) { + obj[key] = 1; + return obj; + }, {}); + var transformPropNamesStr = TRANSFORMABLE_PROPS.join(', '); + // '' means root + var ELEMENT_ANIMATABLE_PROPS = ['', 'style', 'shape', 'extra']; + var transitionInnerStore = makeInner(); + function getElementAnimationConfig(animationType, el, elOption, parentModel, dataIndex) { + var animationProp = animationType + "Animation"; + var config = getAnimationConfig(animationType, parentModel, dataIndex) || {}; + var userDuring = transitionInnerStore(el).userDuring; + // Only set when duration is > 0 and it's need to be animated. + if (config.duration > 0) { + // For simplicity, if during not specified, the previous during will not work any more. + config.during = userDuring ? bind(duringCall, { + el: el, + userDuring: userDuring + }) : null; + config.setToFinal = true; + config.scope = animationType; + } + extend(config, elOption[animationProp]); + return config; + } + function applyUpdateTransition(el, elOption, animatableModel, opts) { + opts = opts || {}; + var dataIndex = opts.dataIndex, + isInit = opts.isInit, + clearStyle = opts.clearStyle; + var hasAnimation = animatableModel.isAnimationEnabled(); + // Save the meta info for further morphing. Like apply on the sub morphing elements. + var store = transitionInnerStore(el); + var styleOpt = elOption.style; + store.userDuring = elOption.during; + var transFromProps = {}; + var propsToSet = {}; + prepareTransformAllPropsFinal(el, elOption, propsToSet); + prepareShapeOrExtraAllPropsFinal('shape', elOption, propsToSet); + prepareShapeOrExtraAllPropsFinal('extra', elOption, propsToSet); + if (!isInit && hasAnimation) { + prepareTransformTransitionFrom(el, elOption, transFromProps); + prepareShapeOrExtraTransitionFrom('shape', el, elOption, transFromProps); + prepareShapeOrExtraTransitionFrom('extra', el, elOption, transFromProps); + prepareStyleTransitionFrom(el, elOption, styleOpt, transFromProps); + } + propsToSet.style = styleOpt; + applyPropsDirectly(el, propsToSet, clearStyle); + applyMiscProps(el, elOption); + if (hasAnimation) { + if (isInit) { + var enterFromProps_1 = {}; + each(ELEMENT_ANIMATABLE_PROPS, function (propName) { + var prop = propName ? elOption[propName] : elOption; + if (prop && prop.enterFrom) { + if (propName) { + enterFromProps_1[propName] = enterFromProps_1[propName] || {}; + } + extend(propName ? enterFromProps_1[propName] : enterFromProps_1, prop.enterFrom); + } + }); + var config = getElementAnimationConfig('enter', el, elOption, animatableModel, dataIndex); + if (config.duration > 0) { + el.animateFrom(enterFromProps_1, config); + } + } else { + applyPropsTransition(el, elOption, dataIndex || 0, animatableModel, transFromProps); + } + } + // Store leave to be used in leave transition. + updateLeaveTo(el, elOption); + styleOpt ? el.dirty() : el.markRedraw(); + } + function updateLeaveTo(el, elOption) { + // Try merge to previous set leaveTo + var leaveToProps = transitionInnerStore(el).leaveToProps; + for (var i = 0; i < ELEMENT_ANIMATABLE_PROPS.length; i++) { + var propName = ELEMENT_ANIMATABLE_PROPS[i]; + var prop = propName ? elOption[propName] : elOption; + if (prop && prop.leaveTo) { + if (!leaveToProps) { + leaveToProps = transitionInnerStore(el).leaveToProps = {}; + } + if (propName) { + leaveToProps[propName] = leaveToProps[propName] || {}; + } + extend(propName ? leaveToProps[propName] : leaveToProps, prop.leaveTo); + } + } + } + function applyLeaveTransition(el, elOption, animatableModel, onRemove) { + if (el) { + var parent_1 = el.parent; + var leaveToProps = transitionInnerStore(el).leaveToProps; + if (leaveToProps) { + // TODO TODO use leave after leaveAnimation in series is introduced + // TODO Data index? + var config = getElementAnimationConfig('update', el, elOption, animatableModel, 0); + config.done = function () { + parent_1.remove(el); + onRemove && onRemove(); + }; + el.animateTo(leaveToProps, config); + } else { + parent_1.remove(el); + onRemove && onRemove(); + } + } + } + function isTransitionAll(transition) { + return transition === 'all'; + } + function applyPropsDirectly(el, + // Can be null/undefined + allPropsFinal, clearStyle) { + var styleOpt = allPropsFinal.style; + if (!el.isGroup && styleOpt) { + if (clearStyle) { + el.useStyle({}); + // When style object changed, how to trade the existing animation? + // It is probably complicated and not needed to cover all the cases. + // But still need consider the case: + // (1) When using init animation on `style.opacity`, and before the animation + // ended users triggers an update by mousewhel. At that time the init + // animation should better be continued rather than terminated. + // So after `useStyle` called, we should change the animation target manually + // to continue the effect of the init animation. + // (2) PENDING: If the previous animation targeted at a `val1`, and currently we need + // to update the value to `val2` and no animation declared, should be terminate + // the previous animation or just modify the target of the animation? + // Therotically That will happen not only on `style` but also on `shape` and + // `transfrom` props. But we haven't handle this case at present yet. + // (3) PENDING: Is it proper to visit `animators` and `targetName`? + var animators = el.animators; + for (var i = 0; i < animators.length; i++) { + var animator = animators[i]; + // targetName is the "topKey". + if (animator.targetName === 'style') { + animator.changeTarget(el.style); + } + } + } + el.setStyle(styleOpt); + } + if (allPropsFinal) { + // Not set style here. + allPropsFinal.style = null; + // Set el to the final state firstly. + allPropsFinal && el.attr(allPropsFinal); + allPropsFinal.style = styleOpt; + } + } + function applyPropsTransition(el, elOption, dataIndex, model, + // Can be null/undefined + transFromProps) { + if (transFromProps) { + var config = getElementAnimationConfig('update', el, elOption, model, dataIndex); + if (config.duration > 0) { + el.animateFrom(transFromProps, config); + } + } + } + function applyMiscProps(el, elOption) { + // Merge by default. + hasOwn(elOption, 'silent') && (el.silent = elOption.silent); + hasOwn(elOption, 'ignore') && (el.ignore = elOption.ignore); + if (el instanceof Displayable) { + hasOwn(elOption, 'invisible') && (el.invisible = elOption.invisible); + } + if (el instanceof Path) { + hasOwn(elOption, 'autoBatch') && (el.autoBatch = elOption.autoBatch); + } + } + // Use it to avoid it be exposed to user. + var tmpDuringScope = {}; + var transitionDuringAPI = { + // Usually other props do not need to be changed in animation during. + setTransform: function (key, val) { + if ("development" !== 'production') { + assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `setTransform`.'); + } + tmpDuringScope.el[key] = val; + return this; + }, + getTransform: function (key) { + if ("development" !== 'production') { + assert(hasOwn(TRANSFORM_PROPS_MAP, key), 'Only ' + transformPropNamesStr + ' available in `getTransform`.'); + } + return tmpDuringScope.el[key]; + }, + setShape: function (key, val) { + if ("development" !== 'production') { + assertNotReserved(key); + } + var el = tmpDuringScope.el; + var shape = el.shape || (el.shape = {}); + shape[key] = val; + el.dirtyShape && el.dirtyShape(); + return this; + }, + getShape: function (key) { + if ("development" !== 'production') { + assertNotReserved(key); + } + var shape = tmpDuringScope.el.shape; + if (shape) { + return shape[key]; + } + }, + setStyle: function (key, val) { + if ("development" !== 'production') { + assertNotReserved(key); + } + var el = tmpDuringScope.el; + var style = el.style; + if (style) { + if ("development" !== 'production') { + if (eqNaN(val)) { + warn('style.' + key + ' must not be assigned with NaN.'); + } + } + style[key] = val; + el.dirtyStyle && el.dirtyStyle(); + } + return this; + }, + getStyle: function (key) { + if ("development" !== 'production') { + assertNotReserved(key); + } + var style = tmpDuringScope.el.style; + if (style) { + return style[key]; + } + }, + setExtra: function (key, val) { + if ("development" !== 'production') { + assertNotReserved(key); + } + var extra = tmpDuringScope.el.extra || (tmpDuringScope.el.extra = {}); + extra[key] = val; + return this; + }, + getExtra: function (key) { + if ("development" !== 'production') { + assertNotReserved(key); + } + var extra = tmpDuringScope.el.extra; + if (extra) { + return extra[key]; + } + } + }; + function assertNotReserved(key) { + if ("development" !== 'production') { + if (key === 'transition' || key === 'enterFrom' || key === 'leaveTo') { + throw new Error('key must not be "' + key + '"'); + } + } + } + function duringCall() { + // Do not provide "percent" until some requirements come. + // Because consider thies case: + // enterFrom: {x: 100, y: 30}, transition: 'x'. + // And enter duration is different from update duration. + // Thus it might be confused about the meaning of "percent" in during callback. + var scope = this; + var el = scope.el; + if (!el) { + return; + } + // If el is remove from zr by reason like legend, during still need to called, + // because el will be added back to zr and the prop value should not be incorrect. + var latestUserDuring = transitionInnerStore(el).userDuring; + var scopeUserDuring = scope.userDuring; + // Ensured a during is only called once in each animation frame. + // If a during is called multiple times in one frame, maybe some users' calculation logic + // might be wrong (not sure whether this usage exists). + // The case of a during might be called twice can be: by default there is a animator for + // 'x', 'y' when init. Before the init animation finished, call `setOption` to start + // another animators for 'style'/'shape'/'extra'. + if (latestUserDuring !== scopeUserDuring) { + // release + scope.el = scope.userDuring = null; + return; + } + tmpDuringScope.el = el; + // Give no `this` to user in "during" calling. + scopeUserDuring(transitionDuringAPI); + // FIXME: if in future meet the case that some prop will be both modified in `during` and `state`, + // consider the issue that the prop might be incorrect when return to "normal" state. + } + + function prepareShapeOrExtraTransitionFrom(mainAttr, fromEl, elOption, transFromProps) { + var attrOpt = elOption[mainAttr]; + if (!attrOpt) { + return; + } + var elPropsInAttr = fromEl[mainAttr]; + var transFromPropsInAttr; + if (elPropsInAttr) { + var transition = elOption.transition; + var attrTransition = attrOpt.transition; + if (attrTransition) { + !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {}); + if (isTransitionAll(attrTransition)) { + extend(transFromPropsInAttr, elPropsInAttr); + } else { + var transitionKeys = normalizeToArray(attrTransition); + for (var i = 0; i < transitionKeys.length; i++) { + var key = transitionKeys[i]; + var elVal = elPropsInAttr[key]; + transFromPropsInAttr[key] = elVal; + } + } + } else if (isTransitionAll(transition) || indexOf(transition, mainAttr) >= 0) { + !transFromPropsInAttr && (transFromPropsInAttr = transFromProps[mainAttr] = {}); + var elPropsInAttrKeys = keys(elPropsInAttr); + for (var i = 0; i < elPropsInAttrKeys.length; i++) { + var key = elPropsInAttrKeys[i]; + var elVal = elPropsInAttr[key]; + if (isNonStyleTransitionEnabled(attrOpt[key], elVal)) { + transFromPropsInAttr[key] = elVal; + } + } + } + } + } + function prepareShapeOrExtraAllPropsFinal(mainAttr, elOption, allProps) { + var attrOpt = elOption[mainAttr]; + if (!attrOpt) { + return; + } + var allPropsInAttr = allProps[mainAttr] = {}; + var keysInAttr = keys(attrOpt); + for (var i = 0; i < keysInAttr.length; i++) { + var key = keysInAttr[i]; + // To avoid share one object with different element, and + // to avoid user modify the object inexpectedly, have to clone. + allPropsInAttr[key] = cloneValue(attrOpt[key]); + } + } + function prepareTransformTransitionFrom(el, elOption, transFromProps) { + var transition = elOption.transition; + var transitionKeys = isTransitionAll(transition) ? TRANSFORMABLE_PROPS : normalizeToArray(transition || []); + for (var i = 0; i < transitionKeys.length; i++) { + var key = transitionKeys[i]; + if (key === 'style' || key === 'shape' || key === 'extra') { + continue; + } + var elVal = el[key]; + if ("development" !== 'production') { + checkTransformPropRefer(key, 'el.transition'); + } + // Do not clone, animator will perform that clone. + transFromProps[key] = elVal; + } + } + function prepareTransformAllPropsFinal(el, elOption, allProps) { + for (var i = 0; i < LEGACY_TRANSFORM_PROPS.length; i++) { + var legacyName = LEGACY_TRANSFORM_PROPS[i]; + var xyName = LEGACY_TRANSFORM_PROPS_MAP[legacyName]; + var legacyArr = elOption[legacyName]; + if (legacyArr) { + allProps[xyName[0]] = legacyArr[0]; + allProps[xyName[1]] = legacyArr[1]; + } + } + for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) { + var key = TRANSFORMABLE_PROPS[i]; + if (elOption[key] != null) { + allProps[key] = elOption[key]; + } + } + } + function prepareStyleTransitionFrom(fromEl, elOption, styleOpt, transFromProps) { + if (!styleOpt) { + return; + } + var fromElStyle = fromEl.style; + var transFromStyleProps; + if (fromElStyle) { + var styleTransition = styleOpt.transition; + var elTransition = elOption.transition; + if (styleTransition && !isTransitionAll(styleTransition)) { + var transitionKeys = normalizeToArray(styleTransition); + !transFromStyleProps && (transFromStyleProps = transFromProps.style = {}); + for (var i = 0; i < transitionKeys.length; i++) { + var key = transitionKeys[i]; + var elVal = fromElStyle[key]; + // Do not clone, see `checkNonStyleTansitionRefer`. + transFromStyleProps[key] = elVal; + } + } else if (fromEl.getAnimationStyleProps && (isTransitionAll(elTransition) || isTransitionAll(styleTransition) || indexOf(elTransition, 'style') >= 0)) { + var animationProps = fromEl.getAnimationStyleProps(); + var animationStyleProps = animationProps ? animationProps.style : null; + if (animationStyleProps) { + !transFromStyleProps && (transFromStyleProps = transFromProps.style = {}); + var styleKeys = keys(styleOpt); + for (var i = 0; i < styleKeys.length; i++) { + var key = styleKeys[i]; + if (animationStyleProps[key]) { + var elVal = fromElStyle[key]; + transFromStyleProps[key] = elVal; + } + } + } + } + } + } + function isNonStyleTransitionEnabled(optVal, elVal) { + // The same as `checkNonStyleTansitionRefer`. + return !isArrayLike(optVal) ? optVal != null && isFinite(optVal) : optVal !== elVal; + } + var checkTransformPropRefer; + if ("development" !== 'production') { + checkTransformPropRefer = function (key, usedIn) { + if (!hasOwn(TRANSFORM_PROPS_MAP, key)) { + warn('Prop `' + key + '` is not a permitted in `' + usedIn + '`. ' + 'Only `' + keys(TRANSFORM_PROPS_MAP).join('`, `') + '` are permitted.'); + } + }; + } + + var getStateToRestore = makeInner(); + var KEYFRAME_EXCLUDE_KEYS = ['percent', 'easing', 'shape', 'style', 'extra']; + /** + * Stop previous keyframe animation and restore the attributes. + * Avoid new keyframe animation starts with wrong internal state when the percent: 0 is not set. + */ + function stopPreviousKeyframeAnimationAndRestore(el) { + // Stop previous keyframe animation. + el.stopAnimation('keyframe'); + // Restore + el.attr(getStateToRestore(el)); + } + function applyKeyframeAnimation(el, animationOpts, animatableModel) { + if (!animatableModel.isAnimationEnabled() || !animationOpts) { + return; + } + if (isArray(animationOpts)) { + each(animationOpts, function (singleAnimationOpts) { + applyKeyframeAnimation(el, singleAnimationOpts, animatableModel); + }); + return; + } + var keyframes = animationOpts.keyframes; + var duration = animationOpts.duration; + if (animatableModel && duration == null) { + // Default to use duration of config. + // NOTE: animation config from payload will be ignored because they are mainly for transitions. + var config = getAnimationConfig('enter', animatableModel, 0); + duration = config && config.duration; + } + if (!keyframes || !duration) { + return; + } + var stateToRestore = getStateToRestore(el); + each(ELEMENT_ANIMATABLE_PROPS, function (targetPropName) { + if (targetPropName && !el[targetPropName]) { + return; + } + var animator; + var endFrameIsSet = false; + // Sort keyframes by percent. + keyframes.sort(function (a, b) { + return a.percent - b.percent; + }); + each(keyframes, function (kf) { + // Stop current animation. + var animators = el.animators; + var kfValues = targetPropName ? kf[targetPropName] : kf; + if ("development" !== 'production') { + if (kf.percent >= 1) { + endFrameIsSet = true; + } + } + if (!kfValues) { + return; + } + var propKeys = keys(kfValues); + if (!targetPropName) { + // PENDING performance? + propKeys = filter(propKeys, function (key) { + return indexOf(KEYFRAME_EXCLUDE_KEYS, key) < 0; + }); + } + if (!propKeys.length) { + return; + } + if (!animator) { + animator = el.animate(targetPropName, animationOpts.loop, true); + animator.scope = 'keyframe'; + } + for (var i = 0; i < animators.length; i++) { + // Stop all other animation that is not keyframe. + if (animators[i] !== animator && animators[i].targetName === animator.targetName) { + animators[i].stopTracks(propKeys); + } + } + targetPropName && (stateToRestore[targetPropName] = stateToRestore[targetPropName] || {}); + var savedTarget = targetPropName ? stateToRestore[targetPropName] : stateToRestore; + each(propKeys, function (key) { + // Save original value. + savedTarget[key] = ((targetPropName ? el[targetPropName] : el) || {})[key]; + }); + animator.whenWithKeys(duration * kf.percent, kfValues, propKeys, kf.easing); + }); + if (!animator) { + return; + } + if ("development" !== 'production') { + if (!endFrameIsSet) { + warn('End frame with percent: 1 is missing in the keyframeAnimation.', true); + } + } + animator.delay(animationOpts.delay || 0).duration(duration).start(animationOpts.easing); + }); + } + + var EMPHASIS = 'emphasis'; + var NORMAL = 'normal'; + var BLUR = 'blur'; + var SELECT = 'select'; + var STATES = [NORMAL, EMPHASIS, BLUR, SELECT]; + var PATH_ITEM_STYLE = { + normal: ['itemStyle'], + emphasis: [EMPHASIS, 'itemStyle'], + blur: [BLUR, 'itemStyle'], + select: [SELECT, 'itemStyle'] + }; + var PATH_LABEL = { + normal: ['label'], + emphasis: [EMPHASIS, 'label'], + blur: [BLUR, 'label'], + select: [SELECT, 'label'] + }; + var DEFAULT_TRANSITION = ['x', 'y']; + // Use prefix to avoid index to be the same as el.name, + // which will cause weird update animation. + var GROUP_DIFF_PREFIX = 'e\0\0'; + var attachedTxInfoTmp = { + normal: {}, + emphasis: {}, + blur: {}, + select: {} + }; + /** + * To reduce total package size of each coordinate systems, the modules `prepareCustom` + * of each coordinate systems are not required by each coordinate systems directly, but + * required by the module `custom`. + * + * prepareInfoForCustomSeries {Function}: optional + * @return {Object} {coordSys: {...}, api: { + * coord: function (data, clamp) {}, // return point in global. + * size: function (dataSize, dataItem) {} // return size of each axis in coordSys. + * }} + */ + var prepareCustoms = { + cartesian2d: cartesianPrepareCustom, + geo: geoPrepareCustom, + single: singlePrepareCustom, + polar: polarPrepareCustom, + calendar: calendarPrepareCustom + }; + function isPath$1(el) { + return el instanceof Path; + } + function isDisplayable(el) { + return el instanceof Displayable; + } + function copyElement(sourceEl, targetEl) { + targetEl.copyTransform(sourceEl); + if (isDisplayable(targetEl) && isDisplayable(sourceEl)) { + targetEl.setStyle(sourceEl.style); + targetEl.z = sourceEl.z; + targetEl.z2 = sourceEl.z2; + targetEl.zlevel = sourceEl.zlevel; + targetEl.invisible = sourceEl.invisible; + targetEl.ignore = sourceEl.ignore; + if (isPath$1(targetEl) && isPath$1(sourceEl)) { + targetEl.setShape(sourceEl.shape); + } + } + } + var CustomChartView = /** @class */function (_super) { + __extends(CustomChartView, _super); + function CustomChartView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CustomChartView.type; + return _this; + } + CustomChartView.prototype.render = function (customSeries, ecModel, api, payload) { + // Clear previously rendered progressive elements. + this._progressiveEls = null; + var oldData = this._data; + var data = customSeries.getData(); + var group = this.group; + var renderItem = makeRenderItem(customSeries, data, ecModel, api); + if (!oldData) { + // Previous render is incremental render or first render. + // Needs remove the incremental rendered elements. + group.removeAll(); + } + data.diff(oldData).add(function (newIdx) { + createOrUpdateItem(api, null, newIdx, renderItem(newIdx, payload), customSeries, group, data); + }).remove(function (oldIdx) { + var el = oldData.getItemGraphicEl(oldIdx); + el && applyLeaveTransition(el, customInnerStore(el).option, customSeries); + }).update(function (newIdx, oldIdx) { + var oldEl = oldData.getItemGraphicEl(oldIdx); + createOrUpdateItem(api, oldEl, newIdx, renderItem(newIdx, payload), customSeries, group, data); + }).execute(); + // Do clipping + var clipPath = customSeries.get('clip', true) ? createClipPath(customSeries.coordinateSystem, false, customSeries) : null; + if (clipPath) { + group.setClipPath(clipPath); + } else { + group.removeClipPath(); + } + this._data = data; + }; + CustomChartView.prototype.incrementalPrepareRender = function (customSeries, ecModel, api) { + this.group.removeAll(); + this._data = null; + }; + CustomChartView.prototype.incrementalRender = function (params, customSeries, ecModel, api, payload) { + var data = customSeries.getData(); + var renderItem = makeRenderItem(customSeries, data, ecModel, api); + var progressiveEls = this._progressiveEls = []; + function setIncrementalAndHoverLayer(el) { + if (!el.isGroup) { + el.incremental = true; + el.ensureState('emphasis').hoverLayer = true; + } + } + for (var idx = params.start; idx < params.end; idx++) { + var el = createOrUpdateItem(null, null, idx, renderItem(idx, payload), customSeries, this.group, data); + if (el) { + el.traverse(setIncrementalAndHoverLayer); + progressiveEls.push(el); + } + } + }; + CustomChartView.prototype.eachRendered = function (cb) { + traverseElements(this._progressiveEls || this.group, cb); + }; + CustomChartView.prototype.filterForExposedEvent = function (eventType, query, targetEl, packedEvent) { + var elementName = query.element; + if (elementName == null || targetEl.name === elementName) { + return true; + } + // Enable to give a name on a group made by `renderItem`, and listen + // events that are triggered by its descendents. + while ((targetEl = targetEl.__hostTarget || targetEl.parent) && targetEl !== this.group) { + if (targetEl.name === elementName) { + return true; + } + } + return false; + }; + CustomChartView.type = 'custom'; + return CustomChartView; + }(ChartView); + function createEl(elOption) { + var graphicType = elOption.type; + var el; + // Those graphic elements are not shapes. They should not be + // overwritten by users, so do them first. + if (graphicType === 'path') { + var shape = elOption.shape; + // Using pathRect brings convenience to users sacle svg path. + var pathRect = shape.width != null && shape.height != null ? { + x: shape.x || 0, + y: shape.y || 0, + width: shape.width, + height: shape.height + } : null; + var pathData = getPathData(shape); + // Path is also used for icon, so layout 'center' by default. + el = makePath(pathData, null, pathRect, shape.layout || 'center'); + customInnerStore(el).customPathData = pathData; + } else if (graphicType === 'image') { + el = new ZRImage({}); + customInnerStore(el).customImagePath = elOption.style.image; + } else if (graphicType === 'text') { + el = new ZRText({}); + // customInnerStore(el).customText = (elOption.style as TextStyleProps).text; + } else if (graphicType === 'group') { + el = new Group(); + } else if (graphicType === 'compoundPath') { + throw new Error('"compoundPath" is not supported yet.'); + } else { + var Clz = getShapeClass(graphicType); + if (!Clz) { + var errMsg = ''; + if ("development" !== 'production') { + errMsg = 'graphic type "' + graphicType + '" can not be found.'; + } + throwError(errMsg); + } + el = new Clz(); + } + customInnerStore(el).customGraphicType = graphicType; + el.name = elOption.name; + // Compat ec4: the default z2 lift is 1. If changing the number, + // some cases probably be broken: hierarchy layout along z, like circle packing, + // where emphasis only intending to modify color/border rather than lift z2. + el.z2EmphasisLift = 1; + el.z2SelectLift = 1; + return el; + } + function updateElNormal( + // Can be null/undefined + api, el, dataIndex, elOption, attachedTxInfo, seriesModel, isInit) { + // Stop and restore before update any other attributes. + stopPreviousKeyframeAnimationAndRestore(el); + var txCfgOpt = attachedTxInfo && attachedTxInfo.normal.cfg; + if (txCfgOpt) { + // PENDING: whether use user object directly rather than clone? + // TODO:5.0 textConfig transition animation? + el.setTextConfig(txCfgOpt); + } + // Default transition ['x', 'y'] + if (elOption && elOption.transition == null) { + elOption.transition = DEFAULT_TRANSITION; + } + // Do some normalization on style. + var styleOpt = elOption && elOption.style; + if (styleOpt) { + if (el.type === 'text') { + var textOptionStyle = styleOpt; + // Compatible with ec4: if `textFill` or `textStroke` exists use them. + hasOwn(textOptionStyle, 'textFill') && (textOptionStyle.fill = textOptionStyle.textFill); + hasOwn(textOptionStyle, 'textStroke') && (textOptionStyle.stroke = textOptionStyle.textStroke); + } + var decalPattern = void 0; + var decalObj = isPath$1(el) ? styleOpt.decal : null; + if (api && decalObj) { + decalObj.dirty = true; + decalPattern = createOrUpdatePatternFromDecal(decalObj, api); + } + // Always overwrite in case user specify this prop. + styleOpt.__decalPattern = decalPattern; + } + if (isDisplayable(el)) { + if (styleOpt) { + var decalPattern = styleOpt.__decalPattern; + if (decalPattern) { + styleOpt.decal = decalPattern; + } + } + } + applyUpdateTransition(el, elOption, seriesModel, { + dataIndex: dataIndex, + isInit: isInit, + clearStyle: true + }); + applyKeyframeAnimation(el, elOption.keyframeAnimation, seriesModel); + } + function updateElOnState(state, el, elStateOpt, styleOpt, attachedTxInfo) { + var elDisplayable = el.isGroup ? null : el; + var txCfgOpt = attachedTxInfo && attachedTxInfo[state].cfg; + // PENDING:5.0 support customize scale change and transition animation? + if (elDisplayable) { + // By default support auto lift color when hover whether `emphasis` specified. + var stateObj = elDisplayable.ensureState(state); + if (styleOpt === false) { + var existingEmphasisState = elDisplayable.getState(state); + if (existingEmphasisState) { + existingEmphasisState.style = null; + } + } else { + // style is needed to enable default emphasis. + stateObj.style = styleOpt || null; + } + // If `elOption.styleEmphasis` or `elOption.emphasis.style` is `false`, + // remove hover style. + // If `elOption.textConfig` or `elOption.emphasis.textConfig` is null/undefined, it does not + // make sense. So for simplicity, we do not ditinguish `hasOwnProperty` and null/undefined. + if (txCfgOpt) { + stateObj.textConfig = txCfgOpt; + } + setDefaultStateProxy(elDisplayable); + } + } + function updateZ$1(el, elOption, seriesModel) { + // Group not support textContent and not support z yet. + if (el.isGroup) { + return; + } + var elDisplayable = el; + var currentZ = seriesModel.currentZ; + var currentZLevel = seriesModel.currentZLevel; + // Always erase. + elDisplayable.z = currentZ; + elDisplayable.zlevel = currentZLevel; + // z2 must not be null/undefined, otherwise sort error may occur. + var optZ2 = elOption.z2; + optZ2 != null && (elDisplayable.z2 = optZ2 || 0); + for (var i = 0; i < STATES.length; i++) { + updateZForEachState(elDisplayable, elOption, STATES[i]); + } + } + function updateZForEachState(elDisplayable, elOption, state) { + var isNormal = state === NORMAL; + var elStateOpt = isNormal ? elOption : retrieveStateOption(elOption, state); + var optZ2 = elStateOpt ? elStateOpt.z2 : null; + var stateObj; + if (optZ2 != null) { + // Do not `ensureState` until required. + stateObj = isNormal ? elDisplayable : elDisplayable.ensureState(state); + stateObj.z2 = optZ2 || 0; + } + } + function makeRenderItem(customSeries, data, ecModel, api) { + var renderItem = customSeries.get('renderItem'); + var coordSys = customSeries.coordinateSystem; + var prepareResult = {}; + if (coordSys) { + if ("development" !== 'production') { + assert(renderItem, 'series.render is required.'); + assert(coordSys.prepareCustoms || prepareCustoms[coordSys.type], 'This coordSys does not support custom series.'); + } + // `coordSys.prepareCustoms` is used for external coord sys like bmap. + prepareResult = coordSys.prepareCustoms ? coordSys.prepareCustoms(coordSys) : prepareCustoms[coordSys.type](coordSys); + } + var userAPI = defaults({ + getWidth: api.getWidth, + getHeight: api.getHeight, + getZr: api.getZr, + getDevicePixelRatio: api.getDevicePixelRatio, + value: value, + style: style, + ordinalRawValue: ordinalRawValue, + styleEmphasis: styleEmphasis, + visual: visual, + barLayout: barLayout, + currentSeriesIndices: currentSeriesIndices, + font: font + }, prepareResult.api || {}); + var userParams = { + // The life cycle of context: current round of rendering. + // The global life cycle is probably not necessary, because + // user can store global status by themselves. + context: {}, + seriesId: customSeries.id, + seriesName: customSeries.name, + seriesIndex: customSeries.seriesIndex, + coordSys: prepareResult.coordSys, + dataInsideLength: data.count(), + encode: wrapEncodeDef(customSeries.getData()) + }; + // If someday intending to refactor them to a class, should consider do not + // break change: currently these attribute member are encapsulated in a closure + // so that do not need to force user to call these method with a scope. + // Do not support call `api` asynchronously without dataIndexInside input. + var currDataIndexInside; + var currItemModel; + var currItemStyleModels = {}; + var currLabelModels = {}; + var seriesItemStyleModels = {}; + var seriesLabelModels = {}; + for (var i = 0; i < STATES.length; i++) { + var stateName = STATES[i]; + seriesItemStyleModels[stateName] = customSeries.getModel(PATH_ITEM_STYLE[stateName]); + seriesLabelModels[stateName] = customSeries.getModel(PATH_LABEL[stateName]); + } + function getItemModel(dataIndexInside) { + return dataIndexInside === currDataIndexInside ? currItemModel || (currItemModel = data.getItemModel(dataIndexInside)) : data.getItemModel(dataIndexInside); + } + function getItemStyleModel(dataIndexInside, state) { + return !data.hasItemOption ? seriesItemStyleModels[state] : dataIndexInside === currDataIndexInside ? currItemStyleModels[state] || (currItemStyleModels[state] = getItemModel(dataIndexInside).getModel(PATH_ITEM_STYLE[state])) : getItemModel(dataIndexInside).getModel(PATH_ITEM_STYLE[state]); + } + function getLabelModel(dataIndexInside, state) { + return !data.hasItemOption ? seriesLabelModels[state] : dataIndexInside === currDataIndexInside ? currLabelModels[state] || (currLabelModels[state] = getItemModel(dataIndexInside).getModel(PATH_LABEL[state])) : getItemModel(dataIndexInside).getModel(PATH_LABEL[state]); + } + return function (dataIndexInside, payload) { + currDataIndexInside = dataIndexInside; + currItemModel = null; + currItemStyleModels = {}; + currLabelModels = {}; + return renderItem && renderItem(defaults({ + dataIndexInside: dataIndexInside, + dataIndex: data.getRawIndex(dataIndexInside), + // Can be used for optimization when zoom or roam. + actionType: payload ? payload.type : null + }, userParams), userAPI); + }; + /** + * @public + * @param dim by default 0. + * @param dataIndexInside by default `currDataIndexInside`. + */ + function value(dim, dataIndexInside) { + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + return data.getStore().get(data.getDimensionIndex(dim || 0), dataIndexInside); + } + /** + * @public + * @param dim by default 0. + * @param dataIndexInside by default `currDataIndexInside`. + */ + function ordinalRawValue(dim, dataIndexInside) { + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + dim = dim || 0; + var dimInfo = data.getDimensionInfo(dim); + if (!dimInfo) { + var dimIndex = data.getDimensionIndex(dim); + return dimIndex >= 0 ? data.getStore().get(dimIndex, dataIndexInside) : undefined; + } + var val = data.get(dimInfo.name, dataIndexInside); + var ordinalMeta = dimInfo && dimInfo.ordinalMeta; + return ordinalMeta ? ordinalMeta.categories[val] : val; + } + /** + * @deprecated The original intention of `api.style` is enable to set itemStyle + * like other series. But it is not necessary and not easy to give a strict definition + * of what it returns. And since echarts5 it needs to be make compat work. So + * deprecates it since echarts5. + * + * By default, `visual` is applied to style (to support visualMap). + * `visual.color` is applied at `fill`. If user want apply visual.color on `stroke`, + * it can be implemented as: + * `api.style({stroke: api.visual('color'), fill: null})`; + * + * [Compat]: since ec5, RectText has been separated from its hosts el. + * so `api.style()` will only return the style from `itemStyle` but not handle `label` + * any more. But `series.label` config is never published in doc. + * We still compat it in `api.style()`. But not encourage to use it and will still not + * to pulish it to doc. + * @public + * @param dataIndexInside by default `currDataIndexInside`. + */ + function style(userProps, dataIndexInside) { + if ("development" !== 'production') { + warnDeprecated('api.style', 'Please write literal style directly instead.'); + } + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + var style = data.getItemVisual(dataIndexInside, 'style'); + var visualColor = style && style.fill; + var opacity = style && style.opacity; + var itemStyle = getItemStyleModel(dataIndexInside, NORMAL).getItemStyle(); + visualColor != null && (itemStyle.fill = visualColor); + opacity != null && (itemStyle.opacity = opacity); + var opt = { + inheritColor: isString(visualColor) ? visualColor : '#000' + }; + var labelModel = getLabelModel(dataIndexInside, NORMAL); + // Now that the feature of "auto adjust text fill/stroke" has been migrated to zrender + // since ec5, we should set `isAttached` as `false` here and make compat in + // `convertToEC4StyleForCustomSerise`. + var textStyle = createTextStyle(labelModel, null, opt, false, true); + textStyle.text = labelModel.getShallow('show') ? retrieve2(customSeries.getFormattedLabel(dataIndexInside, NORMAL), getDefaultLabel(data, dataIndexInside)) : null; + var textConfig = createTextConfig(labelModel, opt, false); + preFetchFromExtra(userProps, itemStyle); + itemStyle = convertToEC4StyleForCustomSerise(itemStyle, textStyle, textConfig); + userProps && applyUserPropsAfter(itemStyle, userProps); + itemStyle.legacy = true; + return itemStyle; + } + /** + * @deprecated The reason see `api.style()` + * @public + * @param dataIndexInside by default `currDataIndexInside`. + */ + function styleEmphasis(userProps, dataIndexInside) { + if ("development" !== 'production') { + warnDeprecated('api.styleEmphasis', 'Please write literal style directly instead.'); + } + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + var itemStyle = getItemStyleModel(dataIndexInside, EMPHASIS).getItemStyle(); + var labelModel = getLabelModel(dataIndexInside, EMPHASIS); + var textStyle = createTextStyle(labelModel, null, null, true, true); + textStyle.text = labelModel.getShallow('show') ? retrieve3(customSeries.getFormattedLabel(dataIndexInside, EMPHASIS), customSeries.getFormattedLabel(dataIndexInside, NORMAL), getDefaultLabel(data, dataIndexInside)) : null; + var textConfig = createTextConfig(labelModel, null, true); + preFetchFromExtra(userProps, itemStyle); + itemStyle = convertToEC4StyleForCustomSerise(itemStyle, textStyle, textConfig); + userProps && applyUserPropsAfter(itemStyle, userProps); + itemStyle.legacy = true; + return itemStyle; + } + function applyUserPropsAfter(itemStyle, extra) { + for (var key in extra) { + if (hasOwn(extra, key)) { + itemStyle[key] = extra[key]; + } + } + } + function preFetchFromExtra(extra, itemStyle) { + // A trick to retrieve those props firstly, which are used to + // apply auto inside fill/stroke in `convertToEC4StyleForCustomSerise`. + // (It's not reasonable but only for a degree of compat) + if (extra) { + extra.textFill && (itemStyle.textFill = extra.textFill); + extra.textPosition && (itemStyle.textPosition = extra.textPosition); + } + } + /** + * @public + * @param dataIndexInside by default `currDataIndexInside`. + */ + function visual(visualType, dataIndexInside) { + dataIndexInside == null && (dataIndexInside = currDataIndexInside); + if (hasOwn(STYLE_VISUAL_TYPE, visualType)) { + var style_1 = data.getItemVisual(dataIndexInside, 'style'); + return style_1 ? style_1[STYLE_VISUAL_TYPE[visualType]] : null; + } + // Only support these visuals. Other visual might be inner tricky + // for performance (like `style`), do not expose to users. + if (hasOwn(NON_STYLE_VISUAL_PROPS, visualType)) { + return data.getItemVisual(dataIndexInside, visualType); + } + } + /** + * @public + * @return If not support, return undefined. + */ + function barLayout(opt) { + if (coordSys.type === 'cartesian2d') { + var baseAxis = coordSys.getBaseAxis(); + return getLayoutOnAxis(defaults({ + axis: baseAxis + }, opt)); + } + } + /** + * @public + */ + function currentSeriesIndices() { + return ecModel.getCurrentSeriesIndices(); + } + /** + * @public + * @return font string + */ + function font(opt) { + return getFont(opt, ecModel); + } + } + function wrapEncodeDef(data) { + var encodeDef = {}; + each(data.dimensions, function (dimName) { + var dimInfo = data.getDimensionInfo(dimName); + if (!dimInfo.isExtraCoord) { + var coordDim = dimInfo.coordDim; + var dataDims = encodeDef[coordDim] = encodeDef[coordDim] || []; + dataDims[dimInfo.coordDimIndex] = data.getDimensionIndex(dimName); + } + }); + return encodeDef; + } + function createOrUpdateItem(api, existsEl, dataIndex, elOption, seriesModel, group, data) { + // [Rule] + // If `renderItem` returns `null`/`undefined`/`false`, remove the previous el if existing. + // (It seems that violate the "merge" principle, but most of users probably intuitively + // regard "return;" as "show nothing element whatever", so make a exception to meet the + // most cases.) + // The rule or "merge" see [STRATEGY_MERGE]. + // If `elOption` is `null`/`undefined`/`false` (when `renderItem` returns nothing). + if (!elOption) { + group.remove(existsEl); + return; + } + var el = doCreateOrUpdateEl(api, existsEl, dataIndex, elOption, seriesModel, group); + el && data.setItemGraphicEl(dataIndex, el); + el && toggleHoverEmphasis(el, elOption.focus, elOption.blurScope, elOption.emphasisDisabled); + return el; + } + function doCreateOrUpdateEl(api, existsEl, dataIndex, elOption, seriesModel, group) { + if ("development" !== 'production') { + assert(elOption, 'should not have an null/undefined element setting'); + } + var toBeReplacedIdx = -1; + var oldEl = existsEl; + if (existsEl && doesElNeedRecreate(existsEl, elOption, seriesModel) + // || ( + // // PENDING: even in one-to-one mapping case, if el is marked as morph, + // // do not sure whether the el will be mapped to another el with different + // // hierarchy in Group tree. So always recreate el rather than reuse the el. + // morphHelper && morphHelper.isOneToOneFrom(el) + // ) + ) { + // Should keep at the original index, otherwise "merge by index" will be incorrect. + toBeReplacedIdx = indexOf(group.childrenRef(), existsEl); + existsEl = null; + } + var isInit = !existsEl; + var el = existsEl; + if (!el) { + el = createEl(elOption); + if (oldEl) { + copyElement(oldEl, el); + } + } else { + // FIMXE:NEXT unified clearState? + // If in some case the performance issue arised, consider + // do not clearState but update cached normal state directly. + el.clearStates(); + } + // Need to set morph: false explictly to disable automatically morphing. + if (elOption.morph === false) { + el.disableMorphing = true; + } else if (el.disableMorphing) { + el.disableMorphing = false; + } + attachedTxInfoTmp.normal.cfg = attachedTxInfoTmp.normal.conOpt = attachedTxInfoTmp.emphasis.cfg = attachedTxInfoTmp.emphasis.conOpt = attachedTxInfoTmp.blur.cfg = attachedTxInfoTmp.blur.conOpt = attachedTxInfoTmp.select.cfg = attachedTxInfoTmp.select.conOpt = null; + attachedTxInfoTmp.isLegacy = false; + doCreateOrUpdateAttachedTx(el, dataIndex, elOption, seriesModel, isInit, attachedTxInfoTmp); + doCreateOrUpdateClipPath(el, dataIndex, elOption, seriesModel, isInit); + updateElNormal(api, el, dataIndex, elOption, attachedTxInfoTmp, seriesModel, isInit); + // `elOption.info` enables user to mount some info on + // elements and use them in event handlers. + // Update them only when user specified, otherwise, remain. + hasOwn(elOption, 'info') && (customInnerStore(el).info = elOption.info); + for (var i = 0; i < STATES.length; i++) { + var stateName = STATES[i]; + if (stateName !== NORMAL) { + var otherStateOpt = retrieveStateOption(elOption, stateName); + var otherStyleOpt = retrieveStyleOptionOnState(elOption, otherStateOpt, stateName); + updateElOnState(stateName, el, otherStateOpt, otherStyleOpt, attachedTxInfoTmp); + } + } + updateZ$1(el, elOption, seriesModel); + if (elOption.type === 'group') { + mergeChildren(api, el, dataIndex, elOption, seriesModel); + } + if (toBeReplacedIdx >= 0) { + group.replaceAt(el, toBeReplacedIdx); + } else { + group.add(el); + } + return el; + } + // `el` must not be null/undefined. + function doesElNeedRecreate(el, elOption, seriesModel) { + var elInner = customInnerStore(el); + var elOptionType = elOption.type; + var elOptionShape = elOption.shape; + var elOptionStyle = elOption.style; + return ( + // Always create new if universal transition is enabled. + // Because we do transition after render. It needs to know what old element is. Replacement will loose it. + seriesModel.isUniversalTransitionEnabled() + // If `elOptionType` is `null`, follow the merge principle. + || elOptionType != null && elOptionType !== elInner.customGraphicType || elOptionType === 'path' && hasOwnPathData(elOptionShape) && getPathData(elOptionShape) !== elInner.customPathData || elOptionType === 'image' && hasOwn(elOptionStyle, 'image') && elOptionStyle.image !== elInner.customImagePath + // // FIXME test and remove this restriction? + // || (elOptionType === 'text' + // && hasOwn(elOptionStyle, 'text') + // && (elOptionStyle as TextStyleProps).text !== elInner.customText + // ) + ); + } + + function doCreateOrUpdateClipPath(el, dataIndex, elOption, seriesModel, isInit) { + // Based on the "merge" principle, if no clipPath provided, + // do nothing. The exists clip will be totally removed only if + // `el.clipPath` is `false`. Otherwise it will be merged/replaced. + var clipPathOpt = elOption.clipPath; + if (clipPathOpt === false) { + if (el && el.getClipPath()) { + el.removeClipPath(); + } + } else if (clipPathOpt) { + var clipPath = el.getClipPath(); + if (clipPath && doesElNeedRecreate(clipPath, clipPathOpt, seriesModel)) { + clipPath = null; + } + if (!clipPath) { + clipPath = createEl(clipPathOpt); + if ("development" !== 'production') { + assert(isPath$1(clipPath), 'Only any type of `path` can be used in `clipPath`, rather than ' + clipPath.type + '.'); + } + el.setClipPath(clipPath); + } + updateElNormal(null, clipPath, dataIndex, clipPathOpt, null, seriesModel, isInit); + } + // If not define `clipPath` in option, do nothing unnecessary. + } + + function doCreateOrUpdateAttachedTx(el, dataIndex, elOption, seriesModel, isInit, attachedTxInfo) { + // Group does not support textContent temporarily until necessary. + if (el.isGroup) { + return; + } + // Normal must be called before emphasis, for `isLegacy` detection. + processTxInfo(elOption, null, attachedTxInfo); + processTxInfo(elOption, EMPHASIS, attachedTxInfo); + // If `elOption.textConfig` or `elOption.textContent` is null/undefined, it does not make sense. + // So for simplicity, if "elOption hasOwnProperty of them but be null/undefined", we do not + // trade them as set to null to el. + // Especially: + // `elOption.textContent: false` means remove textContent. + // `elOption.textContent.emphasis.style: false` means remove the style from emphasis state. + var txConOptNormal = attachedTxInfo.normal.conOpt; + var txConOptEmphasis = attachedTxInfo.emphasis.conOpt; + var txConOptBlur = attachedTxInfo.blur.conOpt; + var txConOptSelect = attachedTxInfo.select.conOpt; + if (txConOptNormal != null || txConOptEmphasis != null || txConOptSelect != null || txConOptBlur != null) { + var textContent = el.getTextContent(); + if (txConOptNormal === false) { + textContent && el.removeTextContent(); + } else { + txConOptNormal = attachedTxInfo.normal.conOpt = txConOptNormal || { + type: 'text' + }; + if (!textContent) { + textContent = createEl(txConOptNormal); + el.setTextContent(textContent); + } else { + // If in some case the performance issue arised, consider + // do not clearState but update cached normal state directly. + textContent.clearStates(); + } + updateElNormal(null, textContent, dataIndex, txConOptNormal, null, seriesModel, isInit); + var txConStlOptNormal = txConOptNormal && txConOptNormal.style; + for (var i = 0; i < STATES.length; i++) { + var stateName = STATES[i]; + if (stateName !== NORMAL) { + var txConOptOtherState = attachedTxInfo[stateName].conOpt; + updateElOnState(stateName, textContent, txConOptOtherState, retrieveStyleOptionOnState(txConOptNormal, txConOptOtherState, stateName), null); + } + } + txConStlOptNormal ? textContent.dirty() : textContent.markRedraw(); + } + } + } + function processTxInfo(elOption, state, attachedTxInfo) { + var stateOpt = !state ? elOption : retrieveStateOption(elOption, state); + var styleOpt = !state ? elOption.style : retrieveStyleOptionOnState(elOption, stateOpt, EMPHASIS); + var elType = elOption.type; + var txCfg = stateOpt ? stateOpt.textConfig : null; + var txConOptNormal = elOption.textContent; + var txConOpt = !txConOptNormal ? null : !state ? txConOptNormal : retrieveStateOption(txConOptNormal, state); + if (styleOpt && ( + // Because emphasis style has little info to detect legacy, + // if normal is legacy, emphasis is trade as legacy. + attachedTxInfo.isLegacy || isEC4CompatibleStyle(styleOpt, elType, !!txCfg, !!txConOpt))) { + attachedTxInfo.isLegacy = true; + var convertResult = convertFromEC4CompatibleStyle(styleOpt, elType, !state); + // Explicitly specified `textConfig` and `textContent` has higher priority than + // the ones generated by legacy style. Otherwise if users use them and `api.style` + // at the same time, they not both work and hardly to known why. + if (!txCfg && convertResult.textConfig) { + txCfg = convertResult.textConfig; + } + if (!txConOpt && convertResult.textContent) { + txConOpt = convertResult.textContent; + } + } + if (!state && txConOpt) { + var txConOptNormal_1 = txConOpt; + // `textContent: {type: 'text'}`, the "type" is easy to be missing. So we tolerate it. + !txConOptNormal_1.type && (txConOptNormal_1.type = 'text'); + if ("development" !== 'production') { + // Do not tolerate incorrcet type for forward compat. + assert(txConOptNormal_1.type === 'text', 'textContent.type must be "text"'); + } + } + var info = !state ? attachedTxInfo.normal : attachedTxInfo[state]; + info.cfg = txCfg; + info.conOpt = txConOpt; + } + function retrieveStateOption(elOption, state) { + return !state ? elOption : elOption ? elOption[state] : null; + } + function retrieveStyleOptionOnState(stateOptionNormal, stateOption, state) { + var style = stateOption && stateOption.style; + if (style == null && state === EMPHASIS && stateOptionNormal) { + style = stateOptionNormal.styleEmphasis; + } + return style; + } + // Usage: + // (1) By default, `elOption.$mergeChildren` is `'byIndex'`, which indicates + // that the existing children will not be removed, and enables the feature + // that update some of the props of some of the children simply by construct + // the returned children of `renderItem` like: + // `var children = group.children = []; children[3] = {opacity: 0.5};` + // (2) If `elOption.$mergeChildren` is `'byName'`, add/update/remove children + // by child.name. But that might be lower performance. + // (3) If `elOption.$mergeChildren` is `false`, the existing children will be + // replaced totally. + // (4) If `!elOption.children`, following the "merge" principle, nothing will + // happen. + // (5) If `elOption.$mergeChildren` is not `false` neither `'byName'` and the + // `el` is a group, and if any of the new child is null, it means to remove + // the element at the same index, if exists. On the other hand, if the new + // child is and empty object `{}`, it means to keep the element not changed. + // + // For implementation simpleness, do not provide a direct way to remove single + // child (otherwise the total indices of the children array have to be modified). + // User can remove a single child by setting its `ignore` to `true`. + function mergeChildren(api, el, dataIndex, elOption, seriesModel) { + var newChildren = elOption.children; + var newLen = newChildren ? newChildren.length : 0; + var mergeChildren = elOption.$mergeChildren; + // `diffChildrenByName` has been deprecated. + var byName = mergeChildren === 'byName' || elOption.diffChildrenByName; + var notMerge = mergeChildren === false; + // For better performance on roam update, only enter if necessary. + if (!newLen && !byName && !notMerge) { + return; + } + if (byName) { + diffGroupChildren({ + api: api, + oldChildren: el.children() || [], + newChildren: newChildren || [], + dataIndex: dataIndex, + seriesModel: seriesModel, + group: el + }); + return; + } + notMerge && el.removeAll(); + // Mapping children of a group simply by index, which + // might be better performance. + var index = 0; + for (; index < newLen; index++) { + var newChild = newChildren[index]; + var oldChild = el.childAt(index); + if (newChild) { + if (newChild.ignore == null) { + // The old child is set to be ignored if null (see comments + // below). So we need to set ignore to be false back. + newChild.ignore = false; + } + doCreateOrUpdateEl(api, oldChild, dataIndex, newChild, seriesModel, el); + } else { + if ("development" !== 'production') { + assert(oldChild, 'renderItem should not return a group containing elements' + ' as null/undefined/{} if they do not exist before.'); + } + // If the new element option is null, it means to remove the old + // element. But we cannot really remove the element from the group + // directly, because the element order may not be stable when this + // element is added back. So we set the element to be ignored. + oldChild.ignore = true; + } + } + for (var i = el.childCount() - 1; i >= index; i--) { + var child = el.childAt(i); + removeChildFromGroup(el, child, seriesModel); + } + } + function removeChildFromGroup(group, child, seriesModel) { + // Do not support leave elements that are not mentioned in the latest + // `renderItem` return. Otherwise users may not have a clear and simple + // concept that how to control all of the elements. + child && applyLeaveTransition(child, customInnerStore(group).option, seriesModel); + } + function diffGroupChildren(context) { + new DataDiffer(context.oldChildren, context.newChildren, getKey, getKey, context).add(processAddUpdate).update(processAddUpdate).remove(processRemove).execute(); + } + function getKey(item, idx) { + var name = item && item.name; + return name != null ? name : GROUP_DIFF_PREFIX + idx; + } + function processAddUpdate(newIndex, oldIndex) { + var context = this.context; + var childOption = newIndex != null ? context.newChildren[newIndex] : null; + var child = oldIndex != null ? context.oldChildren[oldIndex] : null; + doCreateOrUpdateEl(context.api, child, context.dataIndex, childOption, context.seriesModel, context.group); + } + function processRemove(oldIndex) { + var context = this.context; + var child = context.oldChildren[oldIndex]; + child && applyLeaveTransition(child, customInnerStore(child).option, context.seriesModel); + } + /** + * @return SVG Path data. + */ + function getPathData(shape) { + // "d" follows the SVG convention. + return shape && (shape.pathData || shape.d); + } + function hasOwnPathData(shape) { + return shape && (hasOwn(shape, 'pathData') || hasOwn(shape, 'd')); + } + + function install$r(registers) { + registers.registerChartView(CustomChartView); + registers.registerSeriesModel(CustomSeriesModel); + } + + var inner$a = makeInner(); + var clone$3 = clone; + var bind$1 = bind; + /** + * Base axis pointer class in 2D. + */ + var BaseAxisPointer = /** @class */function () { + function BaseAxisPointer() { + this._dragging = false; + /** + * In px, arbitrary value. Do not set too small, + * no animation is ok for most cases. + */ + this.animationThreshold = 15; + } + /** + * @implement + */ + BaseAxisPointer.prototype.render = function (axisModel, axisPointerModel, api, forceRender) { + var value = axisPointerModel.get('value'); + var status = axisPointerModel.get('status'); + // Bind them to `this`, not in closure, otherwise they will not + // be replaced when user calling setOption in not merge mode. + this._axisModel = axisModel; + this._axisPointerModel = axisPointerModel; + this._api = api; + // Optimize: `render` will be called repeatedly during mouse move. + // So it is power consuming if performing `render` each time, + // especially on mobile device. + if (!forceRender && this._lastValue === value && this._lastStatus === status) { + return; + } + this._lastValue = value; + this._lastStatus = status; + var group = this._group; + var handle = this._handle; + if (!status || status === 'hide') { + // Do not clear here, for animation better. + group && group.hide(); + handle && handle.hide(); + return; + } + group && group.show(); + handle && handle.show(); + // Otherwise status is 'show' + var elOption = {}; + this.makeElOption(elOption, value, axisModel, axisPointerModel, api); + // Enable change axis pointer type. + var graphicKey = elOption.graphicKey; + if (graphicKey !== this._lastGraphicKey) { + this.clear(api); + } + this._lastGraphicKey = graphicKey; + var moveAnimation = this._moveAnimation = this.determineAnimation(axisModel, axisPointerModel); + if (!group) { + group = this._group = new Group(); + this.createPointerEl(group, elOption, axisModel, axisPointerModel); + this.createLabelEl(group, elOption, axisModel, axisPointerModel); + api.getZr().add(group); + } else { + var doUpdateProps = curry(updateProps$1, axisPointerModel, moveAnimation); + this.updatePointerEl(group, elOption, doUpdateProps); + this.updateLabelEl(group, elOption, doUpdateProps, axisPointerModel); + } + updateMandatoryProps(group, axisPointerModel, true); + this._renderHandle(value); + }; + /** + * @implement + */ + BaseAxisPointer.prototype.remove = function (api) { + this.clear(api); + }; + /** + * @implement + */ + BaseAxisPointer.prototype.dispose = function (api) { + this.clear(api); + }; + /** + * @protected + */ + BaseAxisPointer.prototype.determineAnimation = function (axisModel, axisPointerModel) { + var animation = axisPointerModel.get('animation'); + var axis = axisModel.axis; + var isCategoryAxis = axis.type === 'category'; + var useSnap = axisPointerModel.get('snap'); + // Value axis without snap always do not snap. + if (!useSnap && !isCategoryAxis) { + return false; + } + if (animation === 'auto' || animation == null) { + var animationThreshold = this.animationThreshold; + if (isCategoryAxis && axis.getBandWidth() > animationThreshold) { + return true; + } + // It is important to auto animation when snap used. Consider if there is + // a dataZoom, animation will be disabled when too many points exist, while + // it will be enabled for better visual effect when little points exist. + if (useSnap) { + var seriesDataCount = getAxisInfo(axisModel).seriesDataCount; + var axisExtent = axis.getExtent(); + // Approximate band width + return Math.abs(axisExtent[0] - axisExtent[1]) / seriesDataCount > animationThreshold; + } + return false; + } + return animation === true; + }; + /** + * add {pointer, label, graphicKey} to elOption + * @protected + */ + BaseAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) { + // Should be implemenented by sub-class. + }; + /** + * @protected + */ + BaseAxisPointer.prototype.createPointerEl = function (group, elOption, axisModel, axisPointerModel) { + var pointerOption = elOption.pointer; + if (pointerOption) { + var pointerEl = inner$a(group).pointerEl = new graphic[pointerOption.type](clone$3(elOption.pointer)); + group.add(pointerEl); + } + }; + /** + * @protected + */ + BaseAxisPointer.prototype.createLabelEl = function (group, elOption, axisModel, axisPointerModel) { + if (elOption.label) { + var labelEl = inner$a(group).labelEl = new ZRText(clone$3(elOption.label)); + group.add(labelEl); + updateLabelShowHide(labelEl, axisPointerModel); + } + }; + /** + * @protected + */ + BaseAxisPointer.prototype.updatePointerEl = function (group, elOption, updateProps) { + var pointerEl = inner$a(group).pointerEl; + if (pointerEl && elOption.pointer) { + pointerEl.setStyle(elOption.pointer.style); + updateProps(pointerEl, { + shape: elOption.pointer.shape + }); + } + }; + /** + * @protected + */ + BaseAxisPointer.prototype.updateLabelEl = function (group, elOption, updateProps, axisPointerModel) { + var labelEl = inner$a(group).labelEl; + if (labelEl) { + labelEl.setStyle(elOption.label.style); + updateProps(labelEl, { + // Consider text length change in vertical axis, animation should + // be used on shape, otherwise the effect will be weird. + // TODOTODO + // shape: elOption.label.shape, + x: elOption.label.x, + y: elOption.label.y + }); + updateLabelShowHide(labelEl, axisPointerModel); + } + }; + /** + * @private + */ + BaseAxisPointer.prototype._renderHandle = function (value) { + if (this._dragging || !this.updateHandleTransform) { + return; + } + var axisPointerModel = this._axisPointerModel; + var zr = this._api.getZr(); + var handle = this._handle; + var handleModel = axisPointerModel.getModel('handle'); + var status = axisPointerModel.get('status'); + if (!handleModel.get('show') || !status || status === 'hide') { + handle && zr.remove(handle); + this._handle = null; + return; + } + var isInit; + if (!this._handle) { + isInit = true; + handle = this._handle = createIcon(handleModel.get('icon'), { + cursor: 'move', + draggable: true, + onmousemove: function (e) { + // For mobile device, prevent screen slider on the button. + stop(e.event); + }, + onmousedown: bind$1(this._onHandleDragMove, this, 0, 0), + drift: bind$1(this._onHandleDragMove, this), + ondragend: bind$1(this._onHandleDragEnd, this) + }); + zr.add(handle); + } + updateMandatoryProps(handle, axisPointerModel, false); + // update style + handle.setStyle(handleModel.getItemStyle(null, ['color', 'borderColor', 'borderWidth', 'opacity', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'])); + // update position + var handleSize = handleModel.get('size'); + if (!isArray(handleSize)) { + handleSize = [handleSize, handleSize]; + } + handle.scaleX = handleSize[0] / 2; + handle.scaleY = handleSize[1] / 2; + createOrUpdate(this, '_doDispatchAxisPointer', handleModel.get('throttle') || 0, 'fixRate'); + this._moveHandleToValue(value, isInit); + }; + BaseAxisPointer.prototype._moveHandleToValue = function (value, isInit) { + updateProps$1(this._axisPointerModel, !isInit && this._moveAnimation, this._handle, getHandleTransProps(this.getHandleTransform(value, this._axisModel, this._axisPointerModel))); + }; + BaseAxisPointer.prototype._onHandleDragMove = function (dx, dy) { + var handle = this._handle; + if (!handle) { + return; + } + this._dragging = true; + // Persistent for throttle. + var trans = this.updateHandleTransform(getHandleTransProps(handle), [dx, dy], this._axisModel, this._axisPointerModel); + this._payloadInfo = trans; + handle.stopAnimation(); + handle.attr(getHandleTransProps(trans)); + inner$a(handle).lastProp = null; + this._doDispatchAxisPointer(); + }; + /** + * Throttled method. + */ + BaseAxisPointer.prototype._doDispatchAxisPointer = function () { + var handle = this._handle; + if (!handle) { + return; + } + var payloadInfo = this._payloadInfo; + var axisModel = this._axisModel; + this._api.dispatchAction({ + type: 'updateAxisPointer', + x: payloadInfo.cursorPoint[0], + y: payloadInfo.cursorPoint[1], + tooltipOption: payloadInfo.tooltipOption, + axesInfo: [{ + axisDim: axisModel.axis.dim, + axisIndex: axisModel.componentIndex + }] + }); + }; + BaseAxisPointer.prototype._onHandleDragEnd = function () { + this._dragging = false; + var handle = this._handle; + if (!handle) { + return; + } + var value = this._axisPointerModel.get('value'); + // Consider snap or categroy axis, handle may be not consistent with + // axisPointer. So move handle to align the exact value position when + // drag ended. + this._moveHandleToValue(value); + // For the effect: tooltip will be shown when finger holding on handle + // button, and will be hidden after finger left handle button. + this._api.dispatchAction({ + type: 'hideTip' + }); + }; + /** + * @private + */ + BaseAxisPointer.prototype.clear = function (api) { + this._lastValue = null; + this._lastStatus = null; + var zr = api.getZr(); + var group = this._group; + var handle = this._handle; + if (zr && group) { + this._lastGraphicKey = null; + group && zr.remove(group); + handle && zr.remove(handle); + this._group = null; + this._handle = null; + this._payloadInfo = null; + } + clear(this, '_doDispatchAxisPointer'); + }; + /** + * @protected + */ + BaseAxisPointer.prototype.doClear = function () { + // Implemented by sub-class if necessary. + }; + BaseAxisPointer.prototype.buildLabel = function (xy, wh, xDimIndex) { + xDimIndex = xDimIndex || 0; + return { + x: xy[xDimIndex], + y: xy[1 - xDimIndex], + width: wh[xDimIndex], + height: wh[1 - xDimIndex] + }; + }; + return BaseAxisPointer; + }(); + function updateProps$1(animationModel, moveAnimation, el, props) { + // Animation optimize. + if (!propsEqual(inner$a(el).lastProp, props)) { + inner$a(el).lastProp = props; + moveAnimation ? updateProps(el, props, animationModel) : (el.stopAnimation(), el.attr(props)); + } + } + function propsEqual(lastProps, newProps) { + if (isObject(lastProps) && isObject(newProps)) { + var equals_1 = true; + each(newProps, function (item, key) { + equals_1 = equals_1 && propsEqual(lastProps[key], item); + }); + return !!equals_1; + } else { + return lastProps === newProps; + } + } + function updateLabelShowHide(labelEl, axisPointerModel) { + labelEl[axisPointerModel.get(['label', 'show']) ? 'show' : 'hide'](); + } + function getHandleTransProps(trans) { + return { + x: trans.x || 0, + y: trans.y || 0, + rotation: trans.rotation || 0 + }; + } + function updateMandatoryProps(group, axisPointerModel, silent) { + var z = axisPointerModel.get('z'); + var zlevel = axisPointerModel.get('zlevel'); + group && group.traverse(function (el) { + if (el.type !== 'group') { + z != null && (el.z = z); + zlevel != null && (el.zlevel = zlevel); + el.silent = silent; + } + }); + } + + function buildElStyle(axisPointerModel) { + var axisPointerType = axisPointerModel.get('type'); + var styleModel = axisPointerModel.getModel(axisPointerType + 'Style'); + var style; + if (axisPointerType === 'line') { + style = styleModel.getLineStyle(); + style.fill = null; + } else if (axisPointerType === 'shadow') { + style = styleModel.getAreaStyle(); + style.stroke = null; + } + return style; + } + /** + * @param {Function} labelPos {align, verticalAlign, position} + */ + function buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos) { + var value = axisPointerModel.get('value'); + var text = getValueLabel(value, axisModel.axis, axisModel.ecModel, axisPointerModel.get('seriesDataIndices'), { + precision: axisPointerModel.get(['label', 'precision']), + formatter: axisPointerModel.get(['label', 'formatter']) + }); + var labelModel = axisPointerModel.getModel('label'); + var paddings = normalizeCssArray$1(labelModel.get('padding') || 0); + var font = labelModel.getFont(); + var textRect = getBoundingRect(text, font); + var position = labelPos.position; + var width = textRect.width + paddings[1] + paddings[3]; + var height = textRect.height + paddings[0] + paddings[2]; + // Adjust by align. + var align = labelPos.align; + align === 'right' && (position[0] -= width); + align === 'center' && (position[0] -= width / 2); + var verticalAlign = labelPos.verticalAlign; + verticalAlign === 'bottom' && (position[1] -= height); + verticalAlign === 'middle' && (position[1] -= height / 2); + // Not overflow ec container + confineInContainer(position, width, height, api); + var bgColor = labelModel.get('backgroundColor'); + if (!bgColor || bgColor === 'auto') { + bgColor = axisModel.get(['axisLine', 'lineStyle', 'color']); + } + elOption.label = { + // shape: {x: 0, y: 0, width: width, height: height, r: labelModel.get('borderRadius')}, + x: position[0], + y: position[1], + style: createTextStyle(labelModel, { + text: text, + font: font, + fill: labelModel.getTextColor(), + padding: paddings, + backgroundColor: bgColor + }), + // Label should be over axisPointer. + z2: 10 + }; + } + // Do not overflow ec container + function confineInContainer(position, width, height, api) { + var viewWidth = api.getWidth(); + var viewHeight = api.getHeight(); + position[0] = Math.min(position[0] + width, viewWidth) - width; + position[1] = Math.min(position[1] + height, viewHeight) - height; + position[0] = Math.max(position[0], 0); + position[1] = Math.max(position[1], 0); + } + function getValueLabel(value, axis, ecModel, seriesDataIndices, opt) { + value = axis.scale.parse(value); + var text = axis.scale.getLabel({ + value: value + }, { + // If `precision` is set, width can be fixed (like '12.00500'), which + // helps to debounce when when moving label. + precision: opt.precision + }); + var formatter = opt.formatter; + if (formatter) { + var params_1 = { + value: getAxisRawValue(axis, { + value: value + }), + axisDimension: axis.dim, + axisIndex: axis.index, + seriesData: [] + }; + each(seriesDataIndices, function (idxItem) { + var series = ecModel.getSeriesByIndex(idxItem.seriesIndex); + var dataIndex = idxItem.dataIndexInside; + var dataParams = series && series.getDataParams(dataIndex); + dataParams && params_1.seriesData.push(dataParams); + }); + if (isString(formatter)) { + text = formatter.replace('{value}', text); + } else if (isFunction(formatter)) { + text = formatter(params_1); + } + } + return text; + } + function getTransformedPosition(axis, value, layoutInfo) { + var transform = create$1(); + rotate(transform, transform, layoutInfo.rotation); + translate(transform, transform, layoutInfo.position); + return applyTransform$1([axis.dataToCoord(value), (layoutInfo.labelOffset || 0) + (layoutInfo.labelDirection || 1) * (layoutInfo.labelMargin || 0)], transform); + } + function buildCartesianSingleLabelElOption(value, elOption, layoutInfo, axisModel, axisPointerModel, api) { + // @ts-ignore + var textLayout = AxisBuilder.innerTextLayout(layoutInfo.rotation, 0, layoutInfo.labelDirection); + layoutInfo.labelMargin = axisPointerModel.get(['label', 'margin']); + buildLabelElOption(elOption, axisModel, axisPointerModel, api, { + position: getTransformedPosition(axisModel.axis, value, layoutInfo), + align: textLayout.textAlign, + verticalAlign: textLayout.textVerticalAlign + }); + } + function makeLineShape(p1, p2, xDimIndex) { + xDimIndex = xDimIndex || 0; + return { + x1: p1[xDimIndex], + y1: p1[1 - xDimIndex], + x2: p2[xDimIndex], + y2: p2[1 - xDimIndex] + }; + } + function makeRectShape(xy, wh, xDimIndex) { + xDimIndex = xDimIndex || 0; + return { + x: xy[xDimIndex], + y: xy[1 - xDimIndex], + width: wh[xDimIndex], + height: wh[1 - xDimIndex] + }; + } + function makeSectorShape(cx, cy, r0, r, startAngle, endAngle) { + return { + cx: cx, + cy: cy, + r0: r0, + r: r, + startAngle: startAngle, + endAngle: endAngle, + clockwise: true + }; + } + + var CartesianAxisPointer = /** @class */function (_super) { + __extends(CartesianAxisPointer, _super); + function CartesianAxisPointer() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** + * @override + */ + CartesianAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) { + var axis = axisModel.axis; + var grid = axis.grid; + var axisPointerType = axisPointerModel.get('type'); + var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent(); + var pixelValue = axis.toGlobalCoord(axis.dataToCoord(value, true)); + if (axisPointerType && axisPointerType !== 'none') { + var elStyle = buildElStyle(axisPointerModel); + var pointerOption = pointerShapeBuilder[axisPointerType](axis, pixelValue, otherExtent); + pointerOption.style = elStyle; + elOption.graphicKey = pointerOption.type; + elOption.pointer = pointerOption; + } + var layoutInfo = layout$1(grid.model, axisModel); + buildCartesianSingleLabelElOption( + // @ts-ignore + value, elOption, layoutInfo, axisModel, axisPointerModel, api); + }; + /** + * @override + */ + CartesianAxisPointer.prototype.getHandleTransform = function (value, axisModel, axisPointerModel) { + var layoutInfo = layout$1(axisModel.axis.grid.model, axisModel, { + labelInside: false + }); + // @ts-ignore + layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']); + var pos = getTransformedPosition(axisModel.axis, value, layoutInfo); + return { + x: pos[0], + y: pos[1], + rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0) + }; + }; + /** + * @override + */ + CartesianAxisPointer.prototype.updateHandleTransform = function (transform, delta, axisModel, axisPointerModel) { + var axis = axisModel.axis; + var grid = axis.grid; + var axisExtent = axis.getGlobalExtent(true); + var otherExtent = getCartesian(grid, axis).getOtherAxis(axis).getGlobalExtent(); + var dimIndex = axis.dim === 'x' ? 0 : 1; + var currPosition = [transform.x, transform.y]; + currPosition[dimIndex] += delta[dimIndex]; + currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]); + currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]); + var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2; + var cursorPoint = [cursorOtherValue, cursorOtherValue]; + cursorPoint[dimIndex] = currPosition[dimIndex]; + // Make tooltip do not overlap axisPointer and in the middle of the grid. + var tooltipOptions = [{ + verticalAlign: 'middle' + }, { + align: 'center' + }]; + return { + x: currPosition[0], + y: currPosition[1], + rotation: transform.rotation, + cursorPoint: cursorPoint, + tooltipOption: tooltipOptions[dimIndex] + }; + }; + return CartesianAxisPointer; + }(BaseAxisPointer); + function getCartesian(grid, axis) { + var opt = {}; + opt[axis.dim + 'AxisIndex'] = axis.index; + return grid.getCartesian(opt); + } + var pointerShapeBuilder = { + line: function (axis, pixelValue, otherExtent) { + var targetShape = makeLineShape([pixelValue, otherExtent[0]], [pixelValue, otherExtent[1]], getAxisDimIndex(axis)); + return { + type: 'Line', + subPixelOptimize: true, + shape: targetShape + }; + }, + shadow: function (axis, pixelValue, otherExtent) { + var bandWidth = Math.max(1, axis.getBandWidth()); + var span = otherExtent[1] - otherExtent[0]; + return { + type: 'Rect', + shape: makeRectShape([pixelValue - bandWidth / 2, otherExtent[0]], [bandWidth, span], getAxisDimIndex(axis)) + }; + } + }; + function getAxisDimIndex(axis) { + return axis.dim === 'x' ? 0 : 1; + } + + var AxisPointerModel = /** @class */function (_super) { + __extends(AxisPointerModel, _super); + function AxisPointerModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = AxisPointerModel.type; + return _this; + } + AxisPointerModel.type = 'axisPointer'; + AxisPointerModel.defaultOption = { + // 'auto' means that show when triggered by tooltip or handle. + show: 'auto', + // zlevel: 0, + z: 50, + type: 'line', + // axispointer triggered by tootip determine snap automatically, + // see `modelHelper`. + snap: false, + triggerTooltip: true, + triggerEmphasis: true, + value: null, + status: null, + link: [], + // Do not set 'auto' here, otherwise global animation: false + // will not effect at this axispointer. + animation: null, + animationDurationUpdate: 200, + lineStyle: { + color: '#B9BEC9', + width: 1, + type: 'dashed' + }, + shadowStyle: { + color: 'rgba(210,219,238,0.2)' + }, + label: { + show: true, + formatter: null, + precision: 'auto', + margin: 3, + color: '#fff', + padding: [5, 7, 5, 7], + backgroundColor: 'auto', + borderColor: null, + borderWidth: 0, + borderRadius: 3 + }, + handle: { + show: false, + // eslint-disable-next-line + icon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z', + size: 45, + // handle margin is from symbol center to axis, which is stable when circular move. + margin: 50, + // color: '#1b8bbd' + // color: '#2f4554' + color: '#333', + shadowBlur: 3, + shadowColor: '#aaa', + shadowOffsetX: 0, + shadowOffsetY: 2, + // For mobile performance + throttle: 40 + } + }; + return AxisPointerModel; + }(ComponentModel); + + var inner$b = makeInner(); + var each$7 = each; + /** + * @param {string} key + * @param {module:echarts/ExtensionAPI} api + * @param {Function} handler + * param: {string} currTrigger + * param: {Array.} point + */ + function register(key, api, handler) { + if (env.node) { + return; + } + var zr = api.getZr(); + inner$b(zr).records || (inner$b(zr).records = {}); + initGlobalListeners(zr, api); + var record = inner$b(zr).records[key] || (inner$b(zr).records[key] = {}); + record.handler = handler; + } + function initGlobalListeners(zr, api) { + if (inner$b(zr).initialized) { + return; + } + inner$b(zr).initialized = true; + useHandler('click', curry(doEnter, 'click')); + useHandler('mousemove', curry(doEnter, 'mousemove')); + // useHandler('mouseout', onLeave); + useHandler('globalout', onLeave); + function useHandler(eventType, cb) { + zr.on(eventType, function (e) { + var dis = makeDispatchAction(api); + each$7(inner$b(zr).records, function (record) { + record && cb(record, e, dis.dispatchAction); + }); + dispatchTooltipFinally(dis.pendings, api); + }); + } + } + function dispatchTooltipFinally(pendings, api) { + var showLen = pendings.showTip.length; + var hideLen = pendings.hideTip.length; + var actuallyPayload; + if (showLen) { + actuallyPayload = pendings.showTip[showLen - 1]; + } else if (hideLen) { + actuallyPayload = pendings.hideTip[hideLen - 1]; + } + if (actuallyPayload) { + actuallyPayload.dispatchAction = null; + api.dispatchAction(actuallyPayload); + } + } + function onLeave(record, e, dispatchAction) { + record.handler('leave', null, dispatchAction); + } + function doEnter(currTrigger, record, e, dispatchAction) { + record.handler(currTrigger, e, dispatchAction); + } + function makeDispatchAction(api) { + var pendings = { + showTip: [], + hideTip: [] + }; + // FIXME + // better approach? + // 'showTip' and 'hideTip' can be triggered by axisPointer and tooltip, + // which may be conflict, (axisPointer call showTip but tooltip call hideTip); + // So we have to add "final stage" to merge those dispatched actions. + var dispatchAction = function (payload) { + var pendingList = pendings[payload.type]; + if (pendingList) { + pendingList.push(payload); + } else { + payload.dispatchAction = dispatchAction; + api.dispatchAction(payload); + } + }; + return { + dispatchAction: dispatchAction, + pendings: pendings + }; + } + function unregister(key, api) { + if (env.node) { + return; + } + var zr = api.getZr(); + var record = (inner$b(zr).records || {})[key]; + if (record) { + inner$b(zr).records[key] = null; + } + } + + var AxisPointerView = /** @class */function (_super) { + __extends(AxisPointerView, _super); + function AxisPointerView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = AxisPointerView.type; + return _this; + } + AxisPointerView.prototype.render = function (globalAxisPointerModel, ecModel, api) { + var globalTooltipModel = ecModel.getComponent('tooltip'); + var triggerOn = globalAxisPointerModel.get('triggerOn') || globalTooltipModel && globalTooltipModel.get('triggerOn') || 'mousemove|click'; + // Register global listener in AxisPointerView to enable + // AxisPointerView to be independent to Tooltip. + register('axisPointer', api, function (currTrigger, e, dispatchAction) { + // If 'none', it is not controlled by mouse totally. + if (triggerOn !== 'none' && (currTrigger === 'leave' || triggerOn.indexOf(currTrigger) >= 0)) { + dispatchAction({ + type: 'updateAxisPointer', + currTrigger: currTrigger, + x: e && e.offsetX, + y: e && e.offsetY + }); + } + }); + }; + AxisPointerView.prototype.remove = function (ecModel, api) { + unregister('axisPointer', api); + }; + AxisPointerView.prototype.dispose = function (ecModel, api) { + unregister('axisPointer', api); + }; + AxisPointerView.type = 'axisPointer'; + return AxisPointerView; + }(ComponentView); + + /** + * @param finder contains {seriesIndex, dataIndex, dataIndexInside} + * @param ecModel + * @return {point: [x, y], el: ...} point Will not be null. + */ + function findPointFromSeries(finder, ecModel) { + var point = []; + var seriesIndex = finder.seriesIndex; + var seriesModel; + if (seriesIndex == null || !(seriesModel = ecModel.getSeriesByIndex(seriesIndex))) { + return { + point: [] + }; + } + var data = seriesModel.getData(); + var dataIndex = queryDataIndex(data, finder); + if (dataIndex == null || dataIndex < 0 || isArray(dataIndex)) { + return { + point: [] + }; + } + var el = data.getItemGraphicEl(dataIndex); + var coordSys = seriesModel.coordinateSystem; + if (seriesModel.getTooltipPosition) { + point = seriesModel.getTooltipPosition(dataIndex) || []; + } else if (coordSys && coordSys.dataToPoint) { + if (finder.isStacked) { + var baseAxis = coordSys.getBaseAxis(); + var valueAxis = coordSys.getOtherAxis(baseAxis); + var valueAxisDim = valueAxis.dim; + var baseAxisDim = baseAxis.dim; + var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0; + var baseDim = data.mapDimension(baseAxisDim); + var stackedData = []; + stackedData[baseDataOffset] = data.get(baseDim, dataIndex); + stackedData[1 - baseDataOffset] = data.get(data.getCalculationInfo('stackResultDimension'), dataIndex); + point = coordSys.dataToPoint(stackedData) || []; + } else { + point = coordSys.dataToPoint(data.getValues(map(coordSys.dimensions, function (dim) { + return data.mapDimension(dim); + }), dataIndex)) || []; + } + } else if (el) { + // Use graphic bounding rect + var rect = el.getBoundingRect().clone(); + rect.applyTransform(el.transform); + point = [rect.x + rect.width / 2, rect.y + rect.height / 2]; + } + return { + point: point, + el: el + }; + } + + var inner$c = makeInner(); + /** + * Basic logic: check all axis, if they do not demand show/highlight, + * then hide/downplay them. + * + * @return content of event obj for echarts.connect. + */ + function axisTrigger(payload, ecModel, api) { + var currTrigger = payload.currTrigger; + var point = [payload.x, payload.y]; + var finder = payload; + var dispatchAction = payload.dispatchAction || bind(api.dispatchAction, api); + var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo; + // Pending + // See #6121. But we are not able to reproduce it yet. + if (!coordSysAxesInfo) { + return; + } + if (illegalPoint(point)) { + // Used in the default behavior of `connection`: use the sample seriesIndex + // and dataIndex. And also used in the tooltipView trigger. + point = findPointFromSeries({ + seriesIndex: finder.seriesIndex, + // Do not use dataIndexInside from other ec instance. + // FIXME: auto detect it? + dataIndex: finder.dataIndex + }, ecModel).point; + } + var isIllegalPoint = illegalPoint(point); + // Axis and value can be specified when calling dispatchAction({type: 'updateAxisPointer'}). + // Notice: In this case, it is difficult to get the `point` (which is necessary to show + // tooltip, so if point is not given, we just use the point found by sample seriesIndex + // and dataIndex. + var inputAxesInfo = finder.axesInfo; + var axesInfo = coordSysAxesInfo.axesInfo; + var shouldHide = currTrigger === 'leave' || illegalPoint(point); + var outputPayload = {}; + var showValueMap = {}; + var dataByCoordSys = { + list: [], + map: {} + }; + var updaters = { + showPointer: curry(showPointer, showValueMap), + showTooltip: curry(showTooltip, dataByCoordSys) + }; + // Process for triggered axes. + each(coordSysAxesInfo.coordSysMap, function (coordSys, coordSysKey) { + // If a point given, it must be contained by the coordinate system. + var coordSysContainsPoint = isIllegalPoint || coordSys.containPoint(point); + each(coordSysAxesInfo.coordSysAxesInfo[coordSysKey], function (axisInfo, key) { + var axis = axisInfo.axis; + var inputAxisInfo = findInputAxisInfo(inputAxesInfo, axisInfo); + // If no inputAxesInfo, no axis is restricted. + if (!shouldHide && coordSysContainsPoint && (!inputAxesInfo || inputAxisInfo)) { + var val = inputAxisInfo && inputAxisInfo.value; + if (val == null && !isIllegalPoint) { + val = axis.pointToData(point); + } + val != null && processOnAxis(axisInfo, val, updaters, false, outputPayload); + } + }); + }); + // Process for linked axes. + var linkTriggers = {}; + each(axesInfo, function (tarAxisInfo, tarKey) { + var linkGroup = tarAxisInfo.linkGroup; + // If axis has been triggered in the previous stage, it should not be triggered by link. + if (linkGroup && !showValueMap[tarKey]) { + each(linkGroup.axesInfo, function (srcAxisInfo, srcKey) { + var srcValItem = showValueMap[srcKey]; + // If srcValItem exist, source axis is triggered, so link to target axis. + if (srcAxisInfo !== tarAxisInfo && srcValItem) { + var val = srcValItem.value; + linkGroup.mapper && (val = tarAxisInfo.axis.scale.parse(linkGroup.mapper(val, makeMapperParam(srcAxisInfo), makeMapperParam(tarAxisInfo)))); + linkTriggers[tarAxisInfo.key] = val; + } + }); + } + }); + each(linkTriggers, function (val, tarKey) { + processOnAxis(axesInfo[tarKey], val, updaters, true, outputPayload); + }); + updateModelActually(showValueMap, axesInfo, outputPayload); + dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction); + dispatchHighDownActually(axesInfo, dispatchAction, api); + return outputPayload; + } + function processOnAxis(axisInfo, newValue, updaters, noSnap, outputFinder) { + var axis = axisInfo.axis; + if (axis.scale.isBlank() || !axis.containData(newValue)) { + return; + } + if (!axisInfo.involveSeries) { + updaters.showPointer(axisInfo, newValue); + return; + } + // Heavy calculation. So put it after axis.containData checking. + var payloadInfo = buildPayloadsBySeries(newValue, axisInfo); + var payloadBatch = payloadInfo.payloadBatch; + var snapToValue = payloadInfo.snapToValue; + // Fill content of event obj for echarts.connect. + // By default use the first involved series data as a sample to connect. + if (payloadBatch[0] && outputFinder.seriesIndex == null) { + extend(outputFinder, payloadBatch[0]); + } + // If no linkSource input, this process is for collecting link + // target, where snap should not be accepted. + if (!noSnap && axisInfo.snap) { + if (axis.containData(snapToValue) && snapToValue != null) { + newValue = snapToValue; + } + } + updaters.showPointer(axisInfo, newValue, payloadBatch); + // Tooltip should always be snapToValue, otherwise there will be + // incorrect "axis value ~ series value" mapping displayed in tooltip. + updaters.showTooltip(axisInfo, payloadInfo, snapToValue); + } + function buildPayloadsBySeries(value, axisInfo) { + var axis = axisInfo.axis; + var dim = axis.dim; + var snapToValue = value; + var payloadBatch = []; + var minDist = Number.MAX_VALUE; + var minDiff = -1; + each(axisInfo.seriesModels, function (series, idx) { + var dataDim = series.getData().mapDimensionsAll(dim); + var seriesNestestValue; + var dataIndices; + if (series.getAxisTooltipData) { + var result = series.getAxisTooltipData(dataDim, value, axis); + dataIndices = result.dataIndices; + seriesNestestValue = result.nestestValue; + } else { + dataIndices = series.getData().indicesOfNearest(dataDim[0], value, + // Add a threshold to avoid find the wrong dataIndex + // when data length is not same. + // false, + axis.type === 'category' ? 0.5 : null); + if (!dataIndices.length) { + return; + } + seriesNestestValue = series.getData().get(dataDim[0], dataIndices[0]); + } + if (seriesNestestValue == null || !isFinite(seriesNestestValue)) { + return; + } + var diff = value - seriesNestestValue; + var dist = Math.abs(diff); + // Consider category case + if (dist <= minDist) { + if (dist < minDist || diff >= 0 && minDiff < 0) { + minDist = dist; + minDiff = diff; + snapToValue = seriesNestestValue; + payloadBatch.length = 0; + } + each(dataIndices, function (dataIndex) { + payloadBatch.push({ + seriesIndex: series.seriesIndex, + dataIndexInside: dataIndex, + dataIndex: series.getData().getRawIndex(dataIndex) + }); + }); + } + }); + return { + payloadBatch: payloadBatch, + snapToValue: snapToValue + }; + } + function showPointer(showValueMap, axisInfo, value, payloadBatch) { + showValueMap[axisInfo.key] = { + value: value, + payloadBatch: payloadBatch + }; + } + function showTooltip(dataByCoordSys, axisInfo, payloadInfo, value) { + var payloadBatch = payloadInfo.payloadBatch; + var axis = axisInfo.axis; + var axisModel = axis.model; + var axisPointerModel = axisInfo.axisPointerModel; + // If no data, do not create anything in dataByCoordSys, + // whose length will be used to judge whether dispatch action. + if (!axisInfo.triggerTooltip || !payloadBatch.length) { + return; + } + var coordSysModel = axisInfo.coordSys.model; + var coordSysKey = makeKey(coordSysModel); + var coordSysItem = dataByCoordSys.map[coordSysKey]; + if (!coordSysItem) { + coordSysItem = dataByCoordSys.map[coordSysKey] = { + coordSysId: coordSysModel.id, + coordSysIndex: coordSysModel.componentIndex, + coordSysType: coordSysModel.type, + coordSysMainType: coordSysModel.mainType, + dataByAxis: [] + }; + dataByCoordSys.list.push(coordSysItem); + } + coordSysItem.dataByAxis.push({ + axisDim: axis.dim, + axisIndex: axisModel.componentIndex, + axisType: axisModel.type, + axisId: axisModel.id, + value: value, + // Caustion: viewHelper.getValueLabel is actually on "view stage", which + // depends that all models have been updated. So it should not be performed + // here. Considering axisPointerModel used here is volatile, which is hard + // to be retrieve in TooltipView, we prepare parameters here. + valueLabelOpt: { + precision: axisPointerModel.get(['label', 'precision']), + formatter: axisPointerModel.get(['label', 'formatter']) + }, + seriesDataIndices: payloadBatch.slice() + }); + } + function updateModelActually(showValueMap, axesInfo, outputPayload) { + var outputAxesInfo = outputPayload.axesInfo = []; + // Basic logic: If no 'show' required, 'hide' this axisPointer. + each(axesInfo, function (axisInfo, key) { + var option = axisInfo.axisPointerModel.option; + var valItem = showValueMap[key]; + if (valItem) { + !axisInfo.useHandle && (option.status = 'show'); + option.value = valItem.value; + // For label formatter param and highlight. + option.seriesDataIndices = (valItem.payloadBatch || []).slice(); + } + // When always show (e.g., handle used), remain + // original value and status. + else { + // If hide, value still need to be set, consider + // click legend to toggle axis blank. + !axisInfo.useHandle && (option.status = 'hide'); + } + // If status is 'hide', should be no info in payload. + option.status === 'show' && outputAxesInfo.push({ + axisDim: axisInfo.axis.dim, + axisIndex: axisInfo.axis.model.componentIndex, + value: option.value + }); + }); + } + function dispatchTooltipActually(dataByCoordSys, point, payload, dispatchAction) { + // Basic logic: If no showTip required, hideTip will be dispatched. + if (illegalPoint(point) || !dataByCoordSys.list.length) { + dispatchAction({ + type: 'hideTip' + }); + return; + } + // In most case only one axis (or event one series is used). It is + // convenient to fetch payload.seriesIndex and payload.dataIndex + // directly. So put the first seriesIndex and dataIndex of the first + // axis on the payload. + var sampleItem = ((dataByCoordSys.list[0].dataByAxis[0] || {}).seriesDataIndices || [])[0] || {}; + dispatchAction({ + type: 'showTip', + escapeConnect: true, + x: point[0], + y: point[1], + tooltipOption: payload.tooltipOption, + position: payload.position, + dataIndexInside: sampleItem.dataIndexInside, + dataIndex: sampleItem.dataIndex, + seriesIndex: sampleItem.seriesIndex, + dataByCoordSys: dataByCoordSys.list + }); + } + function dispatchHighDownActually(axesInfo, dispatchAction, api) { + // FIXME + // highlight status modification should be a stage of main process? + // (Consider confilct (e.g., legend and axisPointer) and setOption) + var zr = api.getZr(); + var highDownKey = 'axisPointerLastHighlights'; + var lastHighlights = inner$c(zr)[highDownKey] || {}; + var newHighlights = inner$c(zr)[highDownKey] = {}; + // Update highlight/downplay status according to axisPointer model. + // Build hash map and remove duplicate incidentally. + each(axesInfo, function (axisInfo, key) { + var option = axisInfo.axisPointerModel.option; + option.status === 'show' && axisInfo.triggerEmphasis && each(option.seriesDataIndices, function (batchItem) { + var key = batchItem.seriesIndex + ' | ' + batchItem.dataIndex; + newHighlights[key] = batchItem; + }); + }); + // Diff. + var toHighlight = []; + var toDownplay = []; + each(lastHighlights, function (batchItem, key) { + !newHighlights[key] && toDownplay.push(batchItem); + }); + each(newHighlights, function (batchItem, key) { + !lastHighlights[key] && toHighlight.push(batchItem); + }); + toDownplay.length && api.dispatchAction({ + type: 'downplay', + escapeConnect: true, + // Not blur others when highlight in axisPointer. + notBlur: true, + batch: toDownplay + }); + toHighlight.length && api.dispatchAction({ + type: 'highlight', + escapeConnect: true, + // Not blur others when highlight in axisPointer. + notBlur: true, + batch: toHighlight + }); + } + function findInputAxisInfo(inputAxesInfo, axisInfo) { + for (var i = 0; i < (inputAxesInfo || []).length; i++) { + var inputAxisInfo = inputAxesInfo[i]; + if (axisInfo.axis.dim === inputAxisInfo.axisDim && axisInfo.axis.model.componentIndex === inputAxisInfo.axisIndex) { + return inputAxisInfo; + } + } + } + function makeMapperParam(axisInfo) { + var axisModel = axisInfo.axis.model; + var item = {}; + var dim = item.axisDim = axisInfo.axis.dim; + item.axisIndex = item[dim + 'AxisIndex'] = axisModel.componentIndex; + item.axisName = item[dim + 'AxisName'] = axisModel.name; + item.axisId = item[dim + 'AxisId'] = axisModel.id; + return item; + } + function illegalPoint(point) { + return !point || point[0] == null || isNaN(point[0]) || point[1] == null || isNaN(point[1]); + } + + function install$s(registers) { + // CartesianAxisPointer is not supposed to be required here. But consider + // echarts.simple.js and online build tooltip, which only require gridSimple, + // CartesianAxisPointer should be able to required somewhere. + AxisView.registerAxisPointerClass('CartesianAxisPointer', CartesianAxisPointer); + registers.registerComponentModel(AxisPointerModel); + registers.registerComponentView(AxisPointerView); + registers.registerPreprocessor(function (option) { + // Always has a global axisPointerModel for default setting. + if (option) { + (!option.axisPointer || option.axisPointer.length === 0) && (option.axisPointer = {}); + var link = option.axisPointer.link; + // Normalize to array to avoid object mergin. But if link + // is not set, remain null/undefined, otherwise it will + // override existent link setting. + if (link && !isArray(link)) { + option.axisPointer.link = [link]; + } + } + }); + // This process should proformed after coordinate systems created + // and series data processed. So put it on statistic processing stage. + registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, function (ecModel, api) { + // Build axisPointerModel, mergin tooltip.axisPointer model for each axis. + // allAxesInfo should be updated when setOption performed. + ecModel.getComponent('axisPointer').coordSysAxesInfo = collect(ecModel, api); + }); + // Broadcast to all views. + registers.registerAction({ + type: 'updateAxisPointer', + event: 'updateAxisPointer', + update: ':updateAxisPointer' + }, axisTrigger); + } + + function install$t(registers) { + use(install$5); + use(install$s); + } + + var PolarAxisPointer = /** @class */function (_super) { + __extends(PolarAxisPointer, _super); + function PolarAxisPointer() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** + * @override + */ + PolarAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) { + var axis = axisModel.axis; + if (axis.dim === 'angle') { + this.animationThreshold = Math.PI / 18; + } + var polar = axis.polar; + var otherAxis = polar.getOtherAxis(axis); + var otherExtent = otherAxis.getExtent(); + var coordValue = axis.dataToCoord(value); + var axisPointerType = axisPointerModel.get('type'); + if (axisPointerType && axisPointerType !== 'none') { + var elStyle = buildElStyle(axisPointerModel); + var pointerOption = pointerShapeBuilder$1[axisPointerType](axis, polar, coordValue, otherExtent); + pointerOption.style = elStyle; + elOption.graphicKey = pointerOption.type; + elOption.pointer = pointerOption; + } + var labelMargin = axisPointerModel.get(['label', 'margin']); + var labelPos = getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin); + buildLabelElOption(elOption, axisModel, axisPointerModel, api, labelPos); + }; + return PolarAxisPointer; + }(BaseAxisPointer); + function getLabelPosition(value, axisModel, axisPointerModel, polar, labelMargin) { + var axis = axisModel.axis; + var coord = axis.dataToCoord(value); + var axisAngle = polar.getAngleAxis().getExtent()[0]; + axisAngle = axisAngle / 180 * Math.PI; + var radiusExtent = polar.getRadiusAxis().getExtent(); + var position; + var align; + var verticalAlign; + if (axis.dim === 'radius') { + var transform = create$1(); + rotate(transform, transform, axisAngle); + translate(transform, transform, [polar.cx, polar.cy]); + position = applyTransform$1([coord, -labelMargin], transform); + var labelRotation = axisModel.getModel('axisLabel').get('rotate') || 0; + // @ts-ignore + var labelLayout = AxisBuilder.innerTextLayout(axisAngle, labelRotation * Math.PI / 180, -1); + align = labelLayout.textAlign; + verticalAlign = labelLayout.textVerticalAlign; + } else { + // angle axis + var r = radiusExtent[1]; + position = polar.coordToPoint([r + labelMargin, coord]); + var cx = polar.cx; + var cy = polar.cy; + align = Math.abs(position[0] - cx) / r < 0.3 ? 'center' : position[0] > cx ? 'left' : 'right'; + verticalAlign = Math.abs(position[1] - cy) / r < 0.3 ? 'middle' : position[1] > cy ? 'top' : 'bottom'; + } + return { + position: position, + align: align, + verticalAlign: verticalAlign + }; + } + var pointerShapeBuilder$1 = { + line: function (axis, polar, coordValue, otherExtent) { + return axis.dim === 'angle' ? { + type: 'Line', + shape: makeLineShape(polar.coordToPoint([otherExtent[0], coordValue]), polar.coordToPoint([otherExtent[1], coordValue])) + } : { + type: 'Circle', + shape: { + cx: polar.cx, + cy: polar.cy, + r: coordValue + } + }; + }, + shadow: function (axis, polar, coordValue, otherExtent) { + var bandWidth = Math.max(1, axis.getBandWidth()); + var radian = Math.PI / 180; + return axis.dim === 'angle' ? { + type: 'Sector', + shape: makeSectorShape(polar.cx, polar.cy, otherExtent[0], otherExtent[1], + // In ECharts y is negative if angle is positive + (-coordValue - bandWidth / 2) * radian, (-coordValue + bandWidth / 2) * radian) + } : { + type: 'Sector', + shape: makeSectorShape(polar.cx, polar.cy, coordValue - bandWidth / 2, coordValue + bandWidth / 2, 0, Math.PI * 2) + }; + } + }; + + var PolarModel = /** @class */function (_super) { + __extends(PolarModel, _super); + function PolarModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = PolarModel.type; + return _this; + } + PolarModel.prototype.findAxisModel = function (axisType) { + var foundAxisModel; + var ecModel = this.ecModel; + ecModel.eachComponent(axisType, function (axisModel) { + if (axisModel.getCoordSysModel() === this) { + foundAxisModel = axisModel; + } + }, this); + return foundAxisModel; + }; + PolarModel.type = 'polar'; + PolarModel.dependencies = ['radiusAxis', 'angleAxis']; + PolarModel.defaultOption = { + // zlevel: 0, + z: 0, + center: ['50%', '50%'], + radius: '80%' + }; + return PolarModel; + }(ComponentModel); + + var PolarAxisModel = /** @class */function (_super) { + __extends(PolarAxisModel, _super); + function PolarAxisModel() { + return _super !== null && _super.apply(this, arguments) || this; + } + PolarAxisModel.prototype.getCoordSysModel = function () { + return this.getReferringComponents('polar', SINGLE_REFERRING).models[0]; + }; + PolarAxisModel.type = 'polarAxis'; + return PolarAxisModel; + }(ComponentModel); + mixin(PolarAxisModel, AxisModelCommonMixin); + var AngleAxisModel = /** @class */function (_super) { + __extends(AngleAxisModel, _super); + function AngleAxisModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = AngleAxisModel.type; + return _this; + } + AngleAxisModel.type = 'angleAxis'; + return AngleAxisModel; + }(PolarAxisModel); + var RadiusAxisModel = /** @class */function (_super) { + __extends(RadiusAxisModel, _super); + function RadiusAxisModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = RadiusAxisModel.type; + return _this; + } + RadiusAxisModel.type = 'radiusAxis'; + return RadiusAxisModel; + }(PolarAxisModel); + + var RadiusAxis = /** @class */function (_super) { + __extends(RadiusAxis, _super); + function RadiusAxis(scale, radiusExtent) { + return _super.call(this, 'radius', scale, radiusExtent) || this; + } + RadiusAxis.prototype.pointToData = function (point, clamp) { + return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1]; + }; + return RadiusAxis; + }(Axis); + RadiusAxis.prototype.dataToRadius = Axis.prototype.dataToCoord; + RadiusAxis.prototype.radiusToData = Axis.prototype.coordToData; + + var inner$d = makeInner(); + var AngleAxis = /** @class */function (_super) { + __extends(AngleAxis, _super); + function AngleAxis(scale, angleExtent) { + return _super.call(this, 'angle', scale, angleExtent || [0, 360]) || this; + } + AngleAxis.prototype.pointToData = function (point, clamp) { + return this.polar.pointToData(point, clamp)[this.dim === 'radius' ? 0 : 1]; + }; + /** + * Only be called in category axis. + * Angle axis uses text height to decide interval + * + * @override + * @return {number} Auto interval for cateogry axis tick and label + */ + AngleAxis.prototype.calculateCategoryInterval = function () { + var axis = this; + var labelModel = axis.getLabelModel(); + var ordinalScale = axis.scale; + var ordinalExtent = ordinalScale.getExtent(); + // Providing this method is for optimization: + // avoid generating a long array by `getTicks` + // in large category data case. + var tickCount = ordinalScale.count(); + if (ordinalExtent[1] - ordinalExtent[0] < 1) { + return 0; + } + var tickValue = ordinalExtent[0]; + var unitSpan = axis.dataToCoord(tickValue + 1) - axis.dataToCoord(tickValue); + var unitH = Math.abs(unitSpan); + // Not precise, just use height as text width + // and each distance from axis line yet. + var rect = getBoundingRect(tickValue == null ? '' : tickValue + '', labelModel.getFont(), 'center', 'top'); + var maxH = Math.max(rect.height, 7); + var dh = maxH / unitH; + // 0/0 is NaN, 1/0 is Infinity. + isNaN(dh) && (dh = Infinity); + var interval = Math.max(0, Math.floor(dh)); + var cache = inner$d(axis.model); + var lastAutoInterval = cache.lastAutoInterval; + var lastTickCount = cache.lastTickCount; + // Use cache to keep interval stable while moving zoom window, + // otherwise the calculated interval might jitter when the zoom + // window size is close to the interval-changing size. + if (lastAutoInterval != null && lastTickCount != null && Math.abs(lastAutoInterval - interval) <= 1 && Math.abs(lastTickCount - tickCount) <= 1 + // Always choose the bigger one, otherwise the critical + // point is not the same when zooming in or zooming out. + && lastAutoInterval > interval) { + interval = lastAutoInterval; + } + // Only update cache if cache not used, otherwise the + // changing of interval is too insensitive. + else { + cache.lastTickCount = tickCount; + cache.lastAutoInterval = interval; + } + return interval; + }; + return AngleAxis; + }(Axis); + AngleAxis.prototype.dataToAngle = Axis.prototype.dataToCoord; + AngleAxis.prototype.angleToData = Axis.prototype.coordToData; + + var polarDimensions = ['radius', 'angle']; + var Polar = /** @class */function () { + function Polar(name) { + this.dimensions = polarDimensions; + this.type = 'polar'; + /** + * x of polar center + */ + this.cx = 0; + /** + * y of polar center + */ + this.cy = 0; + this._radiusAxis = new RadiusAxis(); + this._angleAxis = new AngleAxis(); + this.axisPointerEnabled = true; + this.name = name || ''; + this._radiusAxis.polar = this._angleAxis.polar = this; + } + /** + * If contain coord + */ + Polar.prototype.containPoint = function (point) { + var coord = this.pointToCoord(point); + return this._radiusAxis.contain(coord[0]) && this._angleAxis.contain(coord[1]); + }; + /** + * If contain data + */ + Polar.prototype.containData = function (data) { + return this._radiusAxis.containData(data[0]) && this._angleAxis.containData(data[1]); + }; + Polar.prototype.getAxis = function (dim) { + var key = '_' + dim + 'Axis'; + return this[key]; + }; + Polar.prototype.getAxes = function () { + return [this._radiusAxis, this._angleAxis]; + }; + /** + * Get axes by type of scale + */ + Polar.prototype.getAxesByScale = function (scaleType) { + var axes = []; + var angleAxis = this._angleAxis; + var radiusAxis = this._radiusAxis; + angleAxis.scale.type === scaleType && axes.push(angleAxis); + radiusAxis.scale.type === scaleType && axes.push(radiusAxis); + return axes; + }; + Polar.prototype.getAngleAxis = function () { + return this._angleAxis; + }; + Polar.prototype.getRadiusAxis = function () { + return this._radiusAxis; + }; + Polar.prototype.getOtherAxis = function (axis) { + var angleAxis = this._angleAxis; + return axis === angleAxis ? this._radiusAxis : angleAxis; + }; + /** + * Base axis will be used on stacking. + * + */ + Polar.prototype.getBaseAxis = function () { + return this.getAxesByScale('ordinal')[0] || this.getAxesByScale('time')[0] || this.getAngleAxis(); + }; + Polar.prototype.getTooltipAxes = function (dim) { + var baseAxis = dim != null && dim !== 'auto' ? this.getAxis(dim) : this.getBaseAxis(); + return { + baseAxes: [baseAxis], + otherAxes: [this.getOtherAxis(baseAxis)] + }; + }; + /** + * Convert a single data item to (x, y) point. + * Parameter data is an array which the first element is radius and the second is angle + */ + Polar.prototype.dataToPoint = function (data, clamp) { + return this.coordToPoint([this._radiusAxis.dataToRadius(data[0], clamp), this._angleAxis.dataToAngle(data[1], clamp)]); + }; + /** + * Convert a (x, y) point to data + */ + Polar.prototype.pointToData = function (point, clamp) { + var coord = this.pointToCoord(point); + return [this._radiusAxis.radiusToData(coord[0], clamp), this._angleAxis.angleToData(coord[1], clamp)]; + }; + /** + * Convert a (x, y) point to (radius, angle) coord + */ + Polar.prototype.pointToCoord = function (point) { + var dx = point[0] - this.cx; + var dy = point[1] - this.cy; + var angleAxis = this.getAngleAxis(); + var extent = angleAxis.getExtent(); + var minAngle = Math.min(extent[0], extent[1]); + var maxAngle = Math.max(extent[0], extent[1]); + // Fix fixed extent in polarCreator + // FIXME + angleAxis.inverse ? minAngle = maxAngle - 360 : maxAngle = minAngle + 360; + var radius = Math.sqrt(dx * dx + dy * dy); + dx /= radius; + dy /= radius; + var radian = Math.atan2(-dy, dx) / Math.PI * 180; + // move to angleExtent + var dir = radian < minAngle ? 1 : -1; + while (radian < minAngle || radian > maxAngle) { + radian += dir * 360; + } + return [radius, radian]; + }; + /** + * Convert a (radius, angle) coord to (x, y) point + */ + Polar.prototype.coordToPoint = function (coord) { + var radius = coord[0]; + var radian = coord[1] / 180 * Math.PI; + var x = Math.cos(radian) * radius + this.cx; + // Inverse the y + var y = -Math.sin(radian) * radius + this.cy; + return [x, y]; + }; + /** + * Get ring area of cartesian. + * Area will have a contain function to determine if a point is in the coordinate system. + */ + Polar.prototype.getArea = function () { + var angleAxis = this.getAngleAxis(); + var radiusAxis = this.getRadiusAxis(); + var radiusExtent = radiusAxis.getExtent().slice(); + radiusExtent[0] > radiusExtent[1] && radiusExtent.reverse(); + var angleExtent = angleAxis.getExtent(); + var RADIAN = Math.PI / 180; + return { + cx: this.cx, + cy: this.cy, + r0: radiusExtent[0], + r: radiusExtent[1], + startAngle: -angleExtent[0] * RADIAN, + endAngle: -angleExtent[1] * RADIAN, + clockwise: angleAxis.inverse, + contain: function (x, y) { + // It's a ring shape. + // Start angle and end angle don't matter + var dx = x - this.cx; + var dy = y - this.cy; + // minus a tiny value 1e-4 to avoid being clipped unexpectedly + var d2 = dx * dx + dy * dy - 1e-4; + var r = this.r; + var r0 = this.r0; + return d2 <= r * r && d2 >= r0 * r0; + } + }; + }; + Polar.prototype.convertToPixel = function (ecModel, finder, value) { + var coordSys = getCoordSys$2(finder); + return coordSys === this ? this.dataToPoint(value) : null; + }; + Polar.prototype.convertFromPixel = function (ecModel, finder, pixel) { + var coordSys = getCoordSys$2(finder); + return coordSys === this ? this.pointToData(pixel) : null; + }; + return Polar; + }(); + function getCoordSys$2(finder) { + var seriesModel = finder.seriesModel; + var polarModel = finder.polarModel; + return polarModel && polarModel.coordinateSystem || seriesModel && seriesModel.coordinateSystem; + } + + /** + * Resize method bound to the polar + */ + function resizePolar(polar, polarModel, api) { + var center = polarModel.get('center'); + var width = api.getWidth(); + var height = api.getHeight(); + polar.cx = parsePercent$1(center[0], width); + polar.cy = parsePercent$1(center[1], height); + var radiusAxis = polar.getRadiusAxis(); + var size = Math.min(width, height) / 2; + var radius = polarModel.get('radius'); + if (radius == null) { + radius = [0, '100%']; + } else if (!isArray(radius)) { + // r0 = 0 + radius = [0, radius]; + } + var parsedRadius = [parsePercent$1(radius[0], size), parsePercent$1(radius[1], size)]; + radiusAxis.inverse ? radiusAxis.setExtent(parsedRadius[1], parsedRadius[0]) : radiusAxis.setExtent(parsedRadius[0], parsedRadius[1]); + } + /** + * Update polar + */ + function updatePolarScale(ecModel, api) { + var polar = this; + var angleAxis = polar.getAngleAxis(); + var radiusAxis = polar.getRadiusAxis(); + // Reset scale + angleAxis.scale.setExtent(Infinity, -Infinity); + radiusAxis.scale.setExtent(Infinity, -Infinity); + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.coordinateSystem === polar) { + var data_1 = seriesModel.getData(); + each(getDataDimensionsOnAxis(data_1, 'radius'), function (dim) { + radiusAxis.scale.unionExtentFromData(data_1, dim); + }); + each(getDataDimensionsOnAxis(data_1, 'angle'), function (dim) { + angleAxis.scale.unionExtentFromData(data_1, dim); + }); + } + }); + niceScaleExtent(angleAxis.scale, angleAxis.model); + niceScaleExtent(radiusAxis.scale, radiusAxis.model); + // Fix extent of category angle axis + if (angleAxis.type === 'category' && !angleAxis.onBand) { + var extent = angleAxis.getExtent(); + var diff = 360 / angleAxis.scale.count(); + angleAxis.inverse ? extent[1] += diff : extent[1] -= diff; + angleAxis.setExtent(extent[0], extent[1]); + } + } + function isAngleAxisModel(axisModel) { + return axisModel.mainType === 'angleAxis'; + } + /** + * Set common axis properties + */ + function setAxis(axis, axisModel) { + var _a; + axis.type = axisModel.get('type'); + axis.scale = createScaleByModel(axisModel); + axis.onBand = axisModel.get('boundaryGap') && axis.type === 'category'; + axis.inverse = axisModel.get('inverse'); + if (isAngleAxisModel(axisModel)) { + axis.inverse = axis.inverse !== axisModel.get('clockwise'); + var startAngle = axisModel.get('startAngle'); + var endAngle = (_a = axisModel.get('endAngle')) !== null && _a !== void 0 ? _a : startAngle + (axis.inverse ? -360 : 360); + axis.setExtent(startAngle, endAngle); + } + // Inject axis instance + axisModel.axis = axis; + axis.model = axisModel; + } + var polarCreator = { + dimensions: polarDimensions, + create: function (ecModel, api) { + var polarList = []; + ecModel.eachComponent('polar', function (polarModel, idx) { + var polar = new Polar(idx + ''); + // Inject resize and update method + polar.update = updatePolarScale; + var radiusAxis = polar.getRadiusAxis(); + var angleAxis = polar.getAngleAxis(); + var radiusAxisModel = polarModel.findAxisModel('radiusAxis'); + var angleAxisModel = polarModel.findAxisModel('angleAxis'); + setAxis(radiusAxis, radiusAxisModel); + setAxis(angleAxis, angleAxisModel); + resizePolar(polar, polarModel, api); + polarList.push(polar); + polarModel.coordinateSystem = polar; + polar.model = polarModel; + }); + // Inject coordinateSystem to series + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.get('coordinateSystem') === 'polar') { + var polarModel = seriesModel.getReferringComponents('polar', SINGLE_REFERRING).models[0]; + if ("development" !== 'production') { + if (!polarModel) { + throw new Error('Polar "' + retrieve(seriesModel.get('polarIndex'), seriesModel.get('polarId'), 0) + '" not found'); + } + } + seriesModel.coordinateSystem = polarModel.coordinateSystem; + } + }); + return polarList; + } + }; + + var elementList$1 = ['axisLine', 'axisLabel', 'axisTick', 'minorTick', 'splitLine', 'minorSplitLine', 'splitArea']; + function getAxisLineShape(polar, rExtent, angle) { + rExtent[1] > rExtent[0] && (rExtent = rExtent.slice().reverse()); + var start = polar.coordToPoint([rExtent[0], angle]); + var end = polar.coordToPoint([rExtent[1], angle]); + return { + x1: start[0], + y1: start[1], + x2: end[0], + y2: end[1] + }; + } + function getRadiusIdx(polar) { + var radiusAxis = polar.getRadiusAxis(); + return radiusAxis.inverse ? 0 : 1; + } + // Remove the last tick which will overlap the first tick + function fixAngleOverlap(list) { + var firstItem = list[0]; + var lastItem = list[list.length - 1]; + if (firstItem && lastItem && Math.abs(Math.abs(firstItem.coord - lastItem.coord) - 360) < 1e-4) { + list.pop(); + } + } + var AngleAxisView = /** @class */function (_super) { + __extends(AngleAxisView, _super); + function AngleAxisView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = AngleAxisView.type; + _this.axisPointerClass = 'PolarAxisPointer'; + return _this; + } + AngleAxisView.prototype.render = function (angleAxisModel, ecModel) { + this.group.removeAll(); + if (!angleAxisModel.get('show')) { + return; + } + var angleAxis = angleAxisModel.axis; + var polar = angleAxis.polar; + var radiusExtent = polar.getRadiusAxis().getExtent(); + var ticksAngles = angleAxis.getTicksCoords(); + var minorTickAngles = angleAxis.getMinorTicksCoords(); + var labels = map(angleAxis.getViewLabels(), function (labelItem) { + labelItem = clone(labelItem); + var scale = angleAxis.scale; + var tickValue = scale.type === 'ordinal' ? scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue; + labelItem.coord = angleAxis.dataToCoord(tickValue); + return labelItem; + }); + fixAngleOverlap(labels); + fixAngleOverlap(ticksAngles); + each(elementList$1, function (name) { + if (angleAxisModel.get([name, 'show']) && (!angleAxis.scale.isBlank() || name === 'axisLine')) { + angelAxisElementsBuilders[name](this.group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels); + } + }, this); + }; + AngleAxisView.type = 'angleAxis'; + return AngleAxisView; + }(AxisView); + var angelAxisElementsBuilders = { + axisLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) { + var lineStyleModel = angleAxisModel.getModel(['axisLine', 'lineStyle']); + var angleAxis = polar.getAngleAxis(); + var RADIAN = Math.PI / 180; + var angleExtent = angleAxis.getExtent(); + // extent id of the axis radius (r0 and r) + var rId = getRadiusIdx(polar); + var r0Id = rId ? 0 : 1; + var shape; + var shapeType = Math.abs(angleExtent[1] - angleExtent[0]) === 360 ? 'Circle' : 'Arc'; + if (radiusExtent[r0Id] === 0) { + shape = new graphic[shapeType]({ + shape: { + cx: polar.cx, + cy: polar.cy, + r: radiusExtent[rId], + startAngle: -angleExtent[0] * RADIAN, + endAngle: -angleExtent[1] * RADIAN, + clockwise: angleAxis.inverse + }, + style: lineStyleModel.getLineStyle(), + z2: 1, + silent: true + }); + } else { + shape = new Ring({ + shape: { + cx: polar.cx, + cy: polar.cy, + r: radiusExtent[rId], + r0: radiusExtent[r0Id] + }, + style: lineStyleModel.getLineStyle(), + z2: 1, + silent: true + }); + } + shape.style.fill = null; + group.add(shape); + }, + axisTick: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) { + var tickModel = angleAxisModel.getModel('axisTick'); + var tickLen = (tickModel.get('inside') ? -1 : 1) * tickModel.get('length'); + var radius = radiusExtent[getRadiusIdx(polar)]; + var lines = map(ticksAngles, function (tickAngleItem) { + return new Line({ + shape: getAxisLineShape(polar, [radius, radius + tickLen], tickAngleItem.coord) + }); + }); + group.add(mergePath$1(lines, { + style: defaults(tickModel.getModel('lineStyle').getLineStyle(), { + stroke: angleAxisModel.get(['axisLine', 'lineStyle', 'color']) + }) + })); + }, + minorTick: function (group, angleAxisModel, polar, tickAngles, minorTickAngles, radiusExtent) { + if (!minorTickAngles.length) { + return; + } + var tickModel = angleAxisModel.getModel('axisTick'); + var minorTickModel = angleAxisModel.getModel('minorTick'); + var tickLen = (tickModel.get('inside') ? -1 : 1) * minorTickModel.get('length'); + var radius = radiusExtent[getRadiusIdx(polar)]; + var lines = []; + for (var i = 0; i < minorTickAngles.length; i++) { + for (var k = 0; k < minorTickAngles[i].length; k++) { + lines.push(new Line({ + shape: getAxisLineShape(polar, [radius, radius + tickLen], minorTickAngles[i][k].coord) + })); + } + } + group.add(mergePath$1(lines, { + style: defaults(minorTickModel.getModel('lineStyle').getLineStyle(), defaults(tickModel.getLineStyle(), { + stroke: angleAxisModel.get(['axisLine', 'lineStyle', 'color']) + })) + })); + }, + axisLabel: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent, labels) { + var rawCategoryData = angleAxisModel.getCategories(true); + var commonLabelModel = angleAxisModel.getModel('axisLabel'); + var labelMargin = commonLabelModel.get('margin'); + var triggerEvent = angleAxisModel.get('triggerEvent'); + // Use length of ticksAngles because it may remove the last tick to avoid overlapping + each(labels, function (labelItem, idx) { + var labelModel = commonLabelModel; + var tickValue = labelItem.tickValue; + var r = radiusExtent[getRadiusIdx(polar)]; + var p = polar.coordToPoint([r + labelMargin, labelItem.coord]); + var cx = polar.cx; + var cy = polar.cy; + var labelTextAlign = Math.abs(p[0] - cx) / r < 0.3 ? 'center' : p[0] > cx ? 'left' : 'right'; + var labelTextVerticalAlign = Math.abs(p[1] - cy) / r < 0.3 ? 'middle' : p[1] > cy ? 'top' : 'bottom'; + if (rawCategoryData && rawCategoryData[tickValue]) { + var rawCategoryItem = rawCategoryData[tickValue]; + if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) { + labelModel = new Model(rawCategoryItem.textStyle, commonLabelModel, commonLabelModel.ecModel); + } + } + var textEl = new ZRText({ + silent: AxisBuilder.isLabelSilent(angleAxisModel), + style: createTextStyle(labelModel, { + x: p[0], + y: p[1], + fill: labelModel.getTextColor() || angleAxisModel.get(['axisLine', 'lineStyle', 'color']), + text: labelItem.formattedLabel, + align: labelTextAlign, + verticalAlign: labelTextVerticalAlign + }) + }); + group.add(textEl); + // Pack data for mouse event + if (triggerEvent) { + var eventData = AxisBuilder.makeAxisEventDataBase(angleAxisModel); + eventData.targetType = 'axisLabel'; + eventData.value = labelItem.rawLabel; + getECData(textEl).eventData = eventData; + } + }, this); + }, + splitLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) { + var splitLineModel = angleAxisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineColors = lineStyleModel.get('color'); + var lineCount = 0; + lineColors = lineColors instanceof Array ? lineColors : [lineColors]; + var splitLines = []; + for (var i = 0; i < ticksAngles.length; i++) { + var colorIndex = lineCount++ % lineColors.length; + splitLines[colorIndex] = splitLines[colorIndex] || []; + splitLines[colorIndex].push(new Line({ + shape: getAxisLineShape(polar, radiusExtent, ticksAngles[i].coord) + })); + } + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitLines.length; i++) { + group.add(mergePath$1(splitLines[i], { + style: defaults({ + stroke: lineColors[i % lineColors.length] + }, lineStyleModel.getLineStyle()), + silent: true, + z: angleAxisModel.get('z') + })); + } + }, + minorSplitLine: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) { + if (!minorTickAngles.length) { + return; + } + var minorSplitLineModel = angleAxisModel.getModel('minorSplitLine'); + var lineStyleModel = minorSplitLineModel.getModel('lineStyle'); + var lines = []; + for (var i = 0; i < minorTickAngles.length; i++) { + for (var k = 0; k < minorTickAngles[i].length; k++) { + lines.push(new Line({ + shape: getAxisLineShape(polar, radiusExtent, minorTickAngles[i][k].coord) + })); + } + } + group.add(mergePath$1(lines, { + style: lineStyleModel.getLineStyle(), + silent: true, + z: angleAxisModel.get('z') + })); + }, + splitArea: function (group, angleAxisModel, polar, ticksAngles, minorTickAngles, radiusExtent) { + if (!ticksAngles.length) { + return; + } + var splitAreaModel = angleAxisModel.getModel('splitArea'); + var areaStyleModel = splitAreaModel.getModel('areaStyle'); + var areaColors = areaStyleModel.get('color'); + var lineCount = 0; + areaColors = areaColors instanceof Array ? areaColors : [areaColors]; + var splitAreas = []; + var RADIAN = Math.PI / 180; + var prevAngle = -ticksAngles[0].coord * RADIAN; + var r0 = Math.min(radiusExtent[0], radiusExtent[1]); + var r1 = Math.max(radiusExtent[0], radiusExtent[1]); + var clockwise = angleAxisModel.get('clockwise'); + for (var i = 1, len = ticksAngles.length; i <= len; i++) { + var coord = i === len ? ticksAngles[0].coord : ticksAngles[i].coord; + var colorIndex = lineCount++ % areaColors.length; + splitAreas[colorIndex] = splitAreas[colorIndex] || []; + splitAreas[colorIndex].push(new Sector({ + shape: { + cx: polar.cx, + cy: polar.cy, + r0: r0, + r: r1, + startAngle: prevAngle, + endAngle: -coord * RADIAN, + clockwise: clockwise + }, + silent: true + })); + prevAngle = -coord * RADIAN; + } + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitAreas.length; i++) { + group.add(mergePath$1(splitAreas[i], { + style: defaults({ + fill: areaColors[i % areaColors.length] + }, areaStyleModel.getAreaStyle()), + silent: true + })); + } + } + }; + + var axisBuilderAttrs$2 = ['axisLine', 'axisTickLabel', 'axisName']; + var selfBuilderAttrs$1 = ['splitLine', 'splitArea', 'minorSplitLine']; + var RadiusAxisView = /** @class */function (_super) { + __extends(RadiusAxisView, _super); + function RadiusAxisView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = RadiusAxisView.type; + _this.axisPointerClass = 'PolarAxisPointer'; + return _this; + } + RadiusAxisView.prototype.render = function (radiusAxisModel, ecModel) { + this.group.removeAll(); + if (!radiusAxisModel.get('show')) { + return; + } + var oldAxisGroup = this._axisGroup; + var newAxisGroup = this._axisGroup = new Group(); + this.group.add(newAxisGroup); + var radiusAxis = radiusAxisModel.axis; + var polar = radiusAxis.polar; + var angleAxis = polar.getAngleAxis(); + var ticksCoords = radiusAxis.getTicksCoords(); + var minorTicksCoords = radiusAxis.getMinorTicksCoords(); + var axisAngle = angleAxis.getExtent()[0]; + var radiusExtent = radiusAxis.getExtent(); + var layout = layoutAxis(polar, radiusAxisModel, axisAngle); + var axisBuilder = new AxisBuilder(radiusAxisModel, layout); + each(axisBuilderAttrs$2, axisBuilder.add, axisBuilder); + newAxisGroup.add(axisBuilder.getGroup()); + groupTransition(oldAxisGroup, newAxisGroup, radiusAxisModel); + each(selfBuilderAttrs$1, function (name) { + if (radiusAxisModel.get([name, 'show']) && !radiusAxis.scale.isBlank()) { + axisElementBuilders$1[name](this.group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords); + } + }, this); + }; + RadiusAxisView.type = 'radiusAxis'; + return RadiusAxisView; + }(AxisView); + var axisElementBuilders$1 = { + splitLine: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) { + var splitLineModel = radiusAxisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineColors = lineStyleModel.get('color'); + var lineCount = 0; + var angleAxis = polar.getAngleAxis(); + var RADIAN = Math.PI / 180; + var angleExtent = angleAxis.getExtent(); + var shapeType = Math.abs(angleExtent[1] - angleExtent[0]) === 360 ? 'Circle' : 'Arc'; + lineColors = lineColors instanceof Array ? lineColors : [lineColors]; + var splitLines = []; + for (var i = 0; i < ticksCoords.length; i++) { + var colorIndex = lineCount++ % lineColors.length; + splitLines[colorIndex] = splitLines[colorIndex] || []; + splitLines[colorIndex].push(new graphic[shapeType]({ + shape: { + cx: polar.cx, + cy: polar.cy, + // ensure circle radius >= 0 + r: Math.max(ticksCoords[i].coord, 0), + startAngle: -angleExtent[0] * RADIAN, + endAngle: -angleExtent[1] * RADIAN, + clockwise: angleAxis.inverse + } + })); + } + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitLines.length; i++) { + group.add(mergePath$1(splitLines[i], { + style: defaults({ + stroke: lineColors[i % lineColors.length], + fill: null + }, lineStyleModel.getLineStyle()), + silent: true + })); + } + }, + minorSplitLine: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords) { + if (!minorTicksCoords.length) { + return; + } + var minorSplitLineModel = radiusAxisModel.getModel('minorSplitLine'); + var lineStyleModel = minorSplitLineModel.getModel('lineStyle'); + var lines = []; + for (var i = 0; i < minorTicksCoords.length; i++) { + for (var k = 0; k < minorTicksCoords[i].length; k++) { + lines.push(new Circle({ + shape: { + cx: polar.cx, + cy: polar.cy, + r: minorTicksCoords[i][k].coord + } + })); + } + } + group.add(mergePath$1(lines, { + style: defaults({ + fill: null + }, lineStyleModel.getLineStyle()), + silent: true + })); + }, + splitArea: function (group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) { + if (!ticksCoords.length) { + return; + } + var splitAreaModel = radiusAxisModel.getModel('splitArea'); + var areaStyleModel = splitAreaModel.getModel('areaStyle'); + var areaColors = areaStyleModel.get('color'); + var lineCount = 0; + areaColors = areaColors instanceof Array ? areaColors : [areaColors]; + var splitAreas = []; + var prevRadius = ticksCoords[0].coord; + for (var i = 1; i < ticksCoords.length; i++) { + var colorIndex = lineCount++ % areaColors.length; + splitAreas[colorIndex] = splitAreas[colorIndex] || []; + splitAreas[colorIndex].push(new Sector({ + shape: { + cx: polar.cx, + cy: polar.cy, + r0: prevRadius, + r: ticksCoords[i].coord, + startAngle: 0, + endAngle: Math.PI * 2 + }, + silent: true + })); + prevRadius = ticksCoords[i].coord; + } + // Simple optimization + // Batching the lines if color are the same + for (var i = 0; i < splitAreas.length; i++) { + group.add(mergePath$1(splitAreas[i], { + style: defaults({ + fill: areaColors[i % areaColors.length] + }, areaStyleModel.getAreaStyle()), + silent: true + })); + } + } + }; + /** + * @inner + */ + function layoutAxis(polar, radiusAxisModel, axisAngle) { + return { + position: [polar.cx, polar.cy], + rotation: axisAngle / 180 * Math.PI, + labelDirection: -1, + tickDirection: -1, + nameDirection: 1, + labelRotate: radiusAxisModel.getModel('axisLabel').get('rotate'), + // Over splitLine and splitArea + z2: 1 + }; + } + + function getSeriesStackId$1(seriesModel) { + return seriesModel.get('stack') || '__ec_stack_' + seriesModel.seriesIndex; + } + function getAxisKey$1(polar, axis) { + return axis.dim + polar.model.componentIndex; + } + function barLayoutPolar(seriesType, ecModel, api) { + var lastStackCoords = {}; + var barWidthAndOffset = calRadialBar(filter(ecModel.getSeriesByType(seriesType), function (seriesModel) { + return !ecModel.isSeriesFiltered(seriesModel) && seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'polar'; + })); + ecModel.eachSeriesByType(seriesType, function (seriesModel) { + // Check series coordinate, do layout for polar only + if (seriesModel.coordinateSystem.type !== 'polar') { + return; + } + var data = seriesModel.getData(); + var polar = seriesModel.coordinateSystem; + var baseAxis = polar.getBaseAxis(); + var axisKey = getAxisKey$1(polar, baseAxis); + var stackId = getSeriesStackId$1(seriesModel); + var columnLayoutInfo = barWidthAndOffset[axisKey][stackId]; + var columnOffset = columnLayoutInfo.offset; + var columnWidth = columnLayoutInfo.width; + var valueAxis = polar.getOtherAxis(baseAxis); + var cx = seriesModel.coordinateSystem.cx; + var cy = seriesModel.coordinateSystem.cy; + var barMinHeight = seriesModel.get('barMinHeight') || 0; + var barMinAngle = seriesModel.get('barMinAngle') || 0; + lastStackCoords[stackId] = lastStackCoords[stackId] || []; + var valueDim = data.mapDimension(valueAxis.dim); + var baseDim = data.mapDimension(baseAxis.dim); + var stacked = isDimensionStacked(data, valueDim /* , baseDim */); + var clampLayout = baseAxis.dim !== 'radius' || !seriesModel.get('roundCap', true); + var valueAxisStart = valueAxis.dataToCoord(0); + for (var idx = 0, len = data.count(); idx < len; idx++) { + var value = data.get(valueDim, idx); + var baseValue = data.get(baseDim, idx); + var sign = value >= 0 ? 'p' : 'n'; + var baseCoord = valueAxisStart; + // Because of the barMinHeight, we can not use the value in + // stackResultDimension directly. + // Only ordinal axis can be stacked. + if (stacked) { + if (!lastStackCoords[stackId][baseValue]) { + lastStackCoords[stackId][baseValue] = { + p: valueAxisStart, + n: valueAxisStart // Negative stack + }; + } + // Should also consider #4243 + baseCoord = lastStackCoords[stackId][baseValue][sign]; + } + var r0 = void 0; + var r = void 0; + var startAngle = void 0; + var endAngle = void 0; + // radial sector + if (valueAxis.dim === 'radius') { + var radiusSpan = valueAxis.dataToCoord(value) - valueAxisStart; + var angle = baseAxis.dataToCoord(baseValue); + if (Math.abs(radiusSpan) < barMinHeight) { + radiusSpan = (radiusSpan < 0 ? -1 : 1) * barMinHeight; + } + r0 = baseCoord; + r = baseCoord + radiusSpan; + startAngle = angle - columnOffset; + endAngle = startAngle - columnWidth; + stacked && (lastStackCoords[stackId][baseValue][sign] = r); + } + // tangential sector + else { + var angleSpan = valueAxis.dataToCoord(value, clampLayout) - valueAxisStart; + var radius = baseAxis.dataToCoord(baseValue); + if (Math.abs(angleSpan) < barMinAngle) { + angleSpan = (angleSpan < 0 ? -1 : 1) * barMinAngle; + } + r0 = radius + columnOffset; + r = r0 + columnWidth; + startAngle = baseCoord; + endAngle = baseCoord + angleSpan; + // if the previous stack is at the end of the ring, + // add a round to differentiate it from origin + // let extent = angleAxis.getExtent(); + // let stackCoord = angle; + // if (stackCoord === extent[0] && value > 0) { + // stackCoord = extent[1]; + // } + // else if (stackCoord === extent[1] && value < 0) { + // stackCoord = extent[0]; + // } + stacked && (lastStackCoords[stackId][baseValue][sign] = endAngle); + } + data.setItemLayout(idx, { + cx: cx, + cy: cy, + r0: r0, + r: r, + // Consider that positive angle is anti-clockwise, + // while positive radian of sector is clockwise + startAngle: -startAngle * Math.PI / 180, + endAngle: -endAngle * Math.PI / 180, + /** + * Keep the same logic with bar in catesion: use end value to + * control direction. Notice that if clockwise is true (by + * default), the sector will always draw clockwisely, no matter + * whether endAngle is greater or less than startAngle. + */ + clockwise: startAngle >= endAngle + }); + } + }); + } + /** + * Calculate bar width and offset for radial bar charts + */ + function calRadialBar(barSeries) { + // Columns info on each category axis. Key is polar name + var columnsMap = {}; + each(barSeries, function (seriesModel, idx) { + var data = seriesModel.getData(); + var polar = seriesModel.coordinateSystem; + var baseAxis = polar.getBaseAxis(); + var axisKey = getAxisKey$1(polar, baseAxis); + var axisExtent = baseAxis.getExtent(); + var bandWidth = baseAxis.type === 'category' ? baseAxis.getBandWidth() : Math.abs(axisExtent[1] - axisExtent[0]) / data.count(); + var columnsOnAxis = columnsMap[axisKey] || { + bandWidth: bandWidth, + remainedWidth: bandWidth, + autoWidthCount: 0, + categoryGap: '20%', + gap: '30%', + stacks: {} + }; + var stacks = columnsOnAxis.stacks; + columnsMap[axisKey] = columnsOnAxis; + var stackId = getSeriesStackId$1(seriesModel); + if (!stacks[stackId]) { + columnsOnAxis.autoWidthCount++; + } + stacks[stackId] = stacks[stackId] || { + width: 0, + maxWidth: 0 + }; + var barWidth = parsePercent$1(seriesModel.get('barWidth'), bandWidth); + var barMaxWidth = parsePercent$1(seriesModel.get('barMaxWidth'), bandWidth); + var barGap = seriesModel.get('barGap'); + var barCategoryGap = seriesModel.get('barCategoryGap'); + if (barWidth && !stacks[stackId].width) { + barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth); + stacks[stackId].width = barWidth; + columnsOnAxis.remainedWidth -= barWidth; + } + barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth); + barGap != null && (columnsOnAxis.gap = barGap); + barCategoryGap != null && (columnsOnAxis.categoryGap = barCategoryGap); + }); + var result = {}; + each(columnsMap, function (columnsOnAxis, coordSysName) { + result[coordSysName] = {}; + var stacks = columnsOnAxis.stacks; + var bandWidth = columnsOnAxis.bandWidth; + var categoryGap = parsePercent$1(columnsOnAxis.categoryGap, bandWidth); + var barGapPercent = parsePercent$1(columnsOnAxis.gap, 1); + var remainedWidth = columnsOnAxis.remainedWidth; + var autoWidthCount = columnsOnAxis.autoWidthCount; + var autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent); + autoWidth = Math.max(autoWidth, 0); + // Find if any auto calculated bar exceeded maxBarWidth + each(stacks, function (column, stack) { + var maxWidth = column.maxWidth; + if (maxWidth && maxWidth < autoWidth) { + maxWidth = Math.min(maxWidth, remainedWidth); + if (column.width) { + maxWidth = Math.min(maxWidth, column.width); + } + remainedWidth -= maxWidth; + column.width = maxWidth; + autoWidthCount--; + } + }); + // Recalculate width again + autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent); + autoWidth = Math.max(autoWidth, 0); + var widthSum = 0; + var lastColumn; + each(stacks, function (column, idx) { + if (!column.width) { + column.width = autoWidth; + } + lastColumn = column; + widthSum += column.width * (1 + barGapPercent); + }); + if (lastColumn) { + widthSum -= lastColumn.width * barGapPercent; + } + var offset = -widthSum / 2; + each(stacks, function (column, stackId) { + result[coordSysName][stackId] = result[coordSysName][stackId] || { + offset: offset, + width: column.width + }; + offset += column.width * (1 + barGapPercent); + }); + }); + return result; + } + + var angleAxisExtraOption = { + startAngle: 90, + clockwise: true, + splitNumber: 12, + axisLabel: { + rotate: 0 + } + }; + var radiusAxisExtraOption = { + splitNumber: 5 + }; + var PolarView = /** @class */function (_super) { + __extends(PolarView, _super); + function PolarView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = PolarView.type; + return _this; + } + PolarView.type = 'polar'; + return PolarView; + }(ComponentView); + function install$u(registers) { + use(install$s); + AxisView.registerAxisPointerClass('PolarAxisPointer', PolarAxisPointer); + registers.registerCoordinateSystem('polar', polarCreator); + registers.registerComponentModel(PolarModel); + registers.registerComponentView(PolarView); + // Model and view for angleAxis and radiusAxis + axisModelCreator(registers, 'angle', AngleAxisModel, angleAxisExtraOption); + axisModelCreator(registers, 'radius', RadiusAxisModel, radiusAxisExtraOption); + registers.registerComponentView(AngleAxisView); + registers.registerComponentView(RadiusAxisView); + registers.registerLayout(curry(barLayoutPolar, 'bar')); + } + + function layout$2(axisModel, opt) { + opt = opt || {}; + var single = axisModel.coordinateSystem; + var axis = axisModel.axis; + var layout = {}; + var axisPosition = axis.position; + var orient = axis.orient; + var rect = single.getRect(); + var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height]; + var positionMap = { + horizontal: { + top: rectBound[2], + bottom: rectBound[3] + }, + vertical: { + left: rectBound[0], + right: rectBound[1] + } + }; + layout.position = [orient === 'vertical' ? positionMap.vertical[axisPosition] : rectBound[0], orient === 'horizontal' ? positionMap.horizontal[axisPosition] : rectBound[3]]; + var r = { + horizontal: 0, + vertical: 1 + }; + layout.rotation = Math.PI / 2 * r[orient]; + var directionMap = { + top: -1, + bottom: 1, + right: 1, + left: -1 + }; + layout.labelDirection = layout.tickDirection = layout.nameDirection = directionMap[axisPosition]; + if (axisModel.get(['axisTick', 'inside'])) { + layout.tickDirection = -layout.tickDirection; + } + if (retrieve(opt.labelInside, axisModel.get(['axisLabel', 'inside']))) { + layout.labelDirection = -layout.labelDirection; + } + var labelRotation = opt.rotate; + labelRotation == null && (labelRotation = axisModel.get(['axisLabel', 'rotate'])); + layout.labelRotation = axisPosition === 'top' ? -labelRotation : labelRotation; + layout.z2 = 1; + return layout; + } + + var axisBuilderAttrs$3 = ['axisLine', 'axisTickLabel', 'axisName']; + var selfBuilderAttrs$2 = ['splitArea', 'splitLine']; + var SingleAxisView = /** @class */function (_super) { + __extends(SingleAxisView, _super); + function SingleAxisView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SingleAxisView.type; + _this.axisPointerClass = 'SingleAxisPointer'; + return _this; + } + SingleAxisView.prototype.render = function (axisModel, ecModel, api, payload) { + var group = this.group; + group.removeAll(); + var oldAxisGroup = this._axisGroup; + this._axisGroup = new Group(); + var layout = layout$2(axisModel); + var axisBuilder = new AxisBuilder(axisModel, layout); + each(axisBuilderAttrs$3, axisBuilder.add, axisBuilder); + group.add(this._axisGroup); + group.add(axisBuilder.getGroup()); + each(selfBuilderAttrs$2, function (name) { + if (axisModel.get([name, 'show'])) { + axisElementBuilders$2[name](this, this.group, this._axisGroup, axisModel); + } + }, this); + groupTransition(oldAxisGroup, this._axisGroup, axisModel); + _super.prototype.render.call(this, axisModel, ecModel, api, payload); + }; + SingleAxisView.prototype.remove = function () { + rectCoordAxisHandleRemove(this); + }; + SingleAxisView.type = 'singleAxis'; + return SingleAxisView; + }(AxisView); + var axisElementBuilders$2 = { + splitLine: function (axisView, group, axisGroup, axisModel) { + var axis = axisModel.axis; + if (axis.scale.isBlank()) { + return; + } + var splitLineModel = axisModel.getModel('splitLine'); + var lineStyleModel = splitLineModel.getModel('lineStyle'); + var lineColors = lineStyleModel.get('color'); + lineColors = lineColors instanceof Array ? lineColors : [lineColors]; + var lineWidth = lineStyleModel.get('width'); + var gridRect = axisModel.coordinateSystem.getRect(); + var isHorizontal = axis.isHorizontal(); + var splitLines = []; + var lineCount = 0; + var ticksCoords = axis.getTicksCoords({ + tickModel: splitLineModel + }); + var p1 = []; + var p2 = []; + for (var i = 0; i < ticksCoords.length; ++i) { + var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord); + if (isHorizontal) { + p1[0] = tickCoord; + p1[1] = gridRect.y; + p2[0] = tickCoord; + p2[1] = gridRect.y + gridRect.height; + } else { + p1[0] = gridRect.x; + p1[1] = tickCoord; + p2[0] = gridRect.x + gridRect.width; + p2[1] = tickCoord; + } + var line = new Line({ + shape: { + x1: p1[0], + y1: p1[1], + x2: p2[0], + y2: p2[1] + }, + silent: true + }); + subPixelOptimizeLine$1(line.shape, lineWidth); + var colorIndex = lineCount++ % lineColors.length; + splitLines[colorIndex] = splitLines[colorIndex] || []; + splitLines[colorIndex].push(line); + } + var lineStyle = lineStyleModel.getLineStyle(['color']); + for (var i = 0; i < splitLines.length; ++i) { + group.add(mergePath$1(splitLines[i], { + style: defaults({ + stroke: lineColors[i % lineColors.length] + }, lineStyle), + silent: true + })); + } + }, + splitArea: function (axisView, group, axisGroup, axisModel) { + rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, axisModel); + } + }; + + var SingleAxisModel = /** @class */function (_super) { + __extends(SingleAxisModel, _super); + function SingleAxisModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SingleAxisModel.type; + return _this; + } + SingleAxisModel.prototype.getCoordSysModel = function () { + return this; + }; + SingleAxisModel.type = 'singleAxis'; + SingleAxisModel.layoutMode = 'box'; + SingleAxisModel.defaultOption = { + left: '5%', + top: '5%', + right: '5%', + bottom: '5%', + type: 'value', + position: 'bottom', + orient: 'horizontal', + axisLine: { + show: true, + lineStyle: { + width: 1, + type: 'solid' + } + }, + // Single coordinate system and single axis is the, + // which is used as the parent tooltip model. + // same model, so we set default tooltip show as true. + tooltip: { + show: true + }, + axisTick: { + show: true, + length: 6, + lineStyle: { + width: 1 + } + }, + axisLabel: { + show: true, + interval: 'auto' + }, + splitLine: { + show: true, + lineStyle: { + type: 'dashed', + opacity: 0.2 + } + } + }; + return SingleAxisModel; + }(ComponentModel); + mixin(SingleAxisModel, AxisModelCommonMixin.prototype); + + var SingleAxis = /** @class */function (_super) { + __extends(SingleAxis, _super); + function SingleAxis(dim, scale, coordExtent, axisType, position) { + var _this = _super.call(this, dim, scale, coordExtent) || this; + _this.type = axisType || 'value'; + _this.position = position || 'bottom'; + return _this; + } + /** + * Judge the orient of the axis. + */ + SingleAxis.prototype.isHorizontal = function () { + var position = this.position; + return position === 'top' || position === 'bottom'; + }; + SingleAxis.prototype.pointToData = function (point, clamp) { + return this.coordinateSystem.pointToData(point)[0]; + }; + return SingleAxis; + }(Axis); + + var singleDimensions = ['single']; + /** + * Create a single coordinates system. + */ + var Single = /** @class */function () { + function Single(axisModel, ecModel, api) { + this.type = 'single'; + this.dimension = 'single'; + /** + * Add it just for draw tooltip. + */ + this.dimensions = singleDimensions; + this.axisPointerEnabled = true; + this.model = axisModel; + this._init(axisModel, ecModel, api); + } + /** + * Initialize single coordinate system. + */ + Single.prototype._init = function (axisModel, ecModel, api) { + var dim = this.dimension; + var axis = new SingleAxis(dim, createScaleByModel(axisModel), [0, 0], axisModel.get('type'), axisModel.get('position')); + var isCategory = axis.type === 'category'; + axis.onBand = isCategory && axisModel.get('boundaryGap'); + axis.inverse = axisModel.get('inverse'); + axis.orient = axisModel.get('orient'); + axisModel.axis = axis; + axis.model = axisModel; + axis.coordinateSystem = this; + this._axis = axis; + }; + /** + * Update axis scale after data processed + */ + Single.prototype.update = function (ecModel, api) { + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.coordinateSystem === this) { + var data_1 = seriesModel.getData(); + each(data_1.mapDimensionsAll(this.dimension), function (dim) { + this._axis.scale.unionExtentFromData(data_1, dim); + }, this); + niceScaleExtent(this._axis.scale, this._axis.model); + } + }, this); + }; + /** + * Resize the single coordinate system. + */ + Single.prototype.resize = function (axisModel, api) { + this._rect = getLayoutRect({ + left: axisModel.get('left'), + top: axisModel.get('top'), + right: axisModel.get('right'), + bottom: axisModel.get('bottom'), + width: axisModel.get('width'), + height: axisModel.get('height') + }, { + width: api.getWidth(), + height: api.getHeight() + }); + this._adjustAxis(); + }; + Single.prototype.getRect = function () { + return this._rect; + }; + Single.prototype._adjustAxis = function () { + var rect = this._rect; + var axis = this._axis; + var isHorizontal = axis.isHorizontal(); + var extent = isHorizontal ? [0, rect.width] : [0, rect.height]; + var idx = axis.inverse ? 1 : 0; + axis.setExtent(extent[idx], extent[1 - idx]); + this._updateAxisTransform(axis, isHorizontal ? rect.x : rect.y); + }; + Single.prototype._updateAxisTransform = function (axis, coordBase) { + var axisExtent = axis.getExtent(); + var extentSum = axisExtent[0] + axisExtent[1]; + var isHorizontal = axis.isHorizontal(); + axis.toGlobalCoord = isHorizontal ? function (coord) { + return coord + coordBase; + } : function (coord) { + return extentSum - coord + coordBase; + }; + axis.toLocalCoord = isHorizontal ? function (coord) { + return coord - coordBase; + } : function (coord) { + return extentSum - coord + coordBase; + }; + }; + /** + * Get axis. + */ + Single.prototype.getAxis = function () { + return this._axis; + }; + /** + * Get axis, add it just for draw tooltip. + */ + Single.prototype.getBaseAxis = function () { + return this._axis; + }; + Single.prototype.getAxes = function () { + return [this._axis]; + }; + Single.prototype.getTooltipAxes = function () { + return { + baseAxes: [this.getAxis()], + // Empty otherAxes + otherAxes: [] + }; + }; + /** + * If contain point. + */ + Single.prototype.containPoint = function (point) { + var rect = this.getRect(); + var axis = this.getAxis(); + var orient = axis.orient; + if (orient === 'horizontal') { + return axis.contain(axis.toLocalCoord(point[0])) && point[1] >= rect.y && point[1] <= rect.y + rect.height; + } else { + return axis.contain(axis.toLocalCoord(point[1])) && point[0] >= rect.y && point[0] <= rect.y + rect.height; + } + }; + Single.prototype.pointToData = function (point) { + var axis = this.getAxis(); + return [axis.coordToData(axis.toLocalCoord(point[axis.orient === 'horizontal' ? 0 : 1]))]; + }; + /** + * Convert the series data to concrete point. + * Can be [val] | val + */ + Single.prototype.dataToPoint = function (val) { + var axis = this.getAxis(); + var rect = this.getRect(); + var pt = []; + var idx = axis.orient === 'horizontal' ? 0 : 1; + if (val instanceof Array) { + val = val[0]; + } + pt[idx] = axis.toGlobalCoord(axis.dataToCoord(+val)); + pt[1 - idx] = idx === 0 ? rect.y + rect.height / 2 : rect.x + rect.width / 2; + return pt; + }; + Single.prototype.convertToPixel = function (ecModel, finder, value) { + var coordSys = getCoordSys$3(finder); + return coordSys === this ? this.dataToPoint(value) : null; + }; + Single.prototype.convertFromPixel = function (ecModel, finder, pixel) { + var coordSys = getCoordSys$3(finder); + return coordSys === this ? this.pointToData(pixel) : null; + }; + return Single; + }(); + function getCoordSys$3(finder) { + var seriesModel = finder.seriesModel; + var singleModel = finder.singleAxisModel; + return singleModel && singleModel.coordinateSystem || seriesModel && seriesModel.coordinateSystem; + } + + /** + * Create single coordinate system and inject it into seriesModel. + */ + function create$2(ecModel, api) { + var singles = []; + ecModel.eachComponent('singleAxis', function (axisModel, idx) { + var single = new Single(axisModel, ecModel, api); + single.name = 'single_' + idx; + single.resize(axisModel, api); + axisModel.coordinateSystem = single; + singles.push(single); + }); + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.get('coordinateSystem') === 'singleAxis') { + var singleAxisModel = seriesModel.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0]; + seriesModel.coordinateSystem = singleAxisModel && singleAxisModel.coordinateSystem; + } + }); + return singles; + } + var singleCreator = { + create: create$2, + dimensions: singleDimensions + }; + + var XY = ['x', 'y']; + var WH = ['width', 'height']; + var SingleAxisPointer = /** @class */function (_super) { + __extends(SingleAxisPointer, _super); + function SingleAxisPointer() { + return _super !== null && _super.apply(this, arguments) || this; + } + /** + * @override + */ + SingleAxisPointer.prototype.makeElOption = function (elOption, value, axisModel, axisPointerModel, api) { + var axis = axisModel.axis; + var coordSys = axis.coordinateSystem; + var otherExtent = getGlobalExtent(coordSys, 1 - getPointDimIndex(axis)); + var pixelValue = coordSys.dataToPoint(value)[0]; + var axisPointerType = axisPointerModel.get('type'); + if (axisPointerType && axisPointerType !== 'none') { + var elStyle = buildElStyle(axisPointerModel); + var pointerOption = pointerShapeBuilder$2[axisPointerType](axis, pixelValue, otherExtent); + pointerOption.style = elStyle; + elOption.graphicKey = pointerOption.type; + elOption.pointer = pointerOption; + } + var layoutInfo = layout$2(axisModel); + buildCartesianSingleLabelElOption( + // @ts-ignore + value, elOption, layoutInfo, axisModel, axisPointerModel, api); + }; + /** + * @override + */ + SingleAxisPointer.prototype.getHandleTransform = function (value, axisModel, axisPointerModel) { + var layoutInfo = layout$2(axisModel, { + labelInside: false + }); + // @ts-ignore + layoutInfo.labelMargin = axisPointerModel.get(['handle', 'margin']); + var position = getTransformedPosition(axisModel.axis, value, layoutInfo); + return { + x: position[0], + y: position[1], + rotation: layoutInfo.rotation + (layoutInfo.labelDirection < 0 ? Math.PI : 0) + }; + }; + /** + * @override + */ + SingleAxisPointer.prototype.updateHandleTransform = function (transform, delta, axisModel, axisPointerModel) { + var axis = axisModel.axis; + var coordSys = axis.coordinateSystem; + var dimIndex = getPointDimIndex(axis); + var axisExtent = getGlobalExtent(coordSys, dimIndex); + var currPosition = [transform.x, transform.y]; + currPosition[dimIndex] += delta[dimIndex]; + currPosition[dimIndex] = Math.min(axisExtent[1], currPosition[dimIndex]); + currPosition[dimIndex] = Math.max(axisExtent[0], currPosition[dimIndex]); + var otherExtent = getGlobalExtent(coordSys, 1 - dimIndex); + var cursorOtherValue = (otherExtent[1] + otherExtent[0]) / 2; + var cursorPoint = [cursorOtherValue, cursorOtherValue]; + cursorPoint[dimIndex] = currPosition[dimIndex]; + return { + x: currPosition[0], + y: currPosition[1], + rotation: transform.rotation, + cursorPoint: cursorPoint, + tooltipOption: { + verticalAlign: 'middle' + } + }; + }; + return SingleAxisPointer; + }(BaseAxisPointer); + var pointerShapeBuilder$2 = { + line: function (axis, pixelValue, otherExtent) { + var targetShape = makeLineShape([pixelValue, otherExtent[0]], [pixelValue, otherExtent[1]], getPointDimIndex(axis)); + return { + type: 'Line', + subPixelOptimize: true, + shape: targetShape + }; + }, + shadow: function (axis, pixelValue, otherExtent) { + var bandWidth = axis.getBandWidth(); + var span = otherExtent[1] - otherExtent[0]; + return { + type: 'Rect', + shape: makeRectShape([pixelValue - bandWidth / 2, otherExtent[0]], [bandWidth, span], getPointDimIndex(axis)) + }; + } + }; + function getPointDimIndex(axis) { + return axis.isHorizontal() ? 0 : 1; + } + function getGlobalExtent(coordSys, dimIndex) { + var rect = coordSys.getRect(); + return [rect[XY[dimIndex]], rect[XY[dimIndex]] + rect[WH[dimIndex]]]; + } + + var SingleView = /** @class */function (_super) { + __extends(SingleView, _super); + function SingleView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SingleView.type; + return _this; + } + SingleView.type = 'single'; + return SingleView; + }(ComponentView); + function install$v(registers) { + use(install$s); + AxisView.registerAxisPointerClass('SingleAxisPointer', SingleAxisPointer); + registers.registerComponentView(SingleView); + // Axis + registers.registerComponentView(SingleAxisView); + registers.registerComponentModel(SingleAxisModel); + axisModelCreator(registers, 'single', SingleAxisModel, SingleAxisModel.defaultOption); + registers.registerCoordinateSystem('single', singleCreator); + } + + var CalendarModel = /** @class */function (_super) { + __extends(CalendarModel, _super); + function CalendarModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CalendarModel.type; + return _this; + } + /** + * @override + */ + CalendarModel.prototype.init = function (option, parentModel, ecModel) { + var inputPositionParams = getLayoutParams(option); + _super.prototype.init.apply(this, arguments); + mergeAndNormalizeLayoutParams(option, inputPositionParams); + }; + /** + * @override + */ + CalendarModel.prototype.mergeOption = function (option) { + _super.prototype.mergeOption.apply(this, arguments); + mergeAndNormalizeLayoutParams(this.option, option); + }; + CalendarModel.prototype.getCellSize = function () { + // Has been normalized + return this.option.cellSize; + }; + CalendarModel.type = 'calendar'; + CalendarModel.defaultOption = { + // zlevel: 0, + z: 2, + left: 80, + top: 60, + cellSize: 20, + // horizontal vertical + orient: 'horizontal', + // month separate line style + splitLine: { + show: true, + lineStyle: { + color: '#000', + width: 1, + type: 'solid' + } + }, + // rect style temporarily unused emphasis + itemStyle: { + color: '#fff', + borderWidth: 1, + borderColor: '#ccc' + }, + // week text style + dayLabel: { + show: true, + firstDay: 0, + // start end + position: 'start', + margin: '50%', + color: '#000' + }, + // month text style + monthLabel: { + show: true, + // start end + position: 'start', + margin: 5, + // center or left + align: 'center', + formatter: null, + color: '#000' + }, + // year text style + yearLabel: { + show: true, + // top bottom left right + position: null, + margin: 30, + formatter: null, + color: '#ccc', + fontFamily: 'sans-serif', + fontWeight: 'bolder', + fontSize: 20 + } + }; + return CalendarModel; + }(ComponentModel); + function mergeAndNormalizeLayoutParams(target, raw) { + // Normalize cellSize + var cellSize = target.cellSize; + var cellSizeArr; + if (!isArray(cellSize)) { + cellSizeArr = target.cellSize = [cellSize, cellSize]; + } else { + cellSizeArr = cellSize; + } + if (cellSizeArr.length === 1) { + cellSizeArr[1] = cellSizeArr[0]; + } + var ignoreSize = map([0, 1], function (hvIdx) { + // If user have set `width` or both `left` and `right`, cellSizeArr + // will be automatically set to 'auto', otherwise the default + // setting of cellSizeArr will make `width` setting not work. + if (sizeCalculable(raw, hvIdx)) { + cellSizeArr[hvIdx] = 'auto'; + } + return cellSizeArr[hvIdx] != null && cellSizeArr[hvIdx] !== 'auto'; + }); + mergeLayoutParam(target, raw, { + type: 'box', + ignoreSize: ignoreSize + }); + } + + var CalendarView = /** @class */function (_super) { + __extends(CalendarView, _super); + function CalendarView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = CalendarView.type; + return _this; + } + CalendarView.prototype.render = function (calendarModel, ecModel, api) { + var group = this.group; + group.removeAll(); + var coordSys = calendarModel.coordinateSystem; + // range info + var rangeData = coordSys.getRangeInfo(); + var orient = coordSys.getOrient(); + // locale + var localeModel = ecModel.getLocaleModel(); + this._renderDayRect(calendarModel, rangeData, group); + // _renderLines must be called prior to following function + this._renderLines(calendarModel, rangeData, orient, group); + this._renderYearText(calendarModel, rangeData, orient, group); + this._renderMonthText(calendarModel, localeModel, orient, group); + this._renderWeekText(calendarModel, localeModel, rangeData, orient, group); + }; + // render day rect + CalendarView.prototype._renderDayRect = function (calendarModel, rangeData, group) { + var coordSys = calendarModel.coordinateSystem; + var itemRectStyleModel = calendarModel.getModel('itemStyle').getItemStyle(); + var sw = coordSys.getCellWidth(); + var sh = coordSys.getCellHeight(); + for (var i = rangeData.start.time; i <= rangeData.end.time; i = coordSys.getNextNDay(i, 1).time) { + var point = coordSys.dataToRect([i], false).tl; + // every rect + var rect = new Rect({ + shape: { + x: point[0], + y: point[1], + width: sw, + height: sh + }, + cursor: 'default', + style: itemRectStyleModel + }); + group.add(rect); + } + }; + // render separate line + CalendarView.prototype._renderLines = function (calendarModel, rangeData, orient, group) { + var self = this; + var coordSys = calendarModel.coordinateSystem; + var lineStyleModel = calendarModel.getModel(['splitLine', 'lineStyle']).getLineStyle(); + var show = calendarModel.get(['splitLine', 'show']); + var lineWidth = lineStyleModel.lineWidth; + this._tlpoints = []; + this._blpoints = []; + this._firstDayOfMonth = []; + this._firstDayPoints = []; + var firstDay = rangeData.start; + for (var i = 0; firstDay.time <= rangeData.end.time; i++) { + addPoints(firstDay.formatedDate); + if (i === 0) { + firstDay = coordSys.getDateInfo(rangeData.start.y + '-' + rangeData.start.m); + } + var date = firstDay.date; + date.setMonth(date.getMonth() + 1); + firstDay = coordSys.getDateInfo(date); + } + addPoints(coordSys.getNextNDay(rangeData.end.time, 1).formatedDate); + function addPoints(date) { + self._firstDayOfMonth.push(coordSys.getDateInfo(date)); + self._firstDayPoints.push(coordSys.dataToRect([date], false).tl); + var points = self._getLinePointsOfOneWeek(calendarModel, date, orient); + self._tlpoints.push(points[0]); + self._blpoints.push(points[points.length - 1]); + show && self._drawSplitline(points, lineStyleModel, group); + } + // render top/left line + show && this._drawSplitline(self._getEdgesPoints(self._tlpoints, lineWidth, orient), lineStyleModel, group); + // render bottom/right line + show && this._drawSplitline(self._getEdgesPoints(self._blpoints, lineWidth, orient), lineStyleModel, group); + }; + // get points at both ends + CalendarView.prototype._getEdgesPoints = function (points, lineWidth, orient) { + var rs = [points[0].slice(), points[points.length - 1].slice()]; + var idx = orient === 'horizontal' ? 0 : 1; + // both ends of the line are extend half lineWidth + rs[0][idx] = rs[0][idx] - lineWidth / 2; + rs[1][idx] = rs[1][idx] + lineWidth / 2; + return rs; + }; + // render split line + CalendarView.prototype._drawSplitline = function (points, lineStyle, group) { + var poyline = new Polyline({ + z2: 20, + shape: { + points: points + }, + style: lineStyle + }); + group.add(poyline); + }; + // render month line of one week points + CalendarView.prototype._getLinePointsOfOneWeek = function (calendarModel, date, orient) { + var coordSys = calendarModel.coordinateSystem; + var parsedDate = coordSys.getDateInfo(date); + var points = []; + for (var i = 0; i < 7; i++) { + var tmpD = coordSys.getNextNDay(parsedDate.time, i); + var point = coordSys.dataToRect([tmpD.time], false); + points[2 * tmpD.day] = point.tl; + points[2 * tmpD.day + 1] = point[orient === 'horizontal' ? 'bl' : 'tr']; + } + return points; + }; + CalendarView.prototype._formatterLabel = function (formatter, params) { + if (isString(formatter) && formatter) { + return formatTplSimple(formatter, params); + } + if (isFunction(formatter)) { + return formatter(params); + } + return params.nameMap; + }; + CalendarView.prototype._yearTextPositionControl = function (textEl, point, orient, position, margin) { + var x = point[0]; + var y = point[1]; + var aligns = ['center', 'bottom']; + if (position === 'bottom') { + y += margin; + aligns = ['center', 'top']; + } else if (position === 'left') { + x -= margin; + } else if (position === 'right') { + x += margin; + aligns = ['center', 'top']; + } else { + // top + y -= margin; + } + var rotate = 0; + if (position === 'left' || position === 'right') { + rotate = Math.PI / 2; + } + return { + rotation: rotate, + x: x, + y: y, + style: { + align: aligns[0], + verticalAlign: aligns[1] + } + }; + }; + // render year + CalendarView.prototype._renderYearText = function (calendarModel, rangeData, orient, group) { + var yearLabel = calendarModel.getModel('yearLabel'); + if (!yearLabel.get('show')) { + return; + } + var margin = yearLabel.get('margin'); + var pos = yearLabel.get('position'); + if (!pos) { + pos = orient !== 'horizontal' ? 'top' : 'left'; + } + var points = [this._tlpoints[this._tlpoints.length - 1], this._blpoints[0]]; + var xc = (points[0][0] + points[1][0]) / 2; + var yc = (points[0][1] + points[1][1]) / 2; + var idx = orient === 'horizontal' ? 0 : 1; + var posPoints = { + top: [xc, points[idx][1]], + bottom: [xc, points[1 - idx][1]], + left: [points[1 - idx][0], yc], + right: [points[idx][0], yc] + }; + var name = rangeData.start.y; + if (+rangeData.end.y > +rangeData.start.y) { + name = name + '-' + rangeData.end.y; + } + var formatter = yearLabel.get('formatter'); + var params = { + start: rangeData.start.y, + end: rangeData.end.y, + nameMap: name + }; + var content = this._formatterLabel(formatter, params); + var yearText = new ZRText({ + z2: 30, + style: createTextStyle(yearLabel, { + text: content + }) + }); + yearText.attr(this._yearTextPositionControl(yearText, posPoints[pos], orient, pos, margin)); + group.add(yearText); + }; + CalendarView.prototype._monthTextPositionControl = function (point, isCenter, orient, position, margin) { + var align = 'left'; + var vAlign = 'top'; + var x = point[0]; + var y = point[1]; + if (orient === 'horizontal') { + y = y + margin; + if (isCenter) { + align = 'center'; + } + if (position === 'start') { + vAlign = 'bottom'; + } + } else { + x = x + margin; + if (isCenter) { + vAlign = 'middle'; + } + if (position === 'start') { + align = 'right'; + } + } + return { + x: x, + y: y, + align: align, + verticalAlign: vAlign + }; + }; + // render month and year text + CalendarView.prototype._renderMonthText = function (calendarModel, localeModel, orient, group) { + var monthLabel = calendarModel.getModel('monthLabel'); + if (!monthLabel.get('show')) { + return; + } + var nameMap = monthLabel.get('nameMap'); + var margin = monthLabel.get('margin'); + var pos = monthLabel.get('position'); + var align = monthLabel.get('align'); + var termPoints = [this._tlpoints, this._blpoints]; + if (!nameMap || isString(nameMap)) { + if (nameMap) { + // case-sensitive + localeModel = getLocaleModel(nameMap) || localeModel; + } + // PENDING + // for ZH locale, original form is `一月` but current form is `1月` + nameMap = localeModel.get(['time', 'monthAbbr']) || []; + } + var idx = pos === 'start' ? 0 : 1; + var axis = orient === 'horizontal' ? 0 : 1; + margin = pos === 'start' ? -margin : margin; + var isCenter = align === 'center'; + for (var i = 0; i < termPoints[idx].length - 1; i++) { + var tmp = termPoints[idx][i].slice(); + var firstDay = this._firstDayOfMonth[i]; + if (isCenter) { + var firstDayPoints = this._firstDayPoints[i]; + tmp[axis] = (firstDayPoints[axis] + termPoints[0][i + 1][axis]) / 2; + } + var formatter = monthLabel.get('formatter'); + var name_1 = nameMap[+firstDay.m - 1]; + var params = { + yyyy: firstDay.y, + yy: (firstDay.y + '').slice(2), + MM: firstDay.m, + M: +firstDay.m, + nameMap: name_1 + }; + var content = this._formatterLabel(formatter, params); + var monthText = new ZRText({ + z2: 30, + style: extend(createTextStyle(monthLabel, { + text: content + }), this._monthTextPositionControl(tmp, isCenter, orient, pos, margin)) + }); + group.add(monthText); + } + }; + CalendarView.prototype._weekTextPositionControl = function (point, orient, position, margin, cellSize) { + var align = 'center'; + var vAlign = 'middle'; + var x = point[0]; + var y = point[1]; + var isStart = position === 'start'; + if (orient === 'horizontal') { + x = x + margin + (isStart ? 1 : -1) * cellSize[0] / 2; + align = isStart ? 'right' : 'left'; + } else { + y = y + margin + (isStart ? 1 : -1) * cellSize[1] / 2; + vAlign = isStart ? 'bottom' : 'top'; + } + return { + x: x, + y: y, + align: align, + verticalAlign: vAlign + }; + }; + // render weeks + CalendarView.prototype._renderWeekText = function (calendarModel, localeModel, rangeData, orient, group) { + var dayLabel = calendarModel.getModel('dayLabel'); + if (!dayLabel.get('show')) { + return; + } + var coordSys = calendarModel.coordinateSystem; + var pos = dayLabel.get('position'); + var nameMap = dayLabel.get('nameMap'); + var margin = dayLabel.get('margin'); + var firstDayOfWeek = coordSys.getFirstDayOfWeek(); + if (!nameMap || isString(nameMap)) { + if (nameMap) { + // case-sensitive + localeModel = getLocaleModel(nameMap) || localeModel; + } + // Use the first letter of `dayOfWeekAbbr` if `dayOfWeekShort` doesn't exist in the locale file + var dayOfWeekShort = localeModel.get(['time', 'dayOfWeekShort']); + nameMap = dayOfWeekShort || map(localeModel.get(['time', 'dayOfWeekAbbr']), function (val) { + return val[0]; + }); + } + var start = coordSys.getNextNDay(rangeData.end.time, 7 - rangeData.lweek).time; + var cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()]; + margin = parsePercent$1(margin, Math.min(cellSize[1], cellSize[0])); + if (pos === 'start') { + start = coordSys.getNextNDay(rangeData.start.time, -(7 + rangeData.fweek)).time; + margin = -margin; + } + for (var i = 0; i < 7; i++) { + var tmpD = coordSys.getNextNDay(start, i); + var point = coordSys.dataToRect([tmpD.time], false).center; + var day = i; + day = Math.abs((i + firstDayOfWeek) % 7); + var weekText = new ZRText({ + z2: 30, + style: extend(createTextStyle(dayLabel, { + text: nameMap[day] + }), this._weekTextPositionControl(point, orient, pos, margin, cellSize)) + }); + group.add(weekText); + } + }; + CalendarView.type = 'calendar'; + return CalendarView; + }(ComponentView); + + // (24*60*60*1000) + var PROXIMATE_ONE_DAY = 86400000; + var Calendar = /** @class */function () { + function Calendar(calendarModel, ecModel, api) { + this.type = 'calendar'; + this.dimensions = Calendar.dimensions; + // Required in createListFromData + this.getDimensionsInfo = Calendar.getDimensionsInfo; + this._model = calendarModel; + } + Calendar.getDimensionsInfo = function () { + return [{ + name: 'time', + type: 'time' + }, 'value']; + }; + Calendar.prototype.getRangeInfo = function () { + return this._rangeInfo; + }; + Calendar.prototype.getModel = function () { + return this._model; + }; + Calendar.prototype.getRect = function () { + return this._rect; + }; + Calendar.prototype.getCellWidth = function () { + return this._sw; + }; + Calendar.prototype.getCellHeight = function () { + return this._sh; + }; + Calendar.prototype.getOrient = function () { + return this._orient; + }; + /** + * getFirstDayOfWeek + * + * @example + * 0 : start at Sunday + * 1 : start at Monday + * + * @return {number} + */ + Calendar.prototype.getFirstDayOfWeek = function () { + return this._firstDayOfWeek; + }; + /** + * get date info + * } + */ + Calendar.prototype.getDateInfo = function (date) { + date = parseDate(date); + var y = date.getFullYear(); + var m = date.getMonth() + 1; + var mStr = m < 10 ? '0' + m : '' + m; + var d = date.getDate(); + var dStr = d < 10 ? '0' + d : '' + d; + var day = date.getDay(); + day = Math.abs((day + 7 - this.getFirstDayOfWeek()) % 7); + return { + y: y + '', + m: mStr, + d: dStr, + day: day, + time: date.getTime(), + formatedDate: y + '-' + mStr + '-' + dStr, + date: date + }; + }; + Calendar.prototype.getNextNDay = function (date, n) { + n = n || 0; + if (n === 0) { + return this.getDateInfo(date); + } + date = new Date(this.getDateInfo(date).time); + date.setDate(date.getDate() + n); + return this.getDateInfo(date); + }; + Calendar.prototype.update = function (ecModel, api) { + this._firstDayOfWeek = +this._model.getModel('dayLabel').get('firstDay'); + this._orient = this._model.get('orient'); + this._lineWidth = this._model.getModel('itemStyle').getItemStyle().lineWidth || 0; + this._rangeInfo = this._getRangeInfo(this._initRangeOption()); + var weeks = this._rangeInfo.weeks || 1; + var whNames = ['width', 'height']; + var cellSize = this._model.getCellSize().slice(); + var layoutParams = this._model.getBoxLayoutParams(); + var cellNumbers = this._orient === 'horizontal' ? [weeks, 7] : [7, weeks]; + each([0, 1], function (idx) { + if (cellSizeSpecified(cellSize, idx)) { + layoutParams[whNames[idx]] = cellSize[idx] * cellNumbers[idx]; + } + }); + var whGlobal = { + width: api.getWidth(), + height: api.getHeight() + }; + var calendarRect = this._rect = getLayoutRect(layoutParams, whGlobal); + each([0, 1], function (idx) { + if (!cellSizeSpecified(cellSize, idx)) { + cellSize[idx] = calendarRect[whNames[idx]] / cellNumbers[idx]; + } + }); + function cellSizeSpecified(cellSize, idx) { + return cellSize[idx] != null && cellSize[idx] !== 'auto'; + } + // Has been calculated out number. + this._sw = cellSize[0]; + this._sh = cellSize[1]; + }; + /** + * Convert a time data(time, value) item to (x, y) point. + */ + // TODO Clamp of calendar is not same with cartesian coordinate systems. + // It will return NaN if data exceeds. + Calendar.prototype.dataToPoint = function (data, clamp) { + isArray(data) && (data = data[0]); + clamp == null && (clamp = true); + var dayInfo = this.getDateInfo(data); + var range = this._rangeInfo; + var date = dayInfo.formatedDate; + // if not in range return [NaN, NaN] + if (clamp && !(dayInfo.time >= range.start.time && dayInfo.time < range.end.time + PROXIMATE_ONE_DAY)) { + return [NaN, NaN]; + } + var week = dayInfo.day; + var nthWeek = this._getRangeInfo([range.start.time, date]).nthWeek; + if (this._orient === 'vertical') { + return [this._rect.x + week * this._sw + this._sw / 2, this._rect.y + nthWeek * this._sh + this._sh / 2]; + } + return [this._rect.x + nthWeek * this._sw + this._sw / 2, this._rect.y + week * this._sh + this._sh / 2]; + }; + /** + * Convert a (x, y) point to time data + */ + Calendar.prototype.pointToData = function (point) { + var date = this.pointToDate(point); + return date && date.time; + }; + /** + * Convert a time date item to (x, y) four point. + */ + Calendar.prototype.dataToRect = function (data, clamp) { + var point = this.dataToPoint(data, clamp); + return { + contentShape: { + x: point[0] - (this._sw - this._lineWidth) / 2, + y: point[1] - (this._sh - this._lineWidth) / 2, + width: this._sw - this._lineWidth, + height: this._sh - this._lineWidth + }, + center: point, + tl: [point[0] - this._sw / 2, point[1] - this._sh / 2], + tr: [point[0] + this._sw / 2, point[1] - this._sh / 2], + br: [point[0] + this._sw / 2, point[1] + this._sh / 2], + bl: [point[0] - this._sw / 2, point[1] + this._sh / 2] + }; + }; + /** + * Convert a (x, y) point to time date + * + * @param {Array} point point + * @return {Object} date + */ + Calendar.prototype.pointToDate = function (point) { + var nthX = Math.floor((point[0] - this._rect.x) / this._sw) + 1; + var nthY = Math.floor((point[1] - this._rect.y) / this._sh) + 1; + var range = this._rangeInfo.range; + if (this._orient === 'vertical') { + return this._getDateByWeeksAndDay(nthY, nthX - 1, range); + } + return this._getDateByWeeksAndDay(nthX, nthY - 1, range); + }; + Calendar.prototype.convertToPixel = function (ecModel, finder, value) { + var coordSys = getCoordSys$4(finder); + return coordSys === this ? coordSys.dataToPoint(value) : null; + }; + Calendar.prototype.convertFromPixel = function (ecModel, finder, pixel) { + var coordSys = getCoordSys$4(finder); + return coordSys === this ? coordSys.pointToData(pixel) : null; + }; + Calendar.prototype.containPoint = function (point) { + console.warn('Not implemented.'); + return false; + }; + /** + * initRange + * Normalize to an [start, end] array + */ + Calendar.prototype._initRangeOption = function () { + var range = this._model.get('range'); + var normalizedRange; + // Convert [1990] to 1990 + if (isArray(range) && range.length === 1) { + range = range[0]; + } + if (!isArray(range)) { + var rangeStr = range.toString(); + // One year. + if (/^\d{4}$/.test(rangeStr)) { + normalizedRange = [rangeStr + '-01-01', rangeStr + '-12-31']; + } + // One month + if (/^\d{4}[\/|-]\d{1,2}$/.test(rangeStr)) { + var start = this.getDateInfo(rangeStr); + var firstDay = start.date; + firstDay.setMonth(firstDay.getMonth() + 1); + var end = this.getNextNDay(firstDay, -1); + normalizedRange = [start.formatedDate, end.formatedDate]; + } + // One day + if (/^\d{4}[\/|-]\d{1,2}[\/|-]\d{1,2}$/.test(rangeStr)) { + normalizedRange = [rangeStr, rangeStr]; + } + } else { + normalizedRange = range; + } + if (!normalizedRange) { + if ("development" !== 'production') { + logError('Invalid date range.'); + } + // Not handling it. + return range; + } + var tmp = this._getRangeInfo(normalizedRange); + if (tmp.start.time > tmp.end.time) { + normalizedRange.reverse(); + } + return normalizedRange; + }; + /** + * range info + * + * @private + * @param {Array} range range ['2017-01-01', '2017-07-08'] + * If range[0] > range[1], they will not be reversed. + * @return {Object} obj + */ + Calendar.prototype._getRangeInfo = function (range) { + var parsedRange = [this.getDateInfo(range[0]), this.getDateInfo(range[1])]; + var reversed; + if (parsedRange[0].time > parsedRange[1].time) { + reversed = true; + parsedRange.reverse(); + } + var allDay = Math.floor(parsedRange[1].time / PROXIMATE_ONE_DAY) - Math.floor(parsedRange[0].time / PROXIMATE_ONE_DAY) + 1; + // Consider case1 (#11677 #10430): + // Set the system timezone as "UK", set the range to `['2016-07-01', '2016-12-31']` + // Consider case2: + // Firstly set system timezone as "Time Zone: America/Toronto", + // ``` + // let first = new Date(1478412000000 - 3600 * 1000 * 2.5); + // let second = new Date(1478412000000); + // let allDays = Math.floor(second / ONE_DAY) - Math.floor(first / ONE_DAY) + 1; + // ``` + // will get wrong result because of DST. So we should fix it. + var date = new Date(parsedRange[0].time); + var startDateNum = date.getDate(); + var endDateNum = parsedRange[1].date.getDate(); + date.setDate(startDateNum + allDay - 1); + // The bias can not over a month, so just compare date. + var dateNum = date.getDate(); + if (dateNum !== endDateNum) { + var sign = date.getTime() - parsedRange[1].time > 0 ? 1 : -1; + while ((dateNum = date.getDate()) !== endDateNum && (date.getTime() - parsedRange[1].time) * sign > 0) { + allDay -= sign; + date.setDate(dateNum - sign); + } + } + var weeks = Math.floor((allDay + parsedRange[0].day + 6) / 7); + var nthWeek = reversed ? -weeks + 1 : weeks - 1; + reversed && parsedRange.reverse(); + return { + range: [parsedRange[0].formatedDate, parsedRange[1].formatedDate], + start: parsedRange[0], + end: parsedRange[1], + allDay: allDay, + weeks: weeks, + // From 0. + nthWeek: nthWeek, + fweek: parsedRange[0].day, + lweek: parsedRange[1].day + }; + }; + /** + * get date by nthWeeks and week day in range + * + * @private + * @param {number} nthWeek the week + * @param {number} day the week day + * @param {Array} range [d1, d2] + * @return {Object} + */ + Calendar.prototype._getDateByWeeksAndDay = function (nthWeek, day, range) { + var rangeInfo = this._getRangeInfo(range); + if (nthWeek > rangeInfo.weeks || nthWeek === 0 && day < rangeInfo.fweek || nthWeek === rangeInfo.weeks && day > rangeInfo.lweek) { + return null; + } + var nthDay = (nthWeek - 1) * 7 - rangeInfo.fweek + day; + var date = new Date(rangeInfo.start.time); + date.setDate(+rangeInfo.start.d + nthDay); + return this.getDateInfo(date); + }; + Calendar.create = function (ecModel, api) { + var calendarList = []; + ecModel.eachComponent('calendar', function (calendarModel) { + var calendar = new Calendar(calendarModel, ecModel, api); + calendarList.push(calendar); + calendarModel.coordinateSystem = calendar; + }); + ecModel.eachSeries(function (calendarSeries) { + if (calendarSeries.get('coordinateSystem') === 'calendar') { + // Inject coordinate system + calendarSeries.coordinateSystem = calendarList[calendarSeries.get('calendarIndex') || 0]; + } + }); + return calendarList; + }; + Calendar.dimensions = ['time', 'value']; + return Calendar; + }(); + function getCoordSys$4(finder) { + var calendarModel = finder.calendarModel; + var seriesModel = finder.seriesModel; + var coordSys = calendarModel ? calendarModel.coordinateSystem : seriesModel ? seriesModel.coordinateSystem : null; + return coordSys; + } + + function install$w(registers) { + registers.registerComponentModel(CalendarModel); + registers.registerComponentView(CalendarView); + registers.registerCoordinateSystem('calendar', Calendar); + } + + function setKeyInfoToNewElOption(resultItem, newElOption) { + var existElOption = resultItem.existing; + // Set id and type after id assigned. + newElOption.id = resultItem.keyInfo.id; + !newElOption.type && existElOption && (newElOption.type = existElOption.type); + // Set parent id if not specified + if (newElOption.parentId == null) { + var newElParentOption = newElOption.parentOption; + if (newElParentOption) { + newElOption.parentId = newElParentOption.id; + } else if (existElOption) { + newElOption.parentId = existElOption.parentId; + } + } + // Clear + newElOption.parentOption = null; + } + function isSetLoc(obj, props) { + var isSet; + each(props, function (prop) { + obj[prop] != null && obj[prop] !== 'auto' && (isSet = true); + }); + return isSet; + } + function mergeNewElOptionToExist(existList, index, newElOption) { + // Update existing options, for `getOption` feature. + var newElOptCopy = extend({}, newElOption); + var existElOption = existList[index]; + var $action = newElOption.$action || 'merge'; + if ($action === 'merge') { + if (existElOption) { + if ("development" !== 'production') { + var newType = newElOption.type; + assert(!newType || existElOption.type === newType, 'Please set $action: "replace" to change `type`'); + } + // We can ensure that newElOptCopy and existElOption are not + // the same object, so `merge` will not change newElOptCopy. + merge(existElOption, newElOptCopy, true); + // Rigid body, use ignoreSize. + mergeLayoutParam(existElOption, newElOptCopy, { + ignoreSize: true + }); + // Will be used in render. + copyLayoutParams(newElOption, existElOption); + // Copy transition info to new option so it can be used in the transition. + // DO IT AFTER merge + copyTransitionInfo(newElOption, existElOption); + copyTransitionInfo(newElOption, existElOption, 'shape'); + copyTransitionInfo(newElOption, existElOption, 'style'); + copyTransitionInfo(newElOption, existElOption, 'extra'); + // Copy clipPath + newElOption.clipPath = existElOption.clipPath; + } else { + existList[index] = newElOptCopy; + } + } else if ($action === 'replace') { + existList[index] = newElOptCopy; + } else if ($action === 'remove') { + // null will be cleaned later. + existElOption && (existList[index] = null); + } + } + var TRANSITION_PROPS_TO_COPY = ['transition', 'enterFrom', 'leaveTo']; + var ROOT_TRANSITION_PROPS_TO_COPY = TRANSITION_PROPS_TO_COPY.concat(['enterAnimation', 'updateAnimation', 'leaveAnimation']); + function copyTransitionInfo(target, source, targetProp) { + if (targetProp) { + if (!target[targetProp] && source[targetProp]) { + // TODO avoid creating this empty object when there is no transition configuration. + target[targetProp] = {}; + } + target = target[targetProp]; + source = source[targetProp]; + } + if (!target || !source) { + return; + } + var props = targetProp ? TRANSITION_PROPS_TO_COPY : ROOT_TRANSITION_PROPS_TO_COPY; + for (var i = 0; i < props.length; i++) { + var prop = props[i]; + if (target[prop] == null && source[prop] != null) { + target[prop] = source[prop]; + } + } + } + function setLayoutInfoToExist(existItem, newElOption) { + if (!existItem) { + return; + } + existItem.hv = newElOption.hv = [ + // Rigid body, don't care about `width`. + isSetLoc(newElOption, ['left', 'right']), + // Rigid body, don't care about `height`. + isSetLoc(newElOption, ['top', 'bottom'])]; + // Give default group size. Otherwise layout error may occur. + if (existItem.type === 'group') { + var existingGroupOpt = existItem; + var newGroupOpt = newElOption; + existingGroupOpt.width == null && (existingGroupOpt.width = newGroupOpt.width = 0); + existingGroupOpt.height == null && (existingGroupOpt.height = newGroupOpt.height = 0); + } + } + var GraphicComponentModel = /** @class */function (_super) { + __extends(GraphicComponentModel, _super); + function GraphicComponentModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = GraphicComponentModel.type; + _this.preventAutoZ = true; + return _this; + } + GraphicComponentModel.prototype.mergeOption = function (option, ecModel) { + // Prevent default merge to elements + var elements = this.option.elements; + this.option.elements = null; + _super.prototype.mergeOption.call(this, option, ecModel); + this.option.elements = elements; + }; + GraphicComponentModel.prototype.optionUpdated = function (newOption, isInit) { + var thisOption = this.option; + var newList = (isInit ? thisOption : newOption).elements; + var existList = thisOption.elements = isInit ? [] : thisOption.elements; + var flattenedList = []; + this._flatten(newList, flattenedList, null); + var mappingResult = mappingToExists(existList, flattenedList, 'normalMerge'); + // Clear elOptionsToUpdate + var elOptionsToUpdate = this._elOptionsToUpdate = []; + each(mappingResult, function (resultItem, index) { + var newElOption = resultItem.newOption; + if ("development" !== 'production') { + assert(isObject(newElOption) || resultItem.existing, 'Empty graphic option definition'); + } + if (!newElOption) { + return; + } + elOptionsToUpdate.push(newElOption); + setKeyInfoToNewElOption(resultItem, newElOption); + mergeNewElOptionToExist(existList, index, newElOption); + setLayoutInfoToExist(existList[index], newElOption); + }, this); + // Clean + thisOption.elements = filter(existList, function (item) { + // $action should be volatile, otherwise option gotten from + // `getOption` will contain unexpected $action. + item && delete item.$action; + return item != null; + }); + }; + /** + * Convert + * [{ + * type: 'group', + * id: 'xx', + * children: [{type: 'circle'}, {type: 'polygon'}] + * }] + * to + * [ + * {type: 'group', id: 'xx'}, + * {type: 'circle', parentId: 'xx'}, + * {type: 'polygon', parentId: 'xx'} + * ] + */ + GraphicComponentModel.prototype._flatten = function (optionList, result, parentOption) { + each(optionList, function (option) { + if (!option) { + return; + } + if (parentOption) { + option.parentOption = parentOption; + } + result.push(option); + var children = option.children; + // here we don't judge if option.type is `group` + // when new option doesn't provide `type`, it will cause that the children can't be updated. + if (children && children.length) { + this._flatten(children, result, option); + } + // Deleting for JSON output, and for not affecting group creation. + delete option.children; + }, this); + }; + // FIXME + // Pass to view using payload? setOption has a payload? + GraphicComponentModel.prototype.useElOptionsToUpdate = function () { + var els = this._elOptionsToUpdate; + // Clear to avoid render duplicately when zooming. + this._elOptionsToUpdate = null; + return els; + }; + GraphicComponentModel.type = 'graphic'; + GraphicComponentModel.defaultOption = { + elements: [] + // parentId: null + }; + + return GraphicComponentModel; + }(ComponentModel); + + var nonShapeGraphicElements = { + // Reserved but not supported in graphic component. + path: null, + compoundPath: null, + // Supported in graphic component. + group: Group, + image: ZRImage, + text: ZRText + }; + var inner$e = makeInner(); + // ------------------------ + // View + // ------------------------ + var GraphicComponentView = /** @class */function (_super) { + __extends(GraphicComponentView, _super); + function GraphicComponentView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = GraphicComponentView.type; + return _this; + } + GraphicComponentView.prototype.init = function () { + this._elMap = createHashMap(); + }; + GraphicComponentView.prototype.render = function (graphicModel, ecModel, api) { + // Having leveraged between use cases and algorithm complexity, a very + // simple layout mechanism is used: + // The size(width/height) can be determined by itself or its parent (not + // implemented yet), but can not by its children. (Top-down travel) + // The location(x/y) can be determined by the bounding rect of itself + // (can including its descendants or not) and the size of its parent. + // (Bottom-up travel) + // When `chart.clear()` or `chart.setOption({...}, true)` with the same id, + // view will be reused. + if (graphicModel !== this._lastGraphicModel) { + this._clear(); + } + this._lastGraphicModel = graphicModel; + this._updateElements(graphicModel); + this._relocate(graphicModel, api); + }; + /** + * Update graphic elements. + */ + GraphicComponentView.prototype._updateElements = function (graphicModel) { + var elOptionsToUpdate = graphicModel.useElOptionsToUpdate(); + if (!elOptionsToUpdate) { + return; + } + var elMap = this._elMap; + var rootGroup = this.group; + var globalZ = graphicModel.get('z'); + var globalZLevel = graphicModel.get('zlevel'); + // Top-down tranverse to assign graphic settings to each elements. + each(elOptionsToUpdate, function (elOption) { + var id = convertOptionIdName(elOption.id, null); + var elExisting = id != null ? elMap.get(id) : null; + var parentId = convertOptionIdName(elOption.parentId, null); + var targetElParent = parentId != null ? elMap.get(parentId) : rootGroup; + var elType = elOption.type; + var elOptionStyle = elOption.style; + if (elType === 'text' && elOptionStyle) { + // In top/bottom mode, textVerticalAlign should not be used, which cause + // inaccurately locating. + if (elOption.hv && elOption.hv[1]) { + elOptionStyle.textVerticalAlign = elOptionStyle.textBaseline = elOptionStyle.verticalAlign = elOptionStyle.align = null; + } + } + var textContentOption = elOption.textContent; + var textConfig = elOption.textConfig; + if (elOptionStyle && isEC4CompatibleStyle(elOptionStyle, elType, !!textConfig, !!textContentOption)) { + var convertResult = convertFromEC4CompatibleStyle(elOptionStyle, elType, true); + if (!textConfig && convertResult.textConfig) { + textConfig = elOption.textConfig = convertResult.textConfig; + } + if (!textContentOption && convertResult.textContent) { + textContentOption = convertResult.textContent; + } + } + // Remove unnecessary props to avoid potential problems. + var elOptionCleaned = getCleanedElOption(elOption); + // For simple, do not support parent change, otherwise reorder is needed. + if ("development" !== 'production') { + elExisting && assert(targetElParent === elExisting.parent, 'Changing parent is not supported.'); + } + var $action = elOption.$action || 'merge'; + var isMerge = $action === 'merge'; + var isReplace = $action === 'replace'; + if (isMerge) { + var isInit = !elExisting; + var el_1 = elExisting; + if (isInit) { + el_1 = createEl$1(id, targetElParent, elOption.type, elMap); + } else { + el_1 && (inner$e(el_1).isNew = false); + // Stop and restore before update any other attributes. + stopPreviousKeyframeAnimationAndRestore(el_1); + } + if (el_1) { + applyUpdateTransition(el_1, elOptionCleaned, graphicModel, { + isInit: isInit + }); + updateCommonAttrs(el_1, elOption, globalZ, globalZLevel); + } + } else if (isReplace) { + removeEl(elExisting, elOption, elMap, graphicModel); + var el_2 = createEl$1(id, targetElParent, elOption.type, elMap); + if (el_2) { + applyUpdateTransition(el_2, elOptionCleaned, graphicModel, { + isInit: true + }); + updateCommonAttrs(el_2, elOption, globalZ, globalZLevel); + } + } else if ($action === 'remove') { + updateLeaveTo(elExisting, elOption); + removeEl(elExisting, elOption, elMap, graphicModel); + } + var el = elMap.get(id); + if (el && textContentOption) { + if (isMerge) { + var textContentExisting = el.getTextContent(); + textContentExisting ? textContentExisting.attr(textContentOption) : el.setTextContent(new ZRText(textContentOption)); + } else if (isReplace) { + el.setTextContent(new ZRText(textContentOption)); + } + } + if (el) { + var clipPathOption = elOption.clipPath; + if (clipPathOption) { + var clipPathType = clipPathOption.type; + var clipPath = void 0; + var isInit = false; + if (isMerge) { + var oldClipPath = el.getClipPath(); + isInit = !oldClipPath || inner$e(oldClipPath).type !== clipPathType; + clipPath = isInit ? newEl(clipPathType) : oldClipPath; + } else if (isReplace) { + isInit = true; + clipPath = newEl(clipPathType); + } + el.setClipPath(clipPath); + applyUpdateTransition(clipPath, clipPathOption, graphicModel, { + isInit: isInit + }); + applyKeyframeAnimation(clipPath, clipPathOption.keyframeAnimation, graphicModel); + } + var elInner = inner$e(el); + el.setTextConfig(textConfig); + elInner.option = elOption; + setEventData(el, graphicModel, elOption); + setTooltipConfig({ + el: el, + componentModel: graphicModel, + itemName: el.name, + itemTooltipOption: elOption.tooltip + }); + applyKeyframeAnimation(el, elOption.keyframeAnimation, graphicModel); + } + }); + }; + /** + * Locate graphic elements. + */ + GraphicComponentView.prototype._relocate = function (graphicModel, api) { + var elOptions = graphicModel.option.elements; + var rootGroup = this.group; + var elMap = this._elMap; + var apiWidth = api.getWidth(); + var apiHeight = api.getHeight(); + var xy = ['x', 'y']; + // Top-down to calculate percentage width/height of group + for (var i = 0; i < elOptions.length; i++) { + var elOption = elOptions[i]; + var id = convertOptionIdName(elOption.id, null); + var el = id != null ? elMap.get(id) : null; + if (!el || !el.isGroup) { + continue; + } + var parentEl = el.parent; + var isParentRoot = parentEl === rootGroup; + // Like 'position:absolut' in css, default 0. + var elInner = inner$e(el); + var parentElInner = inner$e(parentEl); + elInner.width = parsePercent$1(elInner.option.width, isParentRoot ? apiWidth : parentElInner.width) || 0; + elInner.height = parsePercent$1(elInner.option.height, isParentRoot ? apiHeight : parentElInner.height) || 0; + } + // Bottom-up tranvese all elements (consider ec resize) to locate elements. + for (var i = elOptions.length - 1; i >= 0; i--) { + var elOption = elOptions[i]; + var id = convertOptionIdName(elOption.id, null); + var el = id != null ? elMap.get(id) : null; + if (!el) { + continue; + } + var parentEl = el.parent; + var parentElInner = inner$e(parentEl); + var containerInfo = parentEl === rootGroup ? { + width: apiWidth, + height: apiHeight + } : { + width: parentElInner.width, + height: parentElInner.height + }; + // PENDING + // Currently, when `bounding: 'all'`, the union bounding rect of the group + // does not include the rect of [0, 0, group.width, group.height], which + // is probably weird for users. Should we make a break change for it? + var layoutPos = {}; + var layouted = positionElement(el, elOption, containerInfo, null, { + hv: elOption.hv, + boundingMode: elOption.bounding + }, layoutPos); + if (!inner$e(el).isNew && layouted) { + var transition = elOption.transition; + var animatePos = {}; + for (var k = 0; k < xy.length; k++) { + var key = xy[k]; + var val = layoutPos[key]; + if (transition && (isTransitionAll(transition) || indexOf(transition, key) >= 0)) { + animatePos[key] = val; + } else { + el[key] = val; + } + } + updateProps(el, animatePos, graphicModel, 0); + } else { + el.attr(layoutPos); + } + } + }; + /** + * Clear all elements. + */ + GraphicComponentView.prototype._clear = function () { + var _this = this; + var elMap = this._elMap; + elMap.each(function (el) { + removeEl(el, inner$e(el).option, elMap, _this._lastGraphicModel); + }); + this._elMap = createHashMap(); + }; + GraphicComponentView.prototype.dispose = function () { + this._clear(); + }; + GraphicComponentView.type = 'graphic'; + return GraphicComponentView; + }(ComponentView); + function newEl(graphicType) { + if ("development" !== 'production') { + assert(graphicType, 'graphic type MUST be set'); + } + var Clz = hasOwn(nonShapeGraphicElements, graphicType) + // Those graphic elements are not shapes. They should not be + // overwritten by users, so do them first. + ? nonShapeGraphicElements[graphicType] : getShapeClass(graphicType); + if ("development" !== 'production') { + assert(Clz, "graphic type " + graphicType + " can not be found"); + } + var el = new Clz({}); + inner$e(el).type = graphicType; + return el; + } + function createEl$1(id, targetElParent, graphicType, elMap) { + var el = newEl(graphicType); + targetElParent.add(el); + elMap.set(id, el); + inner$e(el).id = id; + inner$e(el).isNew = true; + return el; + } + function removeEl(elExisting, elOption, elMap, graphicModel) { + var existElParent = elExisting && elExisting.parent; + if (existElParent) { + elExisting.type === 'group' && elExisting.traverse(function (el) { + removeEl(el, elOption, elMap, graphicModel); + }); + applyLeaveTransition(elExisting, elOption, graphicModel); + elMap.removeKey(inner$e(elExisting).id); + } + } + function updateCommonAttrs(el, elOption, defaultZ, defaultZlevel) { + if (!el.isGroup) { + each([['cursor', Displayable.prototype.cursor], + // We should not support configure z and zlevel in the element level. + // But seems we didn't limit it previously. So here still use it to avoid breaking. + ['zlevel', defaultZlevel || 0], ['z', defaultZ || 0], + // z2 must not be null/undefined, otherwise sort error may occur. + ['z2', 0]], function (item) { + var prop = item[0]; + if (hasOwn(elOption, prop)) { + el[prop] = retrieve2(elOption[prop], item[1]); + } else if (el[prop] == null) { + el[prop] = item[1]; + } + }); + } + each(keys(elOption), function (key) { + // Assign event handlers. + // PENDING: should enumerate all event names or use pattern matching? + if (key.indexOf('on') === 0) { + var val = elOption[key]; + el[key] = isFunction(val) ? val : null; + } + }); + if (hasOwn(elOption, 'draggable')) { + el.draggable = elOption.draggable; + } + // Other attributes + elOption.name != null && (el.name = elOption.name); + elOption.id != null && (el.id = elOption.id); + } + // Remove unnecessary props to avoid potential problems. + function getCleanedElOption(elOption) { + elOption = extend({}, elOption); + each(['id', 'parentId', '$action', 'hv', 'bounding', 'textContent', 'clipPath'].concat(LOCATION_PARAMS), function (name) { + delete elOption[name]; + }); + return elOption; + } + function setEventData(el, graphicModel, elOption) { + var eventData = getECData(el).eventData; + // Simple optimize for large amount of elements that no need event. + if (!el.silent && !el.ignore && !eventData) { + eventData = getECData(el).eventData = { + componentType: 'graphic', + componentIndex: graphicModel.componentIndex, + name: el.name + }; + } + // `elOption.info` enables user to mount some info on + // elements and use them in event handlers. + if (eventData) { + eventData.info = elOption.info; + } + } + + function install$x(registers) { + registers.registerComponentModel(GraphicComponentModel); + registers.registerComponentView(GraphicComponentView); + registers.registerPreprocessor(function (option) { + var graphicOption = option.graphic; + // Convert + // {graphic: [{left: 10, type: 'circle'}, ...]} + // or + // {graphic: {left: 10, type: 'circle'}} + // to + // {graphic: [{elements: [{left: 10, type: 'circle'}, ...]}]} + if (isArray(graphicOption)) { + if (!graphicOption[0] || !graphicOption[0].elements) { + option.graphic = [{ + elements: graphicOption + }]; + } else { + // Only one graphic instance can be instantiated. (We don't + // want that too many views are created in echarts._viewMap.) + option.graphic = [option.graphic[0]]; + } + } else if (graphicOption && !graphicOption.elements) { + option.graphic = [{ + elements: [graphicOption] + }]; + } + }); + } + + var DATA_ZOOM_AXIS_DIMENSIONS = ['x', 'y', 'radius', 'angle', 'single']; + // Supported coords. + // FIXME: polar has been broken (but rarely used). + var SERIES_COORDS = ['cartesian2d', 'polar', 'singleAxis']; + function isCoordSupported(seriesModel) { + var coordType = seriesModel.get('coordinateSystem'); + return indexOf(SERIES_COORDS, coordType) >= 0; + } + function getAxisMainType(axisDim) { + if ("development" !== 'production') { + assert(axisDim); + } + return axisDim + 'Axis'; + } + /** + * If two dataZoomModels has the same axis controlled, we say that they are 'linked'. + * This function finds all linked dataZoomModels start from the given payload. + */ + function findEffectedDataZooms(ecModel, payload) { + // Key: `DataZoomAxisDimension` + var axisRecords = createHashMap(); + var effectedModels = []; + // Key: uid of dataZoomModel + var effectedModelMap = createHashMap(); + // Find the dataZooms specified by payload. + ecModel.eachComponent({ + mainType: 'dataZoom', + query: payload + }, function (dataZoomModel) { + if (!effectedModelMap.get(dataZoomModel.uid)) { + addToEffected(dataZoomModel); + } + }); + // Start from the given dataZoomModels, travel the graph to find + // all of the linked dataZoom models. + var foundNewLink; + do { + foundNewLink = false; + ecModel.eachComponent('dataZoom', processSingle); + } while (foundNewLink); + function processSingle(dataZoomModel) { + if (!effectedModelMap.get(dataZoomModel.uid) && isLinked(dataZoomModel)) { + addToEffected(dataZoomModel); + foundNewLink = true; + } + } + function addToEffected(dataZoom) { + effectedModelMap.set(dataZoom.uid, true); + effectedModels.push(dataZoom); + markAxisControlled(dataZoom); + } + function isLinked(dataZoomModel) { + var isLink = false; + dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) { + var axisIdxArr = axisRecords.get(axisDim); + if (axisIdxArr && axisIdxArr[axisIndex]) { + isLink = true; + } + }); + return isLink; + } + function markAxisControlled(dataZoomModel) { + dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) { + (axisRecords.get(axisDim) || axisRecords.set(axisDim, []))[axisIndex] = true; + }); + } + return effectedModels; + } + /** + * Find the first target coordinate system. + * Available after model built. + * + * @return Like { + * grid: [ + * {model: coord0, axisModels: [axis1, axis3], coordIndex: 1}, + * {model: coord1, axisModels: [axis0, axis2], coordIndex: 0}, + * ... + * ], // cartesians must not be null/undefined. + * polar: [ + * {model: coord0, axisModels: [axis4], coordIndex: 0}, + * ... + * ], // polars must not be null/undefined. + * singleAxis: [ + * {model: coord0, axisModels: [], coordIndex: 0} + * ] + * } + */ + function collectReferCoordSysModelInfo(dataZoomModel) { + var ecModel = dataZoomModel.ecModel; + var coordSysInfoWrap = { + infoList: [], + infoMap: createHashMap() + }; + dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) { + var axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex); + if (!axisModel) { + return; + } + var coordSysModel = axisModel.getCoordSysModel(); + if (!coordSysModel) { + return; + } + var coordSysUid = coordSysModel.uid; + var coordSysInfo = coordSysInfoWrap.infoMap.get(coordSysUid); + if (!coordSysInfo) { + coordSysInfo = { + model: coordSysModel, + axisModels: [] + }; + coordSysInfoWrap.infoList.push(coordSysInfo); + coordSysInfoWrap.infoMap.set(coordSysUid, coordSysInfo); + } + coordSysInfo.axisModels.push(axisModel); + }); + return coordSysInfoWrap; + } + + var DataZoomAxisInfo = /** @class */function () { + function DataZoomAxisInfo() { + this.indexList = []; + this.indexMap = []; + } + DataZoomAxisInfo.prototype.add = function (axisCmptIdx) { + // Remove duplication. + if (!this.indexMap[axisCmptIdx]) { + this.indexList.push(axisCmptIdx); + this.indexMap[axisCmptIdx] = true; + } + }; + return DataZoomAxisInfo; + }(); + var DataZoomModel = /** @class */function (_super) { + __extends(DataZoomModel, _super); + function DataZoomModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = DataZoomModel.type; + _this._autoThrottle = true; + _this._noTarget = true; + /** + * It is `[rangeModeForMin, rangeModeForMax]`. + * The optional values for `rangeMode`: + * + `'value'` mode: the axis extent will always be determined by + * `dataZoom.startValue` and `dataZoom.endValue`, despite + * how data like and how `axis.min` and `axis.max` are. + * + `'percent'` mode: `100` represents 100% of the `[dMin, dMax]`, + * where `dMin` is `axis.min` if `axis.min` specified, otherwise `data.extent[0]`, + * and `dMax` is `axis.max` if `axis.max` specified, otherwise `data.extent[1]`. + * Axis extent will be determined by the result of the percent of `[dMin, dMax]`. + * + * For example, when users are using dynamic data (update data periodically via `setOption`), + * if in `'value`' mode, the window will be kept in a fixed value range despite how + * data are appended, while if in `'percent'` mode, whe window range will be changed alone with + * the appended data (suppose `axis.min` and `axis.max` are not specified). + */ + _this._rangePropMode = ['percent', 'percent']; + return _this; + } + DataZoomModel.prototype.init = function (option, parentModel, ecModel) { + var inputRawOption = retrieveRawOption(option); + /** + * Suppose a "main process" start at the point that model prepared (that is, + * model initialized or merged or method called in `action`). + * We should keep the `main process` idempotent, that is, given a set of values + * on `option`, we get the same result. + * + * But sometimes, values on `option` will be updated for providing users + * a "final calculated value" (`dataZoomProcessor` will do that). Those value + * should not be the base/input of the `main process`. + * + * So in that case we should save and keep the input of the `main process` + * separately, called `settledOption`. + * + * For example, consider the case: + * (Step_1) brush zoom the grid by `toolbox.dataZoom`, + * where the original input `option.startValue`, `option.endValue` are earsed by + * calculated value. + * (Step)2) click the legend to hide and show a series, + * where the new range is calculated by the earsed `startValue` and `endValue`, + * which brings incorrect result. + */ + this.settledOption = inputRawOption; + this.mergeDefaultAndTheme(option, ecModel); + this._doInit(inputRawOption); + }; + DataZoomModel.prototype.mergeOption = function (newOption) { + var inputRawOption = retrieveRawOption(newOption); + // FIX #2591 + merge(this.option, newOption, true); + merge(this.settledOption, inputRawOption, true); + this._doInit(inputRawOption); + }; + DataZoomModel.prototype._doInit = function (inputRawOption) { + var thisOption = this.option; + this._setDefaultThrottle(inputRawOption); + this._updateRangeUse(inputRawOption); + var settledOption = this.settledOption; + each([['start', 'startValue'], ['end', 'endValue']], function (names, index) { + // start/end has higher priority over startValue/endValue if they + // both set, but we should make chart.setOption({endValue: 1000}) + // effective, rather than chart.setOption({endValue: 1000, end: null}). + if (this._rangePropMode[index] === 'value') { + thisOption[names[0]] = settledOption[names[0]] = null; + } + // Otherwise do nothing and use the merge result. + }, this); + this._resetTarget(); + }; + DataZoomModel.prototype._resetTarget = function () { + var optionOrient = this.get('orient', true); + var targetAxisIndexMap = this._targetAxisInfoMap = createHashMap(); + var hasAxisSpecified = this._fillSpecifiedTargetAxis(targetAxisIndexMap); + if (hasAxisSpecified) { + this._orient = optionOrient || this._makeAutoOrientByTargetAxis(); + } else { + this._orient = optionOrient || 'horizontal'; + this._fillAutoTargetAxisByOrient(targetAxisIndexMap, this._orient); + } + this._noTarget = true; + targetAxisIndexMap.each(function (axisInfo) { + if (axisInfo.indexList.length) { + this._noTarget = false; + } + }, this); + }; + DataZoomModel.prototype._fillSpecifiedTargetAxis = function (targetAxisIndexMap) { + var hasAxisSpecified = false; + each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) { + var refering = this.getReferringComponents(getAxisMainType(axisDim), MULTIPLE_REFERRING); + // When user set axisIndex as a empty array, we think that user specify axisIndex + // but do not want use auto mode. Because empty array may be encountered when + // some error occurred. + if (!refering.specified) { + return; + } + hasAxisSpecified = true; + var axisInfo = new DataZoomAxisInfo(); + each(refering.models, function (axisModel) { + axisInfo.add(axisModel.componentIndex); + }); + targetAxisIndexMap.set(axisDim, axisInfo); + }, this); + return hasAxisSpecified; + }; + DataZoomModel.prototype._fillAutoTargetAxisByOrient = function (targetAxisIndexMap, orient) { + var ecModel = this.ecModel; + var needAuto = true; + // Find axis that parallel to dataZoom as default. + if (needAuto) { + var axisDim = orient === 'vertical' ? 'y' : 'x'; + var axisModels = ecModel.findComponents({ + mainType: axisDim + 'Axis' + }); + setParallelAxis(axisModels, axisDim); + } + // Find axis that parallel to dataZoom as default. + if (needAuto) { + var axisModels = ecModel.findComponents({ + mainType: 'singleAxis', + filter: function (axisModel) { + return axisModel.get('orient', true) === orient; + } + }); + setParallelAxis(axisModels, 'single'); + } + function setParallelAxis(axisModels, axisDim) { + // At least use the first parallel axis as the target axis. + var axisModel = axisModels[0]; + if (!axisModel) { + return; + } + var axisInfo = new DataZoomAxisInfo(); + axisInfo.add(axisModel.componentIndex); + targetAxisIndexMap.set(axisDim, axisInfo); + needAuto = false; + // Find parallel axes in the same grid. + if (axisDim === 'x' || axisDim === 'y') { + var gridModel_1 = axisModel.getReferringComponents('grid', SINGLE_REFERRING).models[0]; + gridModel_1 && each(axisModels, function (axModel) { + if (axisModel.componentIndex !== axModel.componentIndex && gridModel_1 === axModel.getReferringComponents('grid', SINGLE_REFERRING).models[0]) { + axisInfo.add(axModel.componentIndex); + } + }); + } + } + if (needAuto) { + // If no parallel axis, find the first category axis as default. (Also consider polar). + each(DATA_ZOOM_AXIS_DIMENSIONS, function (axisDim) { + if (!needAuto) { + return; + } + var axisModels = ecModel.findComponents({ + mainType: getAxisMainType(axisDim), + filter: function (axisModel) { + return axisModel.get('type', true) === 'category'; + } + }); + if (axisModels[0]) { + var axisInfo = new DataZoomAxisInfo(); + axisInfo.add(axisModels[0].componentIndex); + targetAxisIndexMap.set(axisDim, axisInfo); + needAuto = false; + } + }, this); + } + }; + DataZoomModel.prototype._makeAutoOrientByTargetAxis = function () { + var dim; + // Find the first axis + this.eachTargetAxis(function (axisDim) { + !dim && (dim = axisDim); + }, this); + return dim === 'y' ? 'vertical' : 'horizontal'; + }; + DataZoomModel.prototype._setDefaultThrottle = function (inputRawOption) { + // When first time user set throttle, auto throttle ends. + if (inputRawOption.hasOwnProperty('throttle')) { + this._autoThrottle = false; + } + if (this._autoThrottle) { + var globalOption = this.ecModel.option; + this.option.throttle = globalOption.animation && globalOption.animationDurationUpdate > 0 ? 100 : 20; + } + }; + DataZoomModel.prototype._updateRangeUse = function (inputRawOption) { + var rangePropMode = this._rangePropMode; + var rangeModeInOption = this.get('rangeMode'); + each([['start', 'startValue'], ['end', 'endValue']], function (names, index) { + var percentSpecified = inputRawOption[names[0]] != null; + var valueSpecified = inputRawOption[names[1]] != null; + if (percentSpecified && !valueSpecified) { + rangePropMode[index] = 'percent'; + } else if (!percentSpecified && valueSpecified) { + rangePropMode[index] = 'value'; + } else if (rangeModeInOption) { + rangePropMode[index] = rangeModeInOption[index]; + } else if (percentSpecified) { + // percentSpecified && valueSpecified + rangePropMode[index] = 'percent'; + } + // else remain its original setting. + }); + }; + + DataZoomModel.prototype.noTarget = function () { + return this._noTarget; + }; + DataZoomModel.prototype.getFirstTargetAxisModel = function () { + var firstAxisModel; + this.eachTargetAxis(function (axisDim, axisIndex) { + if (firstAxisModel == null) { + firstAxisModel = this.ecModel.getComponent(getAxisMainType(axisDim), axisIndex); + } + }, this); + return firstAxisModel; + }; + /** + * @param {Function} callback param: axisModel, dimNames, axisIndex, dataZoomModel, ecModel + */ + DataZoomModel.prototype.eachTargetAxis = function (callback, context) { + this._targetAxisInfoMap.each(function (axisInfo, axisDim) { + each(axisInfo.indexList, function (axisIndex) { + callback.call(context, axisDim, axisIndex); + }); + }); + }; + /** + * @return If not found, return null/undefined. + */ + DataZoomModel.prototype.getAxisProxy = function (axisDim, axisIndex) { + var axisModel = this.getAxisModel(axisDim, axisIndex); + if (axisModel) { + return axisModel.__dzAxisProxy; + } + }; + /** + * @return If not found, return null/undefined. + */ + DataZoomModel.prototype.getAxisModel = function (axisDim, axisIndex) { + if ("development" !== 'production') { + assert(axisDim && axisIndex != null); + } + var axisInfo = this._targetAxisInfoMap.get(axisDim); + if (axisInfo && axisInfo.indexMap[axisIndex]) { + return this.ecModel.getComponent(getAxisMainType(axisDim), axisIndex); + } + }; + /** + * If not specified, set to undefined. + */ + DataZoomModel.prototype.setRawRange = function (opt) { + var thisOption = this.option; + var settledOption = this.settledOption; + each([['start', 'startValue'], ['end', 'endValue']], function (names) { + // Consider the pair : + // If one has value and the other one is `null/undefined`, we both set them + // to `settledOption`. This strategy enables the feature to clear the original + // value in `settledOption` to `null/undefined`. + // But if both of them are `null/undefined`, we do not set them to `settledOption` + // and keep `settledOption` with the original value. This strategy enables users to + // only set but not set when calling + // `dispatchAction`. + // The pair is treated in the same way. + if (opt[names[0]] != null || opt[names[1]] != null) { + thisOption[names[0]] = settledOption[names[0]] = opt[names[0]]; + thisOption[names[1]] = settledOption[names[1]] = opt[names[1]]; + } + }, this); + this._updateRangeUse(opt); + }; + DataZoomModel.prototype.setCalculatedRange = function (opt) { + var option = this.option; + each(['start', 'startValue', 'end', 'endValue'], function (name) { + option[name] = opt[name]; + }); + }; + DataZoomModel.prototype.getPercentRange = function () { + var axisProxy = this.findRepresentativeAxisProxy(); + if (axisProxy) { + return axisProxy.getDataPercentWindow(); + } + }; + /** + * For example, chart.getModel().getComponent('dataZoom').getValueRange('y', 0); + * + * @return [startValue, endValue] value can only be '-' or finite number. + */ + DataZoomModel.prototype.getValueRange = function (axisDim, axisIndex) { + if (axisDim == null && axisIndex == null) { + var axisProxy = this.findRepresentativeAxisProxy(); + if (axisProxy) { + return axisProxy.getDataValueWindow(); + } + } else { + return this.getAxisProxy(axisDim, axisIndex).getDataValueWindow(); + } + }; + /** + * @param axisModel If axisModel given, find axisProxy + * corresponding to the axisModel + */ + DataZoomModel.prototype.findRepresentativeAxisProxy = function (axisModel) { + if (axisModel) { + return axisModel.__dzAxisProxy; + } + // Find the first hosted axisProxy + var firstProxy; + var axisDimList = this._targetAxisInfoMap.keys(); + for (var i = 0; i < axisDimList.length; i++) { + var axisDim = axisDimList[i]; + var axisInfo = this._targetAxisInfoMap.get(axisDim); + for (var j = 0; j < axisInfo.indexList.length; j++) { + var proxy = this.getAxisProxy(axisDim, axisInfo.indexList[j]); + if (proxy.hostedBy(this)) { + return proxy; + } + if (!firstProxy) { + firstProxy = proxy; + } + } + } + // If no hosted proxy found, still need to return a proxy. + // This case always happens in toolbox dataZoom, where axes are all hosted by + // other dataZooms. + return firstProxy; + }; + DataZoomModel.prototype.getRangePropMode = function () { + return this._rangePropMode.slice(); + }; + DataZoomModel.prototype.getOrient = function () { + if ("development" !== 'production') { + // Should not be called before initialized. + assert(this._orient); + } + return this._orient; + }; + DataZoomModel.type = 'dataZoom'; + DataZoomModel.dependencies = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'series', 'toolbox']; + DataZoomModel.defaultOption = { + // zlevel: 0, + z: 4, + filterMode: 'filter', + start: 0, + end: 100 + }; + return DataZoomModel; + }(ComponentModel); + /** + * Retrieve those raw params from option, which will be cached separately, + * because they will be overwritten by normalized/calculated values in the main + * process. + */ + function retrieveRawOption(option) { + var ret = {}; + each(['start', 'end', 'startValue', 'endValue', 'throttle'], function (name) { + option.hasOwnProperty(name) && (ret[name] = option[name]); + }); + return ret; + } + + var SelectDataZoomModel = /** @class */function (_super) { + __extends(SelectDataZoomModel, _super); + function SelectDataZoomModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SelectDataZoomModel.type; + return _this; + } + SelectDataZoomModel.type = 'dataZoom.select'; + return SelectDataZoomModel; + }(DataZoomModel); + + var DataZoomView = /** @class */function (_super) { + __extends(DataZoomView, _super); + function DataZoomView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = DataZoomView.type; + return _this; + } + DataZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) { + this.dataZoomModel = dataZoomModel; + this.ecModel = ecModel; + this.api = api; + }; + DataZoomView.type = 'dataZoom'; + return DataZoomView; + }(ComponentView); + + var SelectDataZoomView = /** @class */function (_super) { + __extends(SelectDataZoomView, _super); + function SelectDataZoomView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SelectDataZoomView.type; + return _this; + } + SelectDataZoomView.type = 'dataZoom.select'; + return SelectDataZoomView; + }(DataZoomView); + + var each$8 = each; + var asc$1 = asc; + /** + * Operate single axis. + * One axis can only operated by one axis operator. + * Different dataZoomModels may be defined to operate the same axis. + * (i.e. 'inside' data zoom and 'slider' data zoom components) + * So dataZoomModels share one axisProxy in that case. + */ + var AxisProxy = /** @class */function () { + function AxisProxy(dimName, axisIndex, dataZoomModel, ecModel) { + this._dimName = dimName; + this._axisIndex = axisIndex; + this.ecModel = ecModel; + this._dataZoomModel = dataZoomModel; + // /** + // * @readOnly + // * @private + // */ + // this.hasSeriesStacked; + } + /** + * Whether the axisProxy is hosted by dataZoomModel. + */ + AxisProxy.prototype.hostedBy = function (dataZoomModel) { + return this._dataZoomModel === dataZoomModel; + }; + /** + * @return Value can only be NaN or finite value. + */ + AxisProxy.prototype.getDataValueWindow = function () { + return this._valueWindow.slice(); + }; + /** + * @return {Array.} + */ + AxisProxy.prototype.getDataPercentWindow = function () { + return this._percentWindow.slice(); + }; + AxisProxy.prototype.getTargetSeriesModels = function () { + var seriesModels = []; + this.ecModel.eachSeries(function (seriesModel) { + if (isCoordSupported(seriesModel)) { + var axisMainType = getAxisMainType(this._dimName); + var axisModel = seriesModel.getReferringComponents(axisMainType, SINGLE_REFERRING).models[0]; + if (axisModel && this._axisIndex === axisModel.componentIndex) { + seriesModels.push(seriesModel); + } + } + }, this); + return seriesModels; + }; + AxisProxy.prototype.getAxisModel = function () { + return this.ecModel.getComponent(this._dimName + 'Axis', this._axisIndex); + }; + AxisProxy.prototype.getMinMaxSpan = function () { + return clone(this._minMaxSpan); + }; + /** + * Only calculate by given range and this._dataExtent, do not change anything. + */ + AxisProxy.prototype.calculateDataWindow = function (opt) { + var dataExtent = this._dataExtent; + var axisModel = this.getAxisModel(); + var scale = axisModel.axis.scale; + var rangePropMode = this._dataZoomModel.getRangePropMode(); + var percentExtent = [0, 100]; + var percentWindow = []; + var valueWindow = []; + var hasPropModeValue; + each$8(['start', 'end'], function (prop, idx) { + var boundPercent = opt[prop]; + var boundValue = opt[prop + 'Value']; + // Notice: dataZoom is based either on `percentProp` ('start', 'end') or + // on `valueProp` ('startValue', 'endValue'). (They are based on the data extent + // but not min/max of axis, which will be calculated by data window then). + // The former one is suitable for cases that a dataZoom component controls multiple + // axes with different unit or extent, and the latter one is suitable for accurate + // zoom by pixel (e.g., in dataZoomSelect). + // we use `getRangePropMode()` to mark which prop is used. `rangePropMode` is updated + // only when setOption or dispatchAction, otherwise it remains its original value. + // (Why not only record `percentProp` and always map to `valueProp`? Because + // the map `valueProp` -> `percentProp` -> `valueProp` probably not the original + // `valueProp`. consider two axes constrolled by one dataZoom. They have different + // data extent. All of values that are overflow the `dataExtent` will be calculated + // to percent '100%'). + if (rangePropMode[idx] === 'percent') { + boundPercent == null && (boundPercent = percentExtent[idx]); + // Use scale.parse to math round for category or time axis. + boundValue = scale.parse(linearMap(boundPercent, percentExtent, dataExtent)); + } else { + hasPropModeValue = true; + boundValue = boundValue == null ? dataExtent[idx] : scale.parse(boundValue); + // Calculating `percent` from `value` may be not accurate, because + // This calculation can not be inversed, because all of values that + // are overflow the `dataExtent` will be calculated to percent '100%' + boundPercent = linearMap(boundValue, dataExtent, percentExtent); + } + // valueWindow[idx] = round(boundValue); + // percentWindow[idx] = round(boundPercent); + // fallback to extent start/end when parsed value or percent is invalid + valueWindow[idx] = boundValue == null || isNaN(boundValue) ? dataExtent[idx] : boundValue; + percentWindow[idx] = boundPercent == null || isNaN(boundPercent) ? percentExtent[idx] : boundPercent; + }); + asc$1(valueWindow); + asc$1(percentWindow); + // The windows from user calling of `dispatchAction` might be out of the extent, + // or do not obey the `min/maxSpan`, `min/maxValueSpan`. But we don't restrict window + // by `zoomLock` here, because we see `zoomLock` just as a interaction constraint, + // where API is able to initialize/modify the window size even though `zoomLock` + // specified. + var spans = this._minMaxSpan; + hasPropModeValue ? restrictSet(valueWindow, percentWindow, dataExtent, percentExtent, false) : restrictSet(percentWindow, valueWindow, percentExtent, dataExtent, true); + function restrictSet(fromWindow, toWindow, fromExtent, toExtent, toValue) { + var suffix = toValue ? 'Span' : 'ValueSpan'; + sliderMove(0, fromWindow, fromExtent, 'all', spans['min' + suffix], spans['max' + suffix]); + for (var i = 0; i < 2; i++) { + toWindow[i] = linearMap(fromWindow[i], fromExtent, toExtent, true); + toValue && (toWindow[i] = scale.parse(toWindow[i])); + } + } + return { + valueWindow: valueWindow, + percentWindow: percentWindow + }; + }; + /** + * Notice: reset should not be called before series.restoreData() is called, + * so it is recommended to be called in "process stage" but not "model init + * stage". + */ + AxisProxy.prototype.reset = function (dataZoomModel) { + if (dataZoomModel !== this._dataZoomModel) { + return; + } + var targetSeries = this.getTargetSeriesModels(); + // Culculate data window and data extent, and record them. + this._dataExtent = calculateDataExtent(this, this._dimName, targetSeries); + // `calculateDataWindow` uses min/maxSpan. + this._updateMinMaxSpan(); + var dataWindow = this.calculateDataWindow(dataZoomModel.settledOption); + this._valueWindow = dataWindow.valueWindow; + this._percentWindow = dataWindow.percentWindow; + // Update axis setting then. + this._setAxisModel(); + }; + AxisProxy.prototype.filterData = function (dataZoomModel, api) { + if (dataZoomModel !== this._dataZoomModel) { + return; + } + var axisDim = this._dimName; + var seriesModels = this.getTargetSeriesModels(); + var filterMode = dataZoomModel.get('filterMode'); + var valueWindow = this._valueWindow; + if (filterMode === 'none') { + return; + } + // FIXME + // Toolbox may has dataZoom injected. And if there are stacked bar chart + // with NaN data, NaN will be filtered and stack will be wrong. + // So we need to force the mode to be set empty. + // In fect, it is not a big deal that do not support filterMode-'filter' + // when using toolbox#dataZoom, utill tooltip#dataZoom support "single axis + // selection" some day, which might need "adapt to data extent on the + // otherAxis", which is disabled by filterMode-'empty'. + // But currently, stack has been fixed to based on value but not index, + // so this is not an issue any more. + // let otherAxisModel = this.getOtherAxisModel(); + // if (dataZoomModel.get('$fromToolbox') + // && otherAxisModel + // && otherAxisModel.hasSeriesStacked + // ) { + // filterMode = 'empty'; + // } + // TODO + // filterMode 'weakFilter' and 'empty' is not optimized for huge data yet. + each$8(seriesModels, function (seriesModel) { + var seriesData = seriesModel.getData(); + var dataDims = seriesData.mapDimensionsAll(axisDim); + if (!dataDims.length) { + return; + } + if (filterMode === 'weakFilter') { + var store_1 = seriesData.getStore(); + var dataDimIndices_1 = map(dataDims, function (dim) { + return seriesData.getDimensionIndex(dim); + }, seriesData); + seriesData.filterSelf(function (dataIndex) { + var leftOut; + var rightOut; + var hasValue; + for (var i = 0; i < dataDims.length; i++) { + var value = store_1.get(dataDimIndices_1[i], dataIndex); + var thisHasValue = !isNaN(value); + var thisLeftOut = value < valueWindow[0]; + var thisRightOut = value > valueWindow[1]; + if (thisHasValue && !thisLeftOut && !thisRightOut) { + return true; + } + thisHasValue && (hasValue = true); + thisLeftOut && (leftOut = true); + thisRightOut && (rightOut = true); + } + // If both left out and right out, do not filter. + return hasValue && leftOut && rightOut; + }); + } else { + each$8(dataDims, function (dim) { + if (filterMode === 'empty') { + seriesModel.setData(seriesData = seriesData.map(dim, function (value) { + return !isInWindow(value) ? NaN : value; + })); + } else { + var range = {}; + range[dim] = valueWindow; + // console.time('select'); + seriesData.selectRange(range); + // console.timeEnd('select'); + } + }); + } + + each$8(dataDims, function (dim) { + seriesData.setApproximateExtent(valueWindow, dim); + }); + }); + function isInWindow(value) { + return value >= valueWindow[0] && value <= valueWindow[1]; + } + }; + AxisProxy.prototype._updateMinMaxSpan = function () { + var minMaxSpan = this._minMaxSpan = {}; + var dataZoomModel = this._dataZoomModel; + var dataExtent = this._dataExtent; + each$8(['min', 'max'], function (minMax) { + var percentSpan = dataZoomModel.get(minMax + 'Span'); + var valueSpan = dataZoomModel.get(minMax + 'ValueSpan'); + valueSpan != null && (valueSpan = this.getAxisModel().axis.scale.parse(valueSpan)); + // minValueSpan and maxValueSpan has higher priority than minSpan and maxSpan + if (valueSpan != null) { + percentSpan = linearMap(dataExtent[0] + valueSpan, dataExtent, [0, 100], true); + } else if (percentSpan != null) { + valueSpan = linearMap(percentSpan, [0, 100], dataExtent, true) - dataExtent[0]; + } + minMaxSpan[minMax + 'Span'] = percentSpan; + minMaxSpan[minMax + 'ValueSpan'] = valueSpan; + }, this); + }; + AxisProxy.prototype._setAxisModel = function () { + var axisModel = this.getAxisModel(); + var percentWindow = this._percentWindow; + var valueWindow = this._valueWindow; + if (!percentWindow) { + return; + } + // [0, 500]: arbitrary value, guess axis extent. + var precision = getPixelPrecision(valueWindow, [0, 500]); + precision = Math.min(precision, 20); + // For value axis, if min/max/scale are not set, we just use the extent obtained + // by series data, which may be a little different from the extent calculated by + // `axisHelper.getScaleExtent`. But the different just affects the experience a + // little when zooming. So it will not be fixed until some users require it strongly. + var rawExtentInfo = axisModel.axis.scale.rawExtentInfo; + if (percentWindow[0] !== 0) { + rawExtentInfo.setDeterminedMinMax('min', +valueWindow[0].toFixed(precision)); + } + if (percentWindow[1] !== 100) { + rawExtentInfo.setDeterminedMinMax('max', +valueWindow[1].toFixed(precision)); + } + rawExtentInfo.freeze(); + }; + return AxisProxy; + }(); + function calculateDataExtent(axisProxy, axisDim, seriesModels) { + var dataExtent = [Infinity, -Infinity]; + each$8(seriesModels, function (seriesModel) { + unionAxisExtentFromData(dataExtent, seriesModel.getData(), axisDim); + }); + // It is important to get "consistent" extent when more then one axes is + // controlled by a `dataZoom`, otherwise those axes will not be synchronized + // when zooming. But it is difficult to know what is "consistent", considering + // axes have different type or even different meanings (For example, two + // time axes are used to compare data of the same date in different years). + // So basically dataZoom just obtains extent by series.data (in category axis + // extent can be obtained from axis.data). + // Nevertheless, user can set min/max/scale on axes to make extent of axes + // consistent. + var axisModel = axisProxy.getAxisModel(); + var rawExtentResult = ensureScaleRawExtentInfo(axisModel.axis.scale, axisModel, dataExtent).calculate(); + return [rawExtentResult.min, rawExtentResult.max]; + } + + var dataZoomProcessor = { + // `dataZoomProcessor` will only be performed in needed series. Consider if + // there is a line series and a pie series, it is better not to update the + // line series if only pie series is needed to be updated. + getTargetSeries: function (ecModel) { + function eachAxisModel(cb) { + ecModel.eachComponent('dataZoom', function (dataZoomModel) { + dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) { + var axisModel = ecModel.getComponent(getAxisMainType(axisDim), axisIndex); + cb(axisDim, axisIndex, axisModel, dataZoomModel); + }); + }); + } + // FIXME: it brings side-effect to `getTargetSeries`. + // Prepare axis proxies. + eachAxisModel(function (axisDim, axisIndex, axisModel, dataZoomModel) { + // dispose all last axis proxy, in case that some axis are deleted. + axisModel.__dzAxisProxy = null; + }); + var proxyList = []; + eachAxisModel(function (axisDim, axisIndex, axisModel, dataZoomModel) { + // Different dataZooms may constrol the same axis. In that case, + // an axisProxy serves both of them. + if (!axisModel.__dzAxisProxy) { + // Use the first dataZoomModel as the main model of axisProxy. + axisModel.__dzAxisProxy = new AxisProxy(axisDim, axisIndex, dataZoomModel, ecModel); + proxyList.push(axisModel.__dzAxisProxy); + } + }); + var seriesModelMap = createHashMap(); + each(proxyList, function (axisProxy) { + each(axisProxy.getTargetSeriesModels(), function (seriesModel) { + seriesModelMap.set(seriesModel.uid, seriesModel); + }); + }); + return seriesModelMap; + }, + // Consider appendData, where filter should be performed. Because data process is + // in block mode currently, it is not need to worry about that the overallProgress + // execute every frame. + overallReset: function (ecModel, api) { + ecModel.eachComponent('dataZoom', function (dataZoomModel) { + // We calculate window and reset axis here but not in model + // init stage and not after action dispatch handler, because + // reset should be called after seriesData.restoreData. + dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) { + dataZoomModel.getAxisProxy(axisDim, axisIndex).reset(dataZoomModel); + }); + // Caution: data zoom filtering is order sensitive when using + // percent range and no min/max/scale set on axis. + // For example, we have dataZoom definition: + // [ + // {xAxisIndex: 0, start: 30, end: 70}, + // {yAxisIndex: 0, start: 20, end: 80} + // ] + // In this case, [20, 80] of y-dataZoom should be based on data + // that have filtered by x-dataZoom using range of [30, 70], + // but should not be based on full raw data. Thus sliding + // x-dataZoom will change both ranges of xAxis and yAxis, + // while sliding y-dataZoom will only change the range of yAxis. + // So we should filter x-axis after reset x-axis immediately, + // and then reset y-axis and filter y-axis. + dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) { + dataZoomModel.getAxisProxy(axisDim, axisIndex).filterData(dataZoomModel, api); + }); + }); + ecModel.eachComponent('dataZoom', function (dataZoomModel) { + // Fullfill all of the range props so that user + // is able to get them from chart.getOption(). + var axisProxy = dataZoomModel.findRepresentativeAxisProxy(); + if (axisProxy) { + var percentRange = axisProxy.getDataPercentWindow(); + var valueRange = axisProxy.getDataValueWindow(); + dataZoomModel.setCalculatedRange({ + start: percentRange[0], + end: percentRange[1], + startValue: valueRange[0], + endValue: valueRange[1] + }); + } + }); + } + }; + + function installDataZoomAction(registers) { + registers.registerAction('dataZoom', function (payload, ecModel) { + var effectedModels = findEffectedDataZooms(ecModel, payload); + each(effectedModels, function (dataZoomModel) { + dataZoomModel.setRawRange({ + start: payload.start, + end: payload.end, + startValue: payload.startValue, + endValue: payload.endValue + }); + }); + }); + } + + var installed = false; + function installCommon(registers) { + if (installed) { + return; + } + installed = true; + registers.registerProcessor(registers.PRIORITY.PROCESSOR.FILTER, dataZoomProcessor); + installDataZoomAction(registers); + registers.registerSubTypeDefaulter('dataZoom', function () { + // Default 'slider' when no type specified. + return 'slider'; + }); + } + + function install$y(registers) { + registers.registerComponentModel(SelectDataZoomModel); + registers.registerComponentView(SelectDataZoomView); + installCommon(registers); + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + var ToolboxFeature = /** @class */function () { + function ToolboxFeature() {} + return ToolboxFeature; + }(); + var features = {}; + function registerFeature(name, ctor) { + features[name] = ctor; + } + function getFeature(name) { + return features[name]; + } + + var ToolboxModel = /** @class */function (_super) { + __extends(ToolboxModel, _super); + function ToolboxModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ToolboxModel.type; + return _this; + } + ToolboxModel.prototype.optionUpdated = function () { + _super.prototype.optionUpdated.apply(this, arguments); + var ecModel = this.ecModel; + each(this.option.feature, function (featureOpt, featureName) { + var Feature = getFeature(featureName); + if (Feature) { + if (Feature.getDefaultOption) { + Feature.defaultOption = Feature.getDefaultOption(ecModel); + } + merge(featureOpt, Feature.defaultOption); + } + }); + }; + ToolboxModel.type = 'toolbox'; + ToolboxModel.layoutMode = { + type: 'box', + ignoreSize: true + }; + ToolboxModel.defaultOption = { + show: true, + z: 6, + // zlevel: 0, + orient: 'horizontal', + left: 'right', + top: 'top', + // right + // bottom + backgroundColor: 'transparent', + borderColor: '#ccc', + borderRadius: 0, + borderWidth: 0, + padding: 5, + itemSize: 15, + itemGap: 8, + showTitle: true, + iconStyle: { + borderColor: '#666', + color: 'none' + }, + emphasis: { + iconStyle: { + borderColor: '#3E98C5' + } + }, + // textStyle: {}, + // feature + tooltip: { + show: false, + position: 'bottom' + } + }; + return ToolboxModel; + }(ComponentModel); + + /** + * Layout list like component. + * It will box layout each items in group of component and then position the whole group in the viewport + * @param {module:zrender/group/Group} group + * @param {module:echarts/model/Component} componentModel + * @param {module:echarts/ExtensionAPI} + */ + function layout$3(group, componentModel, api) { + var boxLayoutParams = componentModel.getBoxLayoutParams(); + var padding = componentModel.get('padding'); + var viewportSize = { + width: api.getWidth(), + height: api.getHeight() + }; + var rect = getLayoutRect(boxLayoutParams, viewportSize, padding); + box(componentModel.get('orient'), group, componentModel.get('itemGap'), rect.width, rect.height); + positionElement(group, boxLayoutParams, viewportSize, padding); + } + function makeBackground(rect, componentModel) { + var padding = normalizeCssArray$1(componentModel.get('padding')); + var style = componentModel.getItemStyle(['color', 'opacity']); + style.fill = componentModel.get('backgroundColor'); + rect = new Rect({ + shape: { + x: rect.x - padding[3], + y: rect.y - padding[0], + width: rect.width + padding[1] + padding[3], + height: rect.height + padding[0] + padding[2], + r: componentModel.get('borderRadius') + }, + style: style, + silent: true, + z2: -1 + }); + // FIXME + // `subPixelOptimizeRect` may bring some gap between edge of viewpart + // and background rect when setting like `left: 0`, `top: 0`. + // graphic.subPixelOptimizeRect(rect); + return rect; + } + + var ToolboxView = /** @class */function (_super) { + __extends(ToolboxView, _super); + function ToolboxView() { + return _super !== null && _super.apply(this, arguments) || this; + } + ToolboxView.prototype.render = function (toolboxModel, ecModel, api, payload) { + var group = this.group; + group.removeAll(); + if (!toolboxModel.get('show')) { + return; + } + var itemSize = +toolboxModel.get('itemSize'); + var isVertical = toolboxModel.get('orient') === 'vertical'; + var featureOpts = toolboxModel.get('feature') || {}; + var features = this._features || (this._features = {}); + var featureNames = []; + each(featureOpts, function (opt, name) { + featureNames.push(name); + }); + new DataDiffer(this._featureNames || [], featureNames).add(processFeature).update(processFeature).remove(curry(processFeature, null)).execute(); + // Keep for diff. + this._featureNames = featureNames; + function processFeature(newIndex, oldIndex) { + var featureName = featureNames[newIndex]; + var oldName = featureNames[oldIndex]; + var featureOpt = featureOpts[featureName]; + var featureModel = new Model(featureOpt, toolboxModel, toolboxModel.ecModel); + var feature; + // FIX#11236, merge feature title from MagicType newOption. TODO: consider seriesIndex ? + if (payload && payload.newTitle != null && payload.featureName === featureName) { + featureOpt.title = payload.newTitle; + } + if (featureName && !oldName) { + // Create + if (isUserFeatureName(featureName)) { + feature = { + onclick: featureModel.option.onclick, + featureName: featureName + }; + } else { + var Feature = getFeature(featureName); + if (!Feature) { + return; + } + feature = new Feature(); + } + features[featureName] = feature; + } else { + feature = features[oldName]; + // If feature does not exist. + if (!feature) { + return; + } + } + feature.uid = getUID('toolbox-feature'); + feature.model = featureModel; + feature.ecModel = ecModel; + feature.api = api; + var isToolboxFeature = feature instanceof ToolboxFeature; + if (!featureName && oldName) { + isToolboxFeature && feature.dispose && feature.dispose(ecModel, api); + return; + } + if (!featureModel.get('show') || isToolboxFeature && feature.unusable) { + isToolboxFeature && feature.remove && feature.remove(ecModel, api); + return; + } + createIconPaths(featureModel, feature, featureName); + featureModel.setIconStatus = function (iconName, status) { + var option = this.option; + var iconPaths = this.iconPaths; + option.iconStatus = option.iconStatus || {}; + option.iconStatus[iconName] = status; + if (iconPaths[iconName]) { + (status === 'emphasis' ? enterEmphasis : leaveEmphasis)(iconPaths[iconName]); + } + }; + if (feature instanceof ToolboxFeature) { + if (feature.render) { + feature.render(featureModel, ecModel, api, payload); + } + } + } + function createIconPaths(featureModel, feature, featureName) { + var iconStyleModel = featureModel.getModel('iconStyle'); + var iconStyleEmphasisModel = featureModel.getModel(['emphasis', 'iconStyle']); + // If one feature has multiple icons, they are organized as + // { + // icon: { + // foo: '', + // bar: '' + // }, + // title: { + // foo: '', + // bar: '' + // } + // } + var icons = feature instanceof ToolboxFeature && feature.getIcons ? feature.getIcons() : featureModel.get('icon'); + var titles = featureModel.get('title') || {}; + var iconsMap; + var titlesMap; + if (isString(icons)) { + iconsMap = {}; + iconsMap[featureName] = icons; + } else { + iconsMap = icons; + } + if (isString(titles)) { + titlesMap = {}; + titlesMap[featureName] = titles; + } else { + titlesMap = titles; + } + var iconPaths = featureModel.iconPaths = {}; + each(iconsMap, function (iconStr, iconName) { + var path = createIcon(iconStr, {}, { + x: -itemSize / 2, + y: -itemSize / 2, + width: itemSize, + height: itemSize + }); // TODO handling image + path.setStyle(iconStyleModel.getItemStyle()); + var pathEmphasisState = path.ensureState('emphasis'); + pathEmphasisState.style = iconStyleEmphasisModel.getItemStyle(); + // Text position calculation + // TODO: extract `textStyle` from `iconStyle` and use `createTextStyle` + var textContent = new ZRText({ + style: { + text: titlesMap[iconName], + align: iconStyleEmphasisModel.get('textAlign'), + borderRadius: iconStyleEmphasisModel.get('textBorderRadius'), + padding: iconStyleEmphasisModel.get('textPadding'), + fill: null, + font: getFont({ + fontStyle: iconStyleEmphasisModel.get('textFontStyle'), + fontFamily: iconStyleEmphasisModel.get('textFontFamily'), + fontSize: iconStyleEmphasisModel.get('textFontSize'), + fontWeight: iconStyleEmphasisModel.get('textFontWeight') + }, ecModel) + }, + ignore: true + }); + path.setTextContent(textContent); + setTooltipConfig({ + el: path, + componentModel: toolboxModel, + itemName: iconName, + formatterParamsExtra: { + title: titlesMap[iconName] + } + }); + path.__title = titlesMap[iconName]; + path.on('mouseover', function () { + // Should not reuse above hoverStyle, which might be modified. + var hoverStyle = iconStyleEmphasisModel.getItemStyle(); + var defaultTextPosition = isVertical ? toolboxModel.get('right') == null && toolboxModel.get('left') !== 'right' ? 'right' : 'left' : toolboxModel.get('bottom') == null && toolboxModel.get('top') !== 'bottom' ? 'bottom' : 'top'; + textContent.setStyle({ + fill: iconStyleEmphasisModel.get('textFill') || hoverStyle.fill || hoverStyle.stroke || '#000', + backgroundColor: iconStyleEmphasisModel.get('textBackgroundColor') + }); + path.setTextConfig({ + position: iconStyleEmphasisModel.get('textPosition') || defaultTextPosition + }); + textContent.ignore = !toolboxModel.get('showTitle'); + // Use enterEmphasis and leaveEmphasis provide by ec. + // There are flags managed by the echarts. + api.enterEmphasis(this); + }).on('mouseout', function () { + if (featureModel.get(['iconStatus', iconName]) !== 'emphasis') { + api.leaveEmphasis(this); + } + textContent.hide(); + }); + (featureModel.get(['iconStatus', iconName]) === 'emphasis' ? enterEmphasis : leaveEmphasis)(path); + group.add(path); + path.on('click', bind(feature.onclick, feature, ecModel, api, iconName)); + iconPaths[iconName] = path; + }); + } + layout$3(group, toolboxModel, api); + // Render background after group is layout + // FIXME + group.add(makeBackground(group.getBoundingRect(), toolboxModel)); + // Adjust icon title positions to avoid them out of screen + isVertical || group.eachChild(function (icon) { + var titleText = icon.__title; + // const hoverStyle = icon.hoverStyle; + // TODO simplify code? + var emphasisState = icon.ensureState('emphasis'); + var emphasisTextConfig = emphasisState.textConfig || (emphasisState.textConfig = {}); + var textContent = icon.getTextContent(); + var emphasisTextState = textContent && textContent.ensureState('emphasis'); + // May be background element + if (emphasisTextState && !isFunction(emphasisTextState) && titleText) { + var emphasisTextStyle = emphasisTextState.style || (emphasisTextState.style = {}); + var rect = getBoundingRect(titleText, ZRText.makeFont(emphasisTextStyle)); + var offsetX = icon.x + group.x; + var offsetY = icon.y + group.y + itemSize; + var needPutOnTop = false; + if (offsetY + rect.height > api.getHeight()) { + emphasisTextConfig.position = 'top'; + needPutOnTop = true; + } + var topOffset = needPutOnTop ? -5 - rect.height : itemSize + 10; + if (offsetX + rect.width / 2 > api.getWidth()) { + emphasisTextConfig.position = ['100%', topOffset]; + emphasisTextStyle.align = 'right'; + } else if (offsetX - rect.width / 2 < 0) { + emphasisTextConfig.position = [0, topOffset]; + emphasisTextStyle.align = 'left'; + } + } + }); + }; + ToolboxView.prototype.updateView = function (toolboxModel, ecModel, api, payload) { + each(this._features, function (feature) { + feature instanceof ToolboxFeature && feature.updateView && feature.updateView(feature.model, ecModel, api, payload); + }); + }; + // updateLayout(toolboxModel, ecModel, api, payload) { + // zrUtil.each(this._features, function (feature) { + // feature.updateLayout && feature.updateLayout(feature.model, ecModel, api, payload); + // }); + // }, + ToolboxView.prototype.remove = function (ecModel, api) { + each(this._features, function (feature) { + feature instanceof ToolboxFeature && feature.remove && feature.remove(ecModel, api); + }); + this.group.removeAll(); + }; + ToolboxView.prototype.dispose = function (ecModel, api) { + each(this._features, function (feature) { + feature instanceof ToolboxFeature && feature.dispose && feature.dispose(ecModel, api); + }); + }; + ToolboxView.type = 'toolbox'; + return ToolboxView; + }(ComponentView); + function isUserFeatureName(featureName) { + return featureName.indexOf('my') === 0; + } + + /* global window, document */ + var SaveAsImage = /** @class */function (_super) { + __extends(SaveAsImage, _super); + function SaveAsImage() { + return _super !== null && _super.apply(this, arguments) || this; + } + SaveAsImage.prototype.onclick = function (ecModel, api) { + var model = this.model; + var title = model.get('name') || ecModel.get('title.0.text') || 'echarts'; + var isSvg = api.getZr().painter.getType() === 'svg'; + var type = isSvg ? 'svg' : model.get('type', true) || 'png'; + var url = api.getConnectedDataURL({ + type: type, + backgroundColor: model.get('backgroundColor', true) || ecModel.get('backgroundColor') || '#fff', + connectedBackgroundColor: model.get('connectedBackgroundColor'), + excludeComponents: model.get('excludeComponents'), + pixelRatio: model.get('pixelRatio') + }); + var browser = env.browser; + // Chrome, Firefox, New Edge + if (isFunction(MouseEvent) && (browser.newEdge || !browser.ie && !browser.edge)) { + var $a = document.createElement('a'); + $a.download = title + '.' + type; + $a.target = '_blank'; + $a.href = url; + var evt = new MouseEvent('click', { + // some micro front-end framework, window maybe is a Proxy + view: document.defaultView, + bubbles: true, + cancelable: false + }); + $a.dispatchEvent(evt); + } + // IE or old Edge + else { + // @ts-ignore + if (window.navigator.msSaveOrOpenBlob || isSvg) { + var parts = url.split(','); + // data:[][;charset=][;base64], + var base64Encoded = parts[0].indexOf('base64') > -1; + var bstr = isSvg + // should decode the svg data uri first + ? decodeURIComponent(parts[1]) : parts[1]; + // only `atob` when the data uri is encoded with base64 + // otherwise, like `svg` data uri exported by zrender, + // there will be an error, for it's not encoded with base64. + // (just a url-encoded string through `encodeURIComponent`) + base64Encoded && (bstr = window.atob(bstr)); + var filename = title + '.' + type; + // @ts-ignore + if (window.navigator.msSaveOrOpenBlob) { + var n = bstr.length; + var u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + var blob = new Blob([u8arr]); // @ts-ignore + window.navigator.msSaveOrOpenBlob(blob, filename); + } else { + var frame = document.createElement('iframe'); + document.body.appendChild(frame); + var cw = frame.contentWindow; + var doc = cw.document; + doc.open('image/svg+xml', 'replace'); + doc.write(bstr); + doc.close(); + cw.focus(); + doc.execCommand('SaveAs', true, filename); + document.body.removeChild(frame); + } + } else { + var lang = model.get('lang'); + var html = '' + '' + '' + ''; + var tab = window.open(); + tab.document.write(html); + tab.document.title = title; + } + } + }; + SaveAsImage.getDefaultOption = function (ecModel) { + var defaultOption = { + show: true, + icon: 'M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0', + title: ecModel.getLocaleModel().get(['toolbox', 'saveAsImage', 'title']), + type: 'png', + // Default use option.backgroundColor + // backgroundColor: '#fff', + connectedBackgroundColor: '#fff', + name: '', + excludeComponents: ['toolbox'], + // use current pixel ratio of device by default + // pixelRatio: 1, + lang: ecModel.getLocaleModel().get(['toolbox', 'saveAsImage', 'lang']) + }; + return defaultOption; + }; + return SaveAsImage; + }(ToolboxFeature); + + var INNER_STACK_KEYWORD = '__ec_magicType_stack__'; + var radioTypes = [['line', 'bar'], ['stack']]; + var MagicType = /** @class */function (_super) { + __extends(MagicType, _super); + function MagicType() { + return _super !== null && _super.apply(this, arguments) || this; + } + MagicType.prototype.getIcons = function () { + var model = this.model; + var availableIcons = model.get('icon'); + var icons = {}; + each(model.get('type'), function (type) { + if (availableIcons[type]) { + icons[type] = availableIcons[type]; + } + }); + return icons; + }; + MagicType.getDefaultOption = function (ecModel) { + var defaultOption = { + show: true, + type: [], + // Icon group + icon: { + line: 'M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4', + bar: 'M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7', + // eslint-disable-next-line + stack: 'M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z' // jshint ignore:line + }, + + // `line`, `bar`, `stack`, `tiled` + title: ecModel.getLocaleModel().get(['toolbox', 'magicType', 'title']), + option: {}, + seriesIndex: {} + }; + return defaultOption; + }; + MagicType.prototype.onclick = function (ecModel, api, type) { + var model = this.model; + var seriesIndex = model.get(['seriesIndex', type]); + // Not supported magicType + if (!seriesOptGenreator[type]) { + return; + } + var newOption = { + series: [] + }; + var generateNewSeriesTypes = function (seriesModel) { + var seriesType = seriesModel.subType; + var seriesId = seriesModel.id; + var newSeriesOpt = seriesOptGenreator[type](seriesType, seriesId, seriesModel, model); + if (newSeriesOpt) { + // PENDING If merge original option? + defaults(newSeriesOpt, seriesModel.option); + newOption.series.push(newSeriesOpt); + } + // Modify boundaryGap + var coordSys = seriesModel.coordinateSystem; + if (coordSys && coordSys.type === 'cartesian2d' && (type === 'line' || type === 'bar')) { + var categoryAxis = coordSys.getAxesByScale('ordinal')[0]; + if (categoryAxis) { + var axisDim = categoryAxis.dim; + var axisType = axisDim + 'Axis'; + var axisModel = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[0]; + var axisIndex = axisModel.componentIndex; + newOption[axisType] = newOption[axisType] || []; + for (var i = 0; i <= axisIndex; i++) { + newOption[axisType][axisIndex] = newOption[axisType][axisIndex] || {}; + } + newOption[axisType][axisIndex].boundaryGap = type === 'bar'; + } + } + }; + each(radioTypes, function (radio) { + if (indexOf(radio, type) >= 0) { + each(radio, function (item) { + model.setIconStatus(item, 'normal'); + }); + } + }); + model.setIconStatus(type, 'emphasis'); + ecModel.eachComponent({ + mainType: 'series', + query: seriesIndex == null ? null : { + seriesIndex: seriesIndex + } + }, generateNewSeriesTypes); + var newTitle; + var currentType = type; + // Change title of stack + if (type === 'stack') { + // use titles in model instead of ecModel + // as stack and tiled appears in pair, just flip them + // no need of checking stack state + newTitle = merge({ + stack: model.option.title.tiled, + tiled: model.option.title.stack + }, model.option.title); + if (model.get(['iconStatus', type]) !== 'emphasis') { + currentType = 'tiled'; + } + } + api.dispatchAction({ + type: 'changeMagicType', + currentType: currentType, + newOption: newOption, + newTitle: newTitle, + featureName: 'magicType' + }); + }; + return MagicType; + }(ToolboxFeature); + var seriesOptGenreator = { + 'line': function (seriesType, seriesId, seriesModel, model) { + if (seriesType === 'bar') { + return merge({ + id: seriesId, + type: 'line', + // Preserve data related option + data: seriesModel.get('data'), + stack: seriesModel.get('stack'), + markPoint: seriesModel.get('markPoint'), + markLine: seriesModel.get('markLine') + }, model.get(['option', 'line']) || {}, true); + } + }, + 'bar': function (seriesType, seriesId, seriesModel, model) { + if (seriesType === 'line') { + return merge({ + id: seriesId, + type: 'bar', + // Preserve data related option + data: seriesModel.get('data'), + stack: seriesModel.get('stack'), + markPoint: seriesModel.get('markPoint'), + markLine: seriesModel.get('markLine') + }, model.get(['option', 'bar']) || {}, true); + } + }, + 'stack': function (seriesType, seriesId, seriesModel, model) { + var isStack = seriesModel.get('stack') === INNER_STACK_KEYWORD; + if (seriesType === 'line' || seriesType === 'bar') { + model.setIconStatus('stack', isStack ? 'normal' : 'emphasis'); + return merge({ + id: seriesId, + stack: isStack ? '' : INNER_STACK_KEYWORD + }, model.get(['option', 'stack']) || {}, true); + } + } + }; + // TODO: SELF REGISTERED. + registerAction({ + type: 'changeMagicType', + event: 'magicTypeChanged', + update: 'prepareAndUpdate' + }, function (payload, ecModel) { + ecModel.mergeOption(payload.newOption); + }); + + /* global document */ + var BLOCK_SPLITER = new Array(60).join('-'); + var ITEM_SPLITER = '\t'; + /** + * Group series into two types + * 1. on category axis, like line, bar + * 2. others, like scatter, pie + */ + function groupSeries(ecModel) { + var seriesGroupByCategoryAxis = {}; + var otherSeries = []; + var meta = []; + ecModel.eachRawSeries(function (seriesModel) { + var coordSys = seriesModel.coordinateSystem; + if (coordSys && (coordSys.type === 'cartesian2d' || coordSys.type === 'polar')) { + // TODO: TYPE Consider polar? Include polar may increase unecessary bundle size. + var baseAxis = coordSys.getBaseAxis(); + if (baseAxis.type === 'category') { + var key = baseAxis.dim + '_' + baseAxis.index; + if (!seriesGroupByCategoryAxis[key]) { + seriesGroupByCategoryAxis[key] = { + categoryAxis: baseAxis, + valueAxis: coordSys.getOtherAxis(baseAxis), + series: [] + }; + meta.push({ + axisDim: baseAxis.dim, + axisIndex: baseAxis.index + }); + } + seriesGroupByCategoryAxis[key].series.push(seriesModel); + } else { + otherSeries.push(seriesModel); + } + } else { + otherSeries.push(seriesModel); + } + }); + return { + seriesGroupByCategoryAxis: seriesGroupByCategoryAxis, + other: otherSeries, + meta: meta + }; + } + /** + * Assemble content of series on cateogory axis + * @inner + */ + function assembleSeriesWithCategoryAxis(groups) { + var tables = []; + each(groups, function (group, key) { + var categoryAxis = group.categoryAxis; + var valueAxis = group.valueAxis; + var valueAxisDim = valueAxis.dim; + var headers = [' '].concat(map(group.series, function (series) { + return series.name; + })); + // @ts-ignore TODO Polar + var columns = [categoryAxis.model.getCategories()]; + each(group.series, function (series) { + var rawData = series.getRawData(); + columns.push(series.getRawData().mapArray(rawData.mapDimension(valueAxisDim), function (val) { + return val; + })); + }); + // Assemble table content + var lines = [headers.join(ITEM_SPLITER)]; + for (var i = 0; i < columns[0].length; i++) { + var items = []; + for (var j = 0; j < columns.length; j++) { + items.push(columns[j][i]); + } + lines.push(items.join(ITEM_SPLITER)); + } + tables.push(lines.join('\n')); + }); + return tables.join('\n\n' + BLOCK_SPLITER + '\n\n'); + } + /** + * Assemble content of other series + */ + function assembleOtherSeries(series) { + return map(series, function (series) { + var data = series.getRawData(); + var lines = [series.name]; + var vals = []; + data.each(data.dimensions, function () { + var argLen = arguments.length; + var dataIndex = arguments[argLen - 1]; + var name = data.getName(dataIndex); + for (var i = 0; i < argLen - 1; i++) { + vals[i] = arguments[i]; + } + lines.push((name ? name + ITEM_SPLITER : '') + vals.join(ITEM_SPLITER)); + }); + return lines.join('\n'); + }).join('\n\n' + BLOCK_SPLITER + '\n\n'); + } + function getContentFromModel(ecModel) { + var result = groupSeries(ecModel); + return { + value: filter([assembleSeriesWithCategoryAxis(result.seriesGroupByCategoryAxis), assembleOtherSeries(result.other)], function (str) { + return !!str.replace(/[\n\t\s]/g, ''); + }).join('\n\n' + BLOCK_SPLITER + '\n\n'), + meta: result.meta + }; + } + function trim$1(str) { + return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); + } + /** + * If a block is tsv format + */ + function isTSVFormat(block) { + // Simple method to find out if a block is tsv format + var firstLine = block.slice(0, block.indexOf('\n')); + if (firstLine.indexOf(ITEM_SPLITER) >= 0) { + return true; + } + } + var itemSplitRegex = new RegExp('[' + ITEM_SPLITER + ']+', 'g'); + /** + * @param {string} tsv + * @return {Object} + */ + function parseTSVContents(tsv) { + var tsvLines = tsv.split(/\n+/g); + var headers = trim$1(tsvLines.shift()).split(itemSplitRegex); + var categories = []; + var series = map(headers, function (header) { + return { + name: header, + data: [] + }; + }); + for (var i = 0; i < tsvLines.length; i++) { + var items = trim$1(tsvLines[i]).split(itemSplitRegex); + categories.push(items.shift()); + for (var j = 0; j < items.length; j++) { + series[j] && (series[j].data[i] = items[j]); + } + } + return { + series: series, + categories: categories + }; + } + function parseListContents(str) { + var lines = str.split(/\n+/g); + var seriesName = trim$1(lines.shift()); + var data = []; + for (var i = 0; i < lines.length; i++) { + // if line is empty, ignore it. + // there is a case that a user forgot to delete `\n`. + var line = trim$1(lines[i]); + if (!line) { + continue; + } + var items = line.split(itemSplitRegex); + var name_1 = ''; + var value = void 0; + var hasName = false; + if (isNaN(items[0])) { + // First item is name + hasName = true; + name_1 = items[0]; + items = items.slice(1); + data[i] = { + name: name_1, + value: [] + }; + value = data[i].value; + } else { + value = data[i] = []; + } + for (var j = 0; j < items.length; j++) { + value.push(+items[j]); + } + if (value.length === 1) { + hasName ? data[i].value = value[0] : data[i] = value[0]; + } + } + return { + name: seriesName, + data: data + }; + } + function parseContents(str, blockMetaList) { + var blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g')); + var newOption = { + series: [] + }; + each(blocks, function (block, idx) { + if (isTSVFormat(block)) { + var result = parseTSVContents(block); + var blockMeta = blockMetaList[idx]; + var axisKey = blockMeta.axisDim + 'Axis'; + if (blockMeta) { + newOption[axisKey] = newOption[axisKey] || []; + newOption[axisKey][blockMeta.axisIndex] = { + data: result.categories + }; + newOption.series = newOption.series.concat(result.series); + } + } else { + var result = parseListContents(block); + newOption.series.push(result); + } + }); + return newOption; + } + var DataView = /** @class */function (_super) { + __extends(DataView, _super); + function DataView() { + return _super !== null && _super.apply(this, arguments) || this; + } + DataView.prototype.onclick = function (ecModel, api) { + // FIXME: better way? + setTimeout(function () { + api.dispatchAction({ + type: 'hideTip' + }); + }); + var container = api.getDom(); + var model = this.model; + if (this._dom) { + container.removeChild(this._dom); + } + var root = document.createElement('div'); + // use padding to avoid 5px whitespace + root.style.cssText = 'position:absolute;top:0;bottom:0;left:0;right:0;padding:5px'; + root.style.backgroundColor = model.get('backgroundColor') || '#fff'; + // Create elements + var header = document.createElement('h4'); + var lang = model.get('lang') || []; + header.innerHTML = lang[0] || model.get('title'); + header.style.cssText = 'margin:10px 20px'; + header.style.color = model.get('textColor'); + var viewMain = document.createElement('div'); + var textarea = document.createElement('textarea'); + viewMain.style.cssText = 'overflow:auto'; + var optionToContent = model.get('optionToContent'); + var contentToOption = model.get('contentToOption'); + var result = getContentFromModel(ecModel); + if (isFunction(optionToContent)) { + var htmlOrDom = optionToContent(api.getOption()); + if (isString(htmlOrDom)) { + viewMain.innerHTML = htmlOrDom; + } else if (isDom(htmlOrDom)) { + viewMain.appendChild(htmlOrDom); + } + } else { + // Use default textarea + textarea.readOnly = model.get('readOnly'); + var style = textarea.style; + // eslint-disable-next-line max-len + style.cssText = 'display:block;width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;resize:none;box-sizing:border-box;outline:none'; + style.color = model.get('textColor'); + style.borderColor = model.get('textareaBorderColor'); + style.backgroundColor = model.get('textareaColor'); + textarea.value = result.value; + viewMain.appendChild(textarea); + } + var blockMetaList = result.meta; + var buttonContainer = document.createElement('div'); + buttonContainer.style.cssText = 'position:absolute;bottom:5px;left:0;right:0'; + // eslint-disable-next-line max-len + var buttonStyle = 'float:right;margin-right:20px;border:none;cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px'; + var closeButton = document.createElement('div'); + var refreshButton = document.createElement('div'); + buttonStyle += ';background-color:' + model.get('buttonColor'); + buttonStyle += ';color:' + model.get('buttonTextColor'); + var self = this; + function close() { + container.removeChild(root); + self._dom = null; + } + addEventListener(closeButton, 'click', close); + addEventListener(refreshButton, 'click', function () { + if (contentToOption == null && optionToContent != null || contentToOption != null && optionToContent == null) { + if ("development" !== 'production') { + // eslint-disable-next-line + warn('It seems you have just provided one of `contentToOption` and `optionToContent` functions but missed the other one. Data change is ignored.'); + } + close(); + return; + } + var newOption; + try { + if (isFunction(contentToOption)) { + newOption = contentToOption(viewMain, api.getOption()); + } else { + newOption = parseContents(textarea.value, blockMetaList); + } + } catch (e) { + close(); + throw new Error('Data view format error ' + e); + } + if (newOption) { + api.dispatchAction({ + type: 'changeDataView', + newOption: newOption + }); + } + close(); + }); + closeButton.innerHTML = lang[1]; + refreshButton.innerHTML = lang[2]; + refreshButton.style.cssText = closeButton.style.cssText = buttonStyle; + !model.get('readOnly') && buttonContainer.appendChild(refreshButton); + buttonContainer.appendChild(closeButton); + root.appendChild(header); + root.appendChild(viewMain); + root.appendChild(buttonContainer); + viewMain.style.height = container.clientHeight - 80 + 'px'; + container.appendChild(root); + this._dom = root; + }; + DataView.prototype.remove = function (ecModel, api) { + this._dom && api.getDom().removeChild(this._dom); + }; + DataView.prototype.dispose = function (ecModel, api) { + this.remove(ecModel, api); + }; + DataView.getDefaultOption = function (ecModel) { + var defaultOption = { + show: true, + readOnly: false, + optionToContent: null, + contentToOption: null, + // eslint-disable-next-line + icon: 'M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28', + title: ecModel.getLocaleModel().get(['toolbox', 'dataView', 'title']), + lang: ecModel.getLocaleModel().get(['toolbox', 'dataView', 'lang']), + backgroundColor: '#fff', + textColor: '#000', + textareaColor: '#fff', + textareaBorderColor: '#333', + buttonColor: '#c23531', + buttonTextColor: '#fff' + }; + return defaultOption; + }; + return DataView; + }(ToolboxFeature); + /** + * @inner + */ + function tryMergeDataOption(newData, originalData) { + return map(newData, function (newVal, idx) { + var original = originalData && originalData[idx]; + if (isObject(original) && !isArray(original)) { + var newValIsObject = isObject(newVal) && !isArray(newVal); + if (!newValIsObject) { + newVal = { + value: newVal + }; + } + // original data has name but new data has no name + var shouldDeleteName = original.name != null && newVal.name == null; + // Original data has option + newVal = defaults(newVal, original); + shouldDeleteName && delete newVal.name; + return newVal; + } else { + return newVal; + } + }); + } + // TODO: SELF REGISTERED. + registerAction({ + type: 'changeDataView', + event: 'dataViewChanged', + update: 'prepareAndUpdate' + }, function (payload, ecModel) { + var newSeriesOptList = []; + each(payload.newOption.series, function (seriesOpt) { + var seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0]; + if (!seriesModel) { + // New created series + // Geuss the series type + newSeriesOptList.push(extend({ + // Default is scatter + type: 'scatter' + }, seriesOpt)); + } else { + var originalData = seriesModel.get('data'); + newSeriesOptList.push({ + name: seriesOpt.name, + data: tryMergeDataOption(seriesOpt.data, originalData) + }); + } + }); + ecModel.mergeOption(defaults({ + series: newSeriesOptList + }, payload.newOption)); + }); + + var each$9 = each; + var inner$f = makeInner(); + /** + * @param ecModel + * @param newSnapshot key is dataZoomId + */ + function push(ecModel, newSnapshot) { + var storedSnapshots = getStoreSnapshots(ecModel); + // If previous dataZoom can not be found, + // complete an range with current range. + each$9(newSnapshot, function (batchItem, dataZoomId) { + var i = storedSnapshots.length - 1; + for (; i >= 0; i--) { + var snapshot = storedSnapshots[i]; + if (snapshot[dataZoomId]) { + break; + } + } + if (i < 0) { + // No origin range set, create one by current range. + var dataZoomModel = ecModel.queryComponents({ + mainType: 'dataZoom', + subType: 'select', + id: dataZoomId + })[0]; + if (dataZoomModel) { + var percentRange = dataZoomModel.getPercentRange(); + storedSnapshots[0][dataZoomId] = { + dataZoomId: dataZoomId, + start: percentRange[0], + end: percentRange[1] + }; + } + } + }); + storedSnapshots.push(newSnapshot); + } + function pop(ecModel) { + var storedSnapshots = getStoreSnapshots(ecModel); + var head = storedSnapshots[storedSnapshots.length - 1]; + storedSnapshots.length > 1 && storedSnapshots.pop(); + // Find top for all dataZoom. + var snapshot = {}; + each$9(head, function (batchItem, dataZoomId) { + for (var i = storedSnapshots.length - 1; i >= 0; i--) { + batchItem = storedSnapshots[i][dataZoomId]; + if (batchItem) { + snapshot[dataZoomId] = batchItem; + break; + } + } + }); + return snapshot; + } + function clear$1(ecModel) { + inner$f(ecModel).snapshots = null; + } + function count(ecModel) { + return getStoreSnapshots(ecModel).length; + } + /** + * History length of each dataZoom may be different. + * this._history[0] is used to store origin range. + */ + function getStoreSnapshots(ecModel) { + var store = inner$f(ecModel); + if (!store.snapshots) { + store.snapshots = [{}]; + } + return store.snapshots; + } + + var RestoreOption = /** @class */function (_super) { + __extends(RestoreOption, _super); + function RestoreOption() { + return _super !== null && _super.apply(this, arguments) || this; + } + RestoreOption.prototype.onclick = function (ecModel, api) { + clear$1(ecModel); + api.dispatchAction({ + type: 'restore', + from: this.uid + }); + }; + RestoreOption.getDefaultOption = function (ecModel) { + var defaultOption = { + show: true, + // eslint-disable-next-line + icon: 'M3.8,33.4 M47,18.9h9.8V8.7 M56.3,20.1 C52.1,9,40.5,0.6,26.8,2.1C12.6,3.7,1.6,16.2,2.1,30.6 M13,41.1H3.1v10.2 M3.7,39.9c4.2,11.1,15.8,19.5,29.5,18 c14.2-1.6,25.2-14.1,24.7-28.5', + title: ecModel.getLocaleModel().get(['toolbox', 'restore', 'title']) + }; + return defaultOption; + }; + return RestoreOption; + }(ToolboxFeature); + // TODO: SELF REGISTERED. + registerAction({ + type: 'restore', + event: 'restore', + update: 'prepareAndUpdate' + }, function (payload, ecModel) { + ecModel.resetOption('recreate'); + }); + + // FIXME + // how to genarialize to more coordinate systems. + var INCLUDE_FINDER_MAIN_TYPES = ['grid', 'xAxis', 'yAxis', 'geo', 'graph', 'polar', 'radiusAxis', 'angleAxis', 'bmap']; + var BrushTargetManager = /** @class */function () { + /** + * @param finder contains Index/Id/Name of xAxis/yAxis/geo/grid + * Each can be {number|Array.}. like: {xAxisIndex: [3, 4]} + * @param opt.include include coordinate system types. + */ + function BrushTargetManager(finder, ecModel, opt) { + var _this = this; + this._targetInfoList = []; + var foundCpts = parseFinder$1(ecModel, finder); + each(targetInfoBuilders, function (builder, type) { + if (!opt || !opt.include || indexOf(opt.include, type) >= 0) { + builder(foundCpts, _this._targetInfoList); + } + }); + } + BrushTargetManager.prototype.setOutputRanges = function (areas, ecModel) { + this.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) { + (area.coordRanges || (area.coordRanges = [])).push(coordRange); + // area.coordRange is the first of area.coordRanges + if (!area.coordRange) { + area.coordRange = coordRange; + // In 'category' axis, coord to pixel is not reversible, so we can not + // rebuild range by coordRange accrately, which may bring trouble when + // brushing only one item. So we use __rangeOffset to rebuilding range + // by coordRange. And this it only used in brush component so it is no + // need to be adapted to coordRanges. + var result = coordConvert[area.brushType](0, coordSys, coordRange); + area.__rangeOffset = { + offset: diffProcessor[area.brushType](result.values, area.range, [1, 1]), + xyMinMax: result.xyMinMax + }; + } + }); + return areas; + }; + BrushTargetManager.prototype.matchOutputRanges = function (areas, ecModel, cb) { + each(areas, function (area) { + var targetInfo = this.findTargetInfo(area, ecModel); + if (targetInfo && targetInfo !== true) { + each(targetInfo.coordSyses, function (coordSys) { + var result = coordConvert[area.brushType](1, coordSys, area.range, true); + cb(area, result.values, coordSys, ecModel); + }); + } + }, this); + }; + /** + * the `areas` is `BrushModel.areas`. + * Called in layout stage. + * convert `area.coordRange` to global range and set panelId to `area.range`. + */ + BrushTargetManager.prototype.setInputRanges = function (areas, ecModel) { + each(areas, function (area) { + var targetInfo = this.findTargetInfo(area, ecModel); + if ("development" !== 'production') { + assert(!targetInfo || targetInfo === true || area.coordRange, 'coordRange must be specified when coord index specified.'); + assert(!targetInfo || targetInfo !== true || area.range, 'range must be specified in global brush.'); + } + area.range = area.range || []; + // convert coordRange to global range and set panelId. + if (targetInfo && targetInfo !== true) { + area.panelId = targetInfo.panelId; + // (1) area.range should always be calculate from coordRange but does + // not keep its original value, for the sake of the dataZoom scenario, + // where area.coordRange remains unchanged but area.range may be changed. + // (2) Only support converting one coordRange to pixel range in brush + // component. So do not consider `coordRanges`. + // (3) About __rangeOffset, see comment above. + var result = coordConvert[area.brushType](0, targetInfo.coordSys, area.coordRange); + var rangeOffset = area.__rangeOffset; + area.range = rangeOffset ? diffProcessor[area.brushType](result.values, rangeOffset.offset, getScales(result.xyMinMax, rangeOffset.xyMinMax)) : result.values; + } + }, this); + }; + BrushTargetManager.prototype.makePanelOpts = function (api, getDefaultBrushType) { + return map(this._targetInfoList, function (targetInfo) { + var rect = targetInfo.getPanelRect(); + return { + panelId: targetInfo.panelId, + defaultBrushType: getDefaultBrushType ? getDefaultBrushType(targetInfo) : null, + clipPath: makeRectPanelClipPath(rect), + isTargetByCursor: makeRectIsTargetByCursor(rect, api, targetInfo.coordSysModel), + getLinearBrushOtherExtent: makeLinearBrushOtherExtent(rect) + }; + }); + }; + BrushTargetManager.prototype.controlSeries = function (area, seriesModel, ecModel) { + // Check whether area is bound in coord, and series do not belong to that coord. + // If do not do this check, some brush (like lineX) will controll all axes. + var targetInfo = this.findTargetInfo(area, ecModel); + return targetInfo === true || targetInfo && indexOf(targetInfo.coordSyses, seriesModel.coordinateSystem) >= 0; + }; + /** + * If return Object, a coord found. + * If return true, global found. + * Otherwise nothing found. + */ + BrushTargetManager.prototype.findTargetInfo = function (area, ecModel) { + var targetInfoList = this._targetInfoList; + var foundCpts = parseFinder$1(ecModel, area); + for (var i = 0; i < targetInfoList.length; i++) { + var targetInfo = targetInfoList[i]; + var areaPanelId = area.panelId; + if (areaPanelId) { + if (targetInfo.panelId === areaPanelId) { + return targetInfo; + } + } else { + for (var j = 0; j < targetInfoMatchers.length; j++) { + if (targetInfoMatchers[j](foundCpts, targetInfo)) { + return targetInfo; + } + } + } + } + return true; + }; + return BrushTargetManager; + }(); + function formatMinMax(minMax) { + minMax[0] > minMax[1] && minMax.reverse(); + return minMax; + } + function parseFinder$1(ecModel, finder) { + return parseFinder(ecModel, finder, { + includeMainTypes: INCLUDE_FINDER_MAIN_TYPES + }); + } + var targetInfoBuilders = { + grid: function (foundCpts, targetInfoList) { + var xAxisModels = foundCpts.xAxisModels; + var yAxisModels = foundCpts.yAxisModels; + var gridModels = foundCpts.gridModels; + // Remove duplicated. + var gridModelMap = createHashMap(); + var xAxesHas = {}; + var yAxesHas = {}; + if (!xAxisModels && !yAxisModels && !gridModels) { + return; + } + each(xAxisModels, function (axisModel) { + var gridModel = axisModel.axis.grid.model; + gridModelMap.set(gridModel.id, gridModel); + xAxesHas[gridModel.id] = true; + }); + each(yAxisModels, function (axisModel) { + var gridModel = axisModel.axis.grid.model; + gridModelMap.set(gridModel.id, gridModel); + yAxesHas[gridModel.id] = true; + }); + each(gridModels, function (gridModel) { + gridModelMap.set(gridModel.id, gridModel); + xAxesHas[gridModel.id] = true; + yAxesHas[gridModel.id] = true; + }); + gridModelMap.each(function (gridModel) { + var grid = gridModel.coordinateSystem; + var cartesians = []; + each(grid.getCartesians(), function (cartesian, index) { + if (indexOf(xAxisModels, cartesian.getAxis('x').model) >= 0 || indexOf(yAxisModels, cartesian.getAxis('y').model) >= 0) { + cartesians.push(cartesian); + } + }); + targetInfoList.push({ + panelId: 'grid--' + gridModel.id, + gridModel: gridModel, + coordSysModel: gridModel, + // Use the first one as the representitive coordSys. + coordSys: cartesians[0], + coordSyses: cartesians, + getPanelRect: panelRectBuilders.grid, + xAxisDeclared: xAxesHas[gridModel.id], + yAxisDeclared: yAxesHas[gridModel.id] + }); + }); + }, + geo: function (foundCpts, targetInfoList) { + each(foundCpts.geoModels, function (geoModel) { + var coordSys = geoModel.coordinateSystem; + targetInfoList.push({ + panelId: 'geo--' + geoModel.id, + geoModel: geoModel, + coordSysModel: geoModel, + coordSys: coordSys, + coordSyses: [coordSys], + getPanelRect: panelRectBuilders.geo + }); + }); + } + }; + var targetInfoMatchers = [ + // grid + function (foundCpts, targetInfo) { + var xAxisModel = foundCpts.xAxisModel; + var yAxisModel = foundCpts.yAxisModel; + var gridModel = foundCpts.gridModel; + !gridModel && xAxisModel && (gridModel = xAxisModel.axis.grid.model); + !gridModel && yAxisModel && (gridModel = yAxisModel.axis.grid.model); + return gridModel && gridModel === targetInfo.gridModel; + }, + // geo + function (foundCpts, targetInfo) { + var geoModel = foundCpts.geoModel; + return geoModel && geoModel === targetInfo.geoModel; + }]; + var panelRectBuilders = { + grid: function () { + // grid is not Transformable. + return this.coordSys.master.getRect().clone(); + }, + geo: function () { + var coordSys = this.coordSys; + var rect = coordSys.getBoundingRect().clone(); + // geo roam and zoom transform + rect.applyTransform(getTransform(coordSys)); + return rect; + } + }; + var coordConvert = { + lineX: curry(axisConvert, 0), + lineY: curry(axisConvert, 1), + rect: function (to, coordSys, rangeOrCoordRange, clamp) { + var xminymin = to ? coordSys.pointToData([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][0], rangeOrCoordRange[1][0]], clamp); + var xmaxymax = to ? coordSys.pointToData([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp) : coordSys.dataToPoint([rangeOrCoordRange[0][1], rangeOrCoordRange[1][1]], clamp); + var values = [formatMinMax([xminymin[0], xmaxymax[0]]), formatMinMax([xminymin[1], xmaxymax[1]])]; + return { + values: values, + xyMinMax: values + }; + }, + polygon: function (to, coordSys, rangeOrCoordRange, clamp) { + var xyMinMax = [[Infinity, -Infinity], [Infinity, -Infinity]]; + var values = map(rangeOrCoordRange, function (item) { + var p = to ? coordSys.pointToData(item, clamp) : coordSys.dataToPoint(item, clamp); + xyMinMax[0][0] = Math.min(xyMinMax[0][0], p[0]); + xyMinMax[1][0] = Math.min(xyMinMax[1][0], p[1]); + xyMinMax[0][1] = Math.max(xyMinMax[0][1], p[0]); + xyMinMax[1][1] = Math.max(xyMinMax[1][1], p[1]); + return p; + }); + return { + values: values, + xyMinMax: xyMinMax + }; + } + }; + function axisConvert(axisNameIndex, to, coordSys, rangeOrCoordRange) { + if ("development" !== 'production') { + assert(coordSys.type === 'cartesian2d', 'lineX/lineY brush is available only in cartesian2d.'); + } + var axis = coordSys.getAxis(['x', 'y'][axisNameIndex]); + var values = formatMinMax(map([0, 1], function (i) { + return to ? axis.coordToData(axis.toLocalCoord(rangeOrCoordRange[i]), true) : axis.toGlobalCoord(axis.dataToCoord(rangeOrCoordRange[i])); + })); + var xyMinMax = []; + xyMinMax[axisNameIndex] = values; + xyMinMax[1 - axisNameIndex] = [NaN, NaN]; + return { + values: values, + xyMinMax: xyMinMax + }; + } + var diffProcessor = { + lineX: curry(axisDiffProcessor, 0), + lineY: curry(axisDiffProcessor, 1), + rect: function (values, refer, scales) { + return [[values[0][0] - scales[0] * refer[0][0], values[0][1] - scales[0] * refer[0][1]], [values[1][0] - scales[1] * refer[1][0], values[1][1] - scales[1] * refer[1][1]]]; + }, + polygon: function (values, refer, scales) { + return map(values, function (item, idx) { + return [item[0] - scales[0] * refer[idx][0], item[1] - scales[1] * refer[idx][1]]; + }); + } + }; + function axisDiffProcessor(axisNameIndex, values, refer, scales) { + return [values[0] - scales[axisNameIndex] * refer[0], values[1] - scales[axisNameIndex] * refer[1]]; + } + // We have to process scale caused by dataZoom manually, + // although it might be not accurate. + // Return [0~1, 0~1] + function getScales(xyMinMaxCurr, xyMinMaxOrigin) { + var sizeCurr = getSize$1(xyMinMaxCurr); + var sizeOrigin = getSize$1(xyMinMaxOrigin); + var scales = [sizeCurr[0] / sizeOrigin[0], sizeCurr[1] / sizeOrigin[1]]; + isNaN(scales[0]) && (scales[0] = 1); + isNaN(scales[1]) && (scales[1] = 1); + return scales; + } + function getSize$1(xyMinMax) { + return xyMinMax ? [xyMinMax[0][1] - xyMinMax[0][0], xyMinMax[1][1] - xyMinMax[1][0]] : [NaN, NaN]; + } + + var each$a = each; + var DATA_ZOOM_ID_BASE = makeInternalComponentId('toolbox-dataZoom_'); + var DataZoomFeature = /** @class */function (_super) { + __extends(DataZoomFeature, _super); + function DataZoomFeature() { + return _super !== null && _super.apply(this, arguments) || this; + } + DataZoomFeature.prototype.render = function (featureModel, ecModel, api, payload) { + if (!this._brushController) { + this._brushController = new BrushController(api.getZr()); + this._brushController.on('brush', bind(this._onBrush, this)).mount(); + } + updateZoomBtnStatus(featureModel, ecModel, this, payload, api); + updateBackBtnStatus(featureModel, ecModel); + }; + DataZoomFeature.prototype.onclick = function (ecModel, api, type) { + handlers$1[type].call(this); + }; + DataZoomFeature.prototype.remove = function (ecModel, api) { + this._brushController && this._brushController.unmount(); + }; + DataZoomFeature.prototype.dispose = function (ecModel, api) { + this._brushController && this._brushController.dispose(); + }; + DataZoomFeature.prototype._onBrush = function (eventParam) { + var areas = eventParam.areas; + if (!eventParam.isEnd || !areas.length) { + return; + } + var snapshot = {}; + var ecModel = this.ecModel; + this._brushController.updateCovers([]); // remove cover + var brushTargetManager = new BrushTargetManager(makeAxisFinder(this.model), ecModel, { + include: ['grid'] + }); + brushTargetManager.matchOutputRanges(areas, ecModel, function (area, coordRange, coordSys) { + if (coordSys.type !== 'cartesian2d') { + return; + } + var brushType = area.brushType; + if (brushType === 'rect') { + setBatch('x', coordSys, coordRange[0]); + setBatch('y', coordSys, coordRange[1]); + } else { + setBatch({ + lineX: 'x', + lineY: 'y' + }[brushType], coordSys, coordRange); + } + }); + push(ecModel, snapshot); + this._dispatchZoomAction(snapshot); + function setBatch(dimName, coordSys, minMax) { + var axis = coordSys.getAxis(dimName); + var axisModel = axis.model; + var dataZoomModel = findDataZoom(dimName, axisModel, ecModel); + // Restrict range. + var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy(axisModel).getMinMaxSpan(); + if (minMaxSpan.minValueSpan != null || minMaxSpan.maxValueSpan != null) { + minMax = sliderMove(0, minMax.slice(), axis.scale.getExtent(), 0, minMaxSpan.minValueSpan, minMaxSpan.maxValueSpan); + } + dataZoomModel && (snapshot[dataZoomModel.id] = { + dataZoomId: dataZoomModel.id, + startValue: minMax[0], + endValue: minMax[1] + }); + } + function findDataZoom(dimName, axisModel, ecModel) { + var found; + ecModel.eachComponent({ + mainType: 'dataZoom', + subType: 'select' + }, function (dzModel) { + var has = dzModel.getAxisModel(dimName, axisModel.componentIndex); + has && (found = dzModel); + }); + return found; + } + }; + DataZoomFeature.prototype._dispatchZoomAction = function (snapshot) { + var batch = []; + // Convert from hash map to array. + each$a(snapshot, function (batchItem, dataZoomId) { + batch.push(clone(batchItem)); + }); + batch.length && this.api.dispatchAction({ + type: 'dataZoom', + from: this.uid, + batch: batch + }); + }; + DataZoomFeature.getDefaultOption = function (ecModel) { + var defaultOption = { + show: true, + filterMode: 'filter', + // Icon group + icon: { + zoom: 'M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1', + back: 'M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26' + }, + // `zoom`, `back` + title: ecModel.getLocaleModel().get(['toolbox', 'dataZoom', 'title']), + brushStyle: { + borderWidth: 0, + color: 'rgba(210,219,238,0.2)' + } + }; + return defaultOption; + }; + return DataZoomFeature; + }(ToolboxFeature); + var handlers$1 = { + zoom: function () { + var nextActive = !this._isZoomActive; + this.api.dispatchAction({ + type: 'takeGlobalCursor', + key: 'dataZoomSelect', + dataZoomSelectActive: nextActive + }); + }, + back: function () { + this._dispatchZoomAction(pop(this.ecModel)); + } + }; + function makeAxisFinder(dzFeatureModel) { + var setting = { + xAxisIndex: dzFeatureModel.get('xAxisIndex', true), + yAxisIndex: dzFeatureModel.get('yAxisIndex', true), + xAxisId: dzFeatureModel.get('xAxisId', true), + yAxisId: dzFeatureModel.get('yAxisId', true) + }; + // If both `xAxisIndex` `xAxisId` not set, it means 'all'. + // If both `yAxisIndex` `yAxisId` not set, it means 'all'. + // Some old cases set like this below to close yAxis control but leave xAxis control: + // `{ feature: { dataZoom: { yAxisIndex: false } }`. + if (setting.xAxisIndex == null && setting.xAxisId == null) { + setting.xAxisIndex = 'all'; + } + if (setting.yAxisIndex == null && setting.yAxisId == null) { + setting.yAxisIndex = 'all'; + } + return setting; + } + function updateBackBtnStatus(featureModel, ecModel) { + featureModel.setIconStatus('back', count(ecModel) > 1 ? 'emphasis' : 'normal'); + } + function updateZoomBtnStatus(featureModel, ecModel, view, payload, api) { + var zoomActive = view._isZoomActive; + if (payload && payload.type === 'takeGlobalCursor') { + zoomActive = payload.key === 'dataZoomSelect' ? payload.dataZoomSelectActive : false; + } + view._isZoomActive = zoomActive; + featureModel.setIconStatus('zoom', zoomActive ? 'emphasis' : 'normal'); + var brushTargetManager = new BrushTargetManager(makeAxisFinder(featureModel), ecModel, { + include: ['grid'] + }); + var panels = brushTargetManager.makePanelOpts(api, function (targetInfo) { + return targetInfo.xAxisDeclared && !targetInfo.yAxisDeclared ? 'lineX' : !targetInfo.xAxisDeclared && targetInfo.yAxisDeclared ? 'lineY' : 'rect'; + }); + view._brushController.setPanels(panels).enableBrush(zoomActive && panels.length ? { + brushType: 'auto', + brushStyle: featureModel.getModel('brushStyle').getItemStyle() + } : false); + } + registerInternalOptionCreator('dataZoom', function (ecModel) { + var toolboxModel = ecModel.getComponent('toolbox', 0); + var featureDataZoomPath = ['feature', 'dataZoom']; + if (!toolboxModel || toolboxModel.get(featureDataZoomPath) == null) { + return; + } + var dzFeatureModel = toolboxModel.getModel(featureDataZoomPath); + var dzOptions = []; + var finder = makeAxisFinder(dzFeatureModel); + var finderResult = parseFinder(ecModel, finder); + each$a(finderResult.xAxisModels, function (axisModel) { + return buildInternalOptions(axisModel, 'xAxis', 'xAxisIndex'); + }); + each$a(finderResult.yAxisModels, function (axisModel) { + return buildInternalOptions(axisModel, 'yAxis', 'yAxisIndex'); + }); + function buildInternalOptions(axisModel, axisMainType, axisIndexPropName) { + var axisIndex = axisModel.componentIndex; + var newOpt = { + type: 'select', + $fromToolbox: true, + // Default to be filter + filterMode: dzFeatureModel.get('filterMode', true) || 'filter', + // Id for merge mapping. + id: DATA_ZOOM_ID_BASE + axisMainType + axisIndex + }; + newOpt[axisIndexPropName] = axisIndex; + dzOptions.push(newOpt); + } + return dzOptions; + }); + + function install$z(registers) { + registers.registerComponentModel(ToolboxModel); + registers.registerComponentView(ToolboxView); + registerFeature('saveAsImage', SaveAsImage); + registerFeature('magicType', MagicType); + registerFeature('dataView', DataView); + registerFeature('dataZoom', DataZoomFeature); + registerFeature('restore', RestoreOption); + use(install$y); + } + + var TooltipModel = /** @class */function (_super) { + __extends(TooltipModel, _super); + function TooltipModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TooltipModel.type; + return _this; + } + TooltipModel.type = 'tooltip'; + TooltipModel.dependencies = ['axisPointer']; + TooltipModel.defaultOption = { + // zlevel: 0, + z: 60, + show: true, + // tooltip main content + showContent: true, + // 'trigger' only works on coordinate system. + // 'item' | 'axis' | 'none' + trigger: 'item', + // 'click' | 'mousemove' | 'none' + triggerOn: 'mousemove|click', + alwaysShowContent: false, + displayMode: 'single', + renderMode: 'auto', + // whether restraint content inside viewRect. + // If renderMode: 'richText', default true. + // If renderMode: 'html', defaut false (for backward compat). + confine: null, + showDelay: 0, + hideDelay: 100, + // Animation transition time, unit is second + transitionDuration: 0.4, + enterable: false, + backgroundColor: '#fff', + // box shadow + shadowBlur: 10, + shadowColor: 'rgba(0, 0, 0, .2)', + shadowOffsetX: 1, + shadowOffsetY: 2, + // tooltip border radius, unit is px, default is 4 + borderRadius: 4, + // tooltip border width, unit is px, default is 0 (no border) + borderWidth: 1, + // Tooltip inside padding, default is 5 for all direction + // Array is allowed to set up, right, bottom, left, same with css + // The default value: See `tooltip/tooltipMarkup.ts#getPaddingFromTooltipModel`. + padding: null, + // Extra css text + extraCssText: '', + // axis indicator, trigger by axis + axisPointer: { + // default is line + // legal values: 'line' | 'shadow' | 'cross' + type: 'line', + // Valid when type is line, appoint tooltip line locate on which line. Optional + // legal values: 'x' | 'y' | 'angle' | 'radius' | 'auto' + // default is 'auto', chose the axis which type is category. + // for multiply y axis, cartesian coord chose x axis, polar chose angle axis + axis: 'auto', + animation: 'auto', + animationDurationUpdate: 200, + animationEasingUpdate: 'exponentialOut', + crossStyle: { + color: '#999', + width: 1, + type: 'dashed', + // TODO formatter + textStyle: {} + } + // lineStyle and shadowStyle should not be specified here, + // otherwise it will always override those styles on option.axisPointer. + }, + + textStyle: { + color: '#666', + fontSize: 14 + } + }; + return TooltipModel; + }(ComponentModel); + + /* global document */ + function shouldTooltipConfine(tooltipModel) { + var confineOption = tooltipModel.get('confine'); + return confineOption != null ? !!confineOption + // In richText mode, the outside part can not be visible. + : tooltipModel.get('renderMode') === 'richText'; + } + function testStyle(styleProps) { + if (!env.domSupported) { + return; + } + var style = document.documentElement.style; + for (var i = 0, len = styleProps.length; i < len; i++) { + if (styleProps[i] in style) { + return styleProps[i]; + } + } + } + var TRANSFORM_VENDOR = testStyle(['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']); + var TRANSITION_VENDOR = testStyle(['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']); + function toCSSVendorPrefix(styleVendor, styleProp) { + if (!styleVendor) { + return styleProp; + } + styleProp = toCamelCase(styleProp, true); + var idx = styleVendor.indexOf(styleProp); + styleVendor = idx === -1 ? styleProp : "-" + styleVendor.slice(0, idx) + "-" + styleProp; + return styleVendor.toLowerCase(); + } + function getComputedStyle(el, style) { + var stl = el.currentStyle || document.defaultView && document.defaultView.getComputedStyle(el); + return stl ? style ? stl[style] : stl : null; + } + + /* global document, window */ + var CSS_TRANSITION_VENDOR = toCSSVendorPrefix(TRANSITION_VENDOR, 'transition'); + var CSS_TRANSFORM_VENDOR = toCSSVendorPrefix(TRANSFORM_VENDOR, 'transform'); + // eslint-disable-next-line + var gCssText = "position:absolute;display:block;border-style:solid;white-space:nowrap;z-index:9999999;" + (env.transform3dSupported ? 'will-change:transform;' : ''); + function mirrorPos(pos) { + pos = pos === 'left' ? 'right' : pos === 'right' ? 'left' : pos === 'top' ? 'bottom' : 'top'; + return pos; + } + function assembleArrow(tooltipModel, borderColor, arrowPosition) { + if (!isString(arrowPosition) || arrowPosition === 'inside') { + return ''; + } + var backgroundColor = tooltipModel.get('backgroundColor'); + var borderWidth = tooltipModel.get('borderWidth'); + borderColor = convertToColorString(borderColor); + var arrowPos = mirrorPos(arrowPosition); + var arrowSize = Math.max(Math.round(borderWidth) * 1.5, 6); + var positionStyle = ''; + var transformStyle = CSS_TRANSFORM_VENDOR + ':'; + var rotateDeg; + if (indexOf(['left', 'right'], arrowPos) > -1) { + positionStyle += 'top:50%'; + transformStyle += "translateY(-50%) rotate(" + (rotateDeg = arrowPos === 'left' ? -225 : -45) + "deg)"; + } else { + positionStyle += 'left:50%'; + transformStyle += "translateX(-50%) rotate(" + (rotateDeg = arrowPos === 'top' ? 225 : 45) + "deg)"; + } + var rotateRadian = rotateDeg * Math.PI / 180; + var arrowWH = arrowSize + borderWidth; + var rotatedWH = arrowWH * Math.abs(Math.cos(rotateRadian)) + arrowWH * Math.abs(Math.sin(rotateRadian)); + var arrowOffset = Math.round(((rotatedWH - Math.SQRT2 * borderWidth) / 2 + Math.SQRT2 * borderWidth - (rotatedWH - arrowWH) / 2) * 100) / 100; + positionStyle += ";" + arrowPos + ":-" + arrowOffset + "px"; + var borderStyle = borderColor + " solid " + borderWidth + "px;"; + var styleCss = ["position:absolute;width:" + arrowSize + "px;height:" + arrowSize + "px;z-index:-1;", positionStyle + ";" + transformStyle + ";", "border-bottom:" + borderStyle, "border-right:" + borderStyle, "background-color:" + backgroundColor + ";"]; + return "
    "; + } + function assembleTransition(duration, onlyFade) { + var transitionCurve = 'cubic-bezier(0.23,1,0.32,1)'; + var transitionOption = " " + duration / 2 + "s " + transitionCurve; + var transitionText = "opacity" + transitionOption + ",visibility" + transitionOption; + if (!onlyFade) { + transitionOption = " " + duration + "s " + transitionCurve; + transitionText += env.transformSupported ? "," + CSS_TRANSFORM_VENDOR + transitionOption : ",left" + transitionOption + ",top" + transitionOption; + } + return CSS_TRANSITION_VENDOR + ':' + transitionText; + } + function assembleTransform(x, y, toString) { + // If using float on style, the final width of the dom might + // keep changing slightly while mouse move. So `toFixed(0)` them. + var x0 = x.toFixed(0) + 'px'; + var y0 = y.toFixed(0) + 'px'; + // not support transform, use `left` and `top` instead. + if (!env.transformSupported) { + return toString ? "top:" + y0 + ";left:" + x0 + ";" : [['top', y0], ['left', x0]]; + } + // support transform + var is3d = env.transform3dSupported; + var translate = "translate" + (is3d ? '3d' : '') + "(" + x0 + "," + y0 + (is3d ? ',0' : '') + ")"; + return toString ? 'top:0;left:0;' + CSS_TRANSFORM_VENDOR + ':' + translate + ';' : [['top', 0], ['left', 0], [TRANSFORM_VENDOR, translate]]; + } + /** + * @param {Object} textStyle + * @return {string} + * @inner + */ + function assembleFont(textStyleModel) { + var cssText = []; + var fontSize = textStyleModel.get('fontSize'); + var color = textStyleModel.getTextColor(); + color && cssText.push('color:' + color); + cssText.push('font:' + textStyleModel.getFont()); + fontSize + // @ts-ignore, leave it to the tooltip refactor. + && cssText.push('line-height:' + Math.round(fontSize * 3 / 2) + 'px'); + var shadowColor = textStyleModel.get('textShadowColor'); + var shadowBlur = textStyleModel.get('textShadowBlur') || 0; + var shadowOffsetX = textStyleModel.get('textShadowOffsetX') || 0; + var shadowOffsetY = textStyleModel.get('textShadowOffsetY') || 0; + shadowColor && shadowBlur && cssText.push('text-shadow:' + shadowOffsetX + 'px ' + shadowOffsetY + 'px ' + shadowBlur + 'px ' + shadowColor); + each(['decoration', 'align'], function (name) { + var val = textStyleModel.get(name); + val && cssText.push('text-' + name + ':' + val); + }); + return cssText.join(';'); + } + function assembleCssText(tooltipModel, enableTransition, onlyFade) { + var cssText = []; + var transitionDuration = tooltipModel.get('transitionDuration'); + var backgroundColor = tooltipModel.get('backgroundColor'); + var shadowBlur = tooltipModel.get('shadowBlur'); + var shadowColor = tooltipModel.get('shadowColor'); + var shadowOffsetX = tooltipModel.get('shadowOffsetX'); + var shadowOffsetY = tooltipModel.get('shadowOffsetY'); + var textStyleModel = tooltipModel.getModel('textStyle'); + var padding = getPaddingFromTooltipModel(tooltipModel, 'html'); + var boxShadow = shadowOffsetX + "px " + shadowOffsetY + "px " + shadowBlur + "px " + shadowColor; + cssText.push('box-shadow:' + boxShadow); + // Animation transition. Do not animate when transitionDuration is 0. + enableTransition && transitionDuration && cssText.push(assembleTransition(transitionDuration, onlyFade)); + if (backgroundColor) { + cssText.push('background-color:' + backgroundColor); + } + // Border style + each(['width', 'color', 'radius'], function (name) { + var borderName = 'border-' + name; + var camelCase = toCamelCase(borderName); + var val = tooltipModel.get(camelCase); + val != null && cssText.push(borderName + ':' + val + (name === 'color' ? '' : 'px')); + }); + // Text style + cssText.push(assembleFont(textStyleModel)); + // Padding + if (padding != null) { + cssText.push('padding:' + normalizeCssArray$1(padding).join('px ') + 'px'); + } + return cssText.join(';') + ';'; + } + // If not able to make, do not modify the input `out`. + function makeStyleCoord(out, zr, container, zrX, zrY) { + var zrPainter = zr && zr.painter; + if (container) { + var zrViewportRoot = zrPainter && zrPainter.getViewportRoot(); + if (zrViewportRoot) { + // Some APPs might use scale on body, so we support CSS transform here. + transformLocalCoord(out, zrViewportRoot, container, zrX, zrY); + } + } else { + out[0] = zrX; + out[1] = zrY; + // xy should be based on canvas root. But tooltipContent is + // the sibling of canvas root. So padding of ec container + // should be considered here. + var viewportRootOffset = zrPainter && zrPainter.getViewportRootOffset(); + if (viewportRootOffset) { + out[0] += viewportRootOffset.offsetLeft; + out[1] += viewportRootOffset.offsetTop; + } + } + out[2] = out[0] / zr.getWidth(); + out[3] = out[1] / zr.getHeight(); + } + var TooltipHTMLContent = /** @class */function () { + function TooltipHTMLContent(api, opt) { + this._show = false; + this._styleCoord = [0, 0, 0, 0]; + this._enterable = true; + this._alwaysShowContent = false; + this._firstShow = true; + this._longHide = true; + if (env.wxa) { + return null; + } + var el = document.createElement('div'); + // TODO: TYPE + el.domBelongToZr = true; + this.el = el; + var zr = this._zr = api.getZr(); + var appendTo = opt.appendTo; + var container = appendTo && (isString(appendTo) ? document.querySelector(appendTo) : isDom(appendTo) ? appendTo : isFunction(appendTo) && appendTo(api.getDom())); + makeStyleCoord(this._styleCoord, zr, container, api.getWidth() / 2, api.getHeight() / 2); + (container || api.getDom()).appendChild(el); + this._api = api; + this._container = container; + // FIXME + // Is it needed to trigger zr event manually if + // the browser do not support `pointer-events: none`. + var self = this; + el.onmouseenter = function () { + // clear the timeout in hideLater and keep showing tooltip + if (self._enterable) { + clearTimeout(self._hideTimeout); + self._show = true; + } + self._inContent = true; + }; + el.onmousemove = function (e) { + e = e || window.event; + if (!self._enterable) { + // `pointer-events: none` is set to tooltip content div + // if `enterable` is set as `false`, and `el.onmousemove` + // can not be triggered. But in browser that do not + // support `pointer-events`, we need to do this: + // Try trigger zrender event to avoid mouse + // in and out shape too frequently + var handler = zr.handler; + var zrViewportRoot = zr.painter.getViewportRoot(); + normalizeEvent(zrViewportRoot, e, true); + handler.dispatch('mousemove', e); + } + }; + el.onmouseleave = function () { + // set `_inContent` to `false` before `hideLater` + self._inContent = false; + if (self._enterable) { + if (self._show) { + self.hideLater(self._hideDelay); + } + } + }; + } + /** + * Update when tooltip is rendered + */ + TooltipHTMLContent.prototype.update = function (tooltipModel) { + // FIXME + // Move this logic to ec main? + if (!this._container) { + var container = this._api.getDom(); + var position = getComputedStyle(container, 'position'); + var domStyle = container.style; + if (domStyle.position !== 'absolute' && position !== 'absolute') { + domStyle.position = 'relative'; + } + } + // move tooltip if chart resized + var alwaysShowContent = tooltipModel.get('alwaysShowContent'); + alwaysShowContent && this._moveIfResized(); + // update alwaysShowContent + this._alwaysShowContent = alwaysShowContent; + // update className + this.el.className = tooltipModel.get('className') || ''; + // Hide the tooltip + // PENDING + // this.hide(); + }; + + TooltipHTMLContent.prototype.show = function (tooltipModel, nearPointColor) { + clearTimeout(this._hideTimeout); + clearTimeout(this._longHideTimeout); + var el = this.el; + var style = el.style; + var styleCoord = this._styleCoord; + if (!el.innerHTML) { + style.display = 'none'; + } else { + style.cssText = gCssText + assembleCssText(tooltipModel, !this._firstShow, this._longHide) + // initial transform + + assembleTransform(styleCoord[0], styleCoord[1], true) + ("border-color:" + convertToColorString(nearPointColor) + ";") + (tooltipModel.get('extraCssText') || '') + // If mouse occasionally move over the tooltip, a mouseout event will be + // triggered by canvas, and cause some unexpectable result like dragging + // stop, "unfocusAdjacency". Here `pointer-events: none` is used to solve + // it. Although it is not supported by IE8~IE10, fortunately it is a rare + // scenario. + + (";pointer-events:" + (this._enterable ? 'auto' : 'none')); + } + this._show = true; + this._firstShow = false; + this._longHide = false; + }; + TooltipHTMLContent.prototype.setContent = function (content, markers, tooltipModel, borderColor, arrowPosition) { + var el = this.el; + if (content == null) { + el.innerHTML = ''; + return; + } + var arrow = ''; + if (isString(arrowPosition) && tooltipModel.get('trigger') === 'item' && !shouldTooltipConfine(tooltipModel)) { + arrow = assembleArrow(tooltipModel, borderColor, arrowPosition); + } + if (isString(content)) { + el.innerHTML = content + arrow; + } else if (content) { + // Clear previous + el.innerHTML = ''; + if (!isArray(content)) { + content = [content]; + } + for (var i = 0; i < content.length; i++) { + if (isDom(content[i]) && content[i].parentNode !== el) { + el.appendChild(content[i]); + } + } + // no arrow if empty + if (arrow && el.childNodes.length) { + // no need to create a new parent element, but it's not supported by IE 10 and older. + // const arrowEl = document.createRange().createContextualFragment(arrow); + var arrowEl = document.createElement('div'); + arrowEl.innerHTML = arrow; + el.appendChild(arrowEl); + } + } + }; + TooltipHTMLContent.prototype.setEnterable = function (enterable) { + this._enterable = enterable; + }; + TooltipHTMLContent.prototype.getSize = function () { + var el = this.el; + return [el.offsetWidth, el.offsetHeight]; + }; + TooltipHTMLContent.prototype.moveTo = function (zrX, zrY) { + var styleCoord = this._styleCoord; + makeStyleCoord(styleCoord, this._zr, this._container, zrX, zrY); + if (styleCoord[0] != null && styleCoord[1] != null) { + var style_1 = this.el.style; + var transforms = assembleTransform(styleCoord[0], styleCoord[1]); + each(transforms, function (transform) { + style_1[transform[0]] = transform[1]; + }); + } + }; + /** + * when `alwaysShowContent` is true, + * move the tooltip after chart resized + */ + TooltipHTMLContent.prototype._moveIfResized = function () { + // The ratio of left to width + var ratioX = this._styleCoord[2]; + // The ratio of top to height + var ratioY = this._styleCoord[3]; + this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight()); + }; + TooltipHTMLContent.prototype.hide = function () { + var _this = this; + var style = this.el.style; + style.visibility = 'hidden'; + style.opacity = '0'; + env.transform3dSupported && (style.willChange = ''); + this._show = false; + this._longHideTimeout = setTimeout(function () { + return _this._longHide = true; + }, 500); + }; + TooltipHTMLContent.prototype.hideLater = function (time) { + if (this._show && !(this._inContent && this._enterable) && !this._alwaysShowContent) { + if (time) { + this._hideDelay = time; + // Set show false to avoid invoke hideLater multiple times + this._show = false; + this._hideTimeout = setTimeout(bind(this.hide, this), time); + } else { + this.hide(); + } + } + }; + TooltipHTMLContent.prototype.isShow = function () { + return this._show; + }; + TooltipHTMLContent.prototype.dispose = function () { + clearTimeout(this._hideTimeout); + clearTimeout(this._longHideTimeout); + var parentNode = this.el.parentNode; + parentNode && parentNode.removeChild(this.el); + this.el = this._container = null; + }; + return TooltipHTMLContent; + }(); + + var TooltipRichContent = /** @class */function () { + function TooltipRichContent(api) { + this._show = false; + this._styleCoord = [0, 0, 0, 0]; + this._alwaysShowContent = false; + this._enterable = true; + this._zr = api.getZr(); + makeStyleCoord$1(this._styleCoord, this._zr, api.getWidth() / 2, api.getHeight() / 2); + } + /** + * Update when tooltip is rendered + */ + TooltipRichContent.prototype.update = function (tooltipModel) { + var alwaysShowContent = tooltipModel.get('alwaysShowContent'); + alwaysShowContent && this._moveIfResized(); + // update alwaysShowContent + this._alwaysShowContent = alwaysShowContent; + }; + TooltipRichContent.prototype.show = function () { + if (this._hideTimeout) { + clearTimeout(this._hideTimeout); + } + this.el.show(); + this._show = true; + }; + /** + * Set tooltip content + */ + TooltipRichContent.prototype.setContent = function (content, markupStyleCreator, tooltipModel, borderColor, arrowPosition) { + var _this = this; + if (isObject(content)) { + throwError("development" !== 'production' ? 'Passing DOM nodes as content is not supported in richText tooltip!' : ''); + } + if (this.el) { + this._zr.remove(this.el); + } + var textStyleModel = tooltipModel.getModel('textStyle'); + this.el = new ZRText({ + style: { + rich: markupStyleCreator.richTextStyles, + text: content, + lineHeight: 22, + borderWidth: 1, + borderColor: borderColor, + textShadowColor: textStyleModel.get('textShadowColor'), + fill: tooltipModel.get(['textStyle', 'color']), + padding: getPaddingFromTooltipModel(tooltipModel, 'richText'), + verticalAlign: 'top', + align: 'left' + }, + z: tooltipModel.get('z') + }); + each(['backgroundColor', 'borderRadius', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'], function (propName) { + _this.el.style[propName] = tooltipModel.get(propName); + }); + each(['textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY'], function (propName) { + _this.el.style[propName] = textStyleModel.get(propName) || 0; + }); + this._zr.add(this.el); + var self = this; + this.el.on('mouseover', function () { + // clear the timeout in hideLater and keep showing tooltip + if (self._enterable) { + clearTimeout(self._hideTimeout); + self._show = true; + } + self._inContent = true; + }); + this.el.on('mouseout', function () { + if (self._enterable) { + if (self._show) { + self.hideLater(self._hideDelay); + } + } + self._inContent = false; + }); + }; + TooltipRichContent.prototype.setEnterable = function (enterable) { + this._enterable = enterable; + }; + TooltipRichContent.prototype.getSize = function () { + var el = this.el; + var bounding = this.el.getBoundingRect(); + // bounding rect does not include shadow. For renderMode richText, + // if overflow, it will be cut. So calculate them accurately. + var shadowOuterSize = calcShadowOuterSize(el.style); + return [bounding.width + shadowOuterSize.left + shadowOuterSize.right, bounding.height + shadowOuterSize.top + shadowOuterSize.bottom]; + }; + TooltipRichContent.prototype.moveTo = function (x, y) { + var el = this.el; + if (el) { + var styleCoord = this._styleCoord; + makeStyleCoord$1(styleCoord, this._zr, x, y); + x = styleCoord[0]; + y = styleCoord[1]; + var style = el.style; + var borderWidth = mathMaxWith0(style.borderWidth || 0); + var shadowOuterSize = calcShadowOuterSize(style); + // rich text x, y do not include border. + el.x = x + borderWidth + shadowOuterSize.left; + el.y = y + borderWidth + shadowOuterSize.top; + el.markRedraw(); + } + }; + /** + * when `alwaysShowContent` is true, + * move the tooltip after chart resized + */ + TooltipRichContent.prototype._moveIfResized = function () { + // The ratio of left to width + var ratioX = this._styleCoord[2]; + // The ratio of top to height + var ratioY = this._styleCoord[3]; + this.moveTo(ratioX * this._zr.getWidth(), ratioY * this._zr.getHeight()); + }; + TooltipRichContent.prototype.hide = function () { + if (this.el) { + this.el.hide(); + } + this._show = false; + }; + TooltipRichContent.prototype.hideLater = function (time) { + if (this._show && !(this._inContent && this._enterable) && !this._alwaysShowContent) { + if (time) { + this._hideDelay = time; + // Set show false to avoid invoke hideLater multiple times + this._show = false; + this._hideTimeout = setTimeout(bind(this.hide, this), time); + } else { + this.hide(); + } + } + }; + TooltipRichContent.prototype.isShow = function () { + return this._show; + }; + TooltipRichContent.prototype.dispose = function () { + this._zr.remove(this.el); + }; + return TooltipRichContent; + }(); + function mathMaxWith0(val) { + return Math.max(0, val); + } + function calcShadowOuterSize(style) { + var shadowBlur = mathMaxWith0(style.shadowBlur || 0); + var shadowOffsetX = mathMaxWith0(style.shadowOffsetX || 0); + var shadowOffsetY = mathMaxWith0(style.shadowOffsetY || 0); + return { + left: mathMaxWith0(shadowBlur - shadowOffsetX), + right: mathMaxWith0(shadowBlur + shadowOffsetX), + top: mathMaxWith0(shadowBlur - shadowOffsetY), + bottom: mathMaxWith0(shadowBlur + shadowOffsetY) + }; + } + function makeStyleCoord$1(out, zr, zrX, zrY) { + out[0] = zrX; + out[1] = zrY; + out[2] = out[0] / zr.getWidth(); + out[3] = out[1] / zr.getHeight(); + } + + var proxyRect = new Rect({ + shape: { + x: -1, + y: -1, + width: 2, + height: 2 + } + }); + var TooltipView = /** @class */function (_super) { + __extends(TooltipView, _super); + function TooltipView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TooltipView.type; + return _this; + } + TooltipView.prototype.init = function (ecModel, api) { + if (env.node || !api.getDom()) { + return; + } + var tooltipModel = ecModel.getComponent('tooltip'); + var renderMode = this._renderMode = getTooltipRenderMode(tooltipModel.get('renderMode')); + this._tooltipContent = renderMode === 'richText' ? new TooltipRichContent(api) : new TooltipHTMLContent(api, { + appendTo: tooltipModel.get('appendToBody', true) ? 'body' : tooltipModel.get('appendTo', true) + }); + }; + TooltipView.prototype.render = function (tooltipModel, ecModel, api) { + if (env.node || !api.getDom()) { + return; + } + // Reset + this.group.removeAll(); + this._tooltipModel = tooltipModel; + this._ecModel = ecModel; + this._api = api; + var tooltipContent = this._tooltipContent; + tooltipContent.update(tooltipModel); + tooltipContent.setEnterable(tooltipModel.get('enterable')); + this._initGlobalListener(); + this._keepShow(); + // PENDING + // `mousemove` event will be triggered very frequently when the mouse moves fast, + // which causes that the `updatePosition` function was also called frequently. + // In Chrome with devtools open and Firefox, tooltip looks laggy and shakes. See #14695 #16101 + // To avoid frequent triggering, + // consider throttling it in 50ms when transition is enabled + if (this._renderMode !== 'richText' && tooltipModel.get('transitionDuration')) { + createOrUpdate(this, '_updatePosition', 50, 'fixRate'); + } else { + clear(this, '_updatePosition'); + } + }; + TooltipView.prototype._initGlobalListener = function () { + var tooltipModel = this._tooltipModel; + var triggerOn = tooltipModel.get('triggerOn'); + register('itemTooltip', this._api, bind(function (currTrigger, e, dispatchAction) { + // If 'none', it is not controlled by mouse totally. + if (triggerOn !== 'none') { + if (triggerOn.indexOf(currTrigger) >= 0) { + this._tryShow(e, dispatchAction); + } else if (currTrigger === 'leave') { + this._hide(dispatchAction); + } + } + }, this)); + }; + TooltipView.prototype._keepShow = function () { + var tooltipModel = this._tooltipModel; + var ecModel = this._ecModel; + var api = this._api; + var triggerOn = tooltipModel.get('triggerOn'); + // Try to keep the tooltip show when refreshing + if (this._lastX != null && this._lastY != null + // When user is willing to control tooltip totally using API, + // self.manuallyShowTip({x, y}) might cause tooltip hide, + // which is not expected. + && triggerOn !== 'none' && triggerOn !== 'click') { + var self_1 = this; + clearTimeout(this._refreshUpdateTimeout); + this._refreshUpdateTimeout = setTimeout(function () { + // Show tip next tick after other charts are rendered + // In case highlight action has wrong result + // FIXME + !api.isDisposed() && self_1.manuallyShowTip(tooltipModel, ecModel, api, { + x: self_1._lastX, + y: self_1._lastY, + dataByCoordSys: self_1._lastDataByCoordSys + }); + }); + } + }; + /** + * Show tip manually by + * dispatchAction({ + * type: 'showTip', + * x: 10, + * y: 10 + * }); + * Or + * dispatchAction({ + * type: 'showTip', + * seriesIndex: 0, + * dataIndex or dataIndexInside or name + * }); + * + * TODO Batch + */ + TooltipView.prototype.manuallyShowTip = function (tooltipModel, ecModel, api, payload) { + if (payload.from === this.uid || env.node || !api.getDom()) { + return; + } + var dispatchAction = makeDispatchAction$1(payload, api); + // Reset ticket + this._ticket = ''; + // When triggered from axisPointer. + var dataByCoordSys = payload.dataByCoordSys; + var cmptRef = findComponentReference(payload, ecModel, api); + if (cmptRef) { + var rect = cmptRef.el.getBoundingRect().clone(); + rect.applyTransform(cmptRef.el.transform); + this._tryShow({ + offsetX: rect.x + rect.width / 2, + offsetY: rect.y + rect.height / 2, + target: cmptRef.el, + position: payload.position, + // When manully trigger, the mouse is not on the el, so we'd better to + // position tooltip on the bottom of the el and display arrow is possible. + positionDefault: 'bottom' + }, dispatchAction); + } else if (payload.tooltip && payload.x != null && payload.y != null) { + var el = proxyRect; + el.x = payload.x; + el.y = payload.y; + el.update(); + getECData(el).tooltipConfig = { + name: null, + option: payload.tooltip + }; + // Manually show tooltip while view is not using zrender elements. + this._tryShow({ + offsetX: payload.x, + offsetY: payload.y, + target: el + }, dispatchAction); + } else if (dataByCoordSys) { + this._tryShow({ + offsetX: payload.x, + offsetY: payload.y, + position: payload.position, + dataByCoordSys: dataByCoordSys, + tooltipOption: payload.tooltipOption + }, dispatchAction); + } else if (payload.seriesIndex != null) { + if (this._manuallyAxisShowTip(tooltipModel, ecModel, api, payload)) { + return; + } + var pointInfo = findPointFromSeries(payload, ecModel); + var cx = pointInfo.point[0]; + var cy = pointInfo.point[1]; + if (cx != null && cy != null) { + this._tryShow({ + offsetX: cx, + offsetY: cy, + target: pointInfo.el, + position: payload.position, + // When manully trigger, the mouse is not on the el, so we'd better to + // position tooltip on the bottom of the el and display arrow is possible. + positionDefault: 'bottom' + }, dispatchAction); + } + } else if (payload.x != null && payload.y != null) { + // FIXME + // should wrap dispatchAction like `axisPointer/globalListener` ? + api.dispatchAction({ + type: 'updateAxisPointer', + x: payload.x, + y: payload.y + }); + this._tryShow({ + offsetX: payload.x, + offsetY: payload.y, + position: payload.position, + target: api.getZr().findHover(payload.x, payload.y).target + }, dispatchAction); + } + }; + TooltipView.prototype.manuallyHideTip = function (tooltipModel, ecModel, api, payload) { + var tooltipContent = this._tooltipContent; + if (this._tooltipModel) { + tooltipContent.hideLater(this._tooltipModel.get('hideDelay')); + } + this._lastX = this._lastY = this._lastDataByCoordSys = null; + if (payload.from !== this.uid) { + this._hide(makeDispatchAction$1(payload, api)); + } + }; + // Be compatible with previous design, that is, when tooltip.type is 'axis' and + // dispatchAction 'showTip' with seriesIndex and dataIndex will trigger axis pointer + // and tooltip. + TooltipView.prototype._manuallyAxisShowTip = function (tooltipModel, ecModel, api, payload) { + var seriesIndex = payload.seriesIndex; + var dataIndex = payload.dataIndex; + // @ts-ignore + var coordSysAxesInfo = ecModel.getComponent('axisPointer').coordSysAxesInfo; + if (seriesIndex == null || dataIndex == null || coordSysAxesInfo == null) { + return; + } + var seriesModel = ecModel.getSeriesByIndex(seriesIndex); + if (!seriesModel) { + return; + } + var data = seriesModel.getData(); + var tooltipCascadedModel = buildTooltipModel([data.getItemModel(dataIndex), seriesModel, (seriesModel.coordinateSystem || {}).model], this._tooltipModel); + if (tooltipCascadedModel.get('trigger') !== 'axis') { + return; + } + api.dispatchAction({ + type: 'updateAxisPointer', + seriesIndex: seriesIndex, + dataIndex: dataIndex, + position: payload.position + }); + return true; + }; + TooltipView.prototype._tryShow = function (e, dispatchAction) { + var el = e.target; + var tooltipModel = this._tooltipModel; + if (!tooltipModel) { + return; + } + // Save mouse x, mouse y. So we can try to keep showing the tip if chart is refreshed + this._lastX = e.offsetX; + this._lastY = e.offsetY; + var dataByCoordSys = e.dataByCoordSys; + if (dataByCoordSys && dataByCoordSys.length) { + this._showAxisTooltip(dataByCoordSys, e); + } else if (el) { + var ecData = getECData(el); + if (ecData.ssrType === 'legend') { + // Don't trigger tooltip for legend tooltip item + return; + } + this._lastDataByCoordSys = null; + var seriesDispatcher_1; + var cmptDispatcher_1; + findEventDispatcher(el, function (target) { + // Always show item tooltip if mouse is on the element with dataIndex + if (getECData(target).dataIndex != null) { + seriesDispatcher_1 = target; + return true; + } + // Tooltip provided directly. Like legend. + if (getECData(target).tooltipConfig != null) { + cmptDispatcher_1 = target; + return true; + } + }, true); + if (seriesDispatcher_1) { + this._showSeriesItemTooltip(e, seriesDispatcher_1, dispatchAction); + } else if (cmptDispatcher_1) { + this._showComponentItemTooltip(e, cmptDispatcher_1, dispatchAction); + } else { + this._hide(dispatchAction); + } + } else { + this._lastDataByCoordSys = null; + this._hide(dispatchAction); + } + }; + TooltipView.prototype._showOrMove = function (tooltipModel, cb) { + // showDelay is used in this case: tooltip.enterable is set + // as true. User intent to move mouse into tooltip and click + // something. `showDelay` makes it easier to enter the content + // but tooltip do not move immediately. + var delay = tooltipModel.get('showDelay'); + cb = bind(cb, this); + clearTimeout(this._showTimout); + delay > 0 ? this._showTimout = setTimeout(cb, delay) : cb(); + }; + TooltipView.prototype._showAxisTooltip = function (dataByCoordSys, e) { + var ecModel = this._ecModel; + var globalTooltipModel = this._tooltipModel; + var point = [e.offsetX, e.offsetY]; + var singleTooltipModel = buildTooltipModel([e.tooltipOption], globalTooltipModel); + var renderMode = this._renderMode; + var cbParamsList = []; + var articleMarkup = createTooltipMarkup('section', { + blocks: [], + noHeader: true + }); + // Only for legacy: `Serise['formatTooltip']` returns a string. + var markupTextArrLegacy = []; + var markupStyleCreator = new TooltipMarkupStyleCreator(); + each(dataByCoordSys, function (itemCoordSys) { + each(itemCoordSys.dataByAxis, function (axisItem) { + var axisModel = ecModel.getComponent(axisItem.axisDim + 'Axis', axisItem.axisIndex); + var axisValue = axisItem.value; + if (!axisModel || axisValue == null) { + return; + } + var axisValueLabel = getValueLabel(axisValue, axisModel.axis, ecModel, axisItem.seriesDataIndices, axisItem.valueLabelOpt); + var axisSectionMarkup = createTooltipMarkup('section', { + header: axisValueLabel, + noHeader: !trim(axisValueLabel), + sortBlocks: true, + blocks: [] + }); + articleMarkup.blocks.push(axisSectionMarkup); + each(axisItem.seriesDataIndices, function (idxItem) { + var series = ecModel.getSeriesByIndex(idxItem.seriesIndex); + var dataIndex = idxItem.dataIndexInside; + var cbParams = series.getDataParams(dataIndex); + // Can't find data. + if (cbParams.dataIndex < 0) { + return; + } + cbParams.axisDim = axisItem.axisDim; + cbParams.axisIndex = axisItem.axisIndex; + cbParams.axisType = axisItem.axisType; + cbParams.axisId = axisItem.axisId; + cbParams.axisValue = getAxisRawValue(axisModel.axis, { + value: axisValue + }); + cbParams.axisValueLabel = axisValueLabel; + // Pre-create marker style for makers. Users can assemble richText + // text in `formatter` callback and use those markers style. + cbParams.marker = markupStyleCreator.makeTooltipMarker('item', convertToColorString(cbParams.color), renderMode); + var seriesTooltipResult = normalizeTooltipFormatResult(series.formatTooltip(dataIndex, true, null)); + var frag = seriesTooltipResult.frag; + if (frag) { + var valueFormatter = buildTooltipModel([series], globalTooltipModel).get('valueFormatter'); + axisSectionMarkup.blocks.push(valueFormatter ? extend({ + valueFormatter: valueFormatter + }, frag) : frag); + } + if (seriesTooltipResult.text) { + markupTextArrLegacy.push(seriesTooltipResult.text); + } + cbParamsList.push(cbParams); + }); + }); + }); + // In most cases, the second axis is displays upper on the first one. + // So we reverse it to look better. + articleMarkup.blocks.reverse(); + markupTextArrLegacy.reverse(); + var positionExpr = e.position; + var orderMode = singleTooltipModel.get('order'); + var builtMarkupText = buildTooltipMarkup(articleMarkup, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), singleTooltipModel.get('textStyle')); + builtMarkupText && markupTextArrLegacy.unshift(builtMarkupText); + var blockBreak = renderMode === 'richText' ? '\n\n' : '
    '; + var allMarkupText = markupTextArrLegacy.join(blockBreak); + this._showOrMove(singleTooltipModel, function () { + if (this._updateContentNotChangedOnAxis(dataByCoordSys, cbParamsList)) { + this._updatePosition(singleTooltipModel, positionExpr, point[0], point[1], this._tooltipContent, cbParamsList); + } else { + this._showTooltipContent(singleTooltipModel, allMarkupText, cbParamsList, Math.random() + '', point[0], point[1], positionExpr, null, markupStyleCreator); + } + }); + // Do not trigger events here, because this branch only be entered + // from dispatchAction. + }; + + TooltipView.prototype._showSeriesItemTooltip = function (e, dispatcher, dispatchAction) { + var ecModel = this._ecModel; + var ecData = getECData(dispatcher); + // Use dataModel in element if possible + // Used when mouseover on a element like markPoint or edge + // In which case, the data is not main data in series. + var seriesIndex = ecData.seriesIndex; + var seriesModel = ecModel.getSeriesByIndex(seriesIndex); + // For example, graph link. + var dataModel = ecData.dataModel || seriesModel; + var dataIndex = ecData.dataIndex; + var dataType = ecData.dataType; + var data = dataModel.getData(dataType); + var renderMode = this._renderMode; + var positionDefault = e.positionDefault; + var tooltipModel = buildTooltipModel([data.getItemModel(dataIndex), dataModel, seriesModel && (seriesModel.coordinateSystem || {}).model], this._tooltipModel, positionDefault ? { + position: positionDefault + } : null); + var tooltipTrigger = tooltipModel.get('trigger'); + if (tooltipTrigger != null && tooltipTrigger !== 'item') { + return; + } + var params = dataModel.getDataParams(dataIndex, dataType); + var markupStyleCreator = new TooltipMarkupStyleCreator(); + // Pre-create marker style for makers. Users can assemble richText + // text in `formatter` callback and use those markers style. + params.marker = markupStyleCreator.makeTooltipMarker('item', convertToColorString(params.color), renderMode); + var seriesTooltipResult = normalizeTooltipFormatResult(dataModel.formatTooltip(dataIndex, false, dataType)); + var orderMode = tooltipModel.get('order'); + var valueFormatter = tooltipModel.get('valueFormatter'); + var frag = seriesTooltipResult.frag; + var markupText = frag ? buildTooltipMarkup(valueFormatter ? extend({ + valueFormatter: valueFormatter + }, frag) : frag, markupStyleCreator, renderMode, orderMode, ecModel.get('useUTC'), tooltipModel.get('textStyle')) : seriesTooltipResult.text; + var asyncTicket = 'item_' + dataModel.name + '_' + dataIndex; + this._showOrMove(tooltipModel, function () { + this._showTooltipContent(tooltipModel, markupText, params, asyncTicket, e.offsetX, e.offsetY, e.position, e.target, markupStyleCreator); + }); + // FIXME + // duplicated showtip if manuallyShowTip is called from dispatchAction. + dispatchAction({ + type: 'showTip', + dataIndexInside: dataIndex, + dataIndex: data.getRawIndex(dataIndex), + seriesIndex: seriesIndex, + from: this.uid + }); + }; + TooltipView.prototype._showComponentItemTooltip = function (e, el, dispatchAction) { + var ecData = getECData(el); + var tooltipConfig = ecData.tooltipConfig; + var tooltipOpt = tooltipConfig.option || {}; + if (isString(tooltipOpt)) { + var content = tooltipOpt; + tooltipOpt = { + content: content, + // Fixed formatter + formatter: content + }; + } + var tooltipModelCascade = [tooltipOpt]; + var cmpt = this._ecModel.getComponent(ecData.componentMainType, ecData.componentIndex); + if (cmpt) { + tooltipModelCascade.push(cmpt); + } + // In most cases, component tooltip formatter has different params with series tooltip formatter, + // so that they cannot share the same formatter. Since the global tooltip formatter is used for series + // by convention, we do not use it as the default formatter for component. + tooltipModelCascade.push({ + formatter: tooltipOpt.content + }); + var positionDefault = e.positionDefault; + var subTooltipModel = buildTooltipModel(tooltipModelCascade, this._tooltipModel, positionDefault ? { + position: positionDefault + } : null); + var defaultHtml = subTooltipModel.get('content'); + var asyncTicket = Math.random() + ''; + // PENDING: this case do not support richText style yet. + var markupStyleCreator = new TooltipMarkupStyleCreator(); + // Do not check whether `trigger` is 'none' here, because `trigger` + // only works on coordinate system. In fact, we have not found case + // that requires setting `trigger` nothing on component yet. + this._showOrMove(subTooltipModel, function () { + // Use formatterParams from element defined in component + // Avoid users modify it. + var formatterParams = clone(subTooltipModel.get('formatterParams') || {}); + this._showTooltipContent(subTooltipModel, defaultHtml, formatterParams, asyncTicket, e.offsetX, e.offsetY, e.position, el, markupStyleCreator); + }); + // If not dispatch showTip, tip may be hide triggered by axis. + dispatchAction({ + type: 'showTip', + from: this.uid + }); + }; + TooltipView.prototype._showTooltipContent = function ( + // Use Model insteadof TooltipModel because this model may be from series or other options. + // Instead of top level tooltip. + tooltipModel, defaultHtml, params, asyncTicket, x, y, positionExpr, el, markupStyleCreator) { + // Reset ticket + this._ticket = ''; + if (!tooltipModel.get('showContent') || !tooltipModel.get('show')) { + return; + } + var tooltipContent = this._tooltipContent; + tooltipContent.setEnterable(tooltipModel.get('enterable')); + var formatter = tooltipModel.get('formatter'); + positionExpr = positionExpr || tooltipModel.get('position'); + var html = defaultHtml; + var nearPoint = this._getNearestPoint([x, y], params, tooltipModel.get('trigger'), tooltipModel.get('borderColor')); + var nearPointColor = nearPoint.color; + if (formatter) { + if (isString(formatter)) { + var useUTC = tooltipModel.ecModel.get('useUTC'); + var params0 = isArray(params) ? params[0] : params; + var isTimeAxis = params0 && params0.axisType && params0.axisType.indexOf('time') >= 0; + html = formatter; + if (isTimeAxis) { + html = format(params0.axisValue, html, useUTC); + } + html = formatTpl(html, params, true); + } else if (isFunction(formatter)) { + var callback = bind(function (cbTicket, html) { + if (cbTicket === this._ticket) { + tooltipContent.setContent(html, markupStyleCreator, tooltipModel, nearPointColor, positionExpr); + this._updatePosition(tooltipModel, positionExpr, x, y, tooltipContent, params, el); + } + }, this); + this._ticket = asyncTicket; + html = formatter(params, asyncTicket, callback); + } else { + html = formatter; + } + } + tooltipContent.setContent(html, markupStyleCreator, tooltipModel, nearPointColor, positionExpr); + tooltipContent.show(tooltipModel, nearPointColor); + this._updatePosition(tooltipModel, positionExpr, x, y, tooltipContent, params, el); + }; + TooltipView.prototype._getNearestPoint = function (point, tooltipDataParams, trigger, borderColor) { + if (trigger === 'axis' || isArray(tooltipDataParams)) { + return { + color: borderColor || (this._renderMode === 'html' ? '#fff' : 'none') + }; + } + if (!isArray(tooltipDataParams)) { + return { + color: borderColor || tooltipDataParams.color || tooltipDataParams.borderColor + }; + } + }; + TooltipView.prototype._updatePosition = function (tooltipModel, positionExpr, x, + // Mouse x + y, + // Mouse y + content, params, el) { + var viewWidth = this._api.getWidth(); + var viewHeight = this._api.getHeight(); + positionExpr = positionExpr || tooltipModel.get('position'); + var contentSize = content.getSize(); + var align = tooltipModel.get('align'); + var vAlign = tooltipModel.get('verticalAlign'); + var rect = el && el.getBoundingRect().clone(); + el && rect.applyTransform(el.transform); + if (isFunction(positionExpr)) { + // Callback of position can be an array or a string specify the position + positionExpr = positionExpr([x, y], params, content.el, rect, { + viewSize: [viewWidth, viewHeight], + contentSize: contentSize.slice() + }); + } + if (isArray(positionExpr)) { + x = parsePercent$1(positionExpr[0], viewWidth); + y = parsePercent$1(positionExpr[1], viewHeight); + } else if (isObject(positionExpr)) { + var boxLayoutPosition = positionExpr; + boxLayoutPosition.width = contentSize[0]; + boxLayoutPosition.height = contentSize[1]; + var layoutRect = getLayoutRect(boxLayoutPosition, { + width: viewWidth, + height: viewHeight + }); + x = layoutRect.x; + y = layoutRect.y; + align = null; + // When positionExpr is left/top/right/bottom, + // align and verticalAlign will not work. + vAlign = null; + } + // Specify tooltip position by string 'top' 'bottom' 'left' 'right' around graphic element + else if (isString(positionExpr) && el) { + var pos = calcTooltipPosition(positionExpr, rect, contentSize, tooltipModel.get('borderWidth')); + x = pos[0]; + y = pos[1]; + } else { + var pos = refixTooltipPosition(x, y, content, viewWidth, viewHeight, align ? null : 20, vAlign ? null : 20); + x = pos[0]; + y = pos[1]; + } + align && (x -= isCenterAlign(align) ? contentSize[0] / 2 : align === 'right' ? contentSize[0] : 0); + vAlign && (y -= isCenterAlign(vAlign) ? contentSize[1] / 2 : vAlign === 'bottom' ? contentSize[1] : 0); + if (shouldTooltipConfine(tooltipModel)) { + var pos = confineTooltipPosition(x, y, content, viewWidth, viewHeight); + x = pos[0]; + y = pos[1]; + } + content.moveTo(x, y); + }; + // FIXME + // Should we remove this but leave this to user? + TooltipView.prototype._updateContentNotChangedOnAxis = function (dataByCoordSys, cbParamsList) { + var lastCoordSys = this._lastDataByCoordSys; + var lastCbParamsList = this._cbParamsList; + var contentNotChanged = !!lastCoordSys && lastCoordSys.length === dataByCoordSys.length; + contentNotChanged && each(lastCoordSys, function (lastItemCoordSys, indexCoordSys) { + var lastDataByAxis = lastItemCoordSys.dataByAxis || []; + var thisItemCoordSys = dataByCoordSys[indexCoordSys] || {}; + var thisDataByAxis = thisItemCoordSys.dataByAxis || []; + contentNotChanged = contentNotChanged && lastDataByAxis.length === thisDataByAxis.length; + contentNotChanged && each(lastDataByAxis, function (lastItem, indexAxis) { + var thisItem = thisDataByAxis[indexAxis] || {}; + var lastIndices = lastItem.seriesDataIndices || []; + var newIndices = thisItem.seriesDataIndices || []; + contentNotChanged = contentNotChanged && lastItem.value === thisItem.value && lastItem.axisType === thisItem.axisType && lastItem.axisId === thisItem.axisId && lastIndices.length === newIndices.length; + contentNotChanged && each(lastIndices, function (lastIdxItem, j) { + var newIdxItem = newIndices[j]; + contentNotChanged = contentNotChanged && lastIdxItem.seriesIndex === newIdxItem.seriesIndex && lastIdxItem.dataIndex === newIdxItem.dataIndex; + }); + // check is cbParams data value changed + lastCbParamsList && each(lastItem.seriesDataIndices, function (idxItem) { + var seriesIdx = idxItem.seriesIndex; + var cbParams = cbParamsList[seriesIdx]; + var lastCbParams = lastCbParamsList[seriesIdx]; + if (cbParams && lastCbParams && lastCbParams.data !== cbParams.data) { + contentNotChanged = false; + } + }); + }); + }); + this._lastDataByCoordSys = dataByCoordSys; + this._cbParamsList = cbParamsList; + return !!contentNotChanged; + }; + TooltipView.prototype._hide = function (dispatchAction) { + // Do not directly hideLater here, because this behavior may be prevented + // in dispatchAction when showTip is dispatched. + // FIXME + // duplicated hideTip if manuallyHideTip is called from dispatchAction. + this._lastDataByCoordSys = null; + dispatchAction({ + type: 'hideTip', + from: this.uid + }); + }; + TooltipView.prototype.dispose = function (ecModel, api) { + if (env.node || !api.getDom()) { + return; + } + clear(this, '_updatePosition'); + this._tooltipContent.dispose(); + unregister('itemTooltip', api); + }; + TooltipView.type = 'tooltip'; + return TooltipView; + }(ComponentView); + /** + * From top to bottom. (the last one should be globalTooltipModel); + */ + function buildTooltipModel(modelCascade, globalTooltipModel, defaultTooltipOption) { + // Last is always tooltip model. + var ecModel = globalTooltipModel.ecModel; + var resultModel; + if (defaultTooltipOption) { + resultModel = new Model(defaultTooltipOption, ecModel, ecModel); + resultModel = new Model(globalTooltipModel.option, resultModel, ecModel); + } else { + resultModel = globalTooltipModel; + } + for (var i = modelCascade.length - 1; i >= 0; i--) { + var tooltipOpt = modelCascade[i]; + if (tooltipOpt) { + if (tooltipOpt instanceof Model) { + tooltipOpt = tooltipOpt.get('tooltip', true); + } + // In each data item tooltip can be simply write: + // { + // value: 10, + // tooltip: 'Something you need to know' + // } + if (isString(tooltipOpt)) { + tooltipOpt = { + formatter: tooltipOpt + }; + } + if (tooltipOpt) { + resultModel = new Model(tooltipOpt, resultModel, ecModel); + } + } + } + return resultModel; + } + function makeDispatchAction$1(payload, api) { + return payload.dispatchAction || bind(api.dispatchAction, api); + } + function refixTooltipPosition(x, y, content, viewWidth, viewHeight, gapH, gapV) { + var size = content.getSize(); + var width = size[0]; + var height = size[1]; + if (gapH != null) { + // Add extra 2 pixels for this case: + // At present the "values" in default tooltip are using CSS `float: right`. + // When the right edge of the tooltip box is on the right side of the + // viewport, the `float` layout might push the "values" to the second line. + if (x + width + gapH + 2 > viewWidth) { + x -= width + gapH; + } else { + x += gapH; + } + } + if (gapV != null) { + if (y + height + gapV > viewHeight) { + y -= height + gapV; + } else { + y += gapV; + } + } + return [x, y]; + } + function confineTooltipPosition(x, y, content, viewWidth, viewHeight) { + var size = content.getSize(); + var width = size[0]; + var height = size[1]; + x = Math.min(x + width, viewWidth) - width; + y = Math.min(y + height, viewHeight) - height; + x = Math.max(x, 0); + y = Math.max(y, 0); + return [x, y]; + } + function calcTooltipPosition(position, rect, contentSize, borderWidth) { + var domWidth = contentSize[0]; + var domHeight = contentSize[1]; + var offset = Math.ceil(Math.SQRT2 * borderWidth) + 8; + var x = 0; + var y = 0; + var rectWidth = rect.width; + var rectHeight = rect.height; + switch (position) { + case 'inside': + x = rect.x + rectWidth / 2 - domWidth / 2; + y = rect.y + rectHeight / 2 - domHeight / 2; + break; + case 'top': + x = rect.x + rectWidth / 2 - domWidth / 2; + y = rect.y - domHeight - offset; + break; + case 'bottom': + x = rect.x + rectWidth / 2 - domWidth / 2; + y = rect.y + rectHeight + offset; + break; + case 'left': + x = rect.x - domWidth - offset; + y = rect.y + rectHeight / 2 - domHeight / 2; + break; + case 'right': + x = rect.x + rectWidth + offset; + y = rect.y + rectHeight / 2 - domHeight / 2; + } + return [x, y]; + } + function isCenterAlign(align) { + return align === 'center' || align === 'middle'; + } + /** + * Find target component by payload like: + * ```js + * { legendId: 'some_id', name: 'xxx' } + * { toolboxIndex: 1, name: 'xxx' } + * { geoName: 'some_name', name: 'xxx' } + * ``` + * PENDING: at present only + * + * If not found, return null/undefined. + */ + function findComponentReference(payload, ecModel, api) { + var queryOptionMap = preParseFinder(payload).queryOptionMap; + var componentMainType = queryOptionMap.keys()[0]; + if (!componentMainType || componentMainType === 'series') { + return; + } + var queryResult = queryReferringComponents(ecModel, componentMainType, queryOptionMap.get(componentMainType), { + useDefault: false, + enableAll: false, + enableNone: false + }); + var model = queryResult.models[0]; + if (!model) { + return; + } + var view = api.getViewOfComponentModel(model); + var el; + view.group.traverse(function (subEl) { + var tooltipConfig = getECData(subEl).tooltipConfig; + if (tooltipConfig && tooltipConfig.name === payload.name) { + el = subEl; + return true; // stop + } + }); + + if (el) { + return { + componentMainType: componentMainType, + componentIndex: model.componentIndex, + el: el + }; + } + } + + function install$A(registers) { + use(install$s); + registers.registerComponentModel(TooltipModel); + registers.registerComponentView(TooltipView); + /** + * @action + * @property {string} type + * @property {number} seriesIndex + * @property {number} dataIndex + * @property {number} [x] + * @property {number} [y] + */ + registers.registerAction({ + type: 'showTip', + event: 'showTip', + update: 'tooltip:manuallyShowTip' + }, noop); + registers.registerAction({ + type: 'hideTip', + event: 'hideTip', + update: 'tooltip:manuallyHideTip' + }, noop); + } + + var DEFAULT_TOOLBOX_BTNS = ['rect', 'polygon', 'keep', 'clear']; + function brushPreprocessor(option, isNew) { + var brushComponents = normalizeToArray(option ? option.brush : []); + if (!brushComponents.length) { + return; + } + var brushComponentSpecifiedBtns = []; + each(brushComponents, function (brushOpt) { + var tbs = brushOpt.hasOwnProperty('toolbox') ? brushOpt.toolbox : []; + if (tbs instanceof Array) { + brushComponentSpecifiedBtns = brushComponentSpecifiedBtns.concat(tbs); + } + }); + var toolbox = option && option.toolbox; + if (isArray(toolbox)) { + toolbox = toolbox[0]; + } + if (!toolbox) { + toolbox = { + feature: {} + }; + option.toolbox = [toolbox]; + } + var toolboxFeature = toolbox.feature || (toolbox.feature = {}); + var toolboxBrush = toolboxFeature.brush || (toolboxFeature.brush = {}); + var brushTypes = toolboxBrush.type || (toolboxBrush.type = []); + brushTypes.push.apply(brushTypes, brushComponentSpecifiedBtns); + removeDuplicate(brushTypes); + if (isNew && !brushTypes.length) { + brushTypes.push.apply(brushTypes, DEFAULT_TOOLBOX_BTNS); + } + } + function removeDuplicate(arr) { + var map = {}; + each(arr, function (val) { + map[val] = 1; + }); + arr.length = 0; + each(map, function (flag, val) { + arr.push(val); + }); + } + + var each$b = each; + function hasKeys(obj) { + if (obj) { + for (var name_1 in obj) { + if (obj.hasOwnProperty(name_1)) { + return true; + } + } + } + } + function createVisualMappings(option, stateList, supplementVisualOption) { + var visualMappings = {}; + each$b(stateList, function (state) { + var mappings = visualMappings[state] = createMappings(); + each$b(option[state], function (visualData, visualType) { + if (!VisualMapping.isValidType(visualType)) { + return; + } + var mappingOption = { + type: visualType, + visual: visualData + }; + supplementVisualOption && supplementVisualOption(mappingOption, state); + mappings[visualType] = new VisualMapping(mappingOption); + // Prepare a alpha for opacity, for some case that opacity + // is not supported, such as rendering using gradient color. + if (visualType === 'opacity') { + mappingOption = clone(mappingOption); + mappingOption.type = 'colorAlpha'; + mappings.__hidden.__alphaForOpacity = new VisualMapping(mappingOption); + } + }); + }); + return visualMappings; + function createMappings() { + var Creater = function () {}; + // Make sure hidden fields will not be visited by + // object iteration (with hasOwnProperty checking). + Creater.prototype.__hidden = Creater.prototype; + var obj = new Creater(); + return obj; + } + } + function replaceVisualOption(thisOption, newOption, keys) { + // Visual attributes merge is not supported, otherwise it + // brings overcomplicated merge logic. See #2853. So if + // newOption has anyone of these keys, all of these keys + // will be reset. Otherwise, all keys remain. + var has; + each(keys, function (key) { + if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) { + has = true; + } + }); + has && each(keys, function (key) { + if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) { + thisOption[key] = clone(newOption[key]); + } else { + delete thisOption[key]; + } + }); + } + /** + * @param stateList + * @param visualMappings + * @param list + * @param getValueState param: valueOrIndex, return: state. + * @param scope Scope for getValueState + * @param dimension Concrete dimension, if used. + */ + // ???! handle brush? + function applyVisual(stateList, visualMappings, data, getValueState, scope, dimension) { + var visualTypesMap = {}; + each(stateList, function (state) { + var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]); + visualTypesMap[state] = visualTypes; + }); + var dataIndex; + function getVisual(key) { + return getItemVisualFromData(data, dataIndex, key); + } + function setVisual(key, value) { + setItemVisualFromData(data, dataIndex, key, value); + } + if (dimension == null) { + data.each(eachItem); + } else { + data.each([dimension], eachItem); + } + function eachItem(valueOrIndex, index) { + dataIndex = dimension == null ? valueOrIndex // First argument is index + : index; + var rawDataItem = data.getRawDataItem(dataIndex); + // Consider performance + // @ts-ignore + if (rawDataItem && rawDataItem.visualMap === false) { + return; + } + var valueState = getValueState.call(scope, valueOrIndex); + var mappings = visualMappings[valueState]; + var visualTypes = visualTypesMap[valueState]; + for (var i = 0, len = visualTypes.length; i < len; i++) { + var type = visualTypes[i]; + mappings[type] && mappings[type].applyVisual(valueOrIndex, getVisual, setVisual); + } + } + } + /** + * @param data + * @param stateList + * @param visualMappings > + * @param getValueState param: valueOrIndex, return: state. + * @param dim dimension or dimension index. + */ + function incrementalApplyVisual(stateList, visualMappings, getValueState, dim) { + var visualTypesMap = {}; + each(stateList, function (state) { + var visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]); + visualTypesMap[state] = visualTypes; + }); + return { + progress: function progress(params, data) { + var dimIndex; + if (dim != null) { + dimIndex = data.getDimensionIndex(dim); + } + function getVisual(key) { + return getItemVisualFromData(data, dataIndex, key); + } + function setVisual(key, value) { + setItemVisualFromData(data, dataIndex, key, value); + } + var dataIndex; + var store = data.getStore(); + while ((dataIndex = params.next()) != null) { + var rawDataItem = data.getRawDataItem(dataIndex); + // Consider performance + // @ts-ignore + if (rawDataItem && rawDataItem.visualMap === false) { + continue; + } + var value = dim != null ? store.get(dimIndex, dataIndex) : dataIndex; + var valueState = getValueState(value); + var mappings = visualMappings[valueState]; + var visualTypes = visualTypesMap[valueState]; + for (var i = 0, len = visualTypes.length; i < len; i++) { + var type = visualTypes[i]; + mappings[type] && mappings[type].applyVisual(value, getVisual, setVisual); + } + } + } + }; + } + + function makeBrushCommonSelectorForSeries(area) { + var brushType = area.brushType; + // Do not use function binding or curry for performance. + var selectors = { + point: function (itemLayout) { + return selector[brushType].point(itemLayout, selectors, area); + }, + rect: function (itemLayout) { + return selector[brushType].rect(itemLayout, selectors, area); + } + }; + return selectors; + } + var selector = { + lineX: getLineSelectors(0), + lineY: getLineSelectors(1), + rect: { + point: function (itemLayout, selectors, area) { + return itemLayout && area.boundingRect.contain(itemLayout[0], itemLayout[1]); + }, + rect: function (itemLayout, selectors, area) { + return itemLayout && area.boundingRect.intersect(itemLayout); + } + }, + polygon: { + point: function (itemLayout, selectors, area) { + return itemLayout && area.boundingRect.contain(itemLayout[0], itemLayout[1]) && contain$2(area.range, itemLayout[0], itemLayout[1]); + }, + rect: function (itemLayout, selectors, area) { + var points = area.range; + if (!itemLayout || points.length <= 1) { + return false; + } + var x = itemLayout.x; + var y = itemLayout.y; + var width = itemLayout.width; + var height = itemLayout.height; + var p = points[0]; + if (contain$2(points, x, y) || contain$2(points, x + width, y) || contain$2(points, x, y + height) || contain$2(points, x + width, y + height) || BoundingRect.create(itemLayout).contain(p[0], p[1]) || linePolygonIntersect(x, y, x + width, y, points) || linePolygonIntersect(x, y, x, y + height, points) || linePolygonIntersect(x + width, y, x + width, y + height, points) || linePolygonIntersect(x, y + height, x + width, y + height, points)) { + return true; + } + } + } + }; + function getLineSelectors(xyIndex) { + var xy = ['x', 'y']; + var wh = ['width', 'height']; + return { + point: function (itemLayout, selectors, area) { + if (itemLayout) { + var range = area.range; + var p = itemLayout[xyIndex]; + return inLineRange(p, range); + } + }, + rect: function (itemLayout, selectors, area) { + if (itemLayout) { + var range = area.range; + var layoutRange = [itemLayout[xy[xyIndex]], itemLayout[xy[xyIndex]] + itemLayout[wh[xyIndex]]]; + layoutRange[1] < layoutRange[0] && layoutRange.reverse(); + return inLineRange(layoutRange[0], range) || inLineRange(layoutRange[1], range) || inLineRange(range[0], layoutRange) || inLineRange(range[1], layoutRange); + } + } + }; + } + function inLineRange(p, range) { + return range[0] <= p && p <= range[1]; + } + + var STATE_LIST = ['inBrush', 'outOfBrush']; + var DISPATCH_METHOD = '__ecBrushSelect'; + var DISPATCH_FLAG = '__ecInBrushSelectEvent'; + function layoutCovers(ecModel) { + ecModel.eachComponent({ + mainType: 'brush' + }, function (brushModel) { + var brushTargetManager = brushModel.brushTargetManager = new BrushTargetManager(brushModel.option, ecModel); + brushTargetManager.setInputRanges(brushModel.areas, ecModel); + }); + } + /** + * Register the visual encoding if this modules required. + */ + function brushVisual(ecModel, api, payload) { + var brushSelected = []; + var throttleType; + var throttleDelay; + ecModel.eachComponent({ + mainType: 'brush' + }, function (brushModel) { + payload && payload.type === 'takeGlobalCursor' && brushModel.setBrushOption(payload.key === 'brush' ? payload.brushOption : { + brushType: false + }); + }); + layoutCovers(ecModel); + ecModel.eachComponent({ + mainType: 'brush' + }, function (brushModel, brushIndex) { + var thisBrushSelected = { + brushId: brushModel.id, + brushIndex: brushIndex, + brushName: brushModel.name, + areas: clone(brushModel.areas), + selected: [] + }; + // Every brush component exists in event params, convenient + // for user to find by index. + brushSelected.push(thisBrushSelected); + var brushOption = brushModel.option; + var brushLink = brushOption.brushLink; + var linkedSeriesMap = []; + var selectedDataIndexForLink = []; + var rangeInfoBySeries = []; + var hasBrushExists = false; + if (!brushIndex) { + // Only the first throttle setting works. + throttleType = brushOption.throttleType; + throttleDelay = brushOption.throttleDelay; + } + // Add boundingRect and selectors to range. + var areas = map(brushModel.areas, function (area) { + var builder = boundingRectBuilders[area.brushType]; + var selectableArea = defaults({ + boundingRect: builder ? builder(area) : void 0 + }, area); + selectableArea.selectors = makeBrushCommonSelectorForSeries(selectableArea); + return selectableArea; + }); + var visualMappings = createVisualMappings(brushModel.option, STATE_LIST, function (mappingOption) { + mappingOption.mappingMethod = 'fixed'; + }); + isArray(brushLink) && each(brushLink, function (seriesIndex) { + linkedSeriesMap[seriesIndex] = 1; + }); + function linkOthers(seriesIndex) { + return brushLink === 'all' || !!linkedSeriesMap[seriesIndex]; + } + // If no supported brush or no brush on the series, + // all visuals should be in original state. + function brushed(rangeInfoList) { + return !!rangeInfoList.length; + } + /** + * Logic for each series: (If the logic has to be modified one day, do it carefully!) + * + * ( brushed ┬ && ┬hasBrushExist ┬ && linkOthers ) => StepA: ┬record, ┬ StepB: ┬visualByRecord. + * !brushed┘ ├hasBrushExist ┤ └nothing,┘ ├visualByRecord. + * └!hasBrushExist┘ └nothing. + * ( !brushed && ┬hasBrushExist ┬ && linkOthers ) => StepA: nothing, StepB: ┬visualByRecord. + * └!hasBrushExist┘ └nothing. + * ( brushed ┬ && !linkOthers ) => StepA: nothing, StepB: ┬visualByCheck. + * !brushed┘ └nothing. + * ( !brushed && !linkOthers ) => StepA: nothing, StepB: nothing. + */ + // Step A + ecModel.eachSeries(function (seriesModel, seriesIndex) { + var rangeInfoList = rangeInfoBySeries[seriesIndex] = []; + seriesModel.subType === 'parallel' ? stepAParallel(seriesModel, seriesIndex) : stepAOthers(seriesModel, seriesIndex, rangeInfoList); + }); + function stepAParallel(seriesModel, seriesIndex) { + var coordSys = seriesModel.coordinateSystem; + hasBrushExists = hasBrushExists || coordSys.hasAxisBrushed(); + linkOthers(seriesIndex) && coordSys.eachActiveState(seriesModel.getData(), function (activeState, dataIndex) { + activeState === 'active' && (selectedDataIndexForLink[dataIndex] = 1); + }); + } + function stepAOthers(seriesModel, seriesIndex, rangeInfoList) { + if (!seriesModel.brushSelector || brushModelNotControll(brushModel, seriesIndex)) { + return; + } + each(areas, function (area) { + if (brushModel.brushTargetManager.controlSeries(area, seriesModel, ecModel)) { + rangeInfoList.push(area); + } + hasBrushExists = hasBrushExists || brushed(rangeInfoList); + }); + if (linkOthers(seriesIndex) && brushed(rangeInfoList)) { + var data_1 = seriesModel.getData(); + data_1.each(function (dataIndex) { + if (checkInRange(seriesModel, rangeInfoList, data_1, dataIndex)) { + selectedDataIndexForLink[dataIndex] = 1; + } + }); + } + } + // Step B + ecModel.eachSeries(function (seriesModel, seriesIndex) { + var seriesBrushSelected = { + seriesId: seriesModel.id, + seriesIndex: seriesIndex, + seriesName: seriesModel.name, + dataIndex: [] + }; + // Every series exists in event params, convenient + // for user to find series by seriesIndex. + thisBrushSelected.selected.push(seriesBrushSelected); + var rangeInfoList = rangeInfoBySeries[seriesIndex]; + var data = seriesModel.getData(); + var getValueState = linkOthers(seriesIndex) ? function (dataIndex) { + return selectedDataIndexForLink[dataIndex] ? (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush') : 'outOfBrush'; + } : function (dataIndex) { + return checkInRange(seriesModel, rangeInfoList, data, dataIndex) ? (seriesBrushSelected.dataIndex.push(data.getRawIndex(dataIndex)), 'inBrush') : 'outOfBrush'; + }; + // If no supported brush or no brush, all visuals are in original state. + (linkOthers(seriesIndex) ? hasBrushExists : brushed(rangeInfoList)) && applyVisual(STATE_LIST, visualMappings, data, getValueState); + }); + }); + dispatchAction(api, throttleType, throttleDelay, brushSelected, payload); + } + function dispatchAction(api, throttleType, throttleDelay, brushSelected, payload) { + // This event will not be triggered when `setOpion`, otherwise dead lock may + // triggered when do `setOption` in event listener, which we do not find + // satisfactory way to solve yet. Some considered resolutions: + // (a) Diff with prevoius selected data ant only trigger event when changed. + // But store previous data and diff precisely (i.e., not only by dataIndex, but + // also detect value changes in selected data) might bring complexity or fragility. + // (b) Use spectial param like `silent` to suppress event triggering. + // But such kind of volatile param may be weird in `setOption`. + if (!payload) { + return; + } + var zr = api.getZr(); + if (zr[DISPATCH_FLAG]) { + return; + } + if (!zr[DISPATCH_METHOD]) { + zr[DISPATCH_METHOD] = doDispatch; + } + var fn = createOrUpdate(zr, DISPATCH_METHOD, throttleDelay, throttleType); + fn(api, brushSelected); + } + function doDispatch(api, brushSelected) { + if (!api.isDisposed()) { + var zr = api.getZr(); + zr[DISPATCH_FLAG] = true; + api.dispatchAction({ + type: 'brushSelect', + batch: brushSelected + }); + zr[DISPATCH_FLAG] = false; + } + } + function checkInRange(seriesModel, rangeInfoList, data, dataIndex) { + for (var i = 0, len = rangeInfoList.length; i < len; i++) { + var area = rangeInfoList[i]; + if (seriesModel.brushSelector(dataIndex, data, area.selectors, area)) { + return true; + } + } + } + function brushModelNotControll(brushModel, seriesIndex) { + var seriesIndices = brushModel.option.seriesIndex; + return seriesIndices != null && seriesIndices !== 'all' && (isArray(seriesIndices) ? indexOf(seriesIndices, seriesIndex) < 0 : seriesIndex !== seriesIndices); + } + var boundingRectBuilders = { + rect: function (area) { + return getBoundingRectFromMinMax(area.range); + }, + polygon: function (area) { + var minMax; + var range = area.range; + for (var i = 0, len = range.length; i < len; i++) { + minMax = minMax || [[Infinity, -Infinity], [Infinity, -Infinity]]; + var rg = range[i]; + rg[0] < minMax[0][0] && (minMax[0][0] = rg[0]); + rg[0] > minMax[0][1] && (minMax[0][1] = rg[0]); + rg[1] < minMax[1][0] && (minMax[1][0] = rg[1]); + rg[1] > minMax[1][1] && (minMax[1][1] = rg[1]); + } + return minMax && getBoundingRectFromMinMax(minMax); + } + }; + function getBoundingRectFromMinMax(minMax) { + return new BoundingRect(minMax[0][0], minMax[1][0], minMax[0][1] - minMax[0][0], minMax[1][1] - minMax[1][0]); + } + + var BrushView = /** @class */function (_super) { + __extends(BrushView, _super); + function BrushView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = BrushView.type; + return _this; + } + BrushView.prototype.init = function (ecModel, api) { + this.ecModel = ecModel; + this.api = api; + this.model; + (this._brushController = new BrushController(api.getZr())).on('brush', bind(this._onBrush, this)).mount(); + }; + BrushView.prototype.render = function (brushModel, ecModel, api, payload) { + this.model = brushModel; + this._updateController(brushModel, ecModel, api, payload); + }; + BrushView.prototype.updateTransform = function (brushModel, ecModel, api, payload) { + // PENDING: `updateTransform` is a little tricky, whose layout need + // to be calculate mandatorily and other stages will not be performed. + // Take care the correctness of the logic. See #11754 . + layoutCovers(ecModel); + this._updateController(brushModel, ecModel, api, payload); + }; + BrushView.prototype.updateVisual = function (brushModel, ecModel, api, payload) { + this.updateTransform(brushModel, ecModel, api, payload); + }; + BrushView.prototype.updateView = function (brushModel, ecModel, api, payload) { + this._updateController(brushModel, ecModel, api, payload); + }; + BrushView.prototype._updateController = function (brushModel, ecModel, api, payload) { + // Do not update controller when drawing. + (!payload || payload.$from !== brushModel.id) && this._brushController.setPanels(brushModel.brushTargetManager.makePanelOpts(api)).enableBrush(brushModel.brushOption).updateCovers(brushModel.areas.slice()); + }; + // updateLayout: updateController, + // updateVisual: updateController, + BrushView.prototype.dispose = function () { + this._brushController.dispose(); + }; + BrushView.prototype._onBrush = function (eventParam) { + var modelId = this.model.id; + var areas = this.model.brushTargetManager.setOutputRanges(eventParam.areas, this.ecModel); + // Action is not dispatched on drag end, because the drag end + // emits the same params with the last drag move event, and + // may have some delay when using touch pad, which makes + // animation not smooth (when using debounce). + (!eventParam.isEnd || eventParam.removeOnClick) && this.api.dispatchAction({ + type: 'brush', + brushId: modelId, + areas: clone(areas), + $from: modelId + }); + eventParam.isEnd && this.api.dispatchAction({ + type: 'brushEnd', + brushId: modelId, + areas: clone(areas), + $from: modelId + }); + }; + BrushView.type = 'brush'; + return BrushView; + }(ComponentView); + + var DEFAULT_OUT_OF_BRUSH_COLOR = '#ddd'; + var BrushModel = /** @class */function (_super) { + __extends(BrushModel, _super); + function BrushModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = BrushModel.type; + /** + * @readOnly + */ + _this.areas = []; + /** + * Current brush painting area settings. + * @readOnly + */ + _this.brushOption = {}; + return _this; + } + BrushModel.prototype.optionUpdated = function (newOption, isInit) { + var thisOption = this.option; + !isInit && replaceVisualOption(thisOption, newOption, ['inBrush', 'outOfBrush']); + var inBrush = thisOption.inBrush = thisOption.inBrush || {}; + // Always give default visual, consider setOption at the second time. + thisOption.outOfBrush = thisOption.outOfBrush || { + color: DEFAULT_OUT_OF_BRUSH_COLOR + }; + if (!inBrush.hasOwnProperty('liftZ')) { + // Bigger than the highlight z lift, otherwise it will + // be effected by the highlight z when brush. + inBrush.liftZ = 5; + } + }; + /** + * If `areas` is null/undefined, range state remain. + */ + BrushModel.prototype.setAreas = function (areas) { + if ("development" !== 'production') { + assert(isArray(areas)); + each(areas, function (area) { + assert(area.brushType, 'Illegal areas'); + }); + } + // If areas is null/undefined, range state remain. + // This helps user to dispatchAction({type: 'brush'}) with no areas + // set but just want to get the current brush select info from a `brush` event. + if (!areas) { + return; + } + this.areas = map(areas, function (area) { + return generateBrushOption(this.option, area); + }, this); + }; + /** + * Set the current painting brush option. + */ + BrushModel.prototype.setBrushOption = function (brushOption) { + this.brushOption = generateBrushOption(this.option, brushOption); + this.brushType = this.brushOption.brushType; + }; + BrushModel.type = 'brush'; + BrushModel.dependencies = ['geo', 'grid', 'xAxis', 'yAxis', 'parallel', 'series']; + BrushModel.defaultOption = { + seriesIndex: 'all', + brushType: 'rect', + brushMode: 'single', + transformable: true, + brushStyle: { + borderWidth: 1, + color: 'rgba(210,219,238,0.3)', + borderColor: '#D2DBEE' + }, + throttleType: 'fixRate', + throttleDelay: 0, + removeOnClick: true, + z: 10000 + }; + return BrushModel; + }(ComponentModel); + function generateBrushOption(option, brushOption) { + return merge({ + brushType: option.brushType, + brushMode: option.brushMode, + transformable: option.transformable, + brushStyle: new Model(option.brushStyle).getItemStyle(), + removeOnClick: option.removeOnClick, + z: option.z + }, brushOption, true); + } + + var ICON_TYPES = ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear']; + var BrushFeature = /** @class */function (_super) { + __extends(BrushFeature, _super); + function BrushFeature() { + return _super !== null && _super.apply(this, arguments) || this; + } + BrushFeature.prototype.render = function (featureModel, ecModel, api) { + var brushType; + var brushMode; + var isBrushed; + ecModel.eachComponent({ + mainType: 'brush' + }, function (brushModel) { + brushType = brushModel.brushType; + brushMode = brushModel.brushOption.brushMode || 'single'; + isBrushed = isBrushed || !!brushModel.areas.length; + }); + this._brushType = brushType; + this._brushMode = brushMode; + each(featureModel.get('type', true), function (type) { + featureModel.setIconStatus(type, (type === 'keep' ? brushMode === 'multiple' : type === 'clear' ? isBrushed : type === brushType) ? 'emphasis' : 'normal'); + }); + }; + BrushFeature.prototype.updateView = function (featureModel, ecModel, api) { + this.render(featureModel, ecModel, api); + }; + BrushFeature.prototype.getIcons = function () { + var model = this.model; + var availableIcons = model.get('icon', true); + var icons = {}; + each(model.get('type', true), function (type) { + if (availableIcons[type]) { + icons[type] = availableIcons[type]; + } + }); + return icons; + }; + BrushFeature.prototype.onclick = function (ecModel, api, type) { + var brushType = this._brushType; + var brushMode = this._brushMode; + if (type === 'clear') { + // Trigger parallel action firstly + api.dispatchAction({ + type: 'axisAreaSelect', + intervals: [] + }); + api.dispatchAction({ + type: 'brush', + command: 'clear', + // Clear all areas of all brush components. + areas: [] + }); + } else { + api.dispatchAction({ + type: 'takeGlobalCursor', + key: 'brush', + brushOption: { + brushType: type === 'keep' ? brushType : brushType === type ? false : type, + brushMode: type === 'keep' ? brushMode === 'multiple' ? 'single' : 'multiple' : brushMode + } + }); + } + }; + BrushFeature.getDefaultOption = function (ecModel) { + var defaultOption = { + show: true, + type: ICON_TYPES.slice(), + icon: { + /* eslint-disable */ + rect: 'M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13', + polygon: 'M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2', + lineX: 'M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4', + lineY: 'M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4', + keep: 'M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z', + clear: 'M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2' // jshint ignore:line + /* eslint-enable */ + }, + + // `rect`, `polygon`, `lineX`, `lineY`, `keep`, `clear` + title: ecModel.getLocaleModel().get(['toolbox', 'brush', 'title']) + }; + return defaultOption; + }; + return BrushFeature; + }(ToolboxFeature); + + function install$B(registers) { + registers.registerComponentView(BrushView); + registers.registerComponentModel(BrushModel); + registers.registerPreprocessor(brushPreprocessor); + registers.registerVisual(registers.PRIORITY.VISUAL.BRUSH, brushVisual); + registers.registerAction({ + type: 'brush', + event: 'brush', + update: 'updateVisual' + }, function (payload, ecModel) { + ecModel.eachComponent({ + mainType: 'brush', + query: payload + }, function (brushModel) { + brushModel.setAreas(payload.areas); + }); + }); + /** + * payload: { + * brushComponents: [ + * { + * brushId, + * brushIndex, + * brushName, + * series: [ + * { + * seriesId, + * seriesIndex, + * seriesName, + * rawIndices: [21, 34, ...] + * }, + * ... + * ] + * }, + * ... + * ] + * } + */ + registers.registerAction({ + type: 'brushSelect', + event: 'brushSelected', + update: 'none' + }, noop); + registers.registerAction({ + type: 'brushEnd', + event: 'brushEnd', + update: 'none' + }, noop); + registerFeature('brush', BrushFeature); + } + + var TitleModel = /** @class */function (_super) { + __extends(TitleModel, _super); + function TitleModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TitleModel.type; + _this.layoutMode = { + type: 'box', + ignoreSize: true + }; + return _this; + } + TitleModel.type = 'title'; + TitleModel.defaultOption = { + // zlevel: 0, + z: 6, + show: true, + text: '', + target: 'blank', + subtext: '', + subtarget: 'blank', + left: 0, + top: 0, + backgroundColor: 'rgba(0,0,0,0)', + borderColor: '#ccc', + borderWidth: 0, + padding: 5, + itemGap: 10, + textStyle: { + fontSize: 18, + fontWeight: 'bold', + color: '#464646' + }, + subtextStyle: { + fontSize: 12, + color: '#6E7079' + } + }; + return TitleModel; + }(ComponentModel); + // View + var TitleView = /** @class */function (_super) { + __extends(TitleView, _super); + function TitleView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TitleView.type; + return _this; + } + TitleView.prototype.render = function (titleModel, ecModel, api) { + this.group.removeAll(); + if (!titleModel.get('show')) { + return; + } + var group = this.group; + var textStyleModel = titleModel.getModel('textStyle'); + var subtextStyleModel = titleModel.getModel('subtextStyle'); + var textAlign = titleModel.get('textAlign'); + var textVerticalAlign = retrieve2(titleModel.get('textBaseline'), titleModel.get('textVerticalAlign')); + var textEl = new ZRText({ + style: createTextStyle(textStyleModel, { + text: titleModel.get('text'), + fill: textStyleModel.getTextColor() + }, { + disableBox: true + }), + z2: 10 + }); + var textRect = textEl.getBoundingRect(); + var subText = titleModel.get('subtext'); + var subTextEl = new ZRText({ + style: createTextStyle(subtextStyleModel, { + text: subText, + fill: subtextStyleModel.getTextColor(), + y: textRect.height + titleModel.get('itemGap'), + verticalAlign: 'top' + }, { + disableBox: true + }), + z2: 10 + }); + var link = titleModel.get('link'); + var sublink = titleModel.get('sublink'); + var triggerEvent = titleModel.get('triggerEvent', true); + textEl.silent = !link && !triggerEvent; + subTextEl.silent = !sublink && !triggerEvent; + if (link) { + textEl.on('click', function () { + windowOpen(link, '_' + titleModel.get('target')); + }); + } + if (sublink) { + subTextEl.on('click', function () { + windowOpen(sublink, '_' + titleModel.get('subtarget')); + }); + } + getECData(textEl).eventData = getECData(subTextEl).eventData = triggerEvent ? { + componentType: 'title', + componentIndex: titleModel.componentIndex + } : null; + group.add(textEl); + subText && group.add(subTextEl); + // If no subText, but add subTextEl, there will be an empty line. + var groupRect = group.getBoundingRect(); + var layoutOption = titleModel.getBoxLayoutParams(); + layoutOption.width = groupRect.width; + layoutOption.height = groupRect.height; + var layoutRect = getLayoutRect(layoutOption, { + width: api.getWidth(), + height: api.getHeight() + }, titleModel.get('padding')); + // Adjust text align based on position + if (!textAlign) { + // Align left if title is on the left. center and right is same + textAlign = titleModel.get('left') || titleModel.get('right'); + // @ts-ignore + if (textAlign === 'middle') { + textAlign = 'center'; + } + // Adjust layout by text align + if (textAlign === 'right') { + layoutRect.x += layoutRect.width; + } else if (textAlign === 'center') { + layoutRect.x += layoutRect.width / 2; + } + } + if (!textVerticalAlign) { + textVerticalAlign = titleModel.get('top') || titleModel.get('bottom'); + // @ts-ignore + if (textVerticalAlign === 'center') { + textVerticalAlign = 'middle'; + } + if (textVerticalAlign === 'bottom') { + layoutRect.y += layoutRect.height; + } else if (textVerticalAlign === 'middle') { + layoutRect.y += layoutRect.height / 2; + } + textVerticalAlign = textVerticalAlign || 'top'; + } + group.x = layoutRect.x; + group.y = layoutRect.y; + group.markRedraw(); + var alignStyle = { + align: textAlign, + verticalAlign: textVerticalAlign + }; + textEl.setStyle(alignStyle); + subTextEl.setStyle(alignStyle); + // Render background + // Get groupRect again because textAlign has been changed + groupRect = group.getBoundingRect(); + var padding = layoutRect.margin; + var style = titleModel.getItemStyle(['color', 'opacity']); + style.fill = titleModel.get('backgroundColor'); + var rect = new Rect({ + shape: { + x: groupRect.x - padding[3], + y: groupRect.y - padding[0], + width: groupRect.width + padding[1] + padding[3], + height: groupRect.height + padding[0] + padding[2], + r: titleModel.get('borderRadius') + }, + style: style, + subPixelOptimize: true, + silent: true + }); + group.add(rect); + }; + TitleView.type = 'title'; + return TitleView; + }(ComponentView); + function install$C(registers) { + registers.registerComponentModel(TitleModel); + registers.registerComponentView(TitleView); + } + + var TimelineModel = /** @class */function (_super) { + __extends(TimelineModel, _super); + function TimelineModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TimelineModel.type; + _this.layoutMode = 'box'; + return _this; + } + /** + * @override + */ + TimelineModel.prototype.init = function (option, parentModel, ecModel) { + this.mergeDefaultAndTheme(option, ecModel); + this._initData(); + }; + /** + * @override + */ + TimelineModel.prototype.mergeOption = function (option) { + _super.prototype.mergeOption.apply(this, arguments); + this._initData(); + }; + TimelineModel.prototype.setCurrentIndex = function (currentIndex) { + if (currentIndex == null) { + currentIndex = this.option.currentIndex; + } + var count = this._data.count(); + if (this.option.loop) { + currentIndex = (currentIndex % count + count) % count; + } else { + currentIndex >= count && (currentIndex = count - 1); + currentIndex < 0 && (currentIndex = 0); + } + this.option.currentIndex = currentIndex; + }; + /** + * @return {number} currentIndex + */ + TimelineModel.prototype.getCurrentIndex = function () { + return this.option.currentIndex; + }; + /** + * @return {boolean} + */ + TimelineModel.prototype.isIndexMax = function () { + return this.getCurrentIndex() >= this._data.count() - 1; + }; + /** + * @param {boolean} state true: play, false: stop + */ + TimelineModel.prototype.setPlayState = function (state) { + this.option.autoPlay = !!state; + }; + /** + * @return {boolean} true: play, false: stop + */ + TimelineModel.prototype.getPlayState = function () { + return !!this.option.autoPlay; + }; + /** + * @private + */ + TimelineModel.prototype._initData = function () { + var thisOption = this.option; + var dataArr = thisOption.data || []; + var axisType = thisOption.axisType; + var names = this._names = []; + var processedDataArr; + if (axisType === 'category') { + processedDataArr = []; + each(dataArr, function (item, index) { + var value = convertOptionIdName(getDataItemValue(item), ''); + var newItem; + if (isObject(item)) { + newItem = clone(item); + newItem.value = index; + } else { + newItem = index; + } + processedDataArr.push(newItem); + names.push(value); + }); + } else { + processedDataArr = dataArr; + } + var dimType = { + category: 'ordinal', + time: 'time', + value: 'number' + }[axisType] || 'number'; + var data = this._data = new SeriesData([{ + name: 'value', + type: dimType + }], this); + data.initData(processedDataArr, names); + }; + TimelineModel.prototype.getData = function () { + return this._data; + }; + /** + * @public + * @return {Array.} categoreis + */ + TimelineModel.prototype.getCategories = function () { + if (this.get('axisType') === 'category') { + return this._names.slice(); + } + }; + TimelineModel.type = 'timeline'; + /** + * @protected + */ + TimelineModel.defaultOption = { + // zlevel: 0, // 一级层叠 + z: 4, + show: true, + axisType: 'time', + realtime: true, + left: '20%', + top: null, + right: '20%', + bottom: 0, + width: null, + height: 40, + padding: 5, + controlPosition: 'left', + autoPlay: false, + rewind: false, + loop: true, + playInterval: 2000, + currentIndex: 0, + itemStyle: {}, + label: { + color: '#000' + }, + data: [] + }; + return TimelineModel; + }(ComponentModel); + + var SliderTimelineModel = /** @class */function (_super) { + __extends(SliderTimelineModel, _super); + function SliderTimelineModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SliderTimelineModel.type; + return _this; + } + SliderTimelineModel.type = 'timeline.slider'; + /** + * @protected + */ + SliderTimelineModel.defaultOption = inheritDefaultOption(TimelineModel.defaultOption, { + backgroundColor: 'rgba(0,0,0,0)', + borderColor: '#ccc', + borderWidth: 0, + orient: 'horizontal', + inverse: false, + tooltip: { + trigger: 'item' // data item may also have tootip attr. + }, + + symbol: 'circle', + symbolSize: 12, + lineStyle: { + show: true, + width: 2, + color: '#DAE1F5' + }, + label: { + position: 'auto', + // When using number, label position is not + // restricted by viewRect. + // positive: right/bottom, negative: left/top + show: true, + interval: 'auto', + rotate: 0, + // formatter: null, + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#A4B1D7' + }, + itemStyle: { + color: '#A4B1D7', + borderWidth: 1 + }, + checkpointStyle: { + symbol: 'circle', + symbolSize: 15, + color: '#316bf3', + borderColor: '#fff', + borderWidth: 2, + shadowBlur: 2, + shadowOffsetX: 1, + shadowOffsetY: 1, + shadowColor: 'rgba(0, 0, 0, 0.3)', + // borderColor: 'rgba(194,53,49, 0.5)', + animation: true, + animationDuration: 300, + animationEasing: 'quinticInOut' + }, + controlStyle: { + show: true, + showPlayBtn: true, + showPrevBtn: true, + showNextBtn: true, + itemSize: 24, + itemGap: 12, + position: 'left', + playIcon: 'path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z', + stopIcon: 'path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z', + // eslint-disable-next-line max-len + nextIcon: 'M2,18.5A1.52,1.52,0,0,1,.92,18a1.49,1.49,0,0,1,0-2.12L7.81,9.36,1,3.11A1.5,1.5,0,1,1,3,.89l8,7.34a1.48,1.48,0,0,1,.49,1.09,1.51,1.51,0,0,1-.46,1.1L3,18.08A1.5,1.5,0,0,1,2,18.5Z', + // eslint-disable-next-line max-len + prevIcon: 'M10,.5A1.52,1.52,0,0,1,11.08,1a1.49,1.49,0,0,1,0,2.12L4.19,9.64,11,15.89a1.5,1.5,0,1,1-2,2.22L1,10.77A1.48,1.48,0,0,1,.5,9.68,1.51,1.51,0,0,1,1,8.58L9,.92A1.5,1.5,0,0,1,10,.5Z', + prevBtnSize: 18, + nextBtnSize: 18, + color: '#A4B1D7', + borderColor: '#A4B1D7', + borderWidth: 1 + }, + emphasis: { + label: { + show: true, + // 其余属性默认使用全局文本样式,详见TEXTSTYLE + color: '#6f778d' + }, + itemStyle: { + color: '#316BF3' + }, + controlStyle: { + color: '#316BF3', + borderColor: '#316BF3', + borderWidth: 2 + } + }, + progress: { + lineStyle: { + color: '#316BF3' + }, + itemStyle: { + color: '#316BF3' + }, + label: { + color: '#6f778d' + } + }, + data: [] + }); + return SliderTimelineModel; + }(TimelineModel); + mixin(SliderTimelineModel, DataFormatMixin.prototype); + + var TimelineView = /** @class */function (_super) { + __extends(TimelineView, _super); + function TimelineView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = TimelineView.type; + return _this; + } + TimelineView.type = 'timeline'; + return TimelineView; + }(ComponentView); + + /** + * Extend axis 2d + */ + var TimelineAxis = /** @class */function (_super) { + __extends(TimelineAxis, _super); + function TimelineAxis(dim, scale, coordExtent, axisType) { + var _this = _super.call(this, dim, scale, coordExtent) || this; + _this.type = axisType || 'value'; + return _this; + } + /** + * @override + */ + TimelineAxis.prototype.getLabelModel = function () { + // Force override + return this.model.getModel('label'); + }; + /** + * @override + */ + TimelineAxis.prototype.isHorizontal = function () { + return this.model.get('orient') === 'horizontal'; + }; + return TimelineAxis; + }(Axis); + + var PI$8 = Math.PI; + var labelDataIndexStore = makeInner(); + var SliderTimelineView = /** @class */function (_super) { + __extends(SliderTimelineView, _super); + function SliderTimelineView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SliderTimelineView.type; + return _this; + } + SliderTimelineView.prototype.init = function (ecModel, api) { + this.api = api; + }; + /** + * @override + */ + SliderTimelineView.prototype.render = function (timelineModel, ecModel, api) { + this.model = timelineModel; + this.api = api; + this.ecModel = ecModel; + this.group.removeAll(); + if (timelineModel.get('show', true)) { + var layoutInfo_1 = this._layout(timelineModel, api); + var mainGroup_1 = this._createGroup('_mainGroup'); + var labelGroup = this._createGroup('_labelGroup'); + var axis_1 = this._axis = this._createAxis(layoutInfo_1, timelineModel); + timelineModel.formatTooltip = function (dataIndex) { + var name = axis_1.scale.getLabel({ + value: dataIndex + }); + return createTooltipMarkup('nameValue', { + noName: true, + value: name + }); + }; + each(['AxisLine', 'AxisTick', 'Control', 'CurrentPointer'], function (name) { + this['_render' + name](layoutInfo_1, mainGroup_1, axis_1, timelineModel); + }, this); + this._renderAxisLabel(layoutInfo_1, labelGroup, axis_1, timelineModel); + this._position(layoutInfo_1, timelineModel); + } + this._doPlayStop(); + this._updateTicksStatus(); + }; + /** + * @override + */ + SliderTimelineView.prototype.remove = function () { + this._clearTimer(); + this.group.removeAll(); + }; + /** + * @override + */ + SliderTimelineView.prototype.dispose = function () { + this._clearTimer(); + }; + SliderTimelineView.prototype._layout = function (timelineModel, api) { + var labelPosOpt = timelineModel.get(['label', 'position']); + var orient = timelineModel.get('orient'); + var viewRect = getViewRect$5(timelineModel, api); + var parsedLabelPos; + // Auto label offset. + if (labelPosOpt == null || labelPosOpt === 'auto') { + parsedLabelPos = orient === 'horizontal' ? viewRect.y + viewRect.height / 2 < api.getHeight() / 2 ? '-' : '+' : viewRect.x + viewRect.width / 2 < api.getWidth() / 2 ? '+' : '-'; + } else if (isString(labelPosOpt)) { + parsedLabelPos = { + horizontal: { + top: '-', + bottom: '+' + }, + vertical: { + left: '-', + right: '+' + } + }[orient][labelPosOpt]; + } else { + // is number + parsedLabelPos = labelPosOpt; + } + var labelAlignMap = { + horizontal: 'center', + vertical: parsedLabelPos >= 0 || parsedLabelPos === '+' ? 'left' : 'right' + }; + var labelBaselineMap = { + horizontal: parsedLabelPos >= 0 || parsedLabelPos === '+' ? 'top' : 'bottom', + vertical: 'middle' + }; + var rotationMap = { + horizontal: 0, + vertical: PI$8 / 2 + }; + // Position + var mainLength = orient === 'vertical' ? viewRect.height : viewRect.width; + var controlModel = timelineModel.getModel('controlStyle'); + var showControl = controlModel.get('show', true); + var controlSize = showControl ? controlModel.get('itemSize') : 0; + var controlGap = showControl ? controlModel.get('itemGap') : 0; + var sizePlusGap = controlSize + controlGap; + // Special label rotate. + var labelRotation = timelineModel.get(['label', 'rotate']) || 0; + labelRotation = labelRotation * PI$8 / 180; // To radian. + var playPosition; + var prevBtnPosition; + var nextBtnPosition; + var controlPosition = controlModel.get('position', true); + var showPlayBtn = showControl && controlModel.get('showPlayBtn', true); + var showPrevBtn = showControl && controlModel.get('showPrevBtn', true); + var showNextBtn = showControl && controlModel.get('showNextBtn', true); + var xLeft = 0; + var xRight = mainLength; + // position[0] means left, position[1] means middle. + if (controlPosition === 'left' || controlPosition === 'bottom') { + showPlayBtn && (playPosition = [0, 0], xLeft += sizePlusGap); + showPrevBtn && (prevBtnPosition = [xLeft, 0], xLeft += sizePlusGap); + showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); + } else { + // 'top' 'right' + showPlayBtn && (playPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); + showPrevBtn && (prevBtnPosition = [0, 0], xLeft += sizePlusGap); + showNextBtn && (nextBtnPosition = [xRight - controlSize, 0], xRight -= sizePlusGap); + } + var axisExtent = [xLeft, xRight]; + if (timelineModel.get('inverse')) { + axisExtent.reverse(); + } + return { + viewRect: viewRect, + mainLength: mainLength, + orient: orient, + rotation: rotationMap[orient], + labelRotation: labelRotation, + labelPosOpt: parsedLabelPos, + labelAlign: timelineModel.get(['label', 'align']) || labelAlignMap[orient], + labelBaseline: timelineModel.get(['label', 'verticalAlign']) || timelineModel.get(['label', 'baseline']) || labelBaselineMap[orient], + // Based on mainGroup. + playPosition: playPosition, + prevBtnPosition: prevBtnPosition, + nextBtnPosition: nextBtnPosition, + axisExtent: axisExtent, + controlSize: controlSize, + controlGap: controlGap + }; + }; + SliderTimelineView.prototype._position = function (layoutInfo, timelineModel) { + // Position is be called finally, because bounding rect is needed for + // adapt content to fill viewRect (auto adapt offset). + // Timeline may be not all in the viewRect when 'offset' is specified + // as a number, because it is more appropriate that label aligns at + // 'offset' but not the other edge defined by viewRect. + var mainGroup = this._mainGroup; + var labelGroup = this._labelGroup; + var viewRect = layoutInfo.viewRect; + if (layoutInfo.orient === 'vertical') { + // transform to horizontal, inverse rotate by left-top point. + var m = create$1(); + var rotateOriginX = viewRect.x; + var rotateOriginY = viewRect.y + viewRect.height; + translate(m, m, [-rotateOriginX, -rotateOriginY]); + rotate(m, m, -PI$8 / 2); + translate(m, m, [rotateOriginX, rotateOriginY]); + viewRect = viewRect.clone(); + viewRect.applyTransform(m); + } + var viewBound = getBound(viewRect); + var mainBound = getBound(mainGroup.getBoundingRect()); + var labelBound = getBound(labelGroup.getBoundingRect()); + var mainPosition = [mainGroup.x, mainGroup.y]; + var labelsPosition = [labelGroup.x, labelGroup.y]; + labelsPosition[0] = mainPosition[0] = viewBound[0][0]; + var labelPosOpt = layoutInfo.labelPosOpt; + if (labelPosOpt == null || isString(labelPosOpt)) { + // '+' or '-' + var mainBoundIdx = labelPosOpt === '+' ? 0 : 1; + toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx); + toBound(labelsPosition, labelBound, viewBound, 1, 1 - mainBoundIdx); + } else { + var mainBoundIdx = labelPosOpt >= 0 ? 0 : 1; + toBound(mainPosition, mainBound, viewBound, 1, mainBoundIdx); + labelsPosition[1] = mainPosition[1] + labelPosOpt; + } + mainGroup.setPosition(mainPosition); + labelGroup.setPosition(labelsPosition); + mainGroup.rotation = labelGroup.rotation = layoutInfo.rotation; + setOrigin(mainGroup); + setOrigin(labelGroup); + function setOrigin(targetGroup) { + targetGroup.originX = viewBound[0][0] - targetGroup.x; + targetGroup.originY = viewBound[1][0] - targetGroup.y; + } + function getBound(rect) { + // [[xmin, xmax], [ymin, ymax]] + return [[rect.x, rect.x + rect.width], [rect.y, rect.y + rect.height]]; + } + function toBound(fromPos, from, to, dimIdx, boundIdx) { + fromPos[dimIdx] += to[dimIdx][boundIdx] - from[dimIdx][boundIdx]; + } + }; + SliderTimelineView.prototype._createAxis = function (layoutInfo, timelineModel) { + var data = timelineModel.getData(); + var axisType = timelineModel.get('axisType'); + var scale = createScaleByModel$1(timelineModel, axisType); + // Customize scale. The `tickValue` is `dataIndex`. + scale.getTicks = function () { + return data.mapArray(['value'], function (value) { + return { + value: value + }; + }); + }; + var dataExtent = data.getDataExtent('value'); + scale.setExtent(dataExtent[0], dataExtent[1]); + scale.calcNiceTicks(); + var axis = new TimelineAxis('value', scale, layoutInfo.axisExtent, axisType); + axis.model = timelineModel; + return axis; + }; + SliderTimelineView.prototype._createGroup = function (key) { + var newGroup = this[key] = new Group(); + this.group.add(newGroup); + return newGroup; + }; + SliderTimelineView.prototype._renderAxisLine = function (layoutInfo, group, axis, timelineModel) { + var axisExtent = axis.getExtent(); + if (!timelineModel.get(['lineStyle', 'show'])) { + return; + } + var line = new Line({ + shape: { + x1: axisExtent[0], + y1: 0, + x2: axisExtent[1], + y2: 0 + }, + style: extend({ + lineCap: 'round' + }, timelineModel.getModel('lineStyle').getLineStyle()), + silent: true, + z2: 1 + }); + group.add(line); + var progressLine = this._progressLine = new Line({ + shape: { + x1: axisExtent[0], + x2: this._currentPointer ? this._currentPointer.x : axisExtent[0], + y1: 0, + y2: 0 + }, + style: defaults({ + lineCap: 'round', + lineWidth: line.style.lineWidth + }, timelineModel.getModel(['progress', 'lineStyle']).getLineStyle()), + silent: true, + z2: 1 + }); + group.add(progressLine); + }; + SliderTimelineView.prototype._renderAxisTick = function (layoutInfo, group, axis, timelineModel) { + var _this = this; + var data = timelineModel.getData(); + // Show all ticks, despite ignoring strategy. + var ticks = axis.scale.getTicks(); + this._tickSymbols = []; + // The value is dataIndex, see the customized scale. + each(ticks, function (tick) { + var tickCoord = axis.dataToCoord(tick.value); + var itemModel = data.getItemModel(tick.value); + var itemStyleModel = itemModel.getModel('itemStyle'); + var hoverStyleModel = itemModel.getModel(['emphasis', 'itemStyle']); + var progressStyleModel = itemModel.getModel(['progress', 'itemStyle']); + var symbolOpt = { + x: tickCoord, + y: 0, + onclick: bind(_this._changeTimeline, _this, tick.value) + }; + var el = giveSymbol(itemModel, itemStyleModel, group, symbolOpt); + el.ensureState('emphasis').style = hoverStyleModel.getItemStyle(); + el.ensureState('progress').style = progressStyleModel.getItemStyle(); + enableHoverEmphasis(el); + var ecData = getECData(el); + if (itemModel.get('tooltip')) { + ecData.dataIndex = tick.value; + ecData.dataModel = timelineModel; + } else { + ecData.dataIndex = ecData.dataModel = null; + } + _this._tickSymbols.push(el); + }); + }; + SliderTimelineView.prototype._renderAxisLabel = function (layoutInfo, group, axis, timelineModel) { + var _this = this; + var labelModel = axis.getLabelModel(); + if (!labelModel.get('show')) { + return; + } + var data = timelineModel.getData(); + var labels = axis.getViewLabels(); + this._tickLabels = []; + each(labels, function (labelItem) { + // The tickValue is dataIndex, see the customized scale. + var dataIndex = labelItem.tickValue; + var itemModel = data.getItemModel(dataIndex); + var normalLabelModel = itemModel.getModel('label'); + var hoverLabelModel = itemModel.getModel(['emphasis', 'label']); + var progressLabelModel = itemModel.getModel(['progress', 'label']); + var tickCoord = axis.dataToCoord(labelItem.tickValue); + var textEl = new ZRText({ + x: tickCoord, + y: 0, + rotation: layoutInfo.labelRotation - layoutInfo.rotation, + onclick: bind(_this._changeTimeline, _this, dataIndex), + silent: false, + style: createTextStyle(normalLabelModel, { + text: labelItem.formattedLabel, + align: layoutInfo.labelAlign, + verticalAlign: layoutInfo.labelBaseline + }) + }); + textEl.ensureState('emphasis').style = createTextStyle(hoverLabelModel); + textEl.ensureState('progress').style = createTextStyle(progressLabelModel); + group.add(textEl); + enableHoverEmphasis(textEl); + labelDataIndexStore(textEl).dataIndex = dataIndex; + _this._tickLabels.push(textEl); + }); + }; + SliderTimelineView.prototype._renderControl = function (layoutInfo, group, axis, timelineModel) { + var controlSize = layoutInfo.controlSize; + var rotation = layoutInfo.rotation; + var itemStyle = timelineModel.getModel('controlStyle').getItemStyle(); + var hoverStyle = timelineModel.getModel(['emphasis', 'controlStyle']).getItemStyle(); + var playState = timelineModel.getPlayState(); + var inverse = timelineModel.get('inverse', true); + makeBtn(layoutInfo.nextBtnPosition, 'next', bind(this._changeTimeline, this, inverse ? '-' : '+')); + makeBtn(layoutInfo.prevBtnPosition, 'prev', bind(this._changeTimeline, this, inverse ? '+' : '-')); + makeBtn(layoutInfo.playPosition, playState ? 'stop' : 'play', bind(this._handlePlayClick, this, !playState), true); + function makeBtn(position, iconName, onclick, willRotate) { + if (!position) { + return; + } + var iconSize = parsePercent(retrieve2(timelineModel.get(['controlStyle', iconName + 'BtnSize']), controlSize), controlSize); + var rect = [0, -iconSize / 2, iconSize, iconSize]; + var btn = makeControlIcon(timelineModel, iconName + 'Icon', rect, { + x: position[0], + y: position[1], + originX: controlSize / 2, + originY: 0, + rotation: willRotate ? -rotation : 0, + rectHover: true, + style: itemStyle, + onclick: onclick + }); + btn.ensureState('emphasis').style = hoverStyle; + group.add(btn); + enableHoverEmphasis(btn); + } + }; + SliderTimelineView.prototype._renderCurrentPointer = function (layoutInfo, group, axis, timelineModel) { + var data = timelineModel.getData(); + var currentIndex = timelineModel.getCurrentIndex(); + var pointerModel = data.getItemModel(currentIndex).getModel('checkpointStyle'); + var me = this; + var callback = { + onCreate: function (pointer) { + pointer.draggable = true; + pointer.drift = bind(me._handlePointerDrag, me); + pointer.ondragend = bind(me._handlePointerDragend, me); + pointerMoveTo(pointer, me._progressLine, currentIndex, axis, timelineModel, true); + }, + onUpdate: function (pointer) { + pointerMoveTo(pointer, me._progressLine, currentIndex, axis, timelineModel); + } + }; + // Reuse when exists, for animation and drag. + this._currentPointer = giveSymbol(pointerModel, pointerModel, this._mainGroup, {}, this._currentPointer, callback); + }; + SliderTimelineView.prototype._handlePlayClick = function (nextState) { + this._clearTimer(); + this.api.dispatchAction({ + type: 'timelinePlayChange', + playState: nextState, + from: this.uid + }); + }; + SliderTimelineView.prototype._handlePointerDrag = function (dx, dy, e) { + this._clearTimer(); + this._pointerChangeTimeline([e.offsetX, e.offsetY]); + }; + SliderTimelineView.prototype._handlePointerDragend = function (e) { + this._pointerChangeTimeline([e.offsetX, e.offsetY], true); + }; + SliderTimelineView.prototype._pointerChangeTimeline = function (mousePos, trigger) { + var toCoord = this._toAxisCoord(mousePos)[0]; + var axis = this._axis; + var axisExtent = asc(axis.getExtent().slice()); + toCoord > axisExtent[1] && (toCoord = axisExtent[1]); + toCoord < axisExtent[0] && (toCoord = axisExtent[0]); + this._currentPointer.x = toCoord; + this._currentPointer.markRedraw(); + var progressLine = this._progressLine; + if (progressLine) { + progressLine.shape.x2 = toCoord; + progressLine.dirty(); + } + var targetDataIndex = this._findNearestTick(toCoord); + var timelineModel = this.model; + if (trigger || targetDataIndex !== timelineModel.getCurrentIndex() && timelineModel.get('realtime')) { + this._changeTimeline(targetDataIndex); + } + }; + SliderTimelineView.prototype._doPlayStop = function () { + var _this = this; + this._clearTimer(); + if (this.model.getPlayState()) { + this._timer = setTimeout(function () { + // Do not cache + var timelineModel = _this.model; + _this._changeTimeline(timelineModel.getCurrentIndex() + (timelineModel.get('rewind', true) ? -1 : 1)); + }, this.model.get('playInterval')); + } + }; + SliderTimelineView.prototype._toAxisCoord = function (vertex) { + var trans = this._mainGroup.getLocalTransform(); + return applyTransform$1(vertex, trans, true); + }; + SliderTimelineView.prototype._findNearestTick = function (axisCoord) { + var data = this.model.getData(); + var dist = Infinity; + var targetDataIndex; + var axis = this._axis; + data.each(['value'], function (value, dataIndex) { + var coord = axis.dataToCoord(value); + var d = Math.abs(coord - axisCoord); + if (d < dist) { + dist = d; + targetDataIndex = dataIndex; + } + }); + return targetDataIndex; + }; + SliderTimelineView.prototype._clearTimer = function () { + if (this._timer) { + clearTimeout(this._timer); + this._timer = null; + } + }; + SliderTimelineView.prototype._changeTimeline = function (nextIndex) { + var currentIndex = this.model.getCurrentIndex(); + if (nextIndex === '+') { + nextIndex = currentIndex + 1; + } else if (nextIndex === '-') { + nextIndex = currentIndex - 1; + } + this.api.dispatchAction({ + type: 'timelineChange', + currentIndex: nextIndex, + from: this.uid + }); + }; + SliderTimelineView.prototype._updateTicksStatus = function () { + var currentIndex = this.model.getCurrentIndex(); + var tickSymbols = this._tickSymbols; + var tickLabels = this._tickLabels; + if (tickSymbols) { + for (var i = 0; i < tickSymbols.length; i++) { + tickSymbols && tickSymbols[i] && tickSymbols[i].toggleState('progress', i < currentIndex); + } + } + if (tickLabels) { + for (var i = 0; i < tickLabels.length; i++) { + tickLabels && tickLabels[i] && tickLabels[i].toggleState('progress', labelDataIndexStore(tickLabels[i]).dataIndex <= currentIndex); + } + } + }; + SliderTimelineView.type = 'timeline.slider'; + return SliderTimelineView; + }(TimelineView); + function createScaleByModel$1(model, axisType) { + axisType = axisType || model.get('type'); + if (axisType) { + switch (axisType) { + // Buildin scale + case 'category': + return new OrdinalScale({ + ordinalMeta: model.getCategories(), + extent: [Infinity, -Infinity] + }); + case 'time': + return new TimeScale({ + locale: model.ecModel.getLocaleModel(), + useUTC: model.ecModel.get('useUTC') + }); + default: + // default to be value + return new IntervalScale(); + } + } + } + function getViewRect$5(model, api) { + return getLayoutRect(model.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }, model.get('padding')); + } + function makeControlIcon(timelineModel, objPath, rect, opts) { + var style = opts.style; + var icon = createIcon(timelineModel.get(['controlStyle', objPath]), opts || {}, new BoundingRect(rect[0], rect[1], rect[2], rect[3])); + // TODO createIcon won't use style in opt. + if (style) { + icon.setStyle(style); + } + return icon; + } + /** + * Create symbol or update symbol + * opt: basic position and event handlers + */ + function giveSymbol(hostModel, itemStyleModel, group, opt, symbol, callback) { + var color = itemStyleModel.get('color'); + if (!symbol) { + var symbolType = hostModel.get('symbol'); + symbol = createSymbol(symbolType, -1, -1, 2, 2, color); + symbol.setStyle('strokeNoScale', true); + group.add(symbol); + callback && callback.onCreate(symbol); + } else { + symbol.setColor(color); + group.add(symbol); // Group may be new, also need to add. + callback && callback.onUpdate(symbol); + } + // Style + var itemStyle = itemStyleModel.getItemStyle(['color']); + symbol.setStyle(itemStyle); + // Transform and events. + opt = merge({ + rectHover: true, + z2: 100 + }, opt, true); + var symbolSize = normalizeSymbolSize(hostModel.get('symbolSize')); + opt.scaleX = symbolSize[0] / 2; + opt.scaleY = symbolSize[1] / 2; + var symbolOffset = normalizeSymbolOffset(hostModel.get('symbolOffset'), symbolSize); + if (symbolOffset) { + opt.x = (opt.x || 0) + symbolOffset[0]; + opt.y = (opt.y || 0) + symbolOffset[1]; + } + var symbolRotate = hostModel.get('symbolRotate'); + opt.rotation = (symbolRotate || 0) * Math.PI / 180 || 0; + symbol.attr(opt); + // FIXME + // (1) When symbol.style.strokeNoScale is true and updateTransform is not performed, + // getBoundingRect will return wrong result. + // (This is supposed to be resolved in zrender, but it is a little difficult to + // leverage performance and auto updateTransform) + // (2) All of ancesters of symbol do not scale, so we can just updateTransform symbol. + symbol.updateTransform(); + return symbol; + } + function pointerMoveTo(pointer, progressLine, dataIndex, axis, timelineModel, noAnimation) { + if (pointer.dragging) { + return; + } + var pointerModel = timelineModel.getModel('checkpointStyle'); + var toCoord = axis.dataToCoord(timelineModel.getData().get('value', dataIndex)); + if (noAnimation || !pointerModel.get('animation', true)) { + pointer.attr({ + x: toCoord, + y: 0 + }); + progressLine && progressLine.attr({ + shape: { + x2: toCoord + } + }); + } else { + var animationCfg = { + duration: pointerModel.get('animationDuration', true), + easing: pointerModel.get('animationEasing', true) + }; + pointer.stopAnimation(null, true); + pointer.animateTo({ + x: toCoord, + y: 0 + }, animationCfg); + progressLine && progressLine.animateTo({ + shape: { + x2: toCoord + } + }, animationCfg); + } + } + + function installTimelineAction(registers) { + registers.registerAction({ + type: 'timelineChange', + event: 'timelineChanged', + update: 'prepareAndUpdate' + }, function (payload, ecModel, api) { + var timelineModel = ecModel.getComponent('timeline'); + if (timelineModel && payload.currentIndex != null) { + timelineModel.setCurrentIndex(payload.currentIndex); + if (!timelineModel.get('loop', true) && timelineModel.isIndexMax() && timelineModel.getPlayState()) { + timelineModel.setPlayState(false); + // The timeline has played to the end, trigger event + api.dispatchAction({ + type: 'timelinePlayChange', + playState: false, + from: payload.from + }); + } + } + // Set normalized currentIndex to payload. + ecModel.resetOption('timeline', { + replaceMerge: timelineModel.get('replaceMerge', true) + }); + return defaults({ + currentIndex: timelineModel.option.currentIndex + }, payload); + }); + registers.registerAction({ + type: 'timelinePlayChange', + event: 'timelinePlayChanged', + update: 'update' + }, function (payload, ecModel) { + var timelineModel = ecModel.getComponent('timeline'); + if (timelineModel && payload.playState != null) { + timelineModel.setPlayState(payload.playState); + } + }); + } + + function timelinePreprocessor(option) { + var timelineOpt = option && option.timeline; + if (!isArray(timelineOpt)) { + timelineOpt = timelineOpt ? [timelineOpt] : []; + } + each(timelineOpt, function (opt) { + if (!opt) { + return; + } + compatibleEC2(opt); + }); + } + function compatibleEC2(opt) { + var type = opt.type; + var ec2Types = { + 'number': 'value', + 'time': 'time' + }; + // Compatible with ec2 + if (ec2Types[type]) { + opt.axisType = ec2Types[type]; + delete opt.type; + } + transferItem(opt); + if (has(opt, 'controlPosition')) { + var controlStyle = opt.controlStyle || (opt.controlStyle = {}); + if (!has(controlStyle, 'position')) { + controlStyle.position = opt.controlPosition; + } + if (controlStyle.position === 'none' && !has(controlStyle, 'show')) { + controlStyle.show = false; + delete controlStyle.position; + } + delete opt.controlPosition; + } + each(opt.data || [], function (dataItem) { + if (isObject(dataItem) && !isArray(dataItem)) { + if (!has(dataItem, 'value') && has(dataItem, 'name')) { + // In ec2, using name as value. + dataItem.value = dataItem.name; + } + transferItem(dataItem); + } + }); + } + function transferItem(opt) { + var itemStyle = opt.itemStyle || (opt.itemStyle = {}); + var itemStyleEmphasis = itemStyle.emphasis || (itemStyle.emphasis = {}); + // Transfer label out + var label = opt.label || opt.label || {}; + var labelNormal = label.normal || (label.normal = {}); + var excludeLabelAttr = { + normal: 1, + emphasis: 1 + }; + each(label, function (value, name) { + if (!excludeLabelAttr[name] && !has(labelNormal, name)) { + labelNormal[name] = value; + } + }); + if (itemStyleEmphasis.label && !has(label, 'emphasis')) { + label.emphasis = itemStyleEmphasis.label; + delete itemStyleEmphasis.label; + } + } + function has(obj, attr) { + return obj.hasOwnProperty(attr); + } + + function install$D(registers) { + registers.registerComponentModel(SliderTimelineModel); + registers.registerComponentView(SliderTimelineView); + registers.registerSubTypeDefaulter('timeline', function () { + // Only slider now. + return 'slider'; + }); + installTimelineAction(registers); + registers.registerPreprocessor(timelinePreprocessor); + } + + function checkMarkerInSeries(seriesOpts, markerType) { + if (!seriesOpts) { + return false; + } + var seriesOptArr = isArray(seriesOpts) ? seriesOpts : [seriesOpts]; + for (var idx = 0; idx < seriesOptArr.length; idx++) { + if (seriesOptArr[idx] && seriesOptArr[idx][markerType]) { + return true; + } + } + return false; + } + + function fillLabel(opt) { + defaultEmphasis(opt, 'label', ['show']); + } + // { [componentType]: MarkerModel } + var inner$g = makeInner(); + var MarkerModel = /** @class */function (_super) { + __extends(MarkerModel, _super); + function MarkerModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MarkerModel.type; + /** + * If marker model is created by self from series + */ + _this.createdBySelf = false; + return _this; + } + /** + * @overrite + */ + MarkerModel.prototype.init = function (option, parentModel, ecModel) { + if ("development" !== 'production') { + if (this.type === 'marker') { + throw new Error('Marker component is abstract component. Use markLine, markPoint, markArea instead.'); + } + } + this.mergeDefaultAndTheme(option, ecModel); + this._mergeOption(option, ecModel, false, true); + }; + MarkerModel.prototype.isAnimationEnabled = function () { + if (env.node) { + return false; + } + var hostSeries = this.__hostSeries; + return this.getShallow('animation') && hostSeries && hostSeries.isAnimationEnabled(); + }; + /** + * @overrite + */ + MarkerModel.prototype.mergeOption = function (newOpt, ecModel) { + this._mergeOption(newOpt, ecModel, false, false); + }; + MarkerModel.prototype._mergeOption = function (newOpt, ecModel, createdBySelf, isInit) { + var componentType = this.mainType; + if (!createdBySelf) { + ecModel.eachSeries(function (seriesModel) { + // mainType can be markPoint, markLine, markArea + var markerOpt = seriesModel.get(this.mainType, true); + var markerModel = inner$g(seriesModel)[componentType]; + if (!markerOpt || !markerOpt.data) { + inner$g(seriesModel)[componentType] = null; + return; + } + if (!markerModel) { + if (isInit) { + // Default label emphasis `position` and `show` + fillLabel(markerOpt); + } + each(markerOpt.data, function (item) { + // FIXME Overwrite fillLabel method ? + if (item instanceof Array) { + fillLabel(item[0]); + fillLabel(item[1]); + } else { + fillLabel(item); + } + }); + markerModel = this.createMarkerModelFromSeries(markerOpt, this, ecModel); + // markerModel = new ImplementedMarkerModel( + // markerOpt, this, ecModel + // ); + extend(markerModel, { + mainType: this.mainType, + // Use the same series index and name + seriesIndex: seriesModel.seriesIndex, + name: seriesModel.name, + createdBySelf: true + }); + markerModel.__hostSeries = seriesModel; + } else { + markerModel._mergeOption(markerOpt, ecModel, true); + } + inner$g(seriesModel)[componentType] = markerModel; + }, this); + } + }; + MarkerModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) { + var data = this.getData(); + var value = this.getRawValue(dataIndex); + var itemName = data.getName(dataIndex); + return createTooltipMarkup('section', { + header: this.name, + blocks: [createTooltipMarkup('nameValue', { + name: itemName, + value: value, + noName: !itemName, + noValue: value == null + })] + }); + }; + MarkerModel.prototype.getData = function () { + return this._data; + }; + MarkerModel.prototype.setData = function (data) { + this._data = data; + }; + MarkerModel.getMarkerModelFromSeries = function (seriesModel, + // Support three types of markers. Strict check. + componentType) { + return inner$g(seriesModel)[componentType]; + }; + MarkerModel.type = 'marker'; + MarkerModel.dependencies = ['series', 'grid', 'polar', 'geo']; + return MarkerModel; + }(ComponentModel); + mixin(MarkerModel, DataFormatMixin.prototype); + + var MarkPointModel = /** @class */function (_super) { + __extends(MarkPointModel, _super); + function MarkPointModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MarkPointModel.type; + return _this; + } + MarkPointModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) { + return new MarkPointModel(markerOpt, masterMarkerModel, ecModel); + }; + MarkPointModel.type = 'markPoint'; + MarkPointModel.defaultOption = { + // zlevel: 0, + z: 5, + symbol: 'pin', + symbolSize: 50, + // symbolRotate: 0, + // symbolOffset: [0, 0] + tooltip: { + trigger: 'item' + }, + label: { + show: true, + position: 'inside' + }, + itemStyle: { + borderWidth: 2 + }, + emphasis: { + label: { + show: true + } + } + }; + return MarkPointModel; + }(MarkerModel); + + function hasXOrY(item) { + return !(isNaN(parseFloat(item.x)) && isNaN(parseFloat(item.y))); + } + function hasXAndY(item) { + return !isNaN(parseFloat(item.x)) && !isNaN(parseFloat(item.y)); + } + function markerTypeCalculatorWithExtent(markerType, data, otherDataDim, targetDataDim, otherCoordIndex, targetCoordIndex) { + var coordArr = []; + var stacked = isDimensionStacked(data, targetDataDim /* , otherDataDim */); + var calcDataDim = stacked ? data.getCalculationInfo('stackResultDimension') : targetDataDim; + var value = numCalculate(data, calcDataDim, markerType); + var dataIndex = data.indicesOfNearest(calcDataDim, value)[0]; + coordArr[otherCoordIndex] = data.get(otherDataDim, dataIndex); + coordArr[targetCoordIndex] = data.get(calcDataDim, dataIndex); + var coordArrValue = data.get(targetDataDim, dataIndex); + // Make it simple, do not visit all stacked value to count precision. + var precision = getPrecision(data.get(targetDataDim, dataIndex)); + precision = Math.min(precision, 20); + if (precision >= 0) { + coordArr[targetCoordIndex] = +coordArr[targetCoordIndex].toFixed(precision); + } + return [coordArr, coordArrValue]; + } + // TODO Specified percent + var markerTypeCalculator = { + min: curry(markerTypeCalculatorWithExtent, 'min'), + max: curry(markerTypeCalculatorWithExtent, 'max'), + average: curry(markerTypeCalculatorWithExtent, 'average'), + median: curry(markerTypeCalculatorWithExtent, 'median') + }; + /** + * Transform markPoint data item to format used in List by do the following + * 1. Calculate statistic like `max`, `min`, `average` + * 2. Convert `item.xAxis`, `item.yAxis` to `item.coord` array + */ + function dataTransform(seriesModel, item) { + if (!item) { + return; + } + var data = seriesModel.getData(); + var coordSys = seriesModel.coordinateSystem; + var dims = coordSys && coordSys.dimensions; + // 1. If not specify the position with pixel directly + // 2. If `coord` is not a data array. Which uses `xAxis`, + // `yAxis` to specify the coord on each dimension + // parseFloat first because item.x and item.y can be percent string like '20%' + if (!hasXAndY(item) && !isArray(item.coord) && isArray(dims)) { + var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel); + // Clone the option + // Transform the properties xAxis, yAxis, radiusAxis, angleAxis, geoCoord to value + item = clone(item); + if (item.type && markerTypeCalculator[item.type] && axisInfo.baseAxis && axisInfo.valueAxis) { + var otherCoordIndex = indexOf(dims, axisInfo.baseAxis.dim); + var targetCoordIndex = indexOf(dims, axisInfo.valueAxis.dim); + var coordInfo = markerTypeCalculator[item.type](data, axisInfo.baseDataDim, axisInfo.valueDataDim, otherCoordIndex, targetCoordIndex); + item.coord = coordInfo[0]; + // Force to use the value of calculated value. + // let item use the value without stack. + item.value = coordInfo[1]; + } else { + // FIXME Only has one of xAxis and yAxis. + item.coord = [item.xAxis != null ? item.xAxis : item.radiusAxis, item.yAxis != null ? item.yAxis : item.angleAxis]; + } + } + // x y is provided + if (item.coord == null || !isArray(dims)) { + item.coord = []; + } else { + // Each coord support max, min, average + var coord = item.coord; + for (var i = 0; i < 2; i++) { + if (markerTypeCalculator[coord[i]]) { + coord[i] = numCalculate(data, data.mapDimension(dims[i]), coord[i]); + } + } + } + return item; + } + function getAxisInfo$1(item, data, coordSys, seriesModel) { + var ret = {}; + if (item.valueIndex != null || item.valueDim != null) { + ret.valueDataDim = item.valueIndex != null ? data.getDimension(item.valueIndex) : item.valueDim; + ret.valueAxis = coordSys.getAxis(dataDimToCoordDim(seriesModel, ret.valueDataDim)); + ret.baseAxis = coordSys.getOtherAxis(ret.valueAxis); + ret.baseDataDim = data.mapDimension(ret.baseAxis.dim); + } else { + ret.baseAxis = seriesModel.getBaseAxis(); + ret.valueAxis = coordSys.getOtherAxis(ret.baseAxis); + ret.baseDataDim = data.mapDimension(ret.baseAxis.dim); + ret.valueDataDim = data.mapDimension(ret.valueAxis.dim); + } + return ret; + } + function dataDimToCoordDim(seriesModel, dataDim) { + var dimItem = seriesModel.getData().getDimensionInfo(dataDim); + return dimItem && dimItem.coordDim; + } + /** + * Filter data which is out of coordinateSystem range + * [dataFilter description] + */ + function dataFilter$1( + // Currently only polar and cartesian has containData. + coordSys, item) { + // Always return true if there is no coordSys + return coordSys && coordSys.containData && item.coord && !hasXOrY(item) ? coordSys.containData(item.coord) : true; + } + function zoneFilter( + // Currently only polar and cartesian has containData. + coordSys, item1, item2) { + // Always return true if there is no coordSys + return coordSys && coordSys.containZone && item1.coord && item2.coord && !hasXOrY(item1) && !hasXOrY(item2) ? coordSys.containZone(item1.coord, item2.coord) : true; + } + function createMarkerDimValueGetter(inCoordSys, dims) { + return inCoordSys ? function (item, dimName, dataIndex, dimIndex) { + var rawVal = dimIndex < 2 + // x, y, radius, angle + ? item.coord && item.coord[dimIndex] : item.value; + return parseDataValue(rawVal, dims[dimIndex]); + } : function (item, dimName, dataIndex, dimIndex) { + return parseDataValue(item.value, dims[dimIndex]); + }; + } + function numCalculate(data, valueDataDim, type) { + if (type === 'average') { + var sum_1 = 0; + var count_1 = 0; + data.each(valueDataDim, function (val, idx) { + if (!isNaN(val)) { + sum_1 += val; + count_1++; + } + }); + return sum_1 / count_1; + } else if (type === 'median') { + return data.getMedian(valueDataDim); + } else { + // max & min + return data.getDataExtent(valueDataDim)[type === 'max' ? 1 : 0]; + } + } + + var inner$h = makeInner(); + var MarkerView = /** @class */function (_super) { + __extends(MarkerView, _super); + function MarkerView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MarkerView.type; + return _this; + } + MarkerView.prototype.init = function () { + this.markerGroupMap = createHashMap(); + }; + MarkerView.prototype.render = function (markerModel, ecModel, api) { + var _this = this; + var markerGroupMap = this.markerGroupMap; + markerGroupMap.each(function (item) { + inner$h(item).keep = false; + }); + ecModel.eachSeries(function (seriesModel) { + var markerModel = MarkerModel.getMarkerModelFromSeries(seriesModel, _this.type); + markerModel && _this.renderSeries(seriesModel, markerModel, ecModel, api); + }); + markerGroupMap.each(function (item) { + !inner$h(item).keep && _this.group.remove(item.group); + }); + }; + MarkerView.prototype.markKeep = function (drawGroup) { + inner$h(drawGroup).keep = true; + }; + MarkerView.prototype.toggleBlurSeries = function (seriesModelList, isBlur) { + var _this = this; + each(seriesModelList, function (seriesModel) { + var markerModel = MarkerModel.getMarkerModelFromSeries(seriesModel, _this.type); + if (markerModel) { + var data = markerModel.getData(); + data.eachItemGraphicEl(function (el) { + if (el) { + isBlur ? enterBlur(el) : leaveBlur(el); + } + }); + } + }); + }; + MarkerView.type = 'marker'; + return MarkerView; + }(ComponentView); + + function updateMarkerLayout(mpData, seriesModel, api) { + var coordSys = seriesModel.coordinateSystem; + mpData.each(function (idx) { + var itemModel = mpData.getItemModel(idx); + var point; + var xPx = parsePercent$1(itemModel.get('x'), api.getWidth()); + var yPx = parsePercent$1(itemModel.get('y'), api.getHeight()); + if (!isNaN(xPx) && !isNaN(yPx)) { + point = [xPx, yPx]; + } + // Chart like bar may have there own marker positioning logic + else if (seriesModel.getMarkerPosition) { + // Use the getMarkerPosition + point = seriesModel.getMarkerPosition(mpData.getValues(mpData.dimensions, idx)); + } else if (coordSys) { + var x = mpData.get(coordSys.dimensions[0], idx); + var y = mpData.get(coordSys.dimensions[1], idx); + point = coordSys.dataToPoint([x, y]); + } + // Use x, y if has any + if (!isNaN(xPx)) { + point[0] = xPx; + } + if (!isNaN(yPx)) { + point[1] = yPx; + } + mpData.setItemLayout(idx, point); + }); + } + var MarkPointView = /** @class */function (_super) { + __extends(MarkPointView, _super); + function MarkPointView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MarkPointView.type; + return _this; + } + MarkPointView.prototype.updateTransform = function (markPointModel, ecModel, api) { + ecModel.eachSeries(function (seriesModel) { + var mpModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markPoint'); + if (mpModel) { + updateMarkerLayout(mpModel.getData(), seriesModel, api); + this.markerGroupMap.get(seriesModel.id).updateLayout(); + } + }, this); + }; + MarkPointView.prototype.renderSeries = function (seriesModel, mpModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + var seriesId = seriesModel.id; + var seriesData = seriesModel.getData(); + var symbolDrawMap = this.markerGroupMap; + var symbolDraw = symbolDrawMap.get(seriesId) || symbolDrawMap.set(seriesId, new SymbolDraw()); + var mpData = createData(coordSys, seriesModel, mpModel); + // FIXME + mpModel.setData(mpData); + updateMarkerLayout(mpModel.getData(), seriesModel, api); + mpData.each(function (idx) { + var itemModel = mpData.getItemModel(idx); + var symbol = itemModel.getShallow('symbol'); + var symbolSize = itemModel.getShallow('symbolSize'); + var symbolRotate = itemModel.getShallow('symbolRotate'); + var symbolOffset = itemModel.getShallow('symbolOffset'); + var symbolKeepAspect = itemModel.getShallow('symbolKeepAspect'); + // TODO: refactor needed: single data item should not support callback function + if (isFunction(symbol) || isFunction(symbolSize) || isFunction(symbolRotate) || isFunction(symbolOffset)) { + var rawIdx = mpModel.getRawValue(idx); + var dataParams = mpModel.getDataParams(idx); + if (isFunction(symbol)) { + symbol = symbol(rawIdx, dataParams); + } + if (isFunction(symbolSize)) { + // FIXME 这里不兼容 ECharts 2.x,2.x 貌似参数是整个数据? + symbolSize = symbolSize(rawIdx, dataParams); + } + if (isFunction(symbolRotate)) { + symbolRotate = symbolRotate(rawIdx, dataParams); + } + if (isFunction(symbolOffset)) { + symbolOffset = symbolOffset(rawIdx, dataParams); + } + } + var style = itemModel.getModel('itemStyle').getItemStyle(); + var color = getVisualFromData(seriesData, 'color'); + if (!style.fill) { + style.fill = color; + } + mpData.setItemVisual(idx, { + symbol: symbol, + symbolSize: symbolSize, + symbolRotate: symbolRotate, + symbolOffset: symbolOffset, + symbolKeepAspect: symbolKeepAspect, + style: style + }); + }); + // TODO Text are wrong + symbolDraw.updateData(mpData); + this.group.add(symbolDraw.group); + // Set host model for tooltip + // FIXME + mpData.eachItemGraphicEl(function (el) { + el.traverse(function (child) { + getECData(child).dataModel = mpModel; + }); + }); + this.markKeep(symbolDraw); + symbolDraw.group.silent = mpModel.get('silent') || seriesModel.get('silent'); + }; + MarkPointView.type = 'markPoint'; + return MarkPointView; + }(MarkerView); + function createData(coordSys, seriesModel, mpModel) { + var coordDimsInfos; + if (coordSys) { + coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) { + var info = seriesModel.getData().getDimensionInfo(seriesModel.getData().mapDimension(coordDim)) || {}; + // In map series data don't have lng and lat dimension. Fallback to same with coordSys + return extend(extend({}, info), { + name: coordDim, + // DON'T use ordinalMeta to parse and collect ordinal. + ordinalMeta: null + }); + }); + } else { + coordDimsInfos = [{ + name: 'value', + type: 'float' + }]; + } + var mpData = new SeriesData(coordDimsInfos, mpModel); + var dataOpt = map(mpModel.get('data'), curry(dataTransform, seriesModel)); + if (coordSys) { + dataOpt = filter(dataOpt, curry(dataFilter$1, coordSys)); + } + var dimValueGetter = createMarkerDimValueGetter(!!coordSys, coordDimsInfos); + mpData.initData(dataOpt, null, dimValueGetter); + return mpData; + } + + function install$E(registers) { + registers.registerComponentModel(MarkPointModel); + registers.registerComponentView(MarkPointView); + registers.registerPreprocessor(function (opt) { + if (checkMarkerInSeries(opt.series, 'markPoint')) { + // Make sure markPoint component is enabled + opt.markPoint = opt.markPoint || {}; + } + }); + } + + var MarkLineModel = /** @class */function (_super) { + __extends(MarkLineModel, _super); + function MarkLineModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MarkLineModel.type; + return _this; + } + MarkLineModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) { + return new MarkLineModel(markerOpt, masterMarkerModel, ecModel); + }; + MarkLineModel.type = 'markLine'; + MarkLineModel.defaultOption = { + // zlevel: 0, + z: 5, + symbol: ['circle', 'arrow'], + symbolSize: [8, 16], + // symbolRotate: 0, + symbolOffset: 0, + precision: 2, + tooltip: { + trigger: 'item' + }, + label: { + show: true, + position: 'end', + distance: 5 + }, + lineStyle: { + type: 'dashed' + }, + emphasis: { + label: { + show: true + }, + lineStyle: { + width: 3 + } + }, + animationEasing: 'linear' + }; + return MarkLineModel; + }(MarkerModel); + + var inner$i = makeInner(); + var markLineTransform = function (seriesModel, coordSys, mlModel, item) { + var data = seriesModel.getData(); + var itemArray; + if (!isArray(item)) { + // Special type markLine like 'min', 'max', 'average', 'median' + var mlType = item.type; + if (mlType === 'min' || mlType === 'max' || mlType === 'average' || mlType === 'median' + // In case + // data: [{ + // yAxis: 10 + // }] + || item.xAxis != null || item.yAxis != null) { + var valueAxis = void 0; + var value = void 0; + if (item.yAxis != null || item.xAxis != null) { + valueAxis = coordSys.getAxis(item.yAxis != null ? 'y' : 'x'); + value = retrieve(item.yAxis, item.xAxis); + } else { + var axisInfo = getAxisInfo$1(item, data, coordSys, seriesModel); + valueAxis = axisInfo.valueAxis; + var valueDataDim = getStackedDimension(data, axisInfo.valueDataDim); + value = numCalculate(data, valueDataDim, mlType); + } + var valueIndex = valueAxis.dim === 'x' ? 0 : 1; + var baseIndex = 1 - valueIndex; + // Normized to 2d data with start and end point + var mlFrom = clone(item); + var mlTo = { + coord: [] + }; + mlFrom.type = null; + mlFrom.coord = []; + mlFrom.coord[baseIndex] = -Infinity; + mlTo.coord[baseIndex] = Infinity; + var precision = mlModel.get('precision'); + if (precision >= 0 && isNumber(value)) { + value = +value.toFixed(Math.min(precision, 20)); + } + mlFrom.coord[valueIndex] = mlTo.coord[valueIndex] = value; + itemArray = [mlFrom, mlTo, { + type: mlType, + valueIndex: item.valueIndex, + // Force to use the value of calculated value. + value: value + }]; + } else { + // Invalid data + if ("development" !== 'production') { + logError('Invalid markLine data.'); + } + itemArray = []; + } + } else { + itemArray = item; + } + var normalizedItem = [dataTransform(seriesModel, itemArray[0]), dataTransform(seriesModel, itemArray[1]), extend({}, itemArray[2])]; + // Avoid line data type is extended by from(to) data type + normalizedItem[2].type = normalizedItem[2].type || null; + // Merge from option and to option into line option + merge(normalizedItem[2], normalizedItem[0]); + merge(normalizedItem[2], normalizedItem[1]); + return normalizedItem; + }; + function isInfinity(val) { + return !isNaN(val) && !isFinite(val); + } + // If a markLine has one dim + function ifMarkLineHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) { + var otherDimIndex = 1 - dimIndex; + var dimName = coordSys.dimensions[dimIndex]; + return isInfinity(fromCoord[otherDimIndex]) && isInfinity(toCoord[otherDimIndex]) && fromCoord[dimIndex] === toCoord[dimIndex] && coordSys.getAxis(dimName).containData(fromCoord[dimIndex]); + } + function markLineFilter(coordSys, item) { + if (coordSys.type === 'cartesian2d') { + var fromCoord = item[0].coord; + var toCoord = item[1].coord; + // In case + // { + // markLine: { + // data: [{ yAxis: 2 }] + // } + // } + if (fromCoord && toCoord && (ifMarkLineHasOnlyDim(1, fromCoord, toCoord, coordSys) || ifMarkLineHasOnlyDim(0, fromCoord, toCoord, coordSys))) { + return true; + } + } + return dataFilter$1(coordSys, item[0]) && dataFilter$1(coordSys, item[1]); + } + function updateSingleMarkerEndLayout(data, idx, isFrom, seriesModel, api) { + var coordSys = seriesModel.coordinateSystem; + var itemModel = data.getItemModel(idx); + var point; + var xPx = parsePercent$1(itemModel.get('x'), api.getWidth()); + var yPx = parsePercent$1(itemModel.get('y'), api.getHeight()); + if (!isNaN(xPx) && !isNaN(yPx)) { + point = [xPx, yPx]; + } else { + // Chart like bar may have there own marker positioning logic + if (seriesModel.getMarkerPosition) { + // Use the getMarkerPosition + point = seriesModel.getMarkerPosition(data.getValues(data.dimensions, idx)); + } else { + var dims = coordSys.dimensions; + var x = data.get(dims[0], idx); + var y = data.get(dims[1], idx); + point = coordSys.dataToPoint([x, y]); + } + // Expand line to the edge of grid if value on one axis is Inifnity + // In case + // markLine: { + // data: [{ + // yAxis: 2 + // // or + // type: 'average' + // }] + // } + if (isCoordinateSystemType(coordSys, 'cartesian2d')) { + // TODO: TYPE ts@4.1 may still infer it as Axis instead of Axis2D. Not sure if it's a bug + var xAxis = coordSys.getAxis('x'); + var yAxis = coordSys.getAxis('y'); + var dims = coordSys.dimensions; + if (isInfinity(data.get(dims[0], idx))) { + point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[isFrom ? 0 : 1]); + } else if (isInfinity(data.get(dims[1], idx))) { + point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[isFrom ? 0 : 1]); + } + } + // Use x, y if has any + if (!isNaN(xPx)) { + point[0] = xPx; + } + if (!isNaN(yPx)) { + point[1] = yPx; + } + } + data.setItemLayout(idx, point); + } + var MarkLineView = /** @class */function (_super) { + __extends(MarkLineView, _super); + function MarkLineView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MarkLineView.type; + return _this; + } + MarkLineView.prototype.updateTransform = function (markLineModel, ecModel, api) { + ecModel.eachSeries(function (seriesModel) { + var mlModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markLine'); + if (mlModel) { + var mlData_1 = mlModel.getData(); + var fromData_1 = inner$i(mlModel).from; + var toData_1 = inner$i(mlModel).to; + // Update visual and layout of from symbol and to symbol + fromData_1.each(function (idx) { + updateSingleMarkerEndLayout(fromData_1, idx, true, seriesModel, api); + updateSingleMarkerEndLayout(toData_1, idx, false, seriesModel, api); + }); + // Update layout of line + mlData_1.each(function (idx) { + mlData_1.setItemLayout(idx, [fromData_1.getItemLayout(idx), toData_1.getItemLayout(idx)]); + }); + this.markerGroupMap.get(seriesModel.id).updateLayout(); + } + }, this); + }; + MarkLineView.prototype.renderSeries = function (seriesModel, mlModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + var seriesId = seriesModel.id; + var seriesData = seriesModel.getData(); + var lineDrawMap = this.markerGroupMap; + var lineDraw = lineDrawMap.get(seriesId) || lineDrawMap.set(seriesId, new LineDraw()); + this.group.add(lineDraw.group); + var mlData = createList$1(coordSys, seriesModel, mlModel); + var fromData = mlData.from; + var toData = mlData.to; + var lineData = mlData.line; + inner$i(mlModel).from = fromData; + inner$i(mlModel).to = toData; + // Line data for tooltip and formatter + mlModel.setData(lineData); + // TODO + // Functionally, `symbolSize` & `symbolOffset` can also be 2D array now. + // But the related logic and type definition are not finished yet. + // Finish it if required + var symbolType = mlModel.get('symbol'); + var symbolSize = mlModel.get('symbolSize'); + var symbolRotate = mlModel.get('symbolRotate'); + var symbolOffset = mlModel.get('symbolOffset'); + // TODO: support callback function like markPoint + if (!isArray(symbolType)) { + symbolType = [symbolType, symbolType]; + } + if (!isArray(symbolSize)) { + symbolSize = [symbolSize, symbolSize]; + } + if (!isArray(symbolRotate)) { + symbolRotate = [symbolRotate, symbolRotate]; + } + if (!isArray(symbolOffset)) { + symbolOffset = [symbolOffset, symbolOffset]; + } + // Update visual and layout of from symbol and to symbol + mlData.from.each(function (idx) { + updateDataVisualAndLayout(fromData, idx, true); + updateDataVisualAndLayout(toData, idx, false); + }); + // Update visual and layout of line + lineData.each(function (idx) { + var lineStyle = lineData.getItemModel(idx).getModel('lineStyle').getLineStyle(); + // lineData.setItemVisual(idx, { + // color: lineColor || fromData.getItemVisual(idx, 'color') + // }); + lineData.setItemLayout(idx, [fromData.getItemLayout(idx), toData.getItemLayout(idx)]); + if (lineStyle.stroke == null) { + lineStyle.stroke = fromData.getItemVisual(idx, 'style').fill; + } + lineData.setItemVisual(idx, { + fromSymbolKeepAspect: fromData.getItemVisual(idx, 'symbolKeepAspect'), + fromSymbolOffset: fromData.getItemVisual(idx, 'symbolOffset'), + fromSymbolRotate: fromData.getItemVisual(idx, 'symbolRotate'), + fromSymbolSize: fromData.getItemVisual(idx, 'symbolSize'), + fromSymbol: fromData.getItemVisual(idx, 'symbol'), + toSymbolKeepAspect: toData.getItemVisual(idx, 'symbolKeepAspect'), + toSymbolOffset: toData.getItemVisual(idx, 'symbolOffset'), + toSymbolRotate: toData.getItemVisual(idx, 'symbolRotate'), + toSymbolSize: toData.getItemVisual(idx, 'symbolSize'), + toSymbol: toData.getItemVisual(idx, 'symbol'), + style: lineStyle + }); + }); + lineDraw.updateData(lineData); + // Set host model for tooltip + // FIXME + mlData.line.eachItemGraphicEl(function (el) { + getECData(el).dataModel = mlModel; + el.traverse(function (child) { + getECData(child).dataModel = mlModel; + }); + }); + function updateDataVisualAndLayout(data, idx, isFrom) { + var itemModel = data.getItemModel(idx); + updateSingleMarkerEndLayout(data, idx, isFrom, seriesModel, api); + var style = itemModel.getModel('itemStyle').getItemStyle(); + if (style.fill == null) { + style.fill = getVisualFromData(seriesData, 'color'); + } + data.setItemVisual(idx, { + symbolKeepAspect: itemModel.get('symbolKeepAspect'), + // `0` should be considered as a valid value, so use `retrieve2` instead of `||` + symbolOffset: retrieve2(itemModel.get('symbolOffset', true), symbolOffset[isFrom ? 0 : 1]), + symbolRotate: retrieve2(itemModel.get('symbolRotate', true), symbolRotate[isFrom ? 0 : 1]), + // TODO: when 2d array is supported, it should ignore parent + symbolSize: retrieve2(itemModel.get('symbolSize'), symbolSize[isFrom ? 0 : 1]), + symbol: retrieve2(itemModel.get('symbol', true), symbolType[isFrom ? 0 : 1]), + style: style + }); + } + this.markKeep(lineDraw); + lineDraw.group.silent = mlModel.get('silent') || seriesModel.get('silent'); + }; + MarkLineView.type = 'markLine'; + return MarkLineView; + }(MarkerView); + function createList$1(coordSys, seriesModel, mlModel) { + var coordDimsInfos; + if (coordSys) { + coordDimsInfos = map(coordSys && coordSys.dimensions, function (coordDim) { + var info = seriesModel.getData().getDimensionInfo(seriesModel.getData().mapDimension(coordDim)) || {}; + // In map series data don't have lng and lat dimension. Fallback to same with coordSys + return extend(extend({}, info), { + name: coordDim, + // DON'T use ordinalMeta to parse and collect ordinal. + ordinalMeta: null + }); + }); + } else { + coordDimsInfos = [{ + name: 'value', + type: 'float' + }]; + } + var fromData = new SeriesData(coordDimsInfos, mlModel); + var toData = new SeriesData(coordDimsInfos, mlModel); + // No dimensions + var lineData = new SeriesData([], mlModel); + var optData = map(mlModel.get('data'), curry(markLineTransform, seriesModel, coordSys, mlModel)); + if (coordSys) { + optData = filter(optData, curry(markLineFilter, coordSys)); + } + var dimValueGetter = createMarkerDimValueGetter(!!coordSys, coordDimsInfos); + fromData.initData(map(optData, function (item) { + return item[0]; + }), null, dimValueGetter); + toData.initData(map(optData, function (item) { + return item[1]; + }), null, dimValueGetter); + lineData.initData(map(optData, function (item) { + return item[2]; + })); + lineData.hasItemOption = true; + return { + from: fromData, + to: toData, + line: lineData + }; + } + + function install$F(registers) { + registers.registerComponentModel(MarkLineModel); + registers.registerComponentView(MarkLineView); + registers.registerPreprocessor(function (opt) { + if (checkMarkerInSeries(opt.series, 'markLine')) { + // Make sure markLine component is enabled + opt.markLine = opt.markLine || {}; + } + }); + } + + var MarkAreaModel = /** @class */function (_super) { + __extends(MarkAreaModel, _super); + function MarkAreaModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MarkAreaModel.type; + return _this; + } + MarkAreaModel.prototype.createMarkerModelFromSeries = function (markerOpt, masterMarkerModel, ecModel) { + return new MarkAreaModel(markerOpt, masterMarkerModel, ecModel); + }; + MarkAreaModel.type = 'markArea'; + MarkAreaModel.defaultOption = { + // zlevel: 0, + // PENDING + z: 1, + tooltip: { + trigger: 'item' + }, + // markArea should fixed on the coordinate system + animation: false, + label: { + show: true, + position: 'top' + }, + itemStyle: { + // color and borderColor default to use color from series + // color: 'auto' + // borderColor: 'auto' + borderWidth: 0 + }, + emphasis: { + label: { + show: true, + position: 'top' + } + } + }; + return MarkAreaModel; + }(MarkerModel); + + var inner$j = makeInner(); + var markAreaTransform = function (seriesModel, coordSys, maModel, item) { + // item may be null + var item0 = item[0]; + var item1 = item[1]; + if (!item0 || !item1) { + return; + } + var lt = dataTransform(seriesModel, item0); + var rb = dataTransform(seriesModel, item1); + // FIXME make sure lt is less than rb + var ltCoord = lt.coord; + var rbCoord = rb.coord; + ltCoord[0] = retrieve(ltCoord[0], -Infinity); + ltCoord[1] = retrieve(ltCoord[1], -Infinity); + rbCoord[0] = retrieve(rbCoord[0], Infinity); + rbCoord[1] = retrieve(rbCoord[1], Infinity); + // Merge option into one + var result = mergeAll([{}, lt, rb]); + result.coord = [lt.coord, rb.coord]; + result.x0 = lt.x; + result.y0 = lt.y; + result.x1 = rb.x; + result.y1 = rb.y; + return result; + }; + function isInfinity$1(val) { + return !isNaN(val) && !isFinite(val); + } + // If a markArea has one dim + function ifMarkAreaHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) { + var otherDimIndex = 1 - dimIndex; + return isInfinity$1(fromCoord[otherDimIndex]) && isInfinity$1(toCoord[otherDimIndex]); + } + function markAreaFilter(coordSys, item) { + var fromCoord = item.coord[0]; + var toCoord = item.coord[1]; + var item0 = { + coord: fromCoord, + x: item.x0, + y: item.y0 + }; + var item1 = { + coord: toCoord, + x: item.x1, + y: item.y1 + }; + if (isCoordinateSystemType(coordSys, 'cartesian2d')) { + // In case + // { + // markArea: { + // data: [{ yAxis: 2 }] + // } + // } + if (fromCoord && toCoord && (ifMarkAreaHasOnlyDim(1, fromCoord, toCoord) || ifMarkAreaHasOnlyDim(0, fromCoord, toCoord))) { + return true; + } + // Directly returning true may also do the work, + // because markArea will not be shown automatically + // when it's not included in coordinate system. + // But filtering ahead can avoid keeping rendering markArea + // when there are too many of them. + return zoneFilter(coordSys, item0, item1); + } + return dataFilter$1(coordSys, item0) || dataFilter$1(coordSys, item1); + } + // dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0'] + function getSingleMarkerEndPoint(data, idx, dims, seriesModel, api) { + var coordSys = seriesModel.coordinateSystem; + var itemModel = data.getItemModel(idx); + var point; + var xPx = parsePercent$1(itemModel.get(dims[0]), api.getWidth()); + var yPx = parsePercent$1(itemModel.get(dims[1]), api.getHeight()); + if (!isNaN(xPx) && !isNaN(yPx)) { + point = [xPx, yPx]; + } else { + // Chart like bar may have there own marker positioning logic + if (seriesModel.getMarkerPosition) { + // Consider the case that user input the right-bottom point first + // Pick the larger x and y as 'x1' and 'y1' + var pointValue0 = data.getValues(['x0', 'y0'], idx); + var pointValue1 = data.getValues(['x1', 'y1'], idx); + var clampPointValue0 = coordSys.clampData(pointValue0); + var clampPointValue1 = coordSys.clampData(pointValue1); + var pointValue = []; + if (dims[0] === 'x0') { + pointValue[0] = clampPointValue0[0] > clampPointValue1[0] ? pointValue1[0] : pointValue0[0]; + } else { + pointValue[0] = clampPointValue0[0] > clampPointValue1[0] ? pointValue0[0] : pointValue1[0]; + } + if (dims[1] === 'y0') { + pointValue[1] = clampPointValue0[1] > clampPointValue1[1] ? pointValue1[1] : pointValue0[1]; + } else { + pointValue[1] = clampPointValue0[1] > clampPointValue1[1] ? pointValue0[1] : pointValue1[1]; + } + // Use the getMarkerPosition + point = seriesModel.getMarkerPosition(pointValue, dims, true); + } else { + var x = data.get(dims[0], idx); + var y = data.get(dims[1], idx); + var pt = [x, y]; + coordSys.clampData && coordSys.clampData(pt, pt); + point = coordSys.dataToPoint(pt, true); + } + if (isCoordinateSystemType(coordSys, 'cartesian2d')) { + // TODO: TYPE ts@4.1 may still infer it as Axis instead of Axis2D. Not sure if it's a bug + var xAxis = coordSys.getAxis('x'); + var yAxis = coordSys.getAxis('y'); + var x = data.get(dims[0], idx); + var y = data.get(dims[1], idx); + if (isInfinity$1(x)) { + point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]); + } else if (isInfinity$1(y)) { + point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[dims[1] === 'y0' ? 0 : 1]); + } + } + // Use x, y if has any + if (!isNaN(xPx)) { + point[0] = xPx; + } + if (!isNaN(yPx)) { + point[1] = yPx; + } + } + return point; + } + var dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']]; + var MarkAreaView = /** @class */function (_super) { + __extends(MarkAreaView, _super); + function MarkAreaView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = MarkAreaView.type; + return _this; + } + MarkAreaView.prototype.updateTransform = function (markAreaModel, ecModel, api) { + ecModel.eachSeries(function (seriesModel) { + var maModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markArea'); + if (maModel) { + var areaData_1 = maModel.getData(); + areaData_1.each(function (idx) { + var points = map(dimPermutations, function (dim) { + return getSingleMarkerEndPoint(areaData_1, idx, dim, seriesModel, api); + }); + // Layout + areaData_1.setItemLayout(idx, points); + var el = areaData_1.getItemGraphicEl(idx); + el.setShape('points', points); + }); + } + }, this); + }; + MarkAreaView.prototype.renderSeries = function (seriesModel, maModel, ecModel, api) { + var coordSys = seriesModel.coordinateSystem; + var seriesId = seriesModel.id; + var seriesData = seriesModel.getData(); + var areaGroupMap = this.markerGroupMap; + var polygonGroup = areaGroupMap.get(seriesId) || areaGroupMap.set(seriesId, { + group: new Group() + }); + this.group.add(polygonGroup.group); + this.markKeep(polygonGroup); + var areaData = createList$2(coordSys, seriesModel, maModel); + // Line data for tooltip and formatter + maModel.setData(areaData); + // Update visual and layout of line + areaData.each(function (idx) { + // Layout + var points = map(dimPermutations, function (dim) { + return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api); + }); + var xAxisScale = coordSys.getAxis('x').scale; + var yAxisScale = coordSys.getAxis('y').scale; + var xAxisExtent = xAxisScale.getExtent(); + var yAxisExtent = yAxisScale.getExtent(); + var xPointExtent = [xAxisScale.parse(areaData.get('x0', idx)), xAxisScale.parse(areaData.get('x1', idx))]; + var yPointExtent = [yAxisScale.parse(areaData.get('y0', idx)), yAxisScale.parse(areaData.get('y1', idx))]; + asc(xPointExtent); + asc(yPointExtent); + var overlapped = !(xAxisExtent[0] > xPointExtent[1] || xAxisExtent[1] < xPointExtent[0] || yAxisExtent[0] > yPointExtent[1] || yAxisExtent[1] < yPointExtent[0]); + // If none of the area is inside coordSys, allClipped is set to be true + // in layout so that label will not be displayed. See #12591 + var allClipped = !overlapped; + areaData.setItemLayout(idx, { + points: points, + allClipped: allClipped + }); + var style = areaData.getItemModel(idx).getModel('itemStyle').getItemStyle(); + var color$1 = getVisualFromData(seriesData, 'color'); + if (!style.fill) { + style.fill = color$1; + if (isString(style.fill)) { + style.fill = modifyAlpha(style.fill, 0.4); + } + } + if (!style.stroke) { + style.stroke = color$1; + } + // Visual + areaData.setItemVisual(idx, 'style', style); + }); + areaData.diff(inner$j(polygonGroup).data).add(function (idx) { + var layout = areaData.getItemLayout(idx); + if (!layout.allClipped) { + var polygon = new Polygon({ + shape: { + points: layout.points + } + }); + areaData.setItemGraphicEl(idx, polygon); + polygonGroup.group.add(polygon); + } + }).update(function (newIdx, oldIdx) { + var polygon = inner$j(polygonGroup).data.getItemGraphicEl(oldIdx); + var layout = areaData.getItemLayout(newIdx); + if (!layout.allClipped) { + if (polygon) { + updateProps(polygon, { + shape: { + points: layout.points + } + }, maModel, newIdx); + } else { + polygon = new Polygon({ + shape: { + points: layout.points + } + }); + } + areaData.setItemGraphicEl(newIdx, polygon); + polygonGroup.group.add(polygon); + } else if (polygon) { + polygonGroup.group.remove(polygon); + } + }).remove(function (idx) { + var polygon = inner$j(polygonGroup).data.getItemGraphicEl(idx); + polygonGroup.group.remove(polygon); + }).execute(); + areaData.eachItemGraphicEl(function (polygon, idx) { + var itemModel = areaData.getItemModel(idx); + var style = areaData.getItemVisual(idx, 'style'); + polygon.useStyle(areaData.getItemVisual(idx, 'style')); + setLabelStyle(polygon, getLabelStatesModels(itemModel), { + labelFetcher: maModel, + labelDataIndex: idx, + defaultText: areaData.getName(idx) || '', + inheritColor: isString(style.fill) ? modifyAlpha(style.fill, 1) : '#000' + }); + setStatesStylesFromModel(polygon, itemModel); + toggleHoverEmphasis(polygon, null, null, itemModel.get(['emphasis', 'disabled'])); + getECData(polygon).dataModel = maModel; + }); + inner$j(polygonGroup).data = areaData; + polygonGroup.group.silent = maModel.get('silent') || seriesModel.get('silent'); + }; + MarkAreaView.type = 'markArea'; + return MarkAreaView; + }(MarkerView); + function createList$2(coordSys, seriesModel, maModel) { + var areaData; + var dataDims; + var dims = ['x0', 'y0', 'x1', 'y1']; + if (coordSys) { + var coordDimsInfos_1 = map(coordSys && coordSys.dimensions, function (coordDim) { + var data = seriesModel.getData(); + var info = data.getDimensionInfo(data.mapDimension(coordDim)) || {}; + // In map series data don't have lng and lat dimension. Fallback to same with coordSys + return extend(extend({}, info), { + name: coordDim, + // DON'T use ordinalMeta to parse and collect ordinal. + ordinalMeta: null + }); + }); + dataDims = map(dims, function (dim, idx) { + return { + name: dim, + type: coordDimsInfos_1[idx % 2].type + }; + }); + areaData = new SeriesData(dataDims, maModel); + } else { + dataDims = [{ + name: 'value', + type: 'float' + }]; + areaData = new SeriesData(dataDims, maModel); + } + var optData = map(maModel.get('data'), curry(markAreaTransform, seriesModel, coordSys, maModel)); + if (coordSys) { + optData = filter(optData, curry(markAreaFilter, coordSys)); + } + var dimValueGetter = coordSys ? function (item, dimName, dataIndex, dimIndex) { + // TODO should convert to ParsedValue? + var rawVal = item.coord[Math.floor(dimIndex / 2)][dimIndex % 2]; + return parseDataValue(rawVal, dataDims[dimIndex]); + } : function (item, dimName, dataIndex, dimIndex) { + return parseDataValue(item.value, dataDims[dimIndex]); + }; + areaData.initData(optData, null, dimValueGetter); + areaData.hasItemOption = true; + return areaData; + } + + function install$G(registers) { + registers.registerComponentModel(MarkAreaModel); + registers.registerComponentView(MarkAreaView); + registers.registerPreprocessor(function (opt) { + if (checkMarkerInSeries(opt.series, 'markArea')) { + // Make sure markArea component is enabled + opt.markArea = opt.markArea || {}; + } + }); + } + + var getDefaultSelectorOptions = function (ecModel, type) { + if (type === 'all') { + return { + type: 'all', + title: ecModel.getLocaleModel().get(['legend', 'selector', 'all']) + }; + } else if (type === 'inverse') { + return { + type: 'inverse', + title: ecModel.getLocaleModel().get(['legend', 'selector', 'inverse']) + }; + } + }; + var LegendModel = /** @class */function (_super) { + __extends(LegendModel, _super); + function LegendModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = LegendModel.type; + _this.layoutMode = { + type: 'box', + // legend.width/height are maxWidth/maxHeight actually, + // whereas real width/height is calculated by its content. + // (Setting {left: 10, right: 10} does not make sense). + // So consider the case: + // `setOption({legend: {left: 10});` + // then `setOption({legend: {right: 10});` + // The previous `left` should be cleared by setting `ignoreSize`. + ignoreSize: true + }; + return _this; + } + LegendModel.prototype.init = function (option, parentModel, ecModel) { + this.mergeDefaultAndTheme(option, ecModel); + option.selected = option.selected || {}; + this._updateSelector(option); + }; + LegendModel.prototype.mergeOption = function (option, ecModel) { + _super.prototype.mergeOption.call(this, option, ecModel); + this._updateSelector(option); + }; + LegendModel.prototype._updateSelector = function (option) { + var selector = option.selector; + var ecModel = this.ecModel; + if (selector === true) { + selector = option.selector = ['all', 'inverse']; + } + if (isArray(selector)) { + each(selector, function (item, index) { + isString(item) && (item = { + type: item + }); + selector[index] = merge(item, getDefaultSelectorOptions(ecModel, item.type)); + }); + } + }; + LegendModel.prototype.optionUpdated = function () { + this._updateData(this.ecModel); + var legendData = this._data; + // If selectedMode is single, try to select one + if (legendData[0] && this.get('selectedMode') === 'single') { + var hasSelected = false; + // If has any selected in option.selected + for (var i = 0; i < legendData.length; i++) { + var name_1 = legendData[i].get('name'); + if (this.isSelected(name_1)) { + // Force to unselect others + this.select(name_1); + hasSelected = true; + break; + } + } + // Try select the first if selectedMode is single + !hasSelected && this.select(legendData[0].get('name')); + } + }; + LegendModel.prototype._updateData = function (ecModel) { + var potentialData = []; + var availableNames = []; + ecModel.eachRawSeries(function (seriesModel) { + var seriesName = seriesModel.name; + availableNames.push(seriesName); + var isPotential; + if (seriesModel.legendVisualProvider) { + var provider = seriesModel.legendVisualProvider; + var names = provider.getAllNames(); + if (!ecModel.isSeriesFiltered(seriesModel)) { + availableNames = availableNames.concat(names); + } + if (names.length) { + potentialData = potentialData.concat(names); + } else { + isPotential = true; + } + } else { + isPotential = true; + } + if (isPotential && isNameSpecified(seriesModel)) { + potentialData.push(seriesModel.name); + } + }); + /** + * @type {Array.} + * @private + */ + this._availableNames = availableNames; + // If legend.data is not specified in option, use availableNames as data, + // which is convenient for user preparing option. + var rawData = this.get('data') || potentialData; + var legendNameMap = createHashMap(); + var legendData = map(rawData, function (dataItem) { + // Can be string or number + if (isString(dataItem) || isNumber(dataItem)) { + dataItem = { + name: dataItem + }; + } + if (legendNameMap.get(dataItem.name)) { + // remove legend name duplicate + return null; + } + legendNameMap.set(dataItem.name, true); + return new Model(dataItem, this, this.ecModel); + }, this); + /** + * @type {Array.} + * @private + */ + this._data = filter(legendData, function (item) { + return !!item; + }); + }; + LegendModel.prototype.getData = function () { + return this._data; + }; + LegendModel.prototype.select = function (name) { + var selected = this.option.selected; + var selectedMode = this.get('selectedMode'); + if (selectedMode === 'single') { + var data = this._data; + each(data, function (dataItem) { + selected[dataItem.get('name')] = false; + }); + } + selected[name] = true; + }; + LegendModel.prototype.unSelect = function (name) { + if (this.get('selectedMode') !== 'single') { + this.option.selected[name] = false; + } + }; + LegendModel.prototype.toggleSelected = function (name) { + var selected = this.option.selected; + // Default is true + if (!selected.hasOwnProperty(name)) { + selected[name] = true; + } + this[selected[name] ? 'unSelect' : 'select'](name); + }; + LegendModel.prototype.allSelect = function () { + var data = this._data; + var selected = this.option.selected; + each(data, function (dataItem) { + selected[dataItem.get('name', true)] = true; + }); + }; + LegendModel.prototype.inverseSelect = function () { + var data = this._data; + var selected = this.option.selected; + each(data, function (dataItem) { + var name = dataItem.get('name', true); + // Initially, default value is true + if (!selected.hasOwnProperty(name)) { + selected[name] = true; + } + selected[name] = !selected[name]; + }); + }; + LegendModel.prototype.isSelected = function (name) { + var selected = this.option.selected; + return !(selected.hasOwnProperty(name) && !selected[name]) && indexOf(this._availableNames, name) >= 0; + }; + LegendModel.prototype.getOrient = function () { + return this.get('orient') === 'vertical' ? { + index: 1, + name: 'vertical' + } : { + index: 0, + name: 'horizontal' + }; + }; + LegendModel.type = 'legend.plain'; + LegendModel.dependencies = ['series']; + LegendModel.defaultOption = { + // zlevel: 0, + z: 4, + show: true, + orient: 'horizontal', + left: 'center', + // right: 'center', + top: 0, + // bottom: null, + align: 'auto', + backgroundColor: 'rgba(0,0,0,0)', + borderColor: '#ccc', + borderRadius: 0, + borderWidth: 0, + padding: 5, + itemGap: 10, + itemWidth: 25, + itemHeight: 14, + symbolRotate: 'inherit', + symbolKeepAspect: true, + inactiveColor: '#ccc', + inactiveBorderColor: '#ccc', + inactiveBorderWidth: 'auto', + itemStyle: { + color: 'inherit', + opacity: 'inherit', + borderColor: 'inherit', + borderWidth: 'auto', + borderCap: 'inherit', + borderJoin: 'inherit', + borderDashOffset: 'inherit', + borderMiterLimit: 'inherit' + }, + lineStyle: { + width: 'auto', + color: 'inherit', + inactiveColor: '#ccc', + inactiveWidth: 2, + opacity: 'inherit', + type: 'inherit', + cap: 'inherit', + join: 'inherit', + dashOffset: 'inherit', + miterLimit: 'inherit' + }, + textStyle: { + color: '#333' + }, + selectedMode: true, + selector: false, + selectorLabel: { + show: true, + borderRadius: 10, + padding: [3, 5, 3, 5], + fontSize: 12, + fontFamily: 'sans-serif', + color: '#666', + borderWidth: 1, + borderColor: '#666' + }, + emphasis: { + selectorLabel: { + show: true, + color: '#eee', + backgroundColor: '#666' + } + }, + selectorPosition: 'auto', + selectorItemGap: 7, + selectorButtonGap: 10, + tooltip: { + show: false + } + }; + return LegendModel; + }(ComponentModel); + + var curry$1 = curry; + var each$c = each; + var Group$2 = Group; + var LegendView = /** @class */function (_super) { + __extends(LegendView, _super); + function LegendView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = LegendView.type; + _this.newlineDisabled = false; + return _this; + } + LegendView.prototype.init = function () { + this.group.add(this._contentGroup = new Group$2()); + this.group.add(this._selectorGroup = new Group$2()); + this._isFirstRender = true; + }; + /** + * @protected + */ + LegendView.prototype.getContentGroup = function () { + return this._contentGroup; + }; + /** + * @protected + */ + LegendView.prototype.getSelectorGroup = function () { + return this._selectorGroup; + }; + /** + * @override + */ + LegendView.prototype.render = function (legendModel, ecModel, api) { + var isFirstRender = this._isFirstRender; + this._isFirstRender = false; + this.resetInner(); + if (!legendModel.get('show', true)) { + return; + } + var itemAlign = legendModel.get('align'); + var orient = legendModel.get('orient'); + if (!itemAlign || itemAlign === 'auto') { + itemAlign = legendModel.get('left') === 'right' && orient === 'vertical' ? 'right' : 'left'; + } + // selector has been normalized to an array in model + var selector = legendModel.get('selector', true); + var selectorPosition = legendModel.get('selectorPosition', true); + if (selector && (!selectorPosition || selectorPosition === 'auto')) { + selectorPosition = orient === 'horizontal' ? 'end' : 'start'; + } + this.renderInner(itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition); + // Perform layout. + var positionInfo = legendModel.getBoxLayoutParams(); + var viewportSize = { + width: api.getWidth(), + height: api.getHeight() + }; + var padding = legendModel.get('padding'); + var maxSize = getLayoutRect(positionInfo, viewportSize, padding); + var mainRect = this.layoutInner(legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition); + // Place mainGroup, based on the calculated `mainRect`. + var layoutRect = getLayoutRect(defaults({ + width: mainRect.width, + height: mainRect.height + }, positionInfo), viewportSize, padding); + this.group.x = layoutRect.x - mainRect.x; + this.group.y = layoutRect.y - mainRect.y; + this.group.markRedraw(); + // Render background after group is layout. + this.group.add(this._backgroundEl = makeBackground(mainRect, legendModel)); + }; + LegendView.prototype.resetInner = function () { + this.getContentGroup().removeAll(); + this._backgroundEl && this.group.remove(this._backgroundEl); + this.getSelectorGroup().removeAll(); + }; + LegendView.prototype.renderInner = function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) { + var contentGroup = this.getContentGroup(); + var legendDrawnMap = createHashMap(); + var selectMode = legendModel.get('selectedMode'); + var excludeSeriesId = []; + ecModel.eachRawSeries(function (seriesModel) { + !seriesModel.get('legendHoverLink') && excludeSeriesId.push(seriesModel.id); + }); + each$c(legendModel.getData(), function (legendItemModel, dataIndex) { + var name = legendItemModel.get('name'); + // Use empty string or \n as a newline string + if (!this.newlineDisabled && (name === '' || name === '\n')) { + var g = new Group$2(); + // @ts-ignore + g.newline = true; + contentGroup.add(g); + return; + } + // Representitive series. + var seriesModel = ecModel.getSeriesByName(name)[0]; + if (legendDrawnMap.get(name)) { + // Have been drawn + return; + } + // Legend to control series. + if (seriesModel) { + var data = seriesModel.getData(); + var lineVisualStyle = data.getVisual('legendLineStyle') || {}; + var legendIcon = data.getVisual('legendIcon'); + /** + * `data.getVisual('style')` may be the color from the register + * in series. For example, for line series, + */ + var style = data.getVisual('style'); + var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, style, legendIcon, selectMode, api); + itemGroup.on('click', curry$1(dispatchSelectAction, name, null, api, excludeSeriesId)).on('mouseover', curry$1(dispatchHighlightAction, seriesModel.name, null, api, excludeSeriesId)).on('mouseout', curry$1(dispatchDownplayAction, seriesModel.name, null, api, excludeSeriesId)); + if (ecModel.ssr) { + itemGroup.eachChild(function (child) { + var ecData = getECData(child); + ecData.seriesIndex = seriesModel.seriesIndex; + ecData.dataIndex = dataIndex; + ecData.ssrType = 'legend'; + }); + } + legendDrawnMap.set(name, true); + } else { + // Legend to control data. In pie and funnel. + ecModel.eachRawSeries(function (seriesModel) { + // In case multiple series has same data name + if (legendDrawnMap.get(name)) { + return; + } + if (seriesModel.legendVisualProvider) { + var provider = seriesModel.legendVisualProvider; + if (!provider.containName(name)) { + return; + } + var idx = provider.indexOfName(name); + var style = provider.getItemVisual(idx, 'style'); + var legendIcon = provider.getItemVisual(idx, 'legendIcon'); + var colorArr = parse(style.fill); + // Color may be set to transparent in visualMap when data is out of range. + // Do not show nothing. + if (colorArr && colorArr[3] === 0) { + colorArr[3] = 0.2; + // TODO color is set to 0, 0, 0, 0. Should show correct RGBA + style = extend(extend({}, style), { + fill: stringify(colorArr, 'rgba') + }); + } + var itemGroup = this._createItem(seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, {}, style, legendIcon, selectMode, api); + // FIXME: consider different series has items with the same name. + itemGroup.on('click', curry$1(dispatchSelectAction, null, name, api, excludeSeriesId)) + // Should not specify the series name, consider legend controls + // more than one pie series. + .on('mouseover', curry$1(dispatchHighlightAction, null, name, api, excludeSeriesId)).on('mouseout', curry$1(dispatchDownplayAction, null, name, api, excludeSeriesId)); + if (ecModel.ssr) { + itemGroup.eachChild(function (child) { + var ecData = getECData(child); + ecData.seriesIndex = seriesModel.seriesIndex; + ecData.dataIndex = dataIndex; + ecData.ssrType = 'legend'; + }); + } + legendDrawnMap.set(name, true); + } + }, this); + } + if ("development" !== 'production') { + if (!legendDrawnMap.get(name)) { + console.warn(name + ' series not exists. Legend data should be same with series name or data name.'); + } + } + }, this); + if (selector) { + this._createSelector(selector, legendModel, api, orient, selectorPosition); + } + }; + LegendView.prototype._createSelector = function (selector, legendModel, api, orient, selectorPosition) { + var selectorGroup = this.getSelectorGroup(); + each$c(selector, function createSelectorButton(selectorItem) { + var type = selectorItem.type; + var labelText = new ZRText({ + style: { + x: 0, + y: 0, + align: 'center', + verticalAlign: 'middle' + }, + onclick: function () { + api.dispatchAction({ + type: type === 'all' ? 'legendAllSelect' : 'legendInverseSelect' + }); + } + }); + selectorGroup.add(labelText); + var labelModel = legendModel.getModel('selectorLabel'); + var emphasisLabelModel = legendModel.getModel(['emphasis', 'selectorLabel']); + setLabelStyle(labelText, { + normal: labelModel, + emphasis: emphasisLabelModel + }, { + defaultText: selectorItem.title + }); + enableHoverEmphasis(labelText); + }); + }; + LegendView.prototype._createItem = function (seriesModel, name, dataIndex, legendItemModel, legendModel, itemAlign, lineVisualStyle, itemVisualStyle, legendIcon, selectMode, api) { + var drawType = seriesModel.visualDrawType; + var itemWidth = legendModel.get('itemWidth'); + var itemHeight = legendModel.get('itemHeight'); + var isSelected = legendModel.isSelected(name); + var iconRotate = legendItemModel.get('symbolRotate'); + var symbolKeepAspect = legendItemModel.get('symbolKeepAspect'); + var legendIconType = legendItemModel.get('icon'); + legendIcon = legendIconType || legendIcon || 'roundRect'; + var style = getLegendStyle(legendIcon, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected, api); + var itemGroup = new Group$2(); + var textStyleModel = legendItemModel.getModel('textStyle'); + if (isFunction(seriesModel.getLegendIcon) && (!legendIconType || legendIconType === 'inherit')) { + // Series has specific way to define legend icon + itemGroup.add(seriesModel.getLegendIcon({ + itemWidth: itemWidth, + itemHeight: itemHeight, + icon: legendIcon, + iconRotate: iconRotate, + itemStyle: style.itemStyle, + lineStyle: style.lineStyle, + symbolKeepAspect: symbolKeepAspect + })); + } else { + // Use default legend icon policy for most series + var rotate = legendIconType === 'inherit' && seriesModel.getData().getVisual('symbol') ? iconRotate === 'inherit' ? seriesModel.getData().getVisual('symbolRotate') : iconRotate : 0; // No rotation for no icon + itemGroup.add(getDefaultLegendIcon({ + itemWidth: itemWidth, + itemHeight: itemHeight, + icon: legendIcon, + iconRotate: rotate, + itemStyle: style.itemStyle, + lineStyle: style.lineStyle, + symbolKeepAspect: symbolKeepAspect + })); + } + var textX = itemAlign === 'left' ? itemWidth + 5 : -5; + var textAlign = itemAlign; + var formatter = legendModel.get('formatter'); + var content = name; + if (isString(formatter) && formatter) { + content = formatter.replace('{name}', name != null ? name : ''); + } else if (isFunction(formatter)) { + content = formatter(name); + } + var textColor = isSelected ? textStyleModel.getTextColor() : legendItemModel.get('inactiveColor'); + itemGroup.add(new ZRText({ + style: createTextStyle(textStyleModel, { + text: content, + x: textX, + y: itemHeight / 2, + fill: textColor, + align: textAlign, + verticalAlign: 'middle' + }, { + inheritColor: textColor + }) + })); + // Add a invisible rect to increase the area of mouse hover + var hitRect = new Rect({ + shape: itemGroup.getBoundingRect(), + style: { + // Cannot use 'invisible' because SVG SSR will miss the node + fill: 'transparent' + } + }); + var tooltipModel = legendItemModel.getModel('tooltip'); + if (tooltipModel.get('show')) { + setTooltipConfig({ + el: hitRect, + componentModel: legendModel, + itemName: name, + itemTooltipOption: tooltipModel.option + }); + } + itemGroup.add(hitRect); + itemGroup.eachChild(function (child) { + child.silent = true; + }); + hitRect.silent = !selectMode; + this.getContentGroup().add(itemGroup); + enableHoverEmphasis(itemGroup); + // @ts-ignore + itemGroup.__legendDataIndex = dataIndex; + return itemGroup; + }; + LegendView.prototype.layoutInner = function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) { + var contentGroup = this.getContentGroup(); + var selectorGroup = this.getSelectorGroup(); + // Place items in contentGroup. + box(legendModel.get('orient'), contentGroup, legendModel.get('itemGap'), maxSize.width, maxSize.height); + var contentRect = contentGroup.getBoundingRect(); + var contentPos = [-contentRect.x, -contentRect.y]; + selectorGroup.markRedraw(); + contentGroup.markRedraw(); + if (selector) { + // Place buttons in selectorGroup + box( + // Buttons in selectorGroup always layout horizontally + 'horizontal', selectorGroup, legendModel.get('selectorItemGap', true)); + var selectorRect = selectorGroup.getBoundingRect(); + var selectorPos = [-selectorRect.x, -selectorRect.y]; + var selectorButtonGap = legendModel.get('selectorButtonGap', true); + var orientIdx = legendModel.getOrient().index; + var wh = orientIdx === 0 ? 'width' : 'height'; + var hw = orientIdx === 0 ? 'height' : 'width'; + var yx = orientIdx === 0 ? 'y' : 'x'; + if (selectorPosition === 'end') { + selectorPos[orientIdx] += contentRect[wh] + selectorButtonGap; + } else { + contentPos[orientIdx] += selectorRect[wh] + selectorButtonGap; + } + // Always align selector to content as 'middle' + selectorPos[1 - orientIdx] += contentRect[hw] / 2 - selectorRect[hw] / 2; + selectorGroup.x = selectorPos[0]; + selectorGroup.y = selectorPos[1]; + contentGroup.x = contentPos[0]; + contentGroup.y = contentPos[1]; + var mainRect = { + x: 0, + y: 0 + }; + mainRect[wh] = contentRect[wh] + selectorButtonGap + selectorRect[wh]; + mainRect[hw] = Math.max(contentRect[hw], selectorRect[hw]); + mainRect[yx] = Math.min(0, selectorRect[yx] + selectorPos[1 - orientIdx]); + return mainRect; + } else { + contentGroup.x = contentPos[0]; + contentGroup.y = contentPos[1]; + return this.group.getBoundingRect(); + } + }; + /** + * @protected + */ + LegendView.prototype.remove = function () { + this.getContentGroup().removeAll(); + this._isFirstRender = true; + }; + LegendView.type = 'legend.plain'; + return LegendView; + }(ComponentView); + function getLegendStyle(iconType, legendItemModel, lineVisualStyle, itemVisualStyle, drawType, isSelected, api) { + /** + * Use series style if is inherit; + * elsewise, use legend style + */ + function handleCommonProps(style, visualStyle) { + // If lineStyle.width is 'auto', it is set to be 2 if series has border + if (style.lineWidth === 'auto') { + style.lineWidth = visualStyle.lineWidth > 0 ? 2 : 0; + } + each$c(style, function (propVal, propName) { + style[propName] === 'inherit' && (style[propName] = visualStyle[propName]); + }); + } + // itemStyle + var itemStyleModel = legendItemModel.getModel('itemStyle'); + var itemStyle = itemStyleModel.getItemStyle(); + var iconBrushType = iconType.lastIndexOf('empty', 0) === 0 ? 'fill' : 'stroke'; + var decalStyle = itemStyleModel.getShallow('decal'); + itemStyle.decal = !decalStyle || decalStyle === 'inherit' ? itemVisualStyle.decal : createOrUpdatePatternFromDecal(decalStyle, api); + if (itemStyle.fill === 'inherit') { + /** + * Series with visualDrawType as 'stroke' should have + * series stroke as legend fill + */ + itemStyle.fill = itemVisualStyle[drawType]; + } + if (itemStyle.stroke === 'inherit') { + /** + * icon type with "emptyXXX" should use fill color + * in visual style + */ + itemStyle.stroke = itemVisualStyle[iconBrushType]; + } + if (itemStyle.opacity === 'inherit') { + /** + * Use lineStyle.opacity if drawType is stroke + */ + itemStyle.opacity = (drawType === 'fill' ? itemVisualStyle : lineVisualStyle).opacity; + } + handleCommonProps(itemStyle, itemVisualStyle); + // lineStyle + var legendLineModel = legendItemModel.getModel('lineStyle'); + var lineStyle = legendLineModel.getLineStyle(); + handleCommonProps(lineStyle, lineVisualStyle); + // Fix auto color to real color + itemStyle.fill === 'auto' && (itemStyle.fill = itemVisualStyle.fill); + itemStyle.stroke === 'auto' && (itemStyle.stroke = itemVisualStyle.fill); + lineStyle.stroke === 'auto' && (lineStyle.stroke = itemVisualStyle.fill); + if (!isSelected) { + var borderWidth = legendItemModel.get('inactiveBorderWidth'); + /** + * Since stroke is set to be inactiveBorderColor, it may occur that + * there is no border in series but border in legend, so we need to + * use border only when series has border if is set to be auto + */ + var visualHasBorder = itemStyle[iconBrushType]; + itemStyle.lineWidth = borderWidth === 'auto' ? itemVisualStyle.lineWidth > 0 && visualHasBorder ? 2 : 0 : itemStyle.lineWidth; + itemStyle.fill = legendItemModel.get('inactiveColor'); + itemStyle.stroke = legendItemModel.get('inactiveBorderColor'); + lineStyle.stroke = legendLineModel.get('inactiveColor'); + lineStyle.lineWidth = legendLineModel.get('inactiveWidth'); + } + return { + itemStyle: itemStyle, + lineStyle: lineStyle + }; + } + function getDefaultLegendIcon(opt) { + var symboType = opt.icon || 'roundRect'; + var icon = createSymbol(symboType, 0, 0, opt.itemWidth, opt.itemHeight, opt.itemStyle.fill, opt.symbolKeepAspect); + icon.setStyle(opt.itemStyle); + icon.rotation = (opt.iconRotate || 0) * Math.PI / 180; + icon.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]); + if (symboType.indexOf('empty') > -1) { + icon.style.stroke = icon.style.fill; + icon.style.fill = '#fff'; + icon.style.lineWidth = 2; + } + return icon; + } + function dispatchSelectAction(seriesName, dataName, api, excludeSeriesId) { + // downplay before unselect + dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId); + api.dispatchAction({ + type: 'legendToggleSelect', + name: seriesName != null ? seriesName : dataName + }); + // highlight after select + // TODO highlight immediately may cause animation loss. + dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId); + } + function isUseHoverLayer(api) { + var list = api.getZr().storage.getDisplayList(); + var emphasisState; + var i = 0; + var len = list.length; + while (i < len && !(emphasisState = list[i].states.emphasis)) { + i++; + } + return emphasisState && emphasisState.hoverLayer; + } + function dispatchHighlightAction(seriesName, dataName, api, excludeSeriesId) { + // If element hover will move to a hoverLayer. + if (!isUseHoverLayer(api)) { + api.dispatchAction({ + type: 'highlight', + seriesName: seriesName, + name: dataName, + excludeSeriesId: excludeSeriesId + }); + } + } + function dispatchDownplayAction(seriesName, dataName, api, excludeSeriesId) { + // If element hover will move to a hoverLayer. + if (!isUseHoverLayer(api)) { + api.dispatchAction({ + type: 'downplay', + seriesName: seriesName, + name: dataName, + excludeSeriesId: excludeSeriesId + }); + } + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function legendFilter(ecModel) { + var legendModels = ecModel.findComponents({ + mainType: 'legend' + }); + if (legendModels && legendModels.length) { + ecModel.filterSeries(function (series) { + // If in any legend component the status is not selected. + // Because in legend series is assumed selected when it is not in the legend data. + for (var i = 0; i < legendModels.length; i++) { + if (!legendModels[i].isSelected(series.name)) { + return false; + } + } + return true; + }); + } + } + + function legendSelectActionHandler(methodName, payload, ecModel) { + var selectedMap = {}; + var isToggleSelect = methodName === 'toggleSelected'; + var isSelected; + // Update all legend components + ecModel.eachComponent('legend', function (legendModel) { + if (isToggleSelect && isSelected != null) { + // Force other legend has same selected status + // Or the first is toggled to true and other are toggled to false + // In the case one legend has some item unSelected in option. And if other legend + // doesn't has the item, they will assume it is selected. + legendModel[isSelected ? 'select' : 'unSelect'](payload.name); + } else if (methodName === 'allSelect' || methodName === 'inverseSelect') { + legendModel[methodName](); + } else { + legendModel[methodName](payload.name); + isSelected = legendModel.isSelected(payload.name); + } + var legendData = legendModel.getData(); + each(legendData, function (model) { + var name = model.get('name'); + // Wrap element + if (name === '\n' || name === '') { + return; + } + var isItemSelected = legendModel.isSelected(name); + if (selectedMap.hasOwnProperty(name)) { + // Unselected if any legend is unselected + selectedMap[name] = selectedMap[name] && isItemSelected; + } else { + selectedMap[name] = isItemSelected; + } + }); + }); + // Return the event explicitly + return methodName === 'allSelect' || methodName === 'inverseSelect' ? { + selected: selectedMap + } : { + name: payload.name, + selected: selectedMap + }; + } + function installLegendAction(registers) { + /** + * @event legendToggleSelect + * @type {Object} + * @property {string} type 'legendToggleSelect' + * @property {string} [from] + * @property {string} name Series name or data item name + */ + registers.registerAction('legendToggleSelect', 'legendselectchanged', curry(legendSelectActionHandler, 'toggleSelected')); + registers.registerAction('legendAllSelect', 'legendselectall', curry(legendSelectActionHandler, 'allSelect')); + registers.registerAction('legendInverseSelect', 'legendinverseselect', curry(legendSelectActionHandler, 'inverseSelect')); + /** + * @event legendSelect + * @type {Object} + * @property {string} type 'legendSelect' + * @property {string} name Series name or data item name + */ + registers.registerAction('legendSelect', 'legendselected', curry(legendSelectActionHandler, 'select')); + /** + * @event legendUnSelect + * @type {Object} + * @property {string} type 'legendUnSelect' + * @property {string} name Series name or data item name + */ + registers.registerAction('legendUnSelect', 'legendunselected', curry(legendSelectActionHandler, 'unSelect')); + } + + function install$H(registers) { + registers.registerComponentModel(LegendModel); + registers.registerComponentView(LegendView); + registers.registerProcessor(registers.PRIORITY.PROCESSOR.SERIES_FILTER, legendFilter); + registers.registerSubTypeDefaulter('legend', function () { + return 'plain'; + }); + installLegendAction(registers); + } + + var ScrollableLegendModel = /** @class */function (_super) { + __extends(ScrollableLegendModel, _super); + function ScrollableLegendModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ScrollableLegendModel.type; + return _this; + } + /** + * @param {number} scrollDataIndex + */ + ScrollableLegendModel.prototype.setScrollDataIndex = function (scrollDataIndex) { + this.option.scrollDataIndex = scrollDataIndex; + }; + ScrollableLegendModel.prototype.init = function (option, parentModel, ecModel) { + var inputPositionParams = getLayoutParams(option); + _super.prototype.init.call(this, option, parentModel, ecModel); + mergeAndNormalizeLayoutParams$1(this, option, inputPositionParams); + }; + /** + * @override + */ + ScrollableLegendModel.prototype.mergeOption = function (option, ecModel) { + _super.prototype.mergeOption.call(this, option, ecModel); + mergeAndNormalizeLayoutParams$1(this, this.option, option); + }; + ScrollableLegendModel.type = 'legend.scroll'; + ScrollableLegendModel.defaultOption = inheritDefaultOption(LegendModel.defaultOption, { + scrollDataIndex: 0, + pageButtonItemGap: 5, + pageButtonGap: null, + pageButtonPosition: 'end', + pageFormatter: '{current}/{total}', + pageIcons: { + horizontal: ['M0,0L12,-10L12,10z', 'M0,0L-12,-10L-12,10z'], + vertical: ['M0,0L20,0L10,-20z', 'M0,0L20,0L10,20z'] + }, + pageIconColor: '#2f4554', + pageIconInactiveColor: '#aaa', + pageIconSize: 15, + pageTextStyle: { + color: '#333' + }, + animationDurationUpdate: 800 + }); + return ScrollableLegendModel; + }(LegendModel); + // Do not `ignoreSize` to enable setting {left: 10, right: 10}. + function mergeAndNormalizeLayoutParams$1(legendModel, target, raw) { + var orient = legendModel.getOrient(); + var ignoreSize = [1, 1]; + ignoreSize[orient.index] = 0; + mergeLayoutParam(target, raw, { + type: 'box', + ignoreSize: !!ignoreSize + }); + } + + var Group$3 = Group; + var WH$1 = ['width', 'height']; + var XY$1 = ['x', 'y']; + var ScrollableLegendView = /** @class */function (_super) { + __extends(ScrollableLegendView, _super); + function ScrollableLegendView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ScrollableLegendView.type; + _this.newlineDisabled = true; + _this._currentIndex = 0; + return _this; + } + ScrollableLegendView.prototype.init = function () { + _super.prototype.init.call(this); + this.group.add(this._containerGroup = new Group$3()); + this._containerGroup.add(this.getContentGroup()); + this.group.add(this._controllerGroup = new Group$3()); + }; + /** + * @override + */ + ScrollableLegendView.prototype.resetInner = function () { + _super.prototype.resetInner.call(this); + this._controllerGroup.removeAll(); + this._containerGroup.removeClipPath(); + this._containerGroup.__rectSize = null; + }; + /** + * @override + */ + ScrollableLegendView.prototype.renderInner = function (itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition) { + var self = this; + // Render content items. + _super.prototype.renderInner.call(this, itemAlign, legendModel, ecModel, api, selector, orient, selectorPosition); + var controllerGroup = this._controllerGroup; + // FIXME: support be 'auto' adapt to size number text length, + // e.g., '3/12345' should not overlap with the control arrow button. + var pageIconSize = legendModel.get('pageIconSize', true); + var pageIconSizeArr = isArray(pageIconSize) ? pageIconSize : [pageIconSize, pageIconSize]; + createPageButton('pagePrev', 0); + var pageTextStyleModel = legendModel.getModel('pageTextStyle'); + controllerGroup.add(new ZRText({ + name: 'pageText', + style: { + // Placeholder to calculate a proper layout. + text: 'xx/xx', + fill: pageTextStyleModel.getTextColor(), + font: pageTextStyleModel.getFont(), + verticalAlign: 'middle', + align: 'center' + }, + silent: true + })); + createPageButton('pageNext', 1); + function createPageButton(name, iconIdx) { + var pageDataIndexName = name + 'DataIndex'; + var icon = createIcon(legendModel.get('pageIcons', true)[legendModel.getOrient().name][iconIdx], { + // Buttons will be created in each render, so we do not need + // to worry about avoiding using legendModel kept in scope. + onclick: bind(self._pageGo, self, pageDataIndexName, legendModel, api) + }, { + x: -pageIconSizeArr[0] / 2, + y: -pageIconSizeArr[1] / 2, + width: pageIconSizeArr[0], + height: pageIconSizeArr[1] + }); + icon.name = name; + controllerGroup.add(icon); + } + }; + /** + * @override + */ + ScrollableLegendView.prototype.layoutInner = function (legendModel, itemAlign, maxSize, isFirstRender, selector, selectorPosition) { + var selectorGroup = this.getSelectorGroup(); + var orientIdx = legendModel.getOrient().index; + var wh = WH$1[orientIdx]; + var xy = XY$1[orientIdx]; + var hw = WH$1[1 - orientIdx]; + var yx = XY$1[1 - orientIdx]; + selector && box( + // Buttons in selectorGroup always layout horizontally + 'horizontal', selectorGroup, legendModel.get('selectorItemGap', true)); + var selectorButtonGap = legendModel.get('selectorButtonGap', true); + var selectorRect = selectorGroup.getBoundingRect(); + var selectorPos = [-selectorRect.x, -selectorRect.y]; + var processMaxSize = clone(maxSize); + selector && (processMaxSize[wh] = maxSize[wh] - selectorRect[wh] - selectorButtonGap); + var mainRect = this._layoutContentAndController(legendModel, isFirstRender, processMaxSize, orientIdx, wh, hw, yx, xy); + if (selector) { + if (selectorPosition === 'end') { + selectorPos[orientIdx] += mainRect[wh] + selectorButtonGap; + } else { + var offset = selectorRect[wh] + selectorButtonGap; + selectorPos[orientIdx] -= offset; + mainRect[xy] -= offset; + } + mainRect[wh] += selectorRect[wh] + selectorButtonGap; + selectorPos[1 - orientIdx] += mainRect[yx] + mainRect[hw] / 2 - selectorRect[hw] / 2; + mainRect[hw] = Math.max(mainRect[hw], selectorRect[hw]); + mainRect[yx] = Math.min(mainRect[yx], selectorRect[yx] + selectorPos[1 - orientIdx]); + selectorGroup.x = selectorPos[0]; + selectorGroup.y = selectorPos[1]; + selectorGroup.markRedraw(); + } + return mainRect; + }; + ScrollableLegendView.prototype._layoutContentAndController = function (legendModel, isFirstRender, maxSize, orientIdx, wh, hw, yx, xy) { + var contentGroup = this.getContentGroup(); + var containerGroup = this._containerGroup; + var controllerGroup = this._controllerGroup; + // Place items in contentGroup. + box(legendModel.get('orient'), contentGroup, legendModel.get('itemGap'), !orientIdx ? null : maxSize.width, orientIdx ? null : maxSize.height); + box( + // Buttons in controller are layout always horizontally. + 'horizontal', controllerGroup, legendModel.get('pageButtonItemGap', true)); + var contentRect = contentGroup.getBoundingRect(); + var controllerRect = controllerGroup.getBoundingRect(); + var showController = this._showController = contentRect[wh] > maxSize[wh]; + // In case that the inner elements of contentGroup layout do not based on [0, 0] + var contentPos = [-contentRect.x, -contentRect.y]; + // Remain contentPos when scroll animation perfroming. + // If first rendering, `contentGroup.position` is [0, 0], which + // does not make sense and may cause unexepcted animation if adopted. + if (!isFirstRender) { + contentPos[orientIdx] = contentGroup[xy]; + } + // Layout container group based on 0. + var containerPos = [0, 0]; + var controllerPos = [-controllerRect.x, -controllerRect.y]; + var pageButtonGap = retrieve2(legendModel.get('pageButtonGap', true), legendModel.get('itemGap', true)); + // Place containerGroup and controllerGroup and contentGroup. + if (showController) { + var pageButtonPosition = legendModel.get('pageButtonPosition', true); + // controller is on the right / bottom. + if (pageButtonPosition === 'end') { + controllerPos[orientIdx] += maxSize[wh] - controllerRect[wh]; + } + // controller is on the left / top. + else { + containerPos[orientIdx] += controllerRect[wh] + pageButtonGap; + } + } + // Always align controller to content as 'middle'. + controllerPos[1 - orientIdx] += contentRect[hw] / 2 - controllerRect[hw] / 2; + contentGroup.setPosition(contentPos); + containerGroup.setPosition(containerPos); + controllerGroup.setPosition(controllerPos); + // Calculate `mainRect` and set `clipPath`. + // mainRect should not be calculated by `this.group.getBoundingRect()` + // for sake of the overflow. + var mainRect = { + x: 0, + y: 0 + }; + // Consider content may be overflow (should be clipped). + mainRect[wh] = showController ? maxSize[wh] : contentRect[wh]; + mainRect[hw] = Math.max(contentRect[hw], controllerRect[hw]); + // `containerRect[yx] + containerPos[1 - orientIdx]` is 0. + mainRect[yx] = Math.min(0, controllerRect[yx] + controllerPos[1 - orientIdx]); + containerGroup.__rectSize = maxSize[wh]; + if (showController) { + var clipShape = { + x: 0, + y: 0 + }; + clipShape[wh] = Math.max(maxSize[wh] - controllerRect[wh] - pageButtonGap, 0); + clipShape[hw] = mainRect[hw]; + containerGroup.setClipPath(new Rect({ + shape: clipShape + })); + // Consider content may be larger than container, container rect + // can not be obtained from `containerGroup.getBoundingRect()`. + containerGroup.__rectSize = clipShape[wh]; + } else { + // Do not remove or ignore controller. Keep them set as placeholders. + controllerGroup.eachChild(function (child) { + child.attr({ + invisible: true, + silent: true + }); + }); + } + // Content translate animation. + var pageInfo = this._getPageInfo(legendModel); + pageInfo.pageIndex != null && updateProps(contentGroup, { + x: pageInfo.contentPosition[0], + y: pageInfo.contentPosition[1] + }, + // When switch from "show controller" to "not show controller", view should be + // updated immediately without animation, otherwise causes weird effect. + showController ? legendModel : null); + this._updatePageInfoView(legendModel, pageInfo); + return mainRect; + }; + ScrollableLegendView.prototype._pageGo = function (to, legendModel, api) { + var scrollDataIndex = this._getPageInfo(legendModel)[to]; + scrollDataIndex != null && api.dispatchAction({ + type: 'legendScroll', + scrollDataIndex: scrollDataIndex, + legendId: legendModel.id + }); + }; + ScrollableLegendView.prototype._updatePageInfoView = function (legendModel, pageInfo) { + var controllerGroup = this._controllerGroup; + each(['pagePrev', 'pageNext'], function (name) { + var key = name + 'DataIndex'; + var canJump = pageInfo[key] != null; + var icon = controllerGroup.childOfName(name); + if (icon) { + icon.setStyle('fill', canJump ? legendModel.get('pageIconColor', true) : legendModel.get('pageIconInactiveColor', true)); + icon.cursor = canJump ? 'pointer' : 'default'; + } + }); + var pageText = controllerGroup.childOfName('pageText'); + var pageFormatter = legendModel.get('pageFormatter'); + var pageIndex = pageInfo.pageIndex; + var current = pageIndex != null ? pageIndex + 1 : 0; + var total = pageInfo.pageCount; + pageText && pageFormatter && pageText.setStyle('text', isString(pageFormatter) ? pageFormatter.replace('{current}', current == null ? '' : current + '').replace('{total}', total == null ? '' : total + '') : pageFormatter({ + current: current, + total: total + })); + }; + /** + * contentPosition: Array., null when data item not found. + * pageIndex: number, null when data item not found. + * pageCount: number, always be a number, can be 0. + * pagePrevDataIndex: number, null when no previous page. + * pageNextDataIndex: number, null when no next page. + * } + */ + ScrollableLegendView.prototype._getPageInfo = function (legendModel) { + var scrollDataIndex = legendModel.get('scrollDataIndex', true); + var contentGroup = this.getContentGroup(); + var containerRectSize = this._containerGroup.__rectSize; + var orientIdx = legendModel.getOrient().index; + var wh = WH$1[orientIdx]; + var xy = XY$1[orientIdx]; + var targetItemIndex = this._findTargetItemIndex(scrollDataIndex); + var children = contentGroup.children(); + var targetItem = children[targetItemIndex]; + var itemCount = children.length; + var pCount = !itemCount ? 0 : 1; + var result = { + contentPosition: [contentGroup.x, contentGroup.y], + pageCount: pCount, + pageIndex: pCount - 1, + pagePrevDataIndex: null, + pageNextDataIndex: null + }; + if (!targetItem) { + return result; + } + var targetItemInfo = getItemInfo(targetItem); + result.contentPosition[orientIdx] = -targetItemInfo.s; + // Strategy: + // (1) Always align based on the left/top most item. + // (2) It is user-friendly that the last item shown in the + // current window is shown at the begining of next window. + // Otherwise if half of the last item is cut by the window, + // it will have no chance to display entirely. + // (3) Consider that item size probably be different, we + // have calculate pageIndex by size rather than item index, + // and we can not get page index directly by division. + // (4) The window is to narrow to contain more than + // one item, we should make sure that the page can be fliped. + for (var i = targetItemIndex + 1, winStartItemInfo = targetItemInfo, winEndItemInfo = targetItemInfo, currItemInfo = null; i <= itemCount; ++i) { + currItemInfo = getItemInfo(children[i]); + if ( + // Half of the last item is out of the window. + !currItemInfo && winEndItemInfo.e > winStartItemInfo.s + containerRectSize + // If the current item does not intersect with the window, the new page + // can be started at the current item or the last item. + || currItemInfo && !intersect(currItemInfo, winStartItemInfo.s)) { + if (winEndItemInfo.i > winStartItemInfo.i) { + winStartItemInfo = winEndItemInfo; + } else { + // e.g., when page size is smaller than item size. + winStartItemInfo = currItemInfo; + } + if (winStartItemInfo) { + if (result.pageNextDataIndex == null) { + result.pageNextDataIndex = winStartItemInfo.i; + } + ++result.pageCount; + } + } + winEndItemInfo = currItemInfo; + } + for (var i = targetItemIndex - 1, winStartItemInfo = targetItemInfo, winEndItemInfo = targetItemInfo, currItemInfo = null; i >= -1; --i) { + currItemInfo = getItemInfo(children[i]); + if ( + // If the the end item does not intersect with the window started + // from the current item, a page can be settled. + (!currItemInfo || !intersect(winEndItemInfo, currItemInfo.s) + // e.g., when page size is smaller than item size. + ) && winStartItemInfo.i < winEndItemInfo.i) { + winEndItemInfo = winStartItemInfo; + if (result.pagePrevDataIndex == null) { + result.pagePrevDataIndex = winStartItemInfo.i; + } + ++result.pageCount; + ++result.pageIndex; + } + winStartItemInfo = currItemInfo; + } + return result; + function getItemInfo(el) { + if (el) { + var itemRect = el.getBoundingRect(); + var start = itemRect[xy] + el[xy]; + return { + s: start, + e: start + itemRect[wh], + i: el.__legendDataIndex + }; + } + } + function intersect(itemInfo, winStart) { + return itemInfo.e >= winStart && itemInfo.s <= winStart + containerRectSize; + } + }; + ScrollableLegendView.prototype._findTargetItemIndex = function (targetDataIndex) { + if (!this._showController) { + return 0; + } + var index; + var contentGroup = this.getContentGroup(); + var defaultIndex; + contentGroup.eachChild(function (child, idx) { + var legendDataIdx = child.__legendDataIndex; + // FIXME + // If the given targetDataIndex (from model) is illegal, + // we use defaultIndex. But the index on the legend model and + // action payload is still illegal. That case will not be + // changed until some scenario requires. + if (defaultIndex == null && legendDataIdx != null) { + defaultIndex = idx; + } + if (legendDataIdx === targetDataIndex) { + index = idx; + } + }); + return index != null ? index : defaultIndex; + }; + ScrollableLegendView.type = 'legend.scroll'; + return ScrollableLegendView; + }(LegendView); + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + function installScrollableLegendAction(registers) { + /** + * @event legendScroll + * @type {Object} + * @property {string} type 'legendScroll' + * @property {string} scrollDataIndex + */ + registers.registerAction('legendScroll', 'legendscroll', function (payload, ecModel) { + var scrollDataIndex = payload.scrollDataIndex; + scrollDataIndex != null && ecModel.eachComponent({ + mainType: 'legend', + subType: 'scroll', + query: payload + }, function (legendModel) { + legendModel.setScrollDataIndex(scrollDataIndex); + }); + }); + } + + function install$I(registers) { + use(install$H); + registers.registerComponentModel(ScrollableLegendModel); + registers.registerComponentView(ScrollableLegendView); + installScrollableLegendAction(registers); + } + + function install$J(registers) { + use(install$H); + use(install$I); + } + + var InsideZoomModel = /** @class */function (_super) { + __extends(InsideZoomModel, _super); + function InsideZoomModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = InsideZoomModel.type; + return _this; + } + InsideZoomModel.type = 'dataZoom.inside'; + InsideZoomModel.defaultOption = inheritDefaultOption(DataZoomModel.defaultOption, { + disabled: false, + zoomLock: false, + zoomOnMouseWheel: true, + moveOnMouseMove: true, + moveOnMouseWheel: false, + preventDefaultMouseMove: true + }); + return InsideZoomModel; + }(DataZoomModel); + + var inner$k = makeInner(); + function setViewInfoToCoordSysRecord(api, dataZoomModel, getRange) { + inner$k(api).coordSysRecordMap.each(function (coordSysRecord) { + var dzInfo = coordSysRecord.dataZoomInfoMap.get(dataZoomModel.uid); + if (dzInfo) { + dzInfo.getRange = getRange; + } + }); + } + function disposeCoordSysRecordIfNeeded(api, dataZoomModel) { + var coordSysRecordMap = inner$k(api).coordSysRecordMap; + var coordSysKeyArr = coordSysRecordMap.keys(); + for (var i = 0; i < coordSysKeyArr.length; i++) { + var coordSysKey = coordSysKeyArr[i]; + var coordSysRecord = coordSysRecordMap.get(coordSysKey); + var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap; + if (dataZoomInfoMap) { + var dzUid = dataZoomModel.uid; + var dzInfo = dataZoomInfoMap.get(dzUid); + if (dzInfo) { + dataZoomInfoMap.removeKey(dzUid); + if (!dataZoomInfoMap.keys().length) { + disposeCoordSysRecord(coordSysRecordMap, coordSysRecord); + } + } + } + } + } + function disposeCoordSysRecord(coordSysRecordMap, coordSysRecord) { + if (coordSysRecord) { + coordSysRecordMap.removeKey(coordSysRecord.model.uid); + var controller = coordSysRecord.controller; + controller && controller.dispose(); + } + } + function createCoordSysRecord(api, coordSysModel) { + // These init props will never change after record created. + var coordSysRecord = { + model: coordSysModel, + containsPoint: curry(containsPoint, coordSysModel), + dispatchAction: curry(dispatchAction$1, api), + dataZoomInfoMap: null, + controller: null + }; + // Must not do anything depends on coordSysRecord outside the event handler here, + // because coordSysRecord not completed yet. + var controller = coordSysRecord.controller = new RoamController(api.getZr()); + each(['pan', 'zoom', 'scrollMove'], function (eventName) { + controller.on(eventName, function (event) { + var batch = []; + coordSysRecord.dataZoomInfoMap.each(function (dzInfo) { + // Check whether the behaviors (zoomOnMouseWheel, moveOnMouseMove, + // moveOnMouseWheel, ...) enabled. + if (!event.isAvailableBehavior(dzInfo.model.option)) { + return; + } + var method = (dzInfo.getRange || {})[eventName]; + var range = method && method(dzInfo.dzReferCoordSysInfo, coordSysRecord.model.mainType, coordSysRecord.controller, event); + !dzInfo.model.get('disabled', true) && range && batch.push({ + dataZoomId: dzInfo.model.id, + start: range[0], + end: range[1] + }); + }); + batch.length && coordSysRecord.dispatchAction(batch); + }); + }); + return coordSysRecord; + } + /** + * This action will be throttled. + */ + function dispatchAction$1(api, batch) { + if (!api.isDisposed()) { + api.dispatchAction({ + type: 'dataZoom', + animation: { + easing: 'cubicOut', + duration: 100 + }, + batch: batch + }); + } + } + function containsPoint(coordSysModel, e, x, y) { + return coordSysModel.coordinateSystem.containPoint([x, y]); + } + /** + * Merge roamController settings when multiple dataZooms share one roamController. + */ + function mergeControllerParams(dataZoomInfoMap) { + var controlType; + // DO NOT use reserved word (true, false, undefined) as key literally. Even if encapsulated + // as string, it is probably revert to reserved word by compress tool. See #7411. + var prefix = 'type_'; + var typePriority = { + 'type_true': 2, + 'type_move': 1, + 'type_false': 0, + 'type_undefined': -1 + }; + var preventDefaultMouseMove = true; + dataZoomInfoMap.each(function (dataZoomInfo) { + var dataZoomModel = dataZoomInfo.model; + var oneType = dataZoomModel.get('disabled', true) ? false : dataZoomModel.get('zoomLock', true) ? 'move' : true; + if (typePriority[prefix + oneType] > typePriority[prefix + controlType]) { + controlType = oneType; + } + // Prevent default move event by default. If one false, do not prevent. Otherwise + // users may be confused why it does not work when multiple insideZooms exist. + preventDefaultMouseMove = preventDefaultMouseMove && dataZoomModel.get('preventDefaultMouseMove', true); + }); + return { + controlType: controlType, + opt: { + // RoamController will enable all of these functionalities, + // and the final behavior is determined by its event listener + // provided by each inside zoom. + zoomOnMouseWheel: true, + moveOnMouseMove: true, + moveOnMouseWheel: true, + preventDefaultMouseMove: !!preventDefaultMouseMove + } + }; + } + function installDataZoomRoamProcessor(registers) { + registers.registerProcessor(registers.PRIORITY.PROCESSOR.FILTER, function (ecModel, api) { + var apiInner = inner$k(api); + var coordSysRecordMap = apiInner.coordSysRecordMap || (apiInner.coordSysRecordMap = createHashMap()); + coordSysRecordMap.each(function (coordSysRecord) { + // `coordSysRecordMap` always exists (because it holds the `roam controller`, which should + // better not re-create each time), but clear `dataZoomInfoMap` each round of the workflow. + coordSysRecord.dataZoomInfoMap = null; + }); + ecModel.eachComponent({ + mainType: 'dataZoom', + subType: 'inside' + }, function (dataZoomModel) { + var dzReferCoordSysWrap = collectReferCoordSysModelInfo(dataZoomModel); + each(dzReferCoordSysWrap.infoList, function (dzCoordSysInfo) { + var coordSysUid = dzCoordSysInfo.model.uid; + var coordSysRecord = coordSysRecordMap.get(coordSysUid) || coordSysRecordMap.set(coordSysUid, createCoordSysRecord(api, dzCoordSysInfo.model)); + var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap || (coordSysRecord.dataZoomInfoMap = createHashMap()); + // Notice these props might be changed each time for a single dataZoomModel. + dataZoomInfoMap.set(dataZoomModel.uid, { + dzReferCoordSysInfo: dzCoordSysInfo, + model: dataZoomModel, + getRange: null + }); + }); + }); + // (1) Merge dataZoom settings for each coord sys and set to the roam controller. + // (2) Clear coord sys if not refered by any dataZoom. + coordSysRecordMap.each(function (coordSysRecord) { + var controller = coordSysRecord.controller; + var firstDzInfo; + var dataZoomInfoMap = coordSysRecord.dataZoomInfoMap; + if (dataZoomInfoMap) { + var firstDzKey = dataZoomInfoMap.keys()[0]; + if (firstDzKey != null) { + firstDzInfo = dataZoomInfoMap.get(firstDzKey); + } + } + if (!firstDzInfo) { + disposeCoordSysRecord(coordSysRecordMap, coordSysRecord); + return; + } + var controllerParams = mergeControllerParams(dataZoomInfoMap); + controller.enable(controllerParams.controlType, controllerParams.opt); + controller.setPointerChecker(coordSysRecord.containsPoint); + createOrUpdate(coordSysRecord, 'dispatchAction', firstDzInfo.model.get('throttle', true), 'fixRate'); + }); + }); + } + + var InsideZoomView = /** @class */function (_super) { + __extends(InsideZoomView, _super); + function InsideZoomView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = 'dataZoom.inside'; + return _this; + } + InsideZoomView.prototype.render = function (dataZoomModel, ecModel, api) { + _super.prototype.render.apply(this, arguments); + if (dataZoomModel.noTarget()) { + this._clear(); + return; + } + // Hence the `throttle` util ensures to preserve command order, + // here simply updating range all the time will not cause missing + // any of the the roam change. + this.range = dataZoomModel.getPercentRange(); + // Reset controllers. + setViewInfoToCoordSysRecord(api, dataZoomModel, { + pan: bind(getRangeHandlers.pan, this), + zoom: bind(getRangeHandlers.zoom, this), + scrollMove: bind(getRangeHandlers.scrollMove, this) + }); + }; + InsideZoomView.prototype.dispose = function () { + this._clear(); + _super.prototype.dispose.apply(this, arguments); + }; + InsideZoomView.prototype._clear = function () { + disposeCoordSysRecordIfNeeded(this.api, this.dataZoomModel); + this.range = null; + }; + InsideZoomView.type = 'dataZoom.inside'; + return InsideZoomView; + }(DataZoomView); + var getRangeHandlers = { + zoom: function (coordSysInfo, coordSysMainType, controller, e) { + var lastRange = this.range; + var range = lastRange.slice(); + // Calculate transform by the first axis. + var axisModel = coordSysInfo.axisModels[0]; + if (!axisModel) { + return; + } + var directionInfo = getDirectionInfo[coordSysMainType](null, [e.originX, e.originY], axisModel, controller, coordSysInfo); + var percentPoint = (directionInfo.signal > 0 ? directionInfo.pixelStart + directionInfo.pixelLength - directionInfo.pixel : directionInfo.pixel - directionInfo.pixelStart) / directionInfo.pixelLength * (range[1] - range[0]) + range[0]; + var scale = Math.max(1 / e.scale, 0); + range[0] = (range[0] - percentPoint) * scale + percentPoint; + range[1] = (range[1] - percentPoint) * scale + percentPoint; + // Restrict range. + var minMaxSpan = this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan(); + sliderMove(0, range, [0, 100], 0, minMaxSpan.minSpan, minMaxSpan.maxSpan); + this.range = range; + if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) { + return range; + } + }, + pan: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) { + var directionInfo = getDirectionInfo[coordSysMainType]([e.oldX, e.oldY], [e.newX, e.newY], axisModel, controller, coordSysInfo); + return directionInfo.signal * (range[1] - range[0]) * directionInfo.pixel / directionInfo.pixelLength; + }), + scrollMove: makeMover(function (range, axisModel, coordSysInfo, coordSysMainType, controller, e) { + var directionInfo = getDirectionInfo[coordSysMainType]([0, 0], [e.scrollDelta, e.scrollDelta], axisModel, controller, coordSysInfo); + return directionInfo.signal * (range[1] - range[0]) * e.scrollDelta; + }) + }; + function makeMover(getPercentDelta) { + return function (coordSysInfo, coordSysMainType, controller, e) { + var lastRange = this.range; + var range = lastRange.slice(); + // Calculate transform by the first axis. + var axisModel = coordSysInfo.axisModels[0]; + if (!axisModel) { + return; + } + var percentDelta = getPercentDelta(range, axisModel, coordSysInfo, coordSysMainType, controller, e); + sliderMove(percentDelta, range, [0, 100], 'all'); + this.range = range; + if (lastRange[0] !== range[0] || lastRange[1] !== range[1]) { + return range; + } + }; + } + var getDirectionInfo = { + grid: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) { + var axis = axisModel.axis; + var ret = {}; + var rect = coordSysInfo.model.coordinateSystem.getRect(); + oldPoint = oldPoint || [0, 0]; + if (axis.dim === 'x') { + ret.pixel = newPoint[0] - oldPoint[0]; + ret.pixelLength = rect.width; + ret.pixelStart = rect.x; + ret.signal = axis.inverse ? 1 : -1; + } else { + // axis.dim === 'y' + ret.pixel = newPoint[1] - oldPoint[1]; + ret.pixelLength = rect.height; + ret.pixelStart = rect.y; + ret.signal = axis.inverse ? -1 : 1; + } + return ret; + }, + polar: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) { + var axis = axisModel.axis; + var ret = {}; + var polar = coordSysInfo.model.coordinateSystem; + var radiusExtent = polar.getRadiusAxis().getExtent(); + var angleExtent = polar.getAngleAxis().getExtent(); + oldPoint = oldPoint ? polar.pointToCoord(oldPoint) : [0, 0]; + newPoint = polar.pointToCoord(newPoint); + if (axisModel.mainType === 'radiusAxis') { + ret.pixel = newPoint[0] - oldPoint[0]; + // ret.pixelLength = Math.abs(radiusExtent[1] - radiusExtent[0]); + // ret.pixelStart = Math.min(radiusExtent[0], radiusExtent[1]); + ret.pixelLength = radiusExtent[1] - radiusExtent[0]; + ret.pixelStart = radiusExtent[0]; + ret.signal = axis.inverse ? 1 : -1; + } else { + // 'angleAxis' + ret.pixel = newPoint[1] - oldPoint[1]; + // ret.pixelLength = Math.abs(angleExtent[1] - angleExtent[0]); + // ret.pixelStart = Math.min(angleExtent[0], angleExtent[1]); + ret.pixelLength = angleExtent[1] - angleExtent[0]; + ret.pixelStart = angleExtent[0]; + ret.signal = axis.inverse ? -1 : 1; + } + return ret; + }, + singleAxis: function (oldPoint, newPoint, axisModel, controller, coordSysInfo) { + var axis = axisModel.axis; + var rect = coordSysInfo.model.coordinateSystem.getRect(); + var ret = {}; + oldPoint = oldPoint || [0, 0]; + if (axis.orient === 'horizontal') { + ret.pixel = newPoint[0] - oldPoint[0]; + ret.pixelLength = rect.width; + ret.pixelStart = rect.x; + ret.signal = axis.inverse ? 1 : -1; + } else { + // 'vertical' + ret.pixel = newPoint[1] - oldPoint[1]; + ret.pixelLength = rect.height; + ret.pixelStart = rect.y; + ret.signal = axis.inverse ? -1 : 1; + } + return ret; + } + }; + + function install$K(registers) { + installCommon(registers); + registers.registerComponentModel(InsideZoomModel); + registers.registerComponentView(InsideZoomView); + installDataZoomRoamProcessor(registers); + } + + var SliderZoomModel = /** @class */function (_super) { + __extends(SliderZoomModel, _super); + function SliderZoomModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SliderZoomModel.type; + return _this; + } + SliderZoomModel.type = 'dataZoom.slider'; + SliderZoomModel.layoutMode = 'box'; + SliderZoomModel.defaultOption = inheritDefaultOption(DataZoomModel.defaultOption, { + show: true, + // deault value can only be drived in view stage. + right: 'ph', + top: 'ph', + width: 'ph', + height: 'ph', + left: null, + bottom: null, + borderColor: '#d2dbee', + borderRadius: 3, + backgroundColor: 'rgba(47,69,84,0)', + // dataBackgroundColor: '#ddd', + dataBackground: { + lineStyle: { + color: '#d2dbee', + width: 0.5 + }, + areaStyle: { + color: '#d2dbee', + opacity: 0.2 + } + }, + selectedDataBackground: { + lineStyle: { + color: '#8fb0f7', + width: 0.5 + }, + areaStyle: { + color: '#8fb0f7', + opacity: 0.2 + } + }, + // Color of selected window. + fillerColor: 'rgba(135,175,274,0.2)', + handleIcon: 'path://M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z', + // Percent of the slider height + handleSize: '100%', + handleStyle: { + color: '#fff', + borderColor: '#ACB8D1' + }, + moveHandleSize: 7, + moveHandleIcon: 'path://M-320.9-50L-320.9-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-348-41-339-50-320.9-50z M-212.3-50L-212.3-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-239.4-41-230.4-50-212.3-50z M-103.7-50L-103.7-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-130.9-41-121.8-50-103.7-50z', + moveHandleStyle: { + color: '#D2DBEE', + opacity: 0.7 + }, + showDetail: true, + showDataShadow: 'auto', + realtime: true, + zoomLock: false, + textStyle: { + color: '#6E7079' + }, + brushSelect: true, + brushStyle: { + color: 'rgba(135,175,274,0.15)' + }, + emphasis: { + handleStyle: { + borderColor: '#8FB0F7' + }, + moveHandleStyle: { + color: '#8FB0F7' + } + } + }); + return SliderZoomModel; + }(DataZoomModel); + + var Rect$2 = Rect; + // Constants + var DEFAULT_LOCATION_EDGE_GAP = 7; + var DEFAULT_FRAME_BORDER_WIDTH = 1; + var DEFAULT_FILLER_SIZE = 30; + var DEFAULT_MOVE_HANDLE_SIZE = 7; + var HORIZONTAL = 'horizontal'; + var VERTICAL = 'vertical'; + var LABEL_GAP = 5; + var SHOW_DATA_SHADOW_SERIES_TYPE = ['line', 'bar', 'candlestick', 'scatter']; + var REALTIME_ANIMATION_CONFIG = { + easing: 'cubicOut', + duration: 100, + delay: 0 + }; + var SliderZoomView = /** @class */function (_super) { + __extends(SliderZoomView, _super); + function SliderZoomView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = SliderZoomView.type; + _this._displayables = {}; + return _this; + } + SliderZoomView.prototype.init = function (ecModel, api) { + this.api = api; + // A unique handler for each dataZoom component + this._onBrush = bind(this._onBrush, this); + this._onBrushEnd = bind(this._onBrushEnd, this); + }; + SliderZoomView.prototype.render = function (dataZoomModel, ecModel, api, payload) { + _super.prototype.render.apply(this, arguments); + createOrUpdate(this, '_dispatchZoomAction', dataZoomModel.get('throttle'), 'fixRate'); + this._orient = dataZoomModel.getOrient(); + if (dataZoomModel.get('show') === false) { + this.group.removeAll(); + return; + } + if (dataZoomModel.noTarget()) { + this._clear(); + this.group.removeAll(); + return; + } + // Notice: this._resetInterval() should not be executed when payload.type + // is 'dataZoom', origin this._range should be maintained, otherwise 'pan' + // or 'zoom' info will be missed because of 'throttle' of this.dispatchAction, + if (!payload || payload.type !== 'dataZoom' || payload.from !== this.uid) { + this._buildView(); + } + this._updateView(); + }; + SliderZoomView.prototype.dispose = function () { + this._clear(); + _super.prototype.dispose.apply(this, arguments); + }; + SliderZoomView.prototype._clear = function () { + clear(this, '_dispatchZoomAction'); + var zr = this.api.getZr(); + zr.off('mousemove', this._onBrush); + zr.off('mouseup', this._onBrushEnd); + }; + SliderZoomView.prototype._buildView = function () { + var thisGroup = this.group; + thisGroup.removeAll(); + this._brushing = false; + this._displayables.brushRect = null; + this._resetLocation(); + this._resetInterval(); + var barGroup = this._displayables.sliderGroup = new Group(); + this._renderBackground(); + this._renderHandle(); + this._renderDataShadow(); + thisGroup.add(barGroup); + this._positionGroup(); + }; + SliderZoomView.prototype._resetLocation = function () { + var dataZoomModel = this.dataZoomModel; + var api = this.api; + var showMoveHandle = dataZoomModel.get('brushSelect'); + var moveHandleSize = showMoveHandle ? DEFAULT_MOVE_HANDLE_SIZE : 0; + // If some of x/y/width/height are not specified, + // auto-adapt according to target grid. + var coordRect = this._findCoordRect(); + var ecSize = { + width: api.getWidth(), + height: api.getHeight() + }; + // Default align by coordinate system rect. + var positionInfo = this._orient === HORIZONTAL ? { + // Why using 'right', because right should be used in vertical, + // and it is better to be consistent for dealing with position param merge. + right: ecSize.width - coordRect.x - coordRect.width, + top: ecSize.height - DEFAULT_FILLER_SIZE - DEFAULT_LOCATION_EDGE_GAP - moveHandleSize, + width: coordRect.width, + height: DEFAULT_FILLER_SIZE + } : { + right: DEFAULT_LOCATION_EDGE_GAP, + top: coordRect.y, + width: DEFAULT_FILLER_SIZE, + height: coordRect.height + }; + // Do not write back to option and replace value 'ph', because + // the 'ph' value should be recalculated when resize. + var layoutParams = getLayoutParams(dataZoomModel.option); + // Replace the placeholder value. + each(['right', 'top', 'width', 'height'], function (name) { + if (layoutParams[name] === 'ph') { + layoutParams[name] = positionInfo[name]; + } + }); + var layoutRect = getLayoutRect(layoutParams, ecSize); + this._location = { + x: layoutRect.x, + y: layoutRect.y + }; + this._size = [layoutRect.width, layoutRect.height]; + this._orient === VERTICAL && this._size.reverse(); + }; + SliderZoomView.prototype._positionGroup = function () { + var thisGroup = this.group; + var location = this._location; + var orient = this._orient; + // Just use the first axis to determine mapping. + var targetAxisModel = this.dataZoomModel.getFirstTargetAxisModel(); + var inverse = targetAxisModel && targetAxisModel.get('inverse'); + var sliderGroup = this._displayables.sliderGroup; + var otherAxisInverse = (this._dataShadowInfo || {}).otherAxisInverse; + // Transform barGroup. + sliderGroup.attr(orient === HORIZONTAL && !inverse ? { + scaleY: otherAxisInverse ? 1 : -1, + scaleX: 1 + } : orient === HORIZONTAL && inverse ? { + scaleY: otherAxisInverse ? 1 : -1, + scaleX: -1 + } : orient === VERTICAL && !inverse ? { + scaleY: otherAxisInverse ? -1 : 1, + scaleX: 1, + rotation: Math.PI / 2 + } + // Don't use Math.PI, considering shadow direction. + : { + scaleY: otherAxisInverse ? -1 : 1, + scaleX: -1, + rotation: Math.PI / 2 + }); + // Position barGroup + var rect = thisGroup.getBoundingRect([sliderGroup]); + thisGroup.x = location.x - rect.x; + thisGroup.y = location.y - rect.y; + thisGroup.markRedraw(); + }; + SliderZoomView.prototype._getViewExtent = function () { + return [0, this._size[0]]; + }; + SliderZoomView.prototype._renderBackground = function () { + var dataZoomModel = this.dataZoomModel; + var size = this._size; + var barGroup = this._displayables.sliderGroup; + var brushSelect = dataZoomModel.get('brushSelect'); + barGroup.add(new Rect$2({ + silent: true, + shape: { + x: 0, + y: 0, + width: size[0], + height: size[1] + }, + style: { + fill: dataZoomModel.get('backgroundColor') + }, + z2: -40 + })); + // Click panel, over shadow, below handles. + var clickPanel = new Rect$2({ + shape: { + x: 0, + y: 0, + width: size[0], + height: size[1] + }, + style: { + fill: 'transparent' + }, + z2: 0, + onclick: bind(this._onClickPanel, this) + }); + var zr = this.api.getZr(); + if (brushSelect) { + clickPanel.on('mousedown', this._onBrushStart, this); + clickPanel.cursor = 'crosshair'; + zr.on('mousemove', this._onBrush); + zr.on('mouseup', this._onBrushEnd); + } else { + zr.off('mousemove', this._onBrush); + zr.off('mouseup', this._onBrushEnd); + } + barGroup.add(clickPanel); + }; + SliderZoomView.prototype._renderDataShadow = function () { + var info = this._dataShadowInfo = this._prepareDataShadowInfo(); + this._displayables.dataShadowSegs = []; + if (!info) { + return; + } + var size = this._size; + var oldSize = this._shadowSize || []; + var seriesModel = info.series; + var data = seriesModel.getRawData(); + var candlestickDim = seriesModel.getShadowDim && seriesModel.getShadowDim(); + var otherDim = candlestickDim && data.getDimensionInfo(candlestickDim) ? seriesModel.getShadowDim() // @see candlestick + : info.otherDim; + if (otherDim == null) { + return; + } + var polygonPts = this._shadowPolygonPts; + var polylinePts = this._shadowPolylinePts; + // Not re-render if data doesn't change. + if (data !== this._shadowData || otherDim !== this._shadowDim || size[0] !== oldSize[0] || size[1] !== oldSize[1]) { + var otherDataExtent_1 = data.getDataExtent(otherDim); + // Nice extent. + var otherOffset = (otherDataExtent_1[1] - otherDataExtent_1[0]) * 0.3; + otherDataExtent_1 = [otherDataExtent_1[0] - otherOffset, otherDataExtent_1[1] + otherOffset]; + var otherShadowExtent_1 = [0, size[1]]; + var thisShadowExtent = [0, size[0]]; + var areaPoints_1 = [[size[0], 0], [0, 0]]; + var linePoints_1 = []; + var step_1 = thisShadowExtent[1] / (data.count() - 1); + var thisCoord_1 = 0; + // Optimize for large data shadow + var stride_1 = Math.round(data.count() / size[0]); + var lastIsEmpty_1; + data.each([otherDim], function (value, index) { + if (stride_1 > 0 && index % stride_1) { + thisCoord_1 += step_1; + return; + } + // FIXME + // Should consider axis.min/axis.max when drawing dataShadow. + // FIXME + // 应该使用统一的空判断?还是在list里进行空判断? + var isEmpty = value == null || isNaN(value) || value === ''; + // See #4235. + var otherCoord = isEmpty ? 0 : linearMap(value, otherDataExtent_1, otherShadowExtent_1, true); + // Attempt to draw data shadow precisely when there are empty value. + if (isEmpty && !lastIsEmpty_1 && index) { + areaPoints_1.push([areaPoints_1[areaPoints_1.length - 1][0], 0]); + linePoints_1.push([linePoints_1[linePoints_1.length - 1][0], 0]); + } else if (!isEmpty && lastIsEmpty_1) { + areaPoints_1.push([thisCoord_1, 0]); + linePoints_1.push([thisCoord_1, 0]); + } + areaPoints_1.push([thisCoord_1, otherCoord]); + linePoints_1.push([thisCoord_1, otherCoord]); + thisCoord_1 += step_1; + lastIsEmpty_1 = isEmpty; + }); + polygonPts = this._shadowPolygonPts = areaPoints_1; + polylinePts = this._shadowPolylinePts = linePoints_1; + } + this._shadowData = data; + this._shadowDim = otherDim; + this._shadowSize = [size[0], size[1]]; + var dataZoomModel = this.dataZoomModel; + function createDataShadowGroup(isSelectedArea) { + var model = dataZoomModel.getModel(isSelectedArea ? 'selectedDataBackground' : 'dataBackground'); + var group = new Group(); + var polygon = new Polygon({ + shape: { + points: polygonPts + }, + segmentIgnoreThreshold: 1, + style: model.getModel('areaStyle').getAreaStyle(), + silent: true, + z2: -20 + }); + var polyline = new Polyline({ + shape: { + points: polylinePts + }, + segmentIgnoreThreshold: 1, + style: model.getModel('lineStyle').getLineStyle(), + silent: true, + z2: -19 + }); + group.add(polygon); + group.add(polyline); + return group; + } + // let dataBackgroundModel = dataZoomModel.getModel('dataBackground'); + for (var i = 0; i < 3; i++) { + var group = createDataShadowGroup(i === 1); + this._displayables.sliderGroup.add(group); + this._displayables.dataShadowSegs.push(group); + } + }; + SliderZoomView.prototype._prepareDataShadowInfo = function () { + var dataZoomModel = this.dataZoomModel; + var showDataShadow = dataZoomModel.get('showDataShadow'); + if (showDataShadow === false) { + return; + } + // Find a representative series. + var result; + var ecModel = this.ecModel; + dataZoomModel.eachTargetAxis(function (axisDim, axisIndex) { + var seriesModels = dataZoomModel.getAxisProxy(axisDim, axisIndex).getTargetSeriesModels(); + each(seriesModels, function (seriesModel) { + if (result) { + return; + } + if (showDataShadow !== true && indexOf(SHOW_DATA_SHADOW_SERIES_TYPE, seriesModel.get('type')) < 0) { + return; + } + var thisAxis = ecModel.getComponent(getAxisMainType(axisDim), axisIndex).axis; + var otherDim = getOtherDim(axisDim); + var otherAxisInverse; + var coordSys = seriesModel.coordinateSystem; + if (otherDim != null && coordSys.getOtherAxis) { + otherAxisInverse = coordSys.getOtherAxis(thisAxis).inverse; + } + otherDim = seriesModel.getData().mapDimension(otherDim); + result = { + thisAxis: thisAxis, + series: seriesModel, + thisDim: axisDim, + otherDim: otherDim, + otherAxisInverse: otherAxisInverse + }; + }, this); + }, this); + return result; + }; + SliderZoomView.prototype._renderHandle = function () { + var thisGroup = this.group; + var displayables = this._displayables; + var handles = displayables.handles = [null, null]; + var handleLabels = displayables.handleLabels = [null, null]; + var sliderGroup = this._displayables.sliderGroup; + var size = this._size; + var dataZoomModel = this.dataZoomModel; + var api = this.api; + var borderRadius = dataZoomModel.get('borderRadius') || 0; + var brushSelect = dataZoomModel.get('brushSelect'); + var filler = displayables.filler = new Rect$2({ + silent: brushSelect, + style: { + fill: dataZoomModel.get('fillerColor') + }, + textConfig: { + position: 'inside' + } + }); + sliderGroup.add(filler); + // Frame border. + sliderGroup.add(new Rect$2({ + silent: true, + subPixelOptimize: true, + shape: { + x: 0, + y: 0, + width: size[0], + height: size[1], + r: borderRadius + }, + style: { + // deprecated option + stroke: dataZoomModel.get('dataBackgroundColor') || dataZoomModel.get('borderColor'), + lineWidth: DEFAULT_FRAME_BORDER_WIDTH, + fill: 'rgba(0,0,0,0)' + } + })); + // Left and right handle to resize + each([0, 1], function (handleIndex) { + var iconStr = dataZoomModel.get('handleIcon'); + if (!symbolBuildProxies[iconStr] && iconStr.indexOf('path://') < 0 && iconStr.indexOf('image://') < 0) { + // Compatitable with the old icon parsers. Which can use a path string without path:// + iconStr = 'path://' + iconStr; + if ("development" !== 'production') { + deprecateLog('handleIcon now needs \'path://\' prefix when using a path string'); + } + } + var path = createSymbol(iconStr, -1, 0, 2, 2, null, true); + path.attr({ + cursor: getCursor(this._orient), + draggable: true, + drift: bind(this._onDragMove, this, handleIndex), + ondragend: bind(this._onDragEnd, this), + onmouseover: bind(this._showDataInfo, this, true), + onmouseout: bind(this._showDataInfo, this, false), + z2: 5 + }); + var bRect = path.getBoundingRect(); + var handleSize = dataZoomModel.get('handleSize'); + this._handleHeight = parsePercent$1(handleSize, this._size[1]); + this._handleWidth = bRect.width / bRect.height * this._handleHeight; + path.setStyle(dataZoomModel.getModel('handleStyle').getItemStyle()); + path.style.strokeNoScale = true; + path.rectHover = true; + path.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'handleStyle']).getItemStyle(); + enableHoverEmphasis(path); + var handleColor = dataZoomModel.get('handleColor'); // deprecated option + // Compatitable with previous version + if (handleColor != null) { + path.style.fill = handleColor; + } + sliderGroup.add(handles[handleIndex] = path); + var textStyleModel = dataZoomModel.getModel('textStyle'); + thisGroup.add(handleLabels[handleIndex] = new ZRText({ + silent: true, + invisible: true, + style: createTextStyle(textStyleModel, { + x: 0, + y: 0, + text: '', + verticalAlign: 'middle', + align: 'center', + fill: textStyleModel.getTextColor(), + font: textStyleModel.getFont() + }), + z2: 10 + })); + }, this); + // Handle to move. Only visible when brushSelect is set true. + var actualMoveZone = filler; + if (brushSelect) { + var moveHandleHeight = parsePercent$1(dataZoomModel.get('moveHandleSize'), size[1]); + var moveHandle_1 = displayables.moveHandle = new Rect({ + style: dataZoomModel.getModel('moveHandleStyle').getItemStyle(), + silent: true, + shape: { + r: [0, 0, 2, 2], + y: size[1] - 0.5, + height: moveHandleHeight + } + }); + var iconSize = moveHandleHeight * 0.8; + var moveHandleIcon = displayables.moveHandleIcon = createSymbol(dataZoomModel.get('moveHandleIcon'), -iconSize / 2, -iconSize / 2, iconSize, iconSize, '#fff', true); + moveHandleIcon.silent = true; + moveHandleIcon.y = size[1] + moveHandleHeight / 2 - 0.5; + moveHandle_1.ensureState('emphasis').style = dataZoomModel.getModel(['emphasis', 'moveHandleStyle']).getItemStyle(); + var moveZoneExpandSize = Math.min(size[1] / 2, Math.max(moveHandleHeight, 10)); + actualMoveZone = displayables.moveZone = new Rect({ + invisible: true, + shape: { + y: size[1] - moveZoneExpandSize, + height: moveHandleHeight + moveZoneExpandSize + } + }); + actualMoveZone.on('mouseover', function () { + api.enterEmphasis(moveHandle_1); + }).on('mouseout', function () { + api.leaveEmphasis(moveHandle_1); + }); + sliderGroup.add(moveHandle_1); + sliderGroup.add(moveHandleIcon); + sliderGroup.add(actualMoveZone); + } + actualMoveZone.attr({ + draggable: true, + cursor: getCursor(this._orient), + drift: bind(this._onDragMove, this, 'all'), + ondragstart: bind(this._showDataInfo, this, true), + ondragend: bind(this._onDragEnd, this), + onmouseover: bind(this._showDataInfo, this, true), + onmouseout: bind(this._showDataInfo, this, false) + }); + }; + SliderZoomView.prototype._resetInterval = function () { + var range = this._range = this.dataZoomModel.getPercentRange(); + var viewExtent = this._getViewExtent(); + this._handleEnds = [linearMap(range[0], [0, 100], viewExtent, true), linearMap(range[1], [0, 100], viewExtent, true)]; + }; + SliderZoomView.prototype._updateInterval = function (handleIndex, delta) { + var dataZoomModel = this.dataZoomModel; + var handleEnds = this._handleEnds; + var viewExtend = this._getViewExtent(); + var minMaxSpan = dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan(); + var percentExtent = [0, 100]; + sliderMove(delta, handleEnds, viewExtend, dataZoomModel.get('zoomLock') ? 'all' : handleIndex, minMaxSpan.minSpan != null ? linearMap(minMaxSpan.minSpan, percentExtent, viewExtend, true) : null, minMaxSpan.maxSpan != null ? linearMap(minMaxSpan.maxSpan, percentExtent, viewExtend, true) : null); + var lastRange = this._range; + var range = this._range = asc([linearMap(handleEnds[0], viewExtend, percentExtent, true), linearMap(handleEnds[1], viewExtend, percentExtent, true)]); + return !lastRange || lastRange[0] !== range[0] || lastRange[1] !== range[1]; + }; + SliderZoomView.prototype._updateView = function (nonRealtime) { + var displaybles = this._displayables; + var handleEnds = this._handleEnds; + var handleInterval = asc(handleEnds.slice()); + var size = this._size; + each([0, 1], function (handleIndex) { + // Handles + var handle = displaybles.handles[handleIndex]; + var handleHeight = this._handleHeight; + handle.attr({ + scaleX: handleHeight / 2, + scaleY: handleHeight / 2, + // This is a trick, by adding an extra tiny offset to let the default handle's end point align to the drag window. + // NOTE: It may affect some custom shapes a bit. But we prefer to have better result by default. + x: handleEnds[handleIndex] + (handleIndex ? -1 : 1), + y: size[1] / 2 - handleHeight / 2 + }); + }, this); + // Filler + displaybles.filler.setShape({ + x: handleInterval[0], + y: 0, + width: handleInterval[1] - handleInterval[0], + height: size[1] + }); + var viewExtent = { + x: handleInterval[0], + width: handleInterval[1] - handleInterval[0] + }; + // Move handle + if (displaybles.moveHandle) { + displaybles.moveHandle.setShape(viewExtent); + displaybles.moveZone.setShape(viewExtent); + // Force update path on the invisible object + displaybles.moveZone.getBoundingRect(); + displaybles.moveHandleIcon && displaybles.moveHandleIcon.attr('x', viewExtent.x + viewExtent.width / 2); + } + // update clip path of shadow. + var dataShadowSegs = displaybles.dataShadowSegs; + var segIntervals = [0, handleInterval[0], handleInterval[1], size[0]]; + for (var i = 0; i < dataShadowSegs.length; i++) { + var segGroup = dataShadowSegs[i]; + var clipPath = segGroup.getClipPath(); + if (!clipPath) { + clipPath = new Rect(); + segGroup.setClipPath(clipPath); + } + clipPath.setShape({ + x: segIntervals[i], + y: 0, + width: segIntervals[i + 1] - segIntervals[i], + height: size[1] + }); + } + this._updateDataInfo(nonRealtime); + }; + SliderZoomView.prototype._updateDataInfo = function (nonRealtime) { + var dataZoomModel = this.dataZoomModel; + var displaybles = this._displayables; + var handleLabels = displaybles.handleLabels; + var orient = this._orient; + var labelTexts = ['', '']; + // FIXME + // date型,支持formatter,autoformatter(ec2 date.getAutoFormatter) + if (dataZoomModel.get('showDetail')) { + var axisProxy = dataZoomModel.findRepresentativeAxisProxy(); + if (axisProxy) { + var axis = axisProxy.getAxisModel().axis; + var range = this._range; + var dataInterval = nonRealtime + // See #4434, data and axis are not processed and reset yet in non-realtime mode. + ? axisProxy.calculateDataWindow({ + start: range[0], + end: range[1] + }).valueWindow : axisProxy.getDataValueWindow(); + labelTexts = [this._formatLabel(dataInterval[0], axis), this._formatLabel(dataInterval[1], axis)]; + } + } + var orderedHandleEnds = asc(this._handleEnds.slice()); + setLabel.call(this, 0); + setLabel.call(this, 1); + function setLabel(handleIndex) { + // Label + // Text should not transform by barGroup. + // Ignore handlers transform + var barTransform = getTransform(displaybles.handles[handleIndex].parent, this.group); + var direction = transformDirection(handleIndex === 0 ? 'right' : 'left', barTransform); + var offset = this._handleWidth / 2 + LABEL_GAP; + var textPoint = applyTransform$1([orderedHandleEnds[handleIndex] + (handleIndex === 0 ? -offset : offset), this._size[1] / 2], barTransform); + handleLabels[handleIndex].setStyle({ + x: textPoint[0], + y: textPoint[1], + verticalAlign: orient === HORIZONTAL ? 'middle' : direction, + align: orient === HORIZONTAL ? direction : 'center', + text: labelTexts[handleIndex] + }); + } + }; + SliderZoomView.prototype._formatLabel = function (value, axis) { + var dataZoomModel = this.dataZoomModel; + var labelFormatter = dataZoomModel.get('labelFormatter'); + var labelPrecision = dataZoomModel.get('labelPrecision'); + if (labelPrecision == null || labelPrecision === 'auto') { + labelPrecision = axis.getPixelPrecision(); + } + var valueStr = value == null || isNaN(value) ? '' + // FIXME Glue code + : axis.type === 'category' || axis.type === 'time' ? axis.scale.getLabel({ + value: Math.round(value) + }) + // param of toFixed should less then 20. + : value.toFixed(Math.min(labelPrecision, 20)); + return isFunction(labelFormatter) ? labelFormatter(value, valueStr) : isString(labelFormatter) ? labelFormatter.replace('{value}', valueStr) : valueStr; + }; + /** + * @param showOrHide true: show, false: hide + */ + SliderZoomView.prototype._showDataInfo = function (showOrHide) { + // Always show when drgging. + showOrHide = this._dragging || showOrHide; + var displayables = this._displayables; + var handleLabels = displayables.handleLabels; + handleLabels[0].attr('invisible', !showOrHide); + handleLabels[1].attr('invisible', !showOrHide); + // Highlight move handle + displayables.moveHandle && this.api[showOrHide ? 'enterEmphasis' : 'leaveEmphasis'](displayables.moveHandle, 1); + }; + SliderZoomView.prototype._onDragMove = function (handleIndex, dx, dy, event) { + this._dragging = true; + // For mobile device, prevent screen slider on the button. + stop(event.event); + // Transform dx, dy to bar coordination. + var barTransform = this._displayables.sliderGroup.getLocalTransform(); + var vertex = applyTransform$1([dx, dy], barTransform, true); + var changed = this._updateInterval(handleIndex, vertex[0]); + var realtime = this.dataZoomModel.get('realtime'); + this._updateView(!realtime); + // Avoid dispatch dataZoom repeatly but range not changed, + // which cause bad visual effect when progressive enabled. + changed && realtime && this._dispatchZoomAction(true); + }; + SliderZoomView.prototype._onDragEnd = function () { + this._dragging = false; + this._showDataInfo(false); + // While in realtime mode and stream mode, dispatch action when + // drag end will cause the whole view rerender, which is unnecessary. + var realtime = this.dataZoomModel.get('realtime'); + !realtime && this._dispatchZoomAction(false); + }; + SliderZoomView.prototype._onClickPanel = function (e) { + var size = this._size; + var localPoint = this._displayables.sliderGroup.transformCoordToLocal(e.offsetX, e.offsetY); + if (localPoint[0] < 0 || localPoint[0] > size[0] || localPoint[1] < 0 || localPoint[1] > size[1]) { + return; + } + var handleEnds = this._handleEnds; + var center = (handleEnds[0] + handleEnds[1]) / 2; + var changed = this._updateInterval('all', localPoint[0] - center); + this._updateView(); + changed && this._dispatchZoomAction(false); + }; + SliderZoomView.prototype._onBrushStart = function (e) { + var x = e.offsetX; + var y = e.offsetY; + this._brushStart = new Point(x, y); + this._brushing = true; + this._brushStartTime = +new Date(); + // this._updateBrushRect(x, y); + }; + + SliderZoomView.prototype._onBrushEnd = function (e) { + if (!this._brushing) { + return; + } + var brushRect = this._displayables.brushRect; + this._brushing = false; + if (!brushRect) { + return; + } + brushRect.attr('ignore', true); + var brushShape = brushRect.shape; + var brushEndTime = +new Date(); + // console.log(brushEndTime - this._brushStartTime); + if (brushEndTime - this._brushStartTime < 200 && Math.abs(brushShape.width) < 5) { + // Will treat it as a click + return; + } + var viewExtend = this._getViewExtent(); + var percentExtent = [0, 100]; + this._range = asc([linearMap(brushShape.x, viewExtend, percentExtent, true), linearMap(brushShape.x + brushShape.width, viewExtend, percentExtent, true)]); + this._handleEnds = [brushShape.x, brushShape.x + brushShape.width]; + this._updateView(); + this._dispatchZoomAction(false); + }; + SliderZoomView.prototype._onBrush = function (e) { + if (this._brushing) { + // For mobile device, prevent screen slider on the button. + stop(e.event); + this._updateBrushRect(e.offsetX, e.offsetY); + } + }; + SliderZoomView.prototype._updateBrushRect = function (mouseX, mouseY) { + var displayables = this._displayables; + var dataZoomModel = this.dataZoomModel; + var brushRect = displayables.brushRect; + if (!brushRect) { + brushRect = displayables.brushRect = new Rect$2({ + silent: true, + style: dataZoomModel.getModel('brushStyle').getItemStyle() + }); + displayables.sliderGroup.add(brushRect); + } + brushRect.attr('ignore', false); + var brushStart = this._brushStart; + var sliderGroup = this._displayables.sliderGroup; + var endPoint = sliderGroup.transformCoordToLocal(mouseX, mouseY); + var startPoint = sliderGroup.transformCoordToLocal(brushStart.x, brushStart.y); + var size = this._size; + endPoint[0] = Math.max(Math.min(size[0], endPoint[0]), 0); + brushRect.setShape({ + x: startPoint[0], + y: 0, + width: endPoint[0] - startPoint[0], + height: size[1] + }); + }; + /** + * This action will be throttled. + */ + SliderZoomView.prototype._dispatchZoomAction = function (realtime) { + var range = this._range; + this.api.dispatchAction({ + type: 'dataZoom', + from: this.uid, + dataZoomId: this.dataZoomModel.id, + animation: realtime ? REALTIME_ANIMATION_CONFIG : null, + start: range[0], + end: range[1] + }); + }; + SliderZoomView.prototype._findCoordRect = function () { + // Find the grid corresponding to the first axis referred by dataZoom. + var rect; + var coordSysInfoList = collectReferCoordSysModelInfo(this.dataZoomModel).infoList; + if (!rect && coordSysInfoList.length) { + var coordSys = coordSysInfoList[0].model.coordinateSystem; + rect = coordSys.getRect && coordSys.getRect(); + } + if (!rect) { + var width = this.api.getWidth(); + var height = this.api.getHeight(); + rect = { + x: width * 0.2, + y: height * 0.2, + width: width * 0.6, + height: height * 0.6 + }; + } + return rect; + }; + SliderZoomView.type = 'dataZoom.slider'; + return SliderZoomView; + }(DataZoomView); + function getOtherDim(thisDim) { + // FIXME + // 这个逻辑和getOtherAxis里一致,但是写在这里是否不好 + var map = { + x: 'y', + y: 'x', + radius: 'angle', + angle: 'radius' + }; + return map[thisDim]; + } + function getCursor(orient) { + return orient === 'vertical' ? 'ns-resize' : 'ew-resize'; + } + + function install$L(registers) { + registers.registerComponentModel(SliderZoomModel); + registers.registerComponentView(SliderZoomView); + installCommon(registers); + } + + function install$M(registers) { + use(install$K); + use(install$L); + // Do not install './dataZoomSelect', + // since it only work for toolbox dataZoom. + } + + var visualDefault = { + /** + * @public + */ + get: function (visualType, key, isCategory) { + var value = clone((defaultOption$1[visualType] || {})[key]); + return isCategory ? isArray(value) ? value[value.length - 1] : value : value; + } + }; + var defaultOption$1 = { + color: { + active: ['#006edd', '#e0ffff'], + inactive: ['rgba(0,0,0,0)'] + }, + colorHue: { + active: [0, 360], + inactive: [0, 0] + }, + colorSaturation: { + active: [0.3, 1], + inactive: [0, 0] + }, + colorLightness: { + active: [0.9, 0.5], + inactive: [0, 0] + }, + colorAlpha: { + active: [0.3, 1], + inactive: [0, 0] + }, + opacity: { + active: [0.3, 1], + inactive: [0, 0] + }, + symbol: { + active: ['circle', 'roundRect', 'diamond'], + inactive: ['none'] + }, + symbolSize: { + active: [10, 50], + inactive: [0, 0] + } + }; + + var mapVisual$1 = VisualMapping.mapVisual; + var eachVisual = VisualMapping.eachVisual; + var isArray$1 = isArray; + var each$d = each; + var asc$2 = asc; + var linearMap$1 = linearMap; + var VisualMapModel = /** @class */function (_super) { + __extends(VisualMapModel, _super); + function VisualMapModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = VisualMapModel.type; + _this.stateList = ['inRange', 'outOfRange']; + _this.replacableOptionKeys = ['inRange', 'outOfRange', 'target', 'controller', 'color']; + _this.layoutMode = { + type: 'box', + ignoreSize: true + }; + /** + * [lowerBound, upperBound] + */ + _this.dataBound = [-Infinity, Infinity]; + _this.targetVisuals = {}; + _this.controllerVisuals = {}; + return _this; + } + VisualMapModel.prototype.init = function (option, parentModel, ecModel) { + this.mergeDefaultAndTheme(option, ecModel); + }; + /** + * @protected + */ + VisualMapModel.prototype.optionUpdated = function (newOption, isInit) { + var thisOption = this.option; + !isInit && replaceVisualOption(thisOption, newOption, this.replacableOptionKeys); + this.textStyleModel = this.getModel('textStyle'); + this.resetItemSize(); + this.completeVisualOption(); + }; + /** + * @protected + */ + VisualMapModel.prototype.resetVisual = function (supplementVisualOption) { + var stateList = this.stateList; + supplementVisualOption = bind(supplementVisualOption, this); + this.controllerVisuals = createVisualMappings(this.option.controller, stateList, supplementVisualOption); + this.targetVisuals = createVisualMappings(this.option.target, stateList, supplementVisualOption); + }; + /** + * @public + */ + VisualMapModel.prototype.getItemSymbol = function () { + return null; + }; + /** + * @protected + * @return {Array.} An array of series indices. + */ + VisualMapModel.prototype.getTargetSeriesIndices = function () { + var optionSeriesIndex = this.option.seriesIndex; + var seriesIndices = []; + if (optionSeriesIndex == null || optionSeriesIndex === 'all') { + this.ecModel.eachSeries(function (seriesModel, index) { + seriesIndices.push(index); + }); + } else { + seriesIndices = normalizeToArray(optionSeriesIndex); + } + return seriesIndices; + }; + /** + * @public + */ + VisualMapModel.prototype.eachTargetSeries = function (callback, context) { + each(this.getTargetSeriesIndices(), function (seriesIndex) { + var seriesModel = this.ecModel.getSeriesByIndex(seriesIndex); + if (seriesModel) { + callback.call(context, seriesModel); + } + }, this); + }; + /** + * @pubilc + */ + VisualMapModel.prototype.isTargetSeries = function (seriesModel) { + var is = false; + this.eachTargetSeries(function (model) { + model === seriesModel && (is = true); + }); + return is; + }; + /** + * @example + * this.formatValueText(someVal); // format single numeric value to text. + * this.formatValueText(someVal, true); // format single category value to text. + * this.formatValueText([min, max]); // format numeric min-max to text. + * this.formatValueText([this.dataBound[0], max]); // using data lower bound. + * this.formatValueText([min, this.dataBound[1]]); // using data upper bound. + * + * @param value Real value, or this.dataBound[0 or 1]. + * @param isCategory Only available when value is number. + * @param edgeSymbols Open-close symbol when value is interval. + * @protected + */ + VisualMapModel.prototype.formatValueText = function (value, isCategory, edgeSymbols) { + var option = this.option; + var precision = option.precision; + var dataBound = this.dataBound; + var formatter = option.formatter; + var isMinMax; + edgeSymbols = edgeSymbols || ['<', '>']; + if (isArray(value)) { + value = value.slice(); + isMinMax = true; + } + var textValue = isCategory ? value // Value is string when isCategory + : isMinMax ? [toFixed(value[0]), toFixed(value[1])] : toFixed(value); + if (isString(formatter)) { + return formatter.replace('{value}', isMinMax ? textValue[0] : textValue).replace('{value2}', isMinMax ? textValue[1] : textValue); + } else if (isFunction(formatter)) { + return isMinMax ? formatter(value[0], value[1]) : formatter(value); + } + if (isMinMax) { + if (value[0] === dataBound[0]) { + return edgeSymbols[0] + ' ' + textValue[1]; + } else if (value[1] === dataBound[1]) { + return edgeSymbols[1] + ' ' + textValue[0]; + } else { + return textValue[0] + ' - ' + textValue[1]; + } + } else { + // Format single value (includes category case). + return textValue; + } + function toFixed(val) { + return val === dataBound[0] ? 'min' : val === dataBound[1] ? 'max' : (+val).toFixed(Math.min(precision, 20)); + } + }; + /** + * @protected + */ + VisualMapModel.prototype.resetExtent = function () { + var thisOption = this.option; + // Can not calculate data extent by data here. + // Because series and data may be modified in processing stage. + // So we do not support the feature "auto min/max". + var extent = asc$2([thisOption.min, thisOption.max]); + this._dataExtent = extent; + }; + /** + * PENDING: + * delete this method if no outer usage. + * + * Return Concrete dimension. If null/undefined is returned, no dimension is used. + */ + // getDataDimension(data: SeriesData) { + // const optDim = this.option.dimension; + // if (optDim != null) { + // return data.getDimension(optDim); + // } + // const dimNames = data.dimensions; + // for (let i = dimNames.length - 1; i >= 0; i--) { + // const dimName = dimNames[i]; + // const dimInfo = data.getDimensionInfo(dimName); + // if (!dimInfo.isCalculationCoord) { + // return dimName; + // } + // } + // } + VisualMapModel.prototype.getDataDimensionIndex = function (data) { + var optDim = this.option.dimension; + if (optDim != null) { + return data.getDimensionIndex(optDim); + } + var dimNames = data.dimensions; + for (var i = dimNames.length - 1; i >= 0; i--) { + var dimName = dimNames[i]; + var dimInfo = data.getDimensionInfo(dimName); + if (!dimInfo.isCalculationCoord) { + return dimInfo.storeDimIndex; + } + } + }; + VisualMapModel.prototype.getExtent = function () { + return this._dataExtent.slice(); + }; + VisualMapModel.prototype.completeVisualOption = function () { + var ecModel = this.ecModel; + var thisOption = this.option; + var base = { + inRange: thisOption.inRange, + outOfRange: thisOption.outOfRange + }; + var target = thisOption.target || (thisOption.target = {}); + var controller = thisOption.controller || (thisOption.controller = {}); + merge(target, base); // Do not override + merge(controller, base); // Do not override + var isCategory = this.isCategory(); + completeSingle.call(this, target); + completeSingle.call(this, controller); + completeInactive.call(this, target, 'inRange', 'outOfRange'); + // completeInactive.call(this, target, 'outOfRange', 'inRange'); + completeController.call(this, controller); + function completeSingle(base) { + // Compatible with ec2 dataRange.color. + // The mapping order of dataRange.color is: [high value, ..., low value] + // whereas inRange.color and outOfRange.color is [low value, ..., high value] + // Notice: ec2 has no inverse. + if (isArray$1(thisOption.color) + // If there has been inRange: {symbol: ...}, adding color is a mistake. + // So adding color only when no inRange defined. + && !base.inRange) { + base.inRange = { + color: thisOption.color.slice().reverse() + }; + } + // Compatible with previous logic, always give a default color, otherwise + // simple config with no inRange and outOfRange will not work. + // Originally we use visualMap.color as the default color, but setOption at + // the second time the default color will be erased. So we change to use + // constant DEFAULT_COLOR. + // If user do not want the default color, set inRange: {color: null}. + base.inRange = base.inRange || { + color: ecModel.get('gradientColor') + }; + } + function completeInactive(base, stateExist, stateAbsent) { + var optExist = base[stateExist]; + var optAbsent = base[stateAbsent]; + if (optExist && !optAbsent) { + optAbsent = base[stateAbsent] = {}; + each$d(optExist, function (visualData, visualType) { + if (!VisualMapping.isValidType(visualType)) { + return; + } + var defa = visualDefault.get(visualType, 'inactive', isCategory); + if (defa != null) { + optAbsent[visualType] = defa; + // Compatibable with ec2: + // Only inactive color to rgba(0,0,0,0) can not + // make label transparent, so use opacity also. + if (visualType === 'color' && !optAbsent.hasOwnProperty('opacity') && !optAbsent.hasOwnProperty('colorAlpha')) { + optAbsent.opacity = [0, 0]; + } + } + }); + } + } + function completeController(controller) { + var symbolExists = (controller.inRange || {}).symbol || (controller.outOfRange || {}).symbol; + var symbolSizeExists = (controller.inRange || {}).symbolSize || (controller.outOfRange || {}).symbolSize; + var inactiveColor = this.get('inactiveColor'); + var itemSymbol = this.getItemSymbol(); + var defaultSymbol = itemSymbol || 'roundRect'; + each$d(this.stateList, function (state) { + var itemSize = this.itemSize; + var visuals = controller[state]; + // Set inactive color for controller if no other color + // attr (like colorAlpha) specified. + if (!visuals) { + visuals = controller[state] = { + color: isCategory ? inactiveColor : [inactiveColor] + }; + } + // Consistent symbol and symbolSize if not specified. + if (visuals.symbol == null) { + visuals.symbol = symbolExists && clone(symbolExists) || (isCategory ? defaultSymbol : [defaultSymbol]); + } + if (visuals.symbolSize == null) { + visuals.symbolSize = symbolSizeExists && clone(symbolSizeExists) || (isCategory ? itemSize[0] : [itemSize[0], itemSize[0]]); + } + // Filter none + visuals.symbol = mapVisual$1(visuals.symbol, function (symbol) { + return symbol === 'none' ? defaultSymbol : symbol; + }); + // Normalize symbolSize + var symbolSize = visuals.symbolSize; + if (symbolSize != null) { + var max_1 = -Infinity; + // symbolSize can be object when categories defined. + eachVisual(symbolSize, function (value) { + value > max_1 && (max_1 = value); + }); + visuals.symbolSize = mapVisual$1(symbolSize, function (value) { + return linearMap$1(value, [0, max_1], [0, itemSize[0]], true); + }); + } + }, this); + } + }; + VisualMapModel.prototype.resetItemSize = function () { + this.itemSize = [parseFloat(this.get('itemWidth')), parseFloat(this.get('itemHeight'))]; + }; + VisualMapModel.prototype.isCategory = function () { + return !!this.option.categories; + }; + /** + * @public + * @abstract + */ + VisualMapModel.prototype.setSelected = function (selected) {}; + VisualMapModel.prototype.getSelected = function () { + return null; + }; + /** + * @public + * @abstract + */ + VisualMapModel.prototype.getValueState = function (value) { + return null; + }; + /** + * FIXME + * Do not publish to thirt-part-dev temporarily + * util the interface is stable. (Should it return + * a function but not visual meta?) + * + * @pubilc + * @abstract + * @param getColorVisual + * params: value, valueState + * return: color + * @return {Object} visualMeta + * should includes {stops, outerColors} + * outerColor means [colorBeyondMinValue, colorBeyondMaxValue] + */ + VisualMapModel.prototype.getVisualMeta = function (getColorVisual) { + return null; + }; + VisualMapModel.type = 'visualMap'; + VisualMapModel.dependencies = ['series']; + VisualMapModel.defaultOption = { + show: true, + // zlevel: 0, + z: 4, + seriesIndex: 'all', + min: 0, + max: 200, + left: 0, + right: null, + top: null, + bottom: 0, + itemWidth: null, + itemHeight: null, + inverse: false, + orient: 'vertical', + backgroundColor: 'rgba(0,0,0,0)', + borderColor: '#ccc', + contentColor: '#5793f3', + inactiveColor: '#aaa', + borderWidth: 0, + padding: 5, + // 接受数组分别设定上右下左边距,同css + textGap: 10, + precision: 0, + textStyle: { + color: '#333' // 值域文字颜色 + } + }; + + return VisualMapModel; + }(ComponentModel); + + // Constant + var DEFAULT_BAR_BOUND = [20, 140]; + var ContinuousModel = /** @class */function (_super) { + __extends(ContinuousModel, _super); + function ContinuousModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ContinuousModel.type; + return _this; + } + /** + * @override + */ + ContinuousModel.prototype.optionUpdated = function (newOption, isInit) { + _super.prototype.optionUpdated.apply(this, arguments); + this.resetExtent(); + this.resetVisual(function (mappingOption) { + mappingOption.mappingMethod = 'linear'; + mappingOption.dataExtent = this.getExtent(); + }); + this._resetRange(); + }; + /** + * @protected + * @override + */ + ContinuousModel.prototype.resetItemSize = function () { + _super.prototype.resetItemSize.apply(this, arguments); + var itemSize = this.itemSize; + (itemSize[0] == null || isNaN(itemSize[0])) && (itemSize[0] = DEFAULT_BAR_BOUND[0]); + (itemSize[1] == null || isNaN(itemSize[1])) && (itemSize[1] = DEFAULT_BAR_BOUND[1]); + }; + /** + * @private + */ + ContinuousModel.prototype._resetRange = function () { + var dataExtent = this.getExtent(); + var range = this.option.range; + if (!range || range.auto) { + // `range` should always be array (so we don't use other + // value like 'auto') for user-friend. (consider getOption). + dataExtent.auto = 1; + this.option.range = dataExtent; + } else if (isArray(range)) { + if (range[0] > range[1]) { + range.reverse(); + } + range[0] = Math.max(range[0], dataExtent[0]); + range[1] = Math.min(range[1], dataExtent[1]); + } + }; + /** + * @protected + * @override + */ + ContinuousModel.prototype.completeVisualOption = function () { + _super.prototype.completeVisualOption.apply(this, arguments); + each(this.stateList, function (state) { + var symbolSize = this.option.controller[state].symbolSize; + if (symbolSize && symbolSize[0] !== symbolSize[1]) { + symbolSize[0] = symbolSize[1] / 3; // For good looking. + } + }, this); + }; + /** + * @override + */ + ContinuousModel.prototype.setSelected = function (selected) { + this.option.range = selected.slice(); + this._resetRange(); + }; + /** + * @public + */ + ContinuousModel.prototype.getSelected = function () { + var dataExtent = this.getExtent(); + var dataInterval = asc((this.get('range') || []).slice()); + // Clamp + dataInterval[0] > dataExtent[1] && (dataInterval[0] = dataExtent[1]); + dataInterval[1] > dataExtent[1] && (dataInterval[1] = dataExtent[1]); + dataInterval[0] < dataExtent[0] && (dataInterval[0] = dataExtent[0]); + dataInterval[1] < dataExtent[0] && (dataInterval[1] = dataExtent[0]); + return dataInterval; + }; + /** + * @override + */ + ContinuousModel.prototype.getValueState = function (value) { + var range = this.option.range; + var dataExtent = this.getExtent(); + // When range[0] === dataExtent[0], any value larger than dataExtent[0] maps to 'inRange'. + // range[1] is processed likewise. + return (range[0] <= dataExtent[0] || range[0] <= value) && (range[1] >= dataExtent[1] || value <= range[1]) ? 'inRange' : 'outOfRange'; + }; + ContinuousModel.prototype.findTargetDataIndices = function (range) { + var result = []; + this.eachTargetSeries(function (seriesModel) { + var dataIndices = []; + var data = seriesModel.getData(); + data.each(this.getDataDimensionIndex(data), function (value, dataIndex) { + range[0] <= value && value <= range[1] && dataIndices.push(dataIndex); + }, this); + result.push({ + seriesId: seriesModel.id, + dataIndex: dataIndices + }); + }, this); + return result; + }; + /** + * @implement + */ + ContinuousModel.prototype.getVisualMeta = function (getColorVisual) { + var oVals = getColorStopValues(this, 'outOfRange', this.getExtent()); + var iVals = getColorStopValues(this, 'inRange', this.option.range.slice()); + var stops = []; + function setStop(value, valueState) { + stops.push({ + value: value, + color: getColorVisual(value, valueState) + }); + } + // Format to: outOfRange -- inRange -- outOfRange. + var iIdx = 0; + var oIdx = 0; + var iLen = iVals.length; + var oLen = oVals.length; + for (; oIdx < oLen && (!iVals.length || oVals[oIdx] <= iVals[0]); oIdx++) { + // If oVal[oIdx] === iVals[iIdx], oVal[oIdx] should be ignored. + if (oVals[oIdx] < iVals[iIdx]) { + setStop(oVals[oIdx], 'outOfRange'); + } + } + for (var first = 1; iIdx < iLen; iIdx++, first = 0) { + // If range is full, value beyond min, max will be clamped. + // make a singularity + first && stops.length && setStop(iVals[iIdx], 'outOfRange'); + setStop(iVals[iIdx], 'inRange'); + } + for (var first = 1; oIdx < oLen; oIdx++) { + if (!iVals.length || iVals[iVals.length - 1] < oVals[oIdx]) { + // make a singularity + if (first) { + stops.length && setStop(stops[stops.length - 1].value, 'outOfRange'); + first = 0; + } + setStop(oVals[oIdx], 'outOfRange'); + } + } + var stopsLen = stops.length; + return { + stops: stops, + outerColors: [stopsLen ? stops[0].color : 'transparent', stopsLen ? stops[stopsLen - 1].color : 'transparent'] + }; + }; + ContinuousModel.type = 'visualMap.continuous'; + ContinuousModel.defaultOption = inheritDefaultOption(VisualMapModel.defaultOption, { + align: 'auto', + calculable: false, + hoverLink: true, + realtime: true, + handleIcon: 'path://M-11.39,9.77h0a3.5,3.5,0,0,1-3.5,3.5h-22a3.5,3.5,0,0,1-3.5-3.5h0a3.5,3.5,0,0,1,3.5-3.5h22A3.5,3.5,0,0,1-11.39,9.77Z', + handleSize: '120%', + handleStyle: { + borderColor: '#fff', + borderWidth: 1 + }, + indicatorIcon: 'circle', + indicatorSize: '50%', + indicatorStyle: { + borderColor: '#fff', + borderWidth: 2, + shadowBlur: 2, + shadowOffsetX: 1, + shadowOffsetY: 1, + shadowColor: 'rgba(0,0,0,0.2)' + } + // emphasis: { + // handleStyle: { + // shadowBlur: 3, + // shadowOffsetX: 1, + // shadowOffsetY: 1, + // shadowColor: 'rgba(0,0,0,0.2)' + // } + // } + }); + + return ContinuousModel; + }(VisualMapModel); + function getColorStopValues(visualMapModel, valueState, dataExtent) { + if (dataExtent[0] === dataExtent[1]) { + return dataExtent.slice(); + } + // When using colorHue mapping, it is not linear color any more. + // Moreover, canvas gradient seems not to be accurate linear. + // FIXME + // Should be arbitrary value 100? or based on pixel size? + var count = 200; + var step = (dataExtent[1] - dataExtent[0]) / count; + var value = dataExtent[0]; + var stopValues = []; + for (var i = 0; i <= count && value < dataExtent[1]; i++) { + stopValues.push(value); + value += step; + } + stopValues.push(dataExtent[1]); + return stopValues; + } + + var VisualMapView = /** @class */function (_super) { + __extends(VisualMapView, _super); + function VisualMapView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = VisualMapView.type; + _this.autoPositionValues = { + left: 1, + right: 1, + top: 1, + bottom: 1 + }; + return _this; + } + VisualMapView.prototype.init = function (ecModel, api) { + this.ecModel = ecModel; + this.api = api; + }; + /** + * @protected + */ + VisualMapView.prototype.render = function (visualMapModel, ecModel, api, payload // TODO: TYPE + ) { + this.visualMapModel = visualMapModel; + if (visualMapModel.get('show') === false) { + this.group.removeAll(); + return; + } + this.doRender(visualMapModel, ecModel, api, payload); + }; + /** + * @protected + */ + VisualMapView.prototype.renderBackground = function (group) { + var visualMapModel = this.visualMapModel; + var padding = normalizeCssArray$1(visualMapModel.get('padding') || 0); + var rect = group.getBoundingRect(); + group.add(new Rect({ + z2: -1, + silent: true, + shape: { + x: rect.x - padding[3], + y: rect.y - padding[0], + width: rect.width + padding[3] + padding[1], + height: rect.height + padding[0] + padding[2] + }, + style: { + fill: visualMapModel.get('backgroundColor'), + stroke: visualMapModel.get('borderColor'), + lineWidth: visualMapModel.get('borderWidth') + } + })); + }; + /** + * @protected + * @param targetValue can be Infinity or -Infinity + * @param visualCluster Only can be 'color' 'opacity' 'symbol' 'symbolSize' + * @param opts + * @param opts.forceState Specify state, instead of using getValueState method. + * @param opts.convertOpacityToAlpha For color gradient in controller widget. + * @return {*} Visual value. + */ + VisualMapView.prototype.getControllerVisual = function (targetValue, visualCluster, opts) { + opts = opts || {}; + var forceState = opts.forceState; + var visualMapModel = this.visualMapModel; + var visualObj = {}; + // Default values. + if (visualCluster === 'color') { + var defaultColor = visualMapModel.get('contentColor'); + visualObj.color = defaultColor; + } + function getter(key) { + return visualObj[key]; + } + function setter(key, value) { + visualObj[key] = value; + } + var mappings = visualMapModel.controllerVisuals[forceState || visualMapModel.getValueState(targetValue)]; + var visualTypes = VisualMapping.prepareVisualTypes(mappings); + each(visualTypes, function (type) { + var visualMapping = mappings[type]; + if (opts.convertOpacityToAlpha && type === 'opacity') { + type = 'colorAlpha'; + visualMapping = mappings.__alphaForOpacity; + } + if (VisualMapping.dependsOn(type, visualCluster)) { + visualMapping && visualMapping.applyVisual(targetValue, getter, setter); + } + }); + return visualObj[visualCluster]; + }; + VisualMapView.prototype.positionGroup = function (group) { + var model = this.visualMapModel; + var api = this.api; + positionElement(group, model.getBoxLayoutParams(), { + width: api.getWidth(), + height: api.getHeight() + }); + }; + VisualMapView.prototype.doRender = function (visualMapModel, ecModel, api, payload) {}; + VisualMapView.type = 'visualMap'; + return VisualMapView; + }(ComponentView); + + var paramsSet = [['left', 'right', 'width'], ['top', 'bottom', 'height']]; + /** + * @param visualMapModel + * @param api + * @param itemSize always [short, long] + * @return {string} 'left' or 'right' or 'top' or 'bottom' + */ + function getItemAlign(visualMapModel, api, itemSize) { + var modelOption = visualMapModel.option; + var itemAlign = modelOption.align; + if (itemAlign != null && itemAlign !== 'auto') { + return itemAlign; + } + // Auto decision align. + var ecSize = { + width: api.getWidth(), + height: api.getHeight() + }; + var realIndex = modelOption.orient === 'horizontal' ? 1 : 0; + var reals = paramsSet[realIndex]; + var fakeValue = [0, null, 10]; + var layoutInput = {}; + for (var i = 0; i < 3; i++) { + layoutInput[paramsSet[1 - realIndex][i]] = fakeValue[i]; + layoutInput[reals[i]] = i === 2 ? itemSize[0] : modelOption[reals[i]]; + } + var rParam = [['x', 'width', 3], ['y', 'height', 0]][realIndex]; + var rect = getLayoutRect(layoutInput, ecSize, modelOption.padding); + return reals[(rect.margin[rParam[2]] || 0) + rect[rParam[0]] + rect[rParam[1]] * 0.5 < ecSize[rParam[1]] * 0.5 ? 0 : 1]; + } + /** + * Prepare dataIndex for outside usage, where dataIndex means rawIndex, and + * dataIndexInside means filtered index. + */ + // TODO: TYPE more specified payload types. + function makeHighDownBatch(batch, visualMapModel) { + each(batch || [], function (batchItem) { + if (batchItem.dataIndex != null) { + batchItem.dataIndexInside = batchItem.dataIndex; + batchItem.dataIndex = null; + } + batchItem.highlightKey = 'visualMap' + (visualMapModel ? visualMapModel.componentIndex : ''); + }); + return batch; + } + + var linearMap$2 = linearMap; + var each$e = each; + var mathMin$a = Math.min; + var mathMax$a = Math.max; + // Arbitrary value + var HOVER_LINK_SIZE = 12; + var HOVER_LINK_OUT = 6; + // Notice: + // Any "interval" should be by the order of [low, high]. + // "handle0" (handleIndex === 0) maps to + // low data value: this._dataInterval[0] and has low coord. + // "handle1" (handleIndex === 1) maps to + // high data value: this._dataInterval[1] and has high coord. + // The logic of transform is implemented in this._createBarGroup. + var ContinuousView = /** @class */function (_super) { + __extends(ContinuousView, _super); + function ContinuousView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = ContinuousView.type; + _this._shapes = {}; + _this._dataInterval = []; + _this._handleEnds = []; + _this._hoverLinkDataIndices = []; + return _this; + } + ContinuousView.prototype.init = function (ecModel, api) { + _super.prototype.init.call(this, ecModel, api); + this._hoverLinkFromSeriesMouseOver = bind(this._hoverLinkFromSeriesMouseOver, this); + this._hideIndicator = bind(this._hideIndicator, this); + }; + ContinuousView.prototype.doRender = function (visualMapModel, ecModel, api, payload) { + if (!payload || payload.type !== 'selectDataRange' || payload.from !== this.uid) { + this._buildView(); + } + }; + ContinuousView.prototype._buildView = function () { + this.group.removeAll(); + var visualMapModel = this.visualMapModel; + var thisGroup = this.group; + this._orient = visualMapModel.get('orient'); + this._useHandle = visualMapModel.get('calculable'); + this._resetInterval(); + this._renderBar(thisGroup); + var dataRangeText = visualMapModel.get('text'); + this._renderEndsText(thisGroup, dataRangeText, 0); + this._renderEndsText(thisGroup, dataRangeText, 1); + // Do this for background size calculation. + this._updateView(true); + // After updating view, inner shapes is built completely, + // and then background can be rendered. + this.renderBackground(thisGroup); + // Real update view + this._updateView(); + this._enableHoverLinkToSeries(); + this._enableHoverLinkFromSeries(); + this.positionGroup(thisGroup); + }; + ContinuousView.prototype._renderEndsText = function (group, dataRangeText, endsIndex) { + if (!dataRangeText) { + return; + } + // Compatible with ec2, text[0] map to high value, text[1] map low value. + var text = dataRangeText[1 - endsIndex]; + text = text != null ? text + '' : ''; + var visualMapModel = this.visualMapModel; + var textGap = visualMapModel.get('textGap'); + var itemSize = visualMapModel.itemSize; + var barGroup = this._shapes.mainGroup; + var position = this._applyTransform([itemSize[0] / 2, endsIndex === 0 ? -textGap : itemSize[1] + textGap], barGroup); + var align = this._applyTransform(endsIndex === 0 ? 'bottom' : 'top', barGroup); + var orient = this._orient; + var textStyleModel = this.visualMapModel.textStyleModel; + this.group.add(new ZRText({ + style: createTextStyle(textStyleModel, { + x: position[0], + y: position[1], + verticalAlign: orient === 'horizontal' ? 'middle' : align, + align: orient === 'horizontal' ? align : 'center', + text: text + }) + })); + }; + ContinuousView.prototype._renderBar = function (targetGroup) { + var visualMapModel = this.visualMapModel; + var shapes = this._shapes; + var itemSize = visualMapModel.itemSize; + var orient = this._orient; + var useHandle = this._useHandle; + var itemAlign = getItemAlign(visualMapModel, this.api, itemSize); + var mainGroup = shapes.mainGroup = this._createBarGroup(itemAlign); + var gradientBarGroup = new Group(); + mainGroup.add(gradientBarGroup); + // Bar + gradientBarGroup.add(shapes.outOfRange = createPolygon()); + gradientBarGroup.add(shapes.inRange = createPolygon(null, useHandle ? getCursor$1(this._orient) : null, bind(this._dragHandle, this, 'all', false), bind(this._dragHandle, this, 'all', true))); + // A border radius clip. + gradientBarGroup.setClipPath(new Rect({ + shape: { + x: 0, + y: 0, + width: itemSize[0], + height: itemSize[1], + r: 3 + } + })); + var textRect = visualMapModel.textStyleModel.getTextRect('国'); + var textSize = mathMax$a(textRect.width, textRect.height); + // Handle + if (useHandle) { + shapes.handleThumbs = []; + shapes.handleLabels = []; + shapes.handleLabelPoints = []; + this._createHandle(visualMapModel, mainGroup, 0, itemSize, textSize, orient); + this._createHandle(visualMapModel, mainGroup, 1, itemSize, textSize, orient); + } + this._createIndicator(visualMapModel, mainGroup, itemSize, textSize, orient); + targetGroup.add(mainGroup); + }; + ContinuousView.prototype._createHandle = function (visualMapModel, mainGroup, handleIndex, itemSize, textSize, orient) { + var onDrift = bind(this._dragHandle, this, handleIndex, false); + var onDragEnd = bind(this._dragHandle, this, handleIndex, true); + var handleSize = parsePercent(visualMapModel.get('handleSize'), itemSize[0]); + var handleThumb = createSymbol(visualMapModel.get('handleIcon'), -handleSize / 2, -handleSize / 2, handleSize, handleSize, null, true); + var cursor = getCursor$1(this._orient); + handleThumb.attr({ + cursor: cursor, + draggable: true, + drift: onDrift, + ondragend: onDragEnd, + onmousemove: function (e) { + stop(e.event); + } + }); + handleThumb.x = itemSize[0] / 2; + handleThumb.useStyle(visualMapModel.getModel('handleStyle').getItemStyle()); + handleThumb.setStyle({ + strokeNoScale: true, + strokeFirst: true + }); + handleThumb.style.lineWidth *= 2; + handleThumb.ensureState('emphasis').style = visualMapModel.getModel(['emphasis', 'handleStyle']).getItemStyle(); + setAsHighDownDispatcher(handleThumb, true); + mainGroup.add(handleThumb); + // Text is always horizontal layout but should not be effected by + // transform (orient/inverse). So label is built separately but not + // use zrender/graphic/helper/RectText, and is located based on view + // group (according to handleLabelPoint) but not barGroup. + var textStyleModel = this.visualMapModel.textStyleModel; + var handleLabel = new ZRText({ + cursor: cursor, + draggable: true, + drift: onDrift, + onmousemove: function (e) { + // For mobile device, prevent screen slider on the button. + stop(e.event); + }, + ondragend: onDragEnd, + style: createTextStyle(textStyleModel, { + x: 0, + y: 0, + text: '' + }) + }); + handleLabel.ensureState('blur').style = { + opacity: 0.1 + }; + handleLabel.stateTransition = { + duration: 200 + }; + this.group.add(handleLabel); + var handleLabelPoint = [handleSize, 0]; + var shapes = this._shapes; + shapes.handleThumbs[handleIndex] = handleThumb; + shapes.handleLabelPoints[handleIndex] = handleLabelPoint; + shapes.handleLabels[handleIndex] = handleLabel; + }; + ContinuousView.prototype._createIndicator = function (visualMapModel, mainGroup, itemSize, textSize, orient) { + var scale = parsePercent(visualMapModel.get('indicatorSize'), itemSize[0]); + var indicator = createSymbol(visualMapModel.get('indicatorIcon'), -scale / 2, -scale / 2, scale, scale, null, true); + indicator.attr({ + cursor: 'move', + invisible: true, + silent: true, + x: itemSize[0] / 2 + }); + var indicatorStyle = visualMapModel.getModel('indicatorStyle').getItemStyle(); + if (indicator instanceof ZRImage) { + var pathStyle = indicator.style; + indicator.useStyle(extend({ + // TODO other properties like x, y ? + image: pathStyle.image, + x: pathStyle.x, + y: pathStyle.y, + width: pathStyle.width, + height: pathStyle.height + }, indicatorStyle)); + } else { + indicator.useStyle(indicatorStyle); + } + mainGroup.add(indicator); + var textStyleModel = this.visualMapModel.textStyleModel; + var indicatorLabel = new ZRText({ + silent: true, + invisible: true, + style: createTextStyle(textStyleModel, { + x: 0, + y: 0, + text: '' + }) + }); + this.group.add(indicatorLabel); + var indicatorLabelPoint = [(orient === 'horizontal' ? textSize / 2 : HOVER_LINK_OUT) + itemSize[0] / 2, 0]; + var shapes = this._shapes; + shapes.indicator = indicator; + shapes.indicatorLabel = indicatorLabel; + shapes.indicatorLabelPoint = indicatorLabelPoint; + this._firstShowIndicator = true; + }; + ContinuousView.prototype._dragHandle = function (handleIndex, isEnd, + // dx is event from ondragend if isEnd is true. It's not used + dx, dy) { + if (!this._useHandle) { + return; + } + this._dragging = !isEnd; + if (!isEnd) { + // Transform dx, dy to bar coordination. + var vertex = this._applyTransform([dx, dy], this._shapes.mainGroup, true); + this._updateInterval(handleIndex, vertex[1]); + this._hideIndicator(); + // Considering realtime, update view should be executed + // before dispatch action. + this._updateView(); + } + // dragEnd do not dispatch action when realtime. + if (isEnd === !this.visualMapModel.get('realtime')) { + // jshint ignore:line + this.api.dispatchAction({ + type: 'selectDataRange', + from: this.uid, + visualMapId: this.visualMapModel.id, + selected: this._dataInterval.slice() + }); + } + if (isEnd) { + !this._hovering && this._clearHoverLinkToSeries(); + } else if (useHoverLinkOnHandle(this.visualMapModel)) { + this._doHoverLinkToSeries(this._handleEnds[handleIndex], false); + } + }; + ContinuousView.prototype._resetInterval = function () { + var visualMapModel = this.visualMapModel; + var dataInterval = this._dataInterval = visualMapModel.getSelected(); + var dataExtent = visualMapModel.getExtent(); + var sizeExtent = [0, visualMapModel.itemSize[1]]; + this._handleEnds = [linearMap$2(dataInterval[0], dataExtent, sizeExtent, true), linearMap$2(dataInterval[1], dataExtent, sizeExtent, true)]; + }; + /** + * @private + * @param {(number|string)} handleIndex 0 or 1 or 'all' + * @param {number} dx + * @param {number} dy + */ + ContinuousView.prototype._updateInterval = function (handleIndex, delta) { + delta = delta || 0; + var visualMapModel = this.visualMapModel; + var handleEnds = this._handleEnds; + var sizeExtent = [0, visualMapModel.itemSize[1]]; + sliderMove(delta, handleEnds, sizeExtent, handleIndex, + // cross is forbidden + 0); + var dataExtent = visualMapModel.getExtent(); + // Update data interval. + this._dataInterval = [linearMap$2(handleEnds[0], sizeExtent, dataExtent, true), linearMap$2(handleEnds[1], sizeExtent, dataExtent, true)]; + }; + ContinuousView.prototype._updateView = function (forSketch) { + var visualMapModel = this.visualMapModel; + var dataExtent = visualMapModel.getExtent(); + var shapes = this._shapes; + var outOfRangeHandleEnds = [0, visualMapModel.itemSize[1]]; + var inRangeHandleEnds = forSketch ? outOfRangeHandleEnds : this._handleEnds; + var visualInRange = this._createBarVisual(this._dataInterval, dataExtent, inRangeHandleEnds, 'inRange'); + var visualOutOfRange = this._createBarVisual(dataExtent, dataExtent, outOfRangeHandleEnds, 'outOfRange'); + shapes.inRange.setStyle({ + fill: visualInRange.barColor + // opacity: visualInRange.opacity + }).setShape('points', visualInRange.barPoints); + shapes.outOfRange.setStyle({ + fill: visualOutOfRange.barColor + // opacity: visualOutOfRange.opacity + }).setShape('points', visualOutOfRange.barPoints); + this._updateHandle(inRangeHandleEnds, visualInRange); + }; + ContinuousView.prototype._createBarVisual = function (dataInterval, dataExtent, handleEnds, forceState) { + var opts = { + forceState: forceState, + convertOpacityToAlpha: true + }; + var colorStops = this._makeColorGradient(dataInterval, opts); + var symbolSizes = [this.getControllerVisual(dataInterval[0], 'symbolSize', opts), this.getControllerVisual(dataInterval[1], 'symbolSize', opts)]; + var barPoints = this._createBarPoints(handleEnds, symbolSizes); + return { + barColor: new LinearGradient(0, 0, 0, 1, colorStops), + barPoints: barPoints, + handlesColor: [colorStops[0].color, colorStops[colorStops.length - 1].color] + }; + }; + ContinuousView.prototype._makeColorGradient = function (dataInterval, opts) { + // Considering colorHue, which is not linear, so we have to sample + // to calculate gradient color stops, but not only calculate head + // and tail. + var sampleNumber = 100; // Arbitrary value. + var colorStops = []; + var step = (dataInterval[1] - dataInterval[0]) / sampleNumber; + colorStops.push({ + color: this.getControllerVisual(dataInterval[0], 'color', opts), + offset: 0 + }); + for (var i = 1; i < sampleNumber; i++) { + var currValue = dataInterval[0] + step * i; + if (currValue > dataInterval[1]) { + break; + } + colorStops.push({ + color: this.getControllerVisual(currValue, 'color', opts), + offset: i / sampleNumber + }); + } + colorStops.push({ + color: this.getControllerVisual(dataInterval[1], 'color', opts), + offset: 1 + }); + return colorStops; + }; + ContinuousView.prototype._createBarPoints = function (handleEnds, symbolSizes) { + var itemSize = this.visualMapModel.itemSize; + return [[itemSize[0] - symbolSizes[0], handleEnds[0]], [itemSize[0], handleEnds[0]], [itemSize[0], handleEnds[1]], [itemSize[0] - symbolSizes[1], handleEnds[1]]]; + }; + ContinuousView.prototype._createBarGroup = function (itemAlign) { + var orient = this._orient; + var inverse = this.visualMapModel.get('inverse'); + return new Group(orient === 'horizontal' && !inverse ? { + scaleX: itemAlign === 'bottom' ? 1 : -1, + rotation: Math.PI / 2 + } : orient === 'horizontal' && inverse ? { + scaleX: itemAlign === 'bottom' ? -1 : 1, + rotation: -Math.PI / 2 + } : orient === 'vertical' && !inverse ? { + scaleX: itemAlign === 'left' ? 1 : -1, + scaleY: -1 + } : { + scaleX: itemAlign === 'left' ? 1 : -1 + }); + }; + ContinuousView.prototype._updateHandle = function (handleEnds, visualInRange) { + if (!this._useHandle) { + return; + } + var shapes = this._shapes; + var visualMapModel = this.visualMapModel; + var handleThumbs = shapes.handleThumbs; + var handleLabels = shapes.handleLabels; + var itemSize = visualMapModel.itemSize; + var dataExtent = visualMapModel.getExtent(); + each$e([0, 1], function (handleIndex) { + var handleThumb = handleThumbs[handleIndex]; + handleThumb.setStyle('fill', visualInRange.handlesColor[handleIndex]); + handleThumb.y = handleEnds[handleIndex]; + var val = linearMap$2(handleEnds[handleIndex], [0, itemSize[1]], dataExtent, true); + var symbolSize = this.getControllerVisual(val, 'symbolSize'); + handleThumb.scaleX = handleThumb.scaleY = symbolSize / itemSize[0]; + handleThumb.x = itemSize[0] - symbolSize / 2; + // Update handle label position. + var textPoint = applyTransform$1(shapes.handleLabelPoints[handleIndex], getTransform(handleThumb, this.group)); + handleLabels[handleIndex].setStyle({ + x: textPoint[0], + y: textPoint[1], + text: visualMapModel.formatValueText(this._dataInterval[handleIndex]), + verticalAlign: 'middle', + align: this._orient === 'vertical' ? this._applyTransform('left', shapes.mainGroup) : 'center' + }); + }, this); + }; + ContinuousView.prototype._showIndicator = function (cursorValue, textValue, rangeSymbol, halfHoverLinkSize) { + var visualMapModel = this.visualMapModel; + var dataExtent = visualMapModel.getExtent(); + var itemSize = visualMapModel.itemSize; + var sizeExtent = [0, itemSize[1]]; + var shapes = this._shapes; + var indicator = shapes.indicator; + if (!indicator) { + return; + } + indicator.attr('invisible', false); + var opts = { + convertOpacityToAlpha: true + }; + var color = this.getControllerVisual(cursorValue, 'color', opts); + var symbolSize = this.getControllerVisual(cursorValue, 'symbolSize'); + var y = linearMap$2(cursorValue, dataExtent, sizeExtent, true); + var x = itemSize[0] - symbolSize / 2; + var oldIndicatorPos = { + x: indicator.x, + y: indicator.y + }; + // Update handle label position. + indicator.y = y; + indicator.x = x; + var textPoint = applyTransform$1(shapes.indicatorLabelPoint, getTransform(indicator, this.group)); + var indicatorLabel = shapes.indicatorLabel; + indicatorLabel.attr('invisible', false); + var align = this._applyTransform('left', shapes.mainGroup); + var orient = this._orient; + var isHorizontal = orient === 'horizontal'; + indicatorLabel.setStyle({ + text: (rangeSymbol ? rangeSymbol : '') + visualMapModel.formatValueText(textValue), + verticalAlign: isHorizontal ? align : 'middle', + align: isHorizontal ? 'center' : align + }); + var indicatorNewProps = { + x: x, + y: y, + style: { + fill: color + } + }; + var labelNewProps = { + style: { + x: textPoint[0], + y: textPoint[1] + } + }; + if (visualMapModel.ecModel.isAnimationEnabled() && !this._firstShowIndicator) { + var animationCfg = { + duration: 100, + easing: 'cubicInOut', + additive: true + }; + indicator.x = oldIndicatorPos.x; + indicator.y = oldIndicatorPos.y; + indicator.animateTo(indicatorNewProps, animationCfg); + indicatorLabel.animateTo(labelNewProps, animationCfg); + } else { + indicator.attr(indicatorNewProps); + indicatorLabel.attr(labelNewProps); + } + this._firstShowIndicator = false; + var handleLabels = this._shapes.handleLabels; + if (handleLabels) { + for (var i = 0; i < handleLabels.length; i++) { + // Fade out handle labels. + // NOTE: Must use api enter/leave on emphasis/blur/select state. Or the global states manager will change it. + this.api.enterBlur(handleLabels[i]); + } + } + }; + ContinuousView.prototype._enableHoverLinkToSeries = function () { + var self = this; + this._shapes.mainGroup.on('mousemove', function (e) { + self._hovering = true; + if (!self._dragging) { + var itemSize = self.visualMapModel.itemSize; + var pos = self._applyTransform([e.offsetX, e.offsetY], self._shapes.mainGroup, true, true); + // For hover link show when hover handle, which might be + // below or upper than sizeExtent. + pos[1] = mathMin$a(mathMax$a(0, pos[1]), itemSize[1]); + self._doHoverLinkToSeries(pos[1], 0 <= pos[0] && pos[0] <= itemSize[0]); + } + }).on('mouseout', function () { + // When mouse is out of handle, hoverLink still need + // to be displayed when realtime is set as false. + self._hovering = false; + !self._dragging && self._clearHoverLinkToSeries(); + }); + }; + ContinuousView.prototype._enableHoverLinkFromSeries = function () { + var zr = this.api.getZr(); + if (this.visualMapModel.option.hoverLink) { + zr.on('mouseover', this._hoverLinkFromSeriesMouseOver, this); + zr.on('mouseout', this._hideIndicator, this); + } else { + this._clearHoverLinkFromSeries(); + } + }; + ContinuousView.prototype._doHoverLinkToSeries = function (cursorPos, hoverOnBar) { + var visualMapModel = this.visualMapModel; + var itemSize = visualMapModel.itemSize; + if (!visualMapModel.option.hoverLink) { + return; + } + var sizeExtent = [0, itemSize[1]]; + var dataExtent = visualMapModel.getExtent(); + // For hover link show when hover handle, which might be below or upper than sizeExtent. + cursorPos = mathMin$a(mathMax$a(sizeExtent[0], cursorPos), sizeExtent[1]); + var halfHoverLinkSize = getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent); + var hoverRange = [cursorPos - halfHoverLinkSize, cursorPos + halfHoverLinkSize]; + var cursorValue = linearMap$2(cursorPos, sizeExtent, dataExtent, true); + var valueRange = [linearMap$2(hoverRange[0], sizeExtent, dataExtent, true), linearMap$2(hoverRange[1], sizeExtent, dataExtent, true)]; + // Consider data range is out of visualMap range, see test/visualMap-continuous.html, + // where china and india has very large population. + hoverRange[0] < sizeExtent[0] && (valueRange[0] = -Infinity); + hoverRange[1] > sizeExtent[1] && (valueRange[1] = Infinity); + // Do not show indicator when mouse is over handle, + // otherwise labels overlap, especially when dragging. + if (hoverOnBar) { + if (valueRange[0] === -Infinity) { + this._showIndicator(cursorValue, valueRange[1], '< ', halfHoverLinkSize); + } else if (valueRange[1] === Infinity) { + this._showIndicator(cursorValue, valueRange[0], '> ', halfHoverLinkSize); + } else { + this._showIndicator(cursorValue, cursorValue, '≈ ', halfHoverLinkSize); + } + } + // When realtime is set as false, handles, which are in barGroup, + // also trigger hoverLink, which help user to realize where they + // focus on when dragging. (see test/heatmap-large.html) + // When realtime is set as true, highlight will not show when hover + // handle, because the label on handle, which displays a exact value + // but not range, might mislead users. + var oldBatch = this._hoverLinkDataIndices; + var newBatch = []; + if (hoverOnBar || useHoverLinkOnHandle(visualMapModel)) { + newBatch = this._hoverLinkDataIndices = visualMapModel.findTargetDataIndices(valueRange); + } + var resultBatches = compressBatches(oldBatch, newBatch); + this._dispatchHighDown('downplay', makeHighDownBatch(resultBatches[0], visualMapModel)); + this._dispatchHighDown('highlight', makeHighDownBatch(resultBatches[1], visualMapModel)); + }; + ContinuousView.prototype._hoverLinkFromSeriesMouseOver = function (e) { + var ecData; + findEventDispatcher(e.target, function (target) { + var currECData = getECData(target); + if (currECData.dataIndex != null) { + ecData = currECData; + return true; + } + }, true); + if (!ecData) { + return; + } + var dataModel = this.ecModel.getSeriesByIndex(ecData.seriesIndex); + var visualMapModel = this.visualMapModel; + if (!visualMapModel.isTargetSeries(dataModel)) { + return; + } + var data = dataModel.getData(ecData.dataType); + var value = data.getStore().get(visualMapModel.getDataDimensionIndex(data), ecData.dataIndex); + if (!isNaN(value)) { + this._showIndicator(value, value); + } + }; + ContinuousView.prototype._hideIndicator = function () { + var shapes = this._shapes; + shapes.indicator && shapes.indicator.attr('invisible', true); + shapes.indicatorLabel && shapes.indicatorLabel.attr('invisible', true); + var handleLabels = this._shapes.handleLabels; + if (handleLabels) { + for (var i = 0; i < handleLabels.length; i++) { + // Fade out handle labels. + // NOTE: Must use api enter/leave on emphasis/blur/select state. Or the global states manager will change it. + this.api.leaveBlur(handleLabels[i]); + } + } + }; + ContinuousView.prototype._clearHoverLinkToSeries = function () { + this._hideIndicator(); + var indices = this._hoverLinkDataIndices; + this._dispatchHighDown('downplay', makeHighDownBatch(indices, this.visualMapModel)); + indices.length = 0; + }; + ContinuousView.prototype._clearHoverLinkFromSeries = function () { + this._hideIndicator(); + var zr = this.api.getZr(); + zr.off('mouseover', this._hoverLinkFromSeriesMouseOver); + zr.off('mouseout', this._hideIndicator); + }; + ContinuousView.prototype._applyTransform = function (vertex, element, inverse, global) { + var transform = getTransform(element, global ? null : this.group); + return isArray(vertex) ? applyTransform$1(vertex, transform, inverse) : transformDirection(vertex, transform, inverse); + }; + // TODO: TYPE more specified payload types. + ContinuousView.prototype._dispatchHighDown = function (type, batch) { + batch && batch.length && this.api.dispatchAction({ + type: type, + batch: batch + }); + }; + /** + * @override + */ + ContinuousView.prototype.dispose = function () { + this._clearHoverLinkFromSeries(); + this._clearHoverLinkToSeries(); + }; + ContinuousView.type = 'visualMap.continuous'; + return ContinuousView; + }(VisualMapView); + function createPolygon(points, cursor, onDrift, onDragEnd) { + return new Polygon({ + shape: { + points: points + }, + draggable: !!onDrift, + cursor: cursor, + drift: onDrift, + onmousemove: function (e) { + // For mobile device, prevent screen slider on the button. + stop(e.event); + }, + ondragend: onDragEnd + }); + } + function getHalfHoverLinkSize(visualMapModel, dataExtent, sizeExtent) { + var halfHoverLinkSize = HOVER_LINK_SIZE / 2; + var hoverLinkDataSize = visualMapModel.get('hoverLinkDataSize'); + if (hoverLinkDataSize) { + halfHoverLinkSize = linearMap$2(hoverLinkDataSize, dataExtent, sizeExtent, true) / 2; + } + return halfHoverLinkSize; + } + function useHoverLinkOnHandle(visualMapModel) { + var hoverLinkOnHandle = visualMapModel.get('hoverLinkOnHandle'); + return !!(hoverLinkOnHandle == null ? visualMapModel.get('realtime') : hoverLinkOnHandle); + } + function getCursor$1(orient) { + return orient === 'vertical' ? 'ns-resize' : 'ew-resize'; + } + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + + + /** + * AUTO-GENERATED FILE. DO NOT MODIFY. + */ + + /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + var visualMapActionInfo = { + type: 'selectDataRange', + event: 'dataRangeSelected', + // FIXME use updateView appears wrong + update: 'update' + }; + var visualMapActionHander = function (payload, ecModel) { + ecModel.eachComponent({ + mainType: 'visualMap', + query: payload + }, function (model) { + model.setSelected(payload.selected); + }); + }; + + var visualMapEncodingHandlers = [{ + createOnAllSeries: true, + reset: function (seriesModel, ecModel) { + var resetDefines = []; + ecModel.eachComponent('visualMap', function (visualMapModel) { + var pipelineContext = seriesModel.pipelineContext; + if (!visualMapModel.isTargetSeries(seriesModel) || pipelineContext && pipelineContext.large) { + return; + } + resetDefines.push(incrementalApplyVisual(visualMapModel.stateList, visualMapModel.targetVisuals, bind(visualMapModel.getValueState, visualMapModel), visualMapModel.getDataDimensionIndex(seriesModel.getData()))); + }); + return resetDefines; + } + }, + // Only support color. + { + createOnAllSeries: true, + reset: function (seriesModel, ecModel) { + var data = seriesModel.getData(); + var visualMetaList = []; + ecModel.eachComponent('visualMap', function (visualMapModel) { + if (visualMapModel.isTargetSeries(seriesModel)) { + var visualMeta = visualMapModel.getVisualMeta(bind(getColorVisual, null, seriesModel, visualMapModel)) || { + stops: [], + outerColors: [] + }; + var dimIdx = visualMapModel.getDataDimensionIndex(data); + if (dimIdx >= 0) { + // visualMeta.dimension should be dimension index, but not concrete dimension. + visualMeta.dimension = dimIdx; + visualMetaList.push(visualMeta); + } + } + }); + // console.log(JSON.stringify(visualMetaList.map(a => a.stops))); + seriesModel.getData().setVisual('visualMeta', visualMetaList); + } + }]; + // FIXME + // performance and export for heatmap? + // value can be Infinity or -Infinity + function getColorVisual(seriesModel, visualMapModel, value, valueState) { + var mappings = visualMapModel.targetVisuals[valueState]; + var visualTypes = VisualMapping.prepareVisualTypes(mappings); + var resultVisual = { + color: getVisualFromData(seriesModel.getData(), 'color') // default color. + }; + + for (var i = 0, len = visualTypes.length; i < len; i++) { + var type = visualTypes[i]; + var mapping = mappings[type === 'opacity' ? '__alphaForOpacity' : type]; + mapping && mapping.applyVisual(value, getVisual, setVisual); + } + return resultVisual.color; + function getVisual(key) { + return resultVisual[key]; + } + function setVisual(key, value) { + resultVisual[key] = value; + } + } + + var each$f = each; + function visualMapPreprocessor(option) { + var visualMap = option && option.visualMap; + if (!isArray(visualMap)) { + visualMap = visualMap ? [visualMap] : []; + } + each$f(visualMap, function (opt) { + if (!opt) { + return; + } + // rename splitList to pieces + if (has$1(opt, 'splitList') && !has$1(opt, 'pieces')) { + opt.pieces = opt.splitList; + delete opt.splitList; + } + var pieces = opt.pieces; + if (pieces && isArray(pieces)) { + each$f(pieces, function (piece) { + if (isObject(piece)) { + if (has$1(piece, 'start') && !has$1(piece, 'min')) { + piece.min = piece.start; + } + if (has$1(piece, 'end') && !has$1(piece, 'max')) { + piece.max = piece.end; + } + } + }); + } + }); + } + function has$1(obj, name) { + return obj && obj.hasOwnProperty && obj.hasOwnProperty(name); + } + + var installed$1 = false; + function installCommon$1(registers) { + if (installed$1) { + return; + } + installed$1 = true; + registers.registerSubTypeDefaulter('visualMap', function (option) { + // Compatible with ec2, when splitNumber === 0, continuous visualMap will be used. + return !option.categories && (!(option.pieces ? option.pieces.length > 0 : option.splitNumber > 0) || option.calculable) ? 'continuous' : 'piecewise'; + }); + registers.registerAction(visualMapActionInfo, visualMapActionHander); + each(visualMapEncodingHandlers, function (handler) { + registers.registerVisual(registers.PRIORITY.VISUAL.COMPONENT, handler); + }); + registers.registerPreprocessor(visualMapPreprocessor); + } + + function install$N(registers) { + registers.registerComponentModel(ContinuousModel); + registers.registerComponentView(ContinuousView); + installCommon$1(registers); + } + + var PiecewiseModel = /** @class */function (_super) { + __extends(PiecewiseModel, _super); + function PiecewiseModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = PiecewiseModel.type; + /** + * The order is always [low, ..., high]. + * [{text: string, interval: Array.}, ...] + */ + _this._pieceList = []; + return _this; + } + PiecewiseModel.prototype.optionUpdated = function (newOption, isInit) { + _super.prototype.optionUpdated.apply(this, arguments); + this.resetExtent(); + var mode = this._mode = this._determineMode(); + this._pieceList = []; + resetMethods[this._mode].call(this, this._pieceList); + this._resetSelected(newOption, isInit); + var categories = this.option.categories; + this.resetVisual(function (mappingOption, state) { + if (mode === 'categories') { + mappingOption.mappingMethod = 'category'; + mappingOption.categories = clone(categories); + } else { + mappingOption.dataExtent = this.getExtent(); + mappingOption.mappingMethod = 'piecewise'; + mappingOption.pieceList = map(this._pieceList, function (piece) { + piece = clone(piece); + if (state !== 'inRange') { + // FIXME + // outOfRange do not support special visual in pieces. + piece.visual = null; + } + return piece; + }); + } + }); + }; + /** + * @protected + * @override + */ + PiecewiseModel.prototype.completeVisualOption = function () { + // Consider this case: + // visualMap: { + // pieces: [{symbol: 'circle', lt: 0}, {symbol: 'rect', gte: 0}] + // } + // where no inRange/outOfRange set but only pieces. So we should make + // default inRange/outOfRange for this case, otherwise visuals that only + // appear in `pieces` will not be taken into account in visual encoding. + var option = this.option; + var visualTypesInPieces = {}; + var visualTypes = VisualMapping.listVisualTypes(); + var isCategory = this.isCategory(); + each(option.pieces, function (piece) { + each(visualTypes, function (visualType) { + if (piece.hasOwnProperty(visualType)) { + visualTypesInPieces[visualType] = 1; + } + }); + }); + each(visualTypesInPieces, function (v, visualType) { + var exists = false; + each(this.stateList, function (state) { + exists = exists || has(option, state, visualType) || has(option.target, state, visualType); + }, this); + !exists && each(this.stateList, function (state) { + (option[state] || (option[state] = {}))[visualType] = visualDefault.get(visualType, state === 'inRange' ? 'active' : 'inactive', isCategory); + }); + }, this); + function has(obj, state, visualType) { + return obj && obj[state] && obj[state].hasOwnProperty(visualType); + } + _super.prototype.completeVisualOption.apply(this, arguments); + }; + PiecewiseModel.prototype._resetSelected = function (newOption, isInit) { + var thisOption = this.option; + var pieceList = this._pieceList; + // Selected do not merge but all override. + var selected = (isInit ? thisOption : newOption).selected || {}; + thisOption.selected = selected; + // Consider 'not specified' means true. + each(pieceList, function (piece, index) { + var key = this.getSelectedMapKey(piece); + if (!selected.hasOwnProperty(key)) { + selected[key] = true; + } + }, this); + if (thisOption.selectedMode === 'single') { + // Ensure there is only one selected. + var hasSel_1 = false; + each(pieceList, function (piece, index) { + var key = this.getSelectedMapKey(piece); + if (selected[key]) { + hasSel_1 ? selected[key] = false : hasSel_1 = true; + } + }, this); + } + // thisOption.selectedMode === 'multiple', default: all selected. + }; + /** + * @public + */ + PiecewiseModel.prototype.getItemSymbol = function () { + return this.get('itemSymbol'); + }; + /** + * @public + */ + PiecewiseModel.prototype.getSelectedMapKey = function (piece) { + return this._mode === 'categories' ? piece.value + '' : piece.index + ''; + }; + /** + * @public + */ + PiecewiseModel.prototype.getPieceList = function () { + return this._pieceList; + }; + /** + * @return {string} + */ + PiecewiseModel.prototype._determineMode = function () { + var option = this.option; + return option.pieces && option.pieces.length > 0 ? 'pieces' : this.option.categories ? 'categories' : 'splitNumber'; + }; + /** + * @override + */ + PiecewiseModel.prototype.setSelected = function (selected) { + this.option.selected = clone(selected); + }; + /** + * @override + */ + PiecewiseModel.prototype.getValueState = function (value) { + var index = VisualMapping.findPieceIndex(value, this._pieceList); + return index != null ? this.option.selected[this.getSelectedMapKey(this._pieceList[index])] ? 'inRange' : 'outOfRange' : 'outOfRange'; + }; + /** + * @public + * @param pieceIndex piece index in visualMapModel.getPieceList() + */ + PiecewiseModel.prototype.findTargetDataIndices = function (pieceIndex) { + var result = []; + var pieceList = this._pieceList; + this.eachTargetSeries(function (seriesModel) { + var dataIndices = []; + var data = seriesModel.getData(); + data.each(this.getDataDimensionIndex(data), function (value, dataIndex) { + // Should always base on model pieceList, because it is order sensitive. + var pIdx = VisualMapping.findPieceIndex(value, pieceList); + pIdx === pieceIndex && dataIndices.push(dataIndex); + }, this); + result.push({ + seriesId: seriesModel.id, + dataIndex: dataIndices + }); + }, this); + return result; + }; + /** + * @private + * @param piece piece.value or piece.interval is required. + * @return Can be Infinity or -Infinity + */ + PiecewiseModel.prototype.getRepresentValue = function (piece) { + var representValue; + if (this.isCategory()) { + representValue = piece.value; + } else { + if (piece.value != null) { + representValue = piece.value; + } else { + var pieceInterval = piece.interval || []; + representValue = pieceInterval[0] === -Infinity && pieceInterval[1] === Infinity ? 0 : (pieceInterval[0] + pieceInterval[1]) / 2; + } + } + return representValue; + }; + PiecewiseModel.prototype.getVisualMeta = function (getColorVisual) { + // Do not support category. (category axis is ordinal, numerical) + if (this.isCategory()) { + return; + } + var stops = []; + var outerColors = ['', '']; + var visualMapModel = this; + function setStop(interval, valueState) { + var representValue = visualMapModel.getRepresentValue({ + interval: interval + }); // Not category + if (!valueState) { + valueState = visualMapModel.getValueState(representValue); + } + var color = getColorVisual(representValue, valueState); + if (interval[0] === -Infinity) { + outerColors[0] = color; + } else if (interval[1] === Infinity) { + outerColors[1] = color; + } else { + stops.push({ + value: interval[0], + color: color + }, { + value: interval[1], + color: color + }); + } + } + // Suplement + var pieceList = this._pieceList.slice(); + if (!pieceList.length) { + pieceList.push({ + interval: [-Infinity, Infinity] + }); + } else { + var edge = pieceList[0].interval[0]; + edge !== -Infinity && pieceList.unshift({ + interval: [-Infinity, edge] + }); + edge = pieceList[pieceList.length - 1].interval[1]; + edge !== Infinity && pieceList.push({ + interval: [edge, Infinity] + }); + } + var curr = -Infinity; + each(pieceList, function (piece) { + var interval = piece.interval; + if (interval) { + // Fulfill gap. + interval[0] > curr && setStop([curr, interval[0]], 'outOfRange'); + setStop(interval.slice()); + curr = interval[1]; + } + }, this); + return { + stops: stops, + outerColors: outerColors + }; + }; + PiecewiseModel.type = 'visualMap.piecewise'; + PiecewiseModel.defaultOption = inheritDefaultOption(VisualMapModel.defaultOption, { + selected: null, + minOpen: false, + maxOpen: false, + align: 'auto', + itemWidth: 20, + itemHeight: 14, + itemSymbol: 'roundRect', + pieces: null, + categories: null, + splitNumber: 5, + selectedMode: 'multiple', + itemGap: 10, + hoverLink: true // Enable hover highlight. + }); + + return PiecewiseModel; + }(VisualMapModel); + /** + * Key is this._mode + * @type {Object} + * @this {module:echarts/component/viusalMap/PiecewiseMode} + */ + var resetMethods = { + splitNumber: function (outPieceList) { + var thisOption = this.option; + var precision = Math.min(thisOption.precision, 20); + var dataExtent = this.getExtent(); + var splitNumber = thisOption.splitNumber; + splitNumber = Math.max(parseInt(splitNumber, 10), 1); + thisOption.splitNumber = splitNumber; + var splitStep = (dataExtent[1] - dataExtent[0]) / splitNumber; + // Precision auto-adaption + while (+splitStep.toFixed(precision) !== splitStep && precision < 5) { + precision++; + } + thisOption.precision = precision; + splitStep = +splitStep.toFixed(precision); + if (thisOption.minOpen) { + outPieceList.push({ + interval: [-Infinity, dataExtent[0]], + close: [0, 0] + }); + } + for (var index = 0, curr = dataExtent[0]; index < splitNumber; curr += splitStep, index++) { + var max = index === splitNumber - 1 ? dataExtent[1] : curr + splitStep; + outPieceList.push({ + interval: [curr, max], + close: [1, 1] + }); + } + if (thisOption.maxOpen) { + outPieceList.push({ + interval: [dataExtent[1], Infinity], + close: [0, 0] + }); + } + reformIntervals(outPieceList); + each(outPieceList, function (piece, index) { + piece.index = index; + piece.text = this.formatValueText(piece.interval); + }, this); + }, + categories: function (outPieceList) { + var thisOption = this.option; + each(thisOption.categories, function (cate) { + // FIXME category模式也使用pieceList,但在visualMapping中不是使用pieceList。 + // 是否改一致。 + outPieceList.push({ + text: this.formatValueText(cate, true), + value: cate + }); + }, this); + // See "Order Rule". + normalizeReverse(thisOption, outPieceList); + }, + pieces: function (outPieceList) { + var thisOption = this.option; + each(thisOption.pieces, function (pieceListItem, index) { + if (!isObject(pieceListItem)) { + pieceListItem = { + value: pieceListItem + }; + } + var item = { + text: '', + index: index + }; + if (pieceListItem.label != null) { + item.text = pieceListItem.label; + } + if (pieceListItem.hasOwnProperty('value')) { + var value = item.value = pieceListItem.value; + item.interval = [value, value]; + item.close = [1, 1]; + } else { + // `min` `max` is legacy option. + // `lt` `gt` `lte` `gte` is recommended. + var interval = item.interval = []; + var close_1 = item.close = [0, 0]; + var closeList = [1, 0, 1]; + var infinityList = [-Infinity, Infinity]; + var useMinMax = []; + for (var lg = 0; lg < 2; lg++) { + var names = [['gte', 'gt', 'min'], ['lte', 'lt', 'max']][lg]; + for (var i = 0; i < 3 && interval[lg] == null; i++) { + interval[lg] = pieceListItem[names[i]]; + close_1[lg] = closeList[i]; + useMinMax[lg] = i === 2; + } + interval[lg] == null && (interval[lg] = infinityList[lg]); + } + useMinMax[0] && interval[1] === Infinity && (close_1[0] = 0); + useMinMax[1] && interval[0] === -Infinity && (close_1[1] = 0); + if ("development" !== 'production') { + if (interval[0] > interval[1]) { + console.warn('Piece ' + index + 'is illegal: ' + interval + ' lower bound should not greater then uppper bound.'); + } + } + if (interval[0] === interval[1] && close_1[0] && close_1[1]) { + // Consider: [{min: 5, max: 5, visual: {...}}, {min: 0, max: 5}], + // we use value to lift the priority when min === max + item.value = interval[0]; + } + } + item.visual = VisualMapping.retrieveVisuals(pieceListItem); + outPieceList.push(item); + }, this); + // See "Order Rule". + normalizeReverse(thisOption, outPieceList); + // Only pieces + reformIntervals(outPieceList); + each(outPieceList, function (piece) { + var close = piece.close; + var edgeSymbols = [['<', '≤'][close[1]], ['>', '≥'][close[0]]]; + piece.text = piece.text || this.formatValueText(piece.value != null ? piece.value : piece.interval, false, edgeSymbols); + }, this); + } + }; + function normalizeReverse(thisOption, pieceList) { + var inverse = thisOption.inverse; + if (thisOption.orient === 'vertical' ? !inverse : inverse) { + pieceList.reverse(); + } + } + + var PiecewiseVisualMapView = /** @class */function (_super) { + __extends(PiecewiseVisualMapView, _super); + function PiecewiseVisualMapView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = PiecewiseVisualMapView.type; + return _this; + } + PiecewiseVisualMapView.prototype.doRender = function () { + var thisGroup = this.group; + thisGroup.removeAll(); + var visualMapModel = this.visualMapModel; + var textGap = visualMapModel.get('textGap'); + var textStyleModel = visualMapModel.textStyleModel; + var textFont = textStyleModel.getFont(); + var textFill = textStyleModel.getTextColor(); + var itemAlign = this._getItemAlign(); + var itemSize = visualMapModel.itemSize; + var viewData = this._getViewData(); + var endsText = viewData.endsText; + var showLabel = retrieve(visualMapModel.get('showLabel', true), !endsText); + endsText && this._renderEndsText(thisGroup, endsText[0], itemSize, showLabel, itemAlign); + each(viewData.viewPieceList, function (item) { + var piece = item.piece; + var itemGroup = new Group(); + itemGroup.onclick = bind(this._onItemClick, this, piece); + this._enableHoverLink(itemGroup, item.indexInModelPieceList); + // TODO Category + var representValue = visualMapModel.getRepresentValue(piece); + this._createItemSymbol(itemGroup, representValue, [0, 0, itemSize[0], itemSize[1]]); + if (showLabel) { + var visualState = this.visualMapModel.getValueState(representValue); + itemGroup.add(new ZRText({ + style: { + x: itemAlign === 'right' ? -textGap : itemSize[0] + textGap, + y: itemSize[1] / 2, + text: piece.text, + verticalAlign: 'middle', + align: itemAlign, + font: textFont, + fill: textFill, + opacity: visualState === 'outOfRange' ? 0.5 : 1 + } + })); + } + thisGroup.add(itemGroup); + }, this); + endsText && this._renderEndsText(thisGroup, endsText[1], itemSize, showLabel, itemAlign); + box(visualMapModel.get('orient'), thisGroup, visualMapModel.get('itemGap')); + this.renderBackground(thisGroup); + this.positionGroup(thisGroup); + }; + PiecewiseVisualMapView.prototype._enableHoverLink = function (itemGroup, pieceIndex) { + var _this = this; + itemGroup.on('mouseover', function () { + return onHoverLink('highlight'); + }).on('mouseout', function () { + return onHoverLink('downplay'); + }); + var onHoverLink = function (method) { + var visualMapModel = _this.visualMapModel; + // TODO: TYPE More detailed action types + visualMapModel.option.hoverLink && _this.api.dispatchAction({ + type: method, + batch: makeHighDownBatch(visualMapModel.findTargetDataIndices(pieceIndex), visualMapModel) + }); + }; + }; + PiecewiseVisualMapView.prototype._getItemAlign = function () { + var visualMapModel = this.visualMapModel; + var modelOption = visualMapModel.option; + if (modelOption.orient === 'vertical') { + return getItemAlign(visualMapModel, this.api, visualMapModel.itemSize); + } else { + // horizontal, most case left unless specifying right. + var align = modelOption.align; + if (!align || align === 'auto') { + align = 'left'; + } + return align; + } + }; + PiecewiseVisualMapView.prototype._renderEndsText = function (group, text, itemSize, showLabel, itemAlign) { + if (!text) { + return; + } + var itemGroup = new Group(); + var textStyleModel = this.visualMapModel.textStyleModel; + itemGroup.add(new ZRText({ + style: createTextStyle(textStyleModel, { + x: showLabel ? itemAlign === 'right' ? itemSize[0] : 0 : itemSize[0] / 2, + y: itemSize[1] / 2, + verticalAlign: 'middle', + align: showLabel ? itemAlign : 'center', + text: text + }) + })); + group.add(itemGroup); + }; + /** + * @private + * @return {Object} {peiceList, endsText} The order is the same as screen pixel order. + */ + PiecewiseVisualMapView.prototype._getViewData = function () { + var visualMapModel = this.visualMapModel; + var viewPieceList = map(visualMapModel.getPieceList(), function (piece, index) { + return { + piece: piece, + indexInModelPieceList: index + }; + }); + var endsText = visualMapModel.get('text'); + // Consider orient and inverse. + var orient = visualMapModel.get('orient'); + var inverse = visualMapModel.get('inverse'); + // Order of model pieceList is always [low, ..., high] + if (orient === 'horizontal' ? inverse : !inverse) { + viewPieceList.reverse(); + } + // Origin order of endsText is [high, low] + else if (endsText) { + endsText = endsText.slice().reverse(); + } + return { + viewPieceList: viewPieceList, + endsText: endsText + }; + }; + PiecewiseVisualMapView.prototype._createItemSymbol = function (group, representValue, shapeParam) { + group.add(createSymbol( + // symbol will be string + this.getControllerVisual(representValue, 'symbol'), shapeParam[0], shapeParam[1], shapeParam[2], shapeParam[3], + // color will be string + this.getControllerVisual(representValue, 'color'))); + }; + PiecewiseVisualMapView.prototype._onItemClick = function (piece) { + var visualMapModel = this.visualMapModel; + var option = visualMapModel.option; + var selectedMode = option.selectedMode; + if (!selectedMode) { + return; + } + var selected = clone(option.selected); + var newKey = visualMapModel.getSelectedMapKey(piece); + if (selectedMode === 'single' || selectedMode === true) { + selected[newKey] = true; + each(selected, function (o, key) { + selected[key] = key === newKey; + }); + } else { + selected[newKey] = !selected[newKey]; + } + this.api.dispatchAction({ + type: 'selectDataRange', + from: this.uid, + visualMapId: this.visualMapModel.id, + selected: selected + }); + }; + PiecewiseVisualMapView.type = 'visualMap.piecewise'; + return PiecewiseVisualMapView; + }(VisualMapView); + + function install$O(registers) { + registers.registerComponentModel(PiecewiseModel); + registers.registerComponentView(PiecewiseVisualMapView); + installCommon$1(registers); + } + + function install$P(registers) { + use(install$N); + use(install$O); + // Do not install './dataZoomSelect', + // since it only work for toolbox dataZoom. + } + + var DEFAULT_OPTION = { + label: { + enabled: true + }, + decal: { + show: false + } + }; + var inner$l = makeInner(); + var decalPaletteScope = {}; + function ariaVisual(ecModel, api) { + var ariaModel = ecModel.getModel('aria'); + // See "area enabled" detection code in `GlobalModel.ts`. + if (!ariaModel.get('enabled')) { + return; + } + var defaultOption = clone(DEFAULT_OPTION); + merge(defaultOption.label, ecModel.getLocaleModel().get('aria'), false); + merge(ariaModel.option, defaultOption, false); + setDecal(); + setLabel(); + function setDecal() { + var decalModel = ariaModel.getModel('decal'); + var useDecal = decalModel.get('show'); + if (useDecal) { + // Each type of series use one scope. + // Pie and funnel are using different scopes. + var paletteScopeGroupByType_1 = createHashMap(); + ecModel.eachSeries(function (seriesModel) { + if (seriesModel.isColorBySeries()) { + return; + } + var decalScope = paletteScopeGroupByType_1.get(seriesModel.type); + if (!decalScope) { + decalScope = {}; + paletteScopeGroupByType_1.set(seriesModel.type, decalScope); + } + inner$l(seriesModel).scope = decalScope; + }); + ecModel.eachRawSeries(function (seriesModel) { + if (ecModel.isSeriesFiltered(seriesModel)) { + return; + } + if (isFunction(seriesModel.enableAriaDecal)) { + // Let series define how to use decal palette on data + seriesModel.enableAriaDecal(); + return; + } + var data = seriesModel.getData(); + if (!seriesModel.isColorBySeries()) { + var dataAll_1 = seriesModel.getRawData(); + var idxMap_1 = {}; + var decalScope_1 = inner$l(seriesModel).scope; + data.each(function (idx) { + var rawIdx = data.getRawIndex(idx); + idxMap_1[rawIdx] = idx; + }); + var dataCount_1 = dataAll_1.count(); + dataAll_1.each(function (rawIdx) { + var idx = idxMap_1[rawIdx]; + var name = dataAll_1.getName(rawIdx) || rawIdx + ''; + var paletteDecal = getDecalFromPalette(seriesModel.ecModel, name, decalScope_1, dataCount_1); + var specifiedDecal = data.getItemVisual(idx, 'decal'); + data.setItemVisual(idx, 'decal', mergeDecal(specifiedDecal, paletteDecal)); + }); + } else { + var paletteDecal = getDecalFromPalette(seriesModel.ecModel, seriesModel.name, decalPaletteScope, ecModel.getSeriesCount()); + var specifiedDecal = data.getVisual('decal'); + data.setVisual('decal', mergeDecal(specifiedDecal, paletteDecal)); + } + function mergeDecal(specifiedDecal, paletteDecal) { + // Merge decal from palette to decal from itemStyle. + // User do not need to specify all of the decal props. + var resultDecal = specifiedDecal ? extend(extend({}, paletteDecal), specifiedDecal) : paletteDecal; + resultDecal.dirty = true; + return resultDecal; + } + }); + } + } + function setLabel() { + var labelLocale = ecModel.getLocaleModel().get('aria'); + var labelModel = ariaModel.getModel('label'); + labelModel.option = defaults(labelModel.option, labelLocale); + if (!labelModel.get('enabled')) { + return; + } + var dom = api.getZr().dom; + if (labelModel.get('description')) { + dom.setAttribute('aria-label', labelModel.get('description')); + return; + } + var seriesCnt = ecModel.getSeriesCount(); + var maxDataCnt = labelModel.get(['data', 'maxCount']) || 10; + var maxSeriesCnt = labelModel.get(['series', 'maxCount']) || 10; + var displaySeriesCnt = Math.min(seriesCnt, maxSeriesCnt); + var ariaLabel; + if (seriesCnt < 1) { + // No series, no aria label + return; + } else { + var title = getTitle(); + if (title) { + var withTitle = labelModel.get(['general', 'withTitle']); + ariaLabel = replace(withTitle, { + title: title + }); + } else { + ariaLabel = labelModel.get(['general', 'withoutTitle']); + } + var seriesLabels_1 = []; + var prefix = seriesCnt > 1 ? labelModel.get(['series', 'multiple', 'prefix']) : labelModel.get(['series', 'single', 'prefix']); + ariaLabel += replace(prefix, { + seriesCount: seriesCnt + }); + ecModel.eachSeries(function (seriesModel, idx) { + if (idx < displaySeriesCnt) { + var seriesLabel = void 0; + var seriesName = seriesModel.get('name'); + var withName = seriesName ? 'withName' : 'withoutName'; + seriesLabel = seriesCnt > 1 ? labelModel.get(['series', 'multiple', withName]) : labelModel.get(['series', 'single', withName]); + seriesLabel = replace(seriesLabel, { + seriesId: seriesModel.seriesIndex, + seriesName: seriesModel.get('name'), + seriesType: getSeriesTypeName(seriesModel.subType) + }); + var data = seriesModel.getData(); + if (data.count() > maxDataCnt) { + // Show part of data + var partialLabel = labelModel.get(['data', 'partialData']); + seriesLabel += replace(partialLabel, { + displayCnt: maxDataCnt + }); + } else { + seriesLabel += labelModel.get(['data', 'allData']); + } + var middleSeparator_1 = labelModel.get(['data', 'separator', 'middle']); + var endSeparator_1 = labelModel.get(['data', 'separator', 'end']); + var dataLabels = []; + for (var i = 0; i < data.count(); i++) { + if (i < maxDataCnt) { + var name_1 = data.getName(i); + var value = data.getValues(i); + var dataLabel = labelModel.get(['data', name_1 ? 'withName' : 'withoutName']); + dataLabels.push(replace(dataLabel, { + name: name_1, + value: value.join(middleSeparator_1) + })); + } + } + seriesLabel += dataLabels.join(middleSeparator_1) + endSeparator_1; + seriesLabels_1.push(seriesLabel); + } + }); + var separatorModel = labelModel.getModel(['series', 'multiple', 'separator']); + var middleSeparator = separatorModel.get('middle'); + var endSeparator = separatorModel.get('end'); + ariaLabel += seriesLabels_1.join(middleSeparator) + endSeparator; + dom.setAttribute('aria-label', ariaLabel); + } + } + function replace(str, keyValues) { + if (!isString(str)) { + return str; + } + var result = str; + each(keyValues, function (value, key) { + result = result.replace(new RegExp('\\{\\s*' + key + '\\s*\\}', 'g'), value); + }); + return result; + } + function getTitle() { + var title = ecModel.get('title'); + if (title && title.length) { + title = title[0]; + } + return title && title.text; + } + function getSeriesTypeName(type) { + var typeNames = ecModel.getLocaleModel().get(['series', 'typeNames']); + return typeNames[type] || typeNames.chart; + } + } + + function ariaPreprocessor(option) { + if (!option || !option.aria) { + return; + } + var aria = option.aria; + // aria.show is deprecated and should use aria.enabled instead + if (aria.show != null) { + aria.enabled = aria.show; + } + aria.label = aria.label || {}; + // move description, general, series, data to be under aria.label + each(['description', 'general', 'series', 'data'], function (name) { + if (aria[name] != null) { + aria.label[name] = aria[name]; + } + }); + } + + function install$Q(registers) { + registers.registerPreprocessor(ariaPreprocessor); + registers.registerVisual(registers.PRIORITY.VISUAL.ARIA, ariaVisual); + } + + var RELATIONAL_EXPRESSION_OP_ALIAS_MAP = { + value: 'eq', + // PENDING: not good for literal semantic? + '<': 'lt', + '<=': 'lte', + '>': 'gt', + '>=': 'gte', + '=': 'eq', + '!=': 'ne', + '<>': 'ne' + // Might be misleading for sake of the difference between '==' and '===', + // so don't support them. + // '==': 'eq', + // '===': 'seq', + // '!==': 'sne' + // PENDING: Whether support some common alias "ge", "le", "neq"? + // ge: 'gte', + // le: 'lte', + // neq: 'ne', + }; + // type RelationalExpressionOpEvaluate = (tarVal: unknown, condVal: unknown) => boolean; + var RegExpEvaluator = /** @class */function () { + function RegExpEvaluator(rVal) { + // Support condVal: RegExp | string + var condValue = this._condVal = isString(rVal) ? new RegExp(rVal) : isRegExp(rVal) ? rVal : null; + if (condValue == null) { + var errMsg = ''; + if ("development" !== 'production') { + errMsg = makePrintable('Illegal regexp', rVal, 'in'); + } + throwError(errMsg); + } + } + RegExpEvaluator.prototype.evaluate = function (lVal) { + var type = typeof lVal; + return isString(type) ? this._condVal.test(lVal) : isNumber(type) ? this._condVal.test(lVal + '') : false; + }; + return RegExpEvaluator; + }(); + var ConstConditionInternal = /** @class */function () { + function ConstConditionInternal() {} + ConstConditionInternal.prototype.evaluate = function () { + return this.value; + }; + return ConstConditionInternal; + }(); + var AndConditionInternal = /** @class */function () { + function AndConditionInternal() {} + AndConditionInternal.prototype.evaluate = function () { + var children = this.children; + for (var i = 0; i < children.length; i++) { + if (!children[i].evaluate()) { + return false; + } + } + return true; + }; + return AndConditionInternal; + }(); + var OrConditionInternal = /** @class */function () { + function OrConditionInternal() {} + OrConditionInternal.prototype.evaluate = function () { + var children = this.children; + for (var i = 0; i < children.length; i++) { + if (children[i].evaluate()) { + return true; + } + } + return false; + }; + return OrConditionInternal; + }(); + var NotConditionInternal = /** @class */function () { + function NotConditionInternal() {} + NotConditionInternal.prototype.evaluate = function () { + return !this.child.evaluate(); + }; + return NotConditionInternal; + }(); + var RelationalConditionInternal = /** @class */function () { + function RelationalConditionInternal() {} + RelationalConditionInternal.prototype.evaluate = function () { + var needParse = !!this.valueParser; + // Call getValue with no `this`. + var getValue = this.getValue; + var tarValRaw = getValue(this.valueGetterParam); + var tarValParsed = needParse ? this.valueParser(tarValRaw) : null; + // Relational cond follow "and" logic internally. + for (var i = 0; i < this.subCondList.length; i++) { + if (!this.subCondList[i].evaluate(needParse ? tarValParsed : tarValRaw)) { + return false; + } + } + return true; + }; + return RelationalConditionInternal; + }(); + function parseOption(exprOption, getters) { + if (exprOption === true || exprOption === false) { + var cond = new ConstConditionInternal(); + cond.value = exprOption; + return cond; + } + var errMsg = ''; + if (!isObjectNotArray(exprOption)) { + if ("development" !== 'production') { + errMsg = makePrintable('Illegal config. Expect a plain object but actually', exprOption); + } + throwError(errMsg); + } + if (exprOption.and) { + return parseAndOrOption('and', exprOption, getters); + } else if (exprOption.or) { + return parseAndOrOption('or', exprOption, getters); + } else if (exprOption.not) { + return parseNotOption(exprOption, getters); + } + return parseRelationalOption(exprOption, getters); + } + function parseAndOrOption(op, exprOption, getters) { + var subOptionArr = exprOption[op]; + var errMsg = ''; + if ("development" !== 'production') { + errMsg = makePrintable('"and"/"or" condition should only be `' + op + ': [...]` and must not be empty array.', 'Illegal condition:', exprOption); + } + if (!isArray(subOptionArr)) { + throwError(errMsg); + } + if (!subOptionArr.length) { + throwError(errMsg); + } + var cond = op === 'and' ? new AndConditionInternal() : new OrConditionInternal(); + cond.children = map(subOptionArr, function (subOption) { + return parseOption(subOption, getters); + }); + if (!cond.children.length) { + throwError(errMsg); + } + return cond; + } + function parseNotOption(exprOption, getters) { + var subOption = exprOption.not; + var errMsg = ''; + if ("development" !== 'production') { + errMsg = makePrintable('"not" condition should only be `not: {}`.', 'Illegal condition:', exprOption); + } + if (!isObjectNotArray(subOption)) { + throwError(errMsg); + } + var cond = new NotConditionInternal(); + cond.child = parseOption(subOption, getters); + if (!cond.child) { + throwError(errMsg); + } + return cond; + } + function parseRelationalOption(exprOption, getters) { + var errMsg = ''; + var valueGetterParam = getters.prepareGetValue(exprOption); + var subCondList = []; + var exprKeys = keys(exprOption); + var parserName = exprOption.parser; + var valueParser = parserName ? getRawValueParser(parserName) : null; + for (var i = 0; i < exprKeys.length; i++) { + var keyRaw = exprKeys[i]; + if (keyRaw === 'parser' || getters.valueGetterAttrMap.get(keyRaw)) { + continue; + } + var op = hasOwn(RELATIONAL_EXPRESSION_OP_ALIAS_MAP, keyRaw) ? RELATIONAL_EXPRESSION_OP_ALIAS_MAP[keyRaw] : keyRaw; + var condValueRaw = exprOption[keyRaw]; + var condValueParsed = valueParser ? valueParser(condValueRaw) : condValueRaw; + var evaluator = createFilterComparator(op, condValueParsed) || op === 'reg' && new RegExpEvaluator(condValueParsed); + if (!evaluator) { + if ("development" !== 'production') { + errMsg = makePrintable('Illegal relational operation: "' + keyRaw + '" in condition:', exprOption); + } + throwError(errMsg); + } + subCondList.push(evaluator); + } + if (!subCondList.length) { + if ("development" !== 'production') { + errMsg = makePrintable('Relational condition must have at least one operator.', 'Illegal condition:', exprOption); + } + // No relational operator always disabled in case of dangers result. + throwError(errMsg); + } + var cond = new RelationalConditionInternal(); + cond.valueGetterParam = valueGetterParam; + cond.valueParser = valueParser; + cond.getValue = getters.getValue; + cond.subCondList = subCondList; + return cond; + } + function isObjectNotArray(val) { + return isObject(val) && !isArrayLike(val); + } + var ConditionalExpressionParsed = /** @class */function () { + function ConditionalExpressionParsed(exprOption, getters) { + this._cond = parseOption(exprOption, getters); + } + ConditionalExpressionParsed.prototype.evaluate = function () { + return this._cond.evaluate(); + }; + return ConditionalExpressionParsed; + }(); + function parseConditionalExpression(exprOption, getters) { + return new ConditionalExpressionParsed(exprOption, getters); + } + + var filterTransform = { + type: 'echarts:filter', + // PENDING: enhance to filter by index rather than create new data + transform: function (params) { + // [Caveat] Fail-Fast: + // Do not return the whole dataset unless user config indicates it explicitly. + // For example, if no condition is specified by mistake, returning an empty result + // is better than returning the entire raw source for the user to find the mistake. + var upstream = params.upstream; + var rawItem; + var condition = parseConditionalExpression(params.config, { + valueGetterAttrMap: createHashMap({ + dimension: true + }), + prepareGetValue: function (exprOption) { + var errMsg = ''; + var dimLoose = exprOption.dimension; + if (!hasOwn(exprOption, 'dimension')) { + if ("development" !== 'production') { + errMsg = makePrintable('Relation condition must has prop "dimension" specified.', 'Illegal condition:', exprOption); + } + throwError(errMsg); + } + var dimInfo = upstream.getDimensionInfo(dimLoose); + if (!dimInfo) { + if ("development" !== 'production') { + errMsg = makePrintable('Can not find dimension info via: ' + dimLoose + '.\n', 'Existing dimensions: ', upstream.cloneAllDimensionInfo(), '.\n', 'Illegal condition:', exprOption, '.\n'); + } + throwError(errMsg); + } + return { + dimIdx: dimInfo.index + }; + }, + getValue: function (param) { + return upstream.retrieveValueFromItem(rawItem, param.dimIdx); + } + }); + var resultData = []; + for (var i = 0, len = upstream.count(); i < len; i++) { + rawItem = upstream.getRawDataItem(i); + if (condition.evaluate()) { + resultData.push(rawItem); + } + } + return { + data: resultData + }; + } + }; + + var sampleLog = ''; + if ("development" !== 'production') { + sampleLog = ['Valid config is like:', '{ dimension: "age", order: "asc" }', 'or [{ dimension: "age", order: "asc"], { dimension: "date", order: "desc" }]'].join(' '); + } + var sortTransform = { + type: 'echarts:sort', + transform: function (params) { + var upstream = params.upstream; + var config = params.config; + var errMsg = ''; + // Normalize + // const orderExprList: OrderExpression[] = isArray(config[0]) + // ? config as OrderExpression[] + // : [config as OrderExpression]; + var orderExprList = normalizeToArray(config); + if (!orderExprList.length) { + if ("development" !== 'production') { + errMsg = 'Empty `config` in sort transform.'; + } + throwError(errMsg); + } + var orderDefList = []; + each(orderExprList, function (orderExpr) { + var dimLoose = orderExpr.dimension; + var order = orderExpr.order; + var parserName = orderExpr.parser; + var incomparable = orderExpr.incomparable; + if (dimLoose == null) { + if ("development" !== 'production') { + errMsg = 'Sort transform config must has "dimension" specified.' + sampleLog; + } + throwError(errMsg); + } + if (order !== 'asc' && order !== 'desc') { + if ("development" !== 'production') { + errMsg = 'Sort transform config must has "order" specified.' + sampleLog; + } + throwError(errMsg); + } + if (incomparable && incomparable !== 'min' && incomparable !== 'max') { + var errMsg_1 = ''; + if ("development" !== 'production') { + errMsg_1 = 'incomparable must be "min" or "max" rather than "' + incomparable + '".'; + } + throwError(errMsg_1); + } + if (order !== 'asc' && order !== 'desc') { + var errMsg_2 = ''; + if ("development" !== 'production') { + errMsg_2 = 'order must be "asc" or "desc" rather than "' + order + '".'; + } + throwError(errMsg_2); + } + var dimInfo = upstream.getDimensionInfo(dimLoose); + if (!dimInfo) { + if ("development" !== 'production') { + errMsg = makePrintable('Can not find dimension info via: ' + dimLoose + '.\n', 'Existing dimensions: ', upstream.cloneAllDimensionInfo(), '.\n', 'Illegal config:', orderExpr, '.\n'); + } + throwError(errMsg); + } + var parser = parserName ? getRawValueParser(parserName) : null; + if (parserName && !parser) { + if ("development" !== 'production') { + errMsg = makePrintable('Invalid parser name ' + parserName + '.\n', 'Illegal config:', orderExpr, '.\n'); + } + throwError(errMsg); + } + orderDefList.push({ + dimIdx: dimInfo.index, + parser: parser, + comparator: new SortOrderComparator(order, incomparable) + }); + }); + // TODO: support it? + var sourceFormat = upstream.sourceFormat; + if (sourceFormat !== SOURCE_FORMAT_ARRAY_ROWS && sourceFormat !== SOURCE_FORMAT_OBJECT_ROWS) { + if ("development" !== 'production') { + errMsg = 'sourceFormat "' + sourceFormat + '" is not supported yet'; + } + throwError(errMsg); + } + // Other upstream format are all array. + var resultData = []; + for (var i = 0, len = upstream.count(); i < len; i++) { + resultData.push(upstream.getRawDataItem(i)); + } + resultData.sort(function (item0, item1) { + for (var i = 0; i < orderDefList.length; i++) { + var orderDef = orderDefList[i]; + var val0 = upstream.retrieveValueFromItem(item0, orderDef.dimIdx); + var val1 = upstream.retrieveValueFromItem(item1, orderDef.dimIdx); + if (orderDef.parser) { + val0 = orderDef.parser(val0); + val1 = orderDef.parser(val1); + } + var result = orderDef.comparator.evaluate(val0, val1); + if (result !== 0) { + return result; + } + } + return 0; + }); + return { + data: resultData + }; + } + }; + + function install$R(registers) { + registers.registerTransform(filterTransform); + registers.registerTransform(sortTransform); + } + + var DatasetModel = /** @class */function (_super) { + __extends(DatasetModel, _super); + function DatasetModel() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = 'dataset'; + return _this; + } + DatasetModel.prototype.init = function (option, parentModel, ecModel) { + _super.prototype.init.call(this, option, parentModel, ecModel); + this._sourceManager = new SourceManager(this); + disableTransformOptionMerge(this); + }; + DatasetModel.prototype.mergeOption = function (newOption, ecModel) { + _super.prototype.mergeOption.call(this, newOption, ecModel); + disableTransformOptionMerge(this); + }; + DatasetModel.prototype.optionUpdated = function () { + this._sourceManager.dirty(); + }; + DatasetModel.prototype.getSourceManager = function () { + return this._sourceManager; + }; + DatasetModel.type = 'dataset'; + DatasetModel.defaultOption = { + seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN + }; + return DatasetModel; + }(ComponentModel); + var DatasetView = /** @class */function (_super) { + __extends(DatasetView, _super); + function DatasetView() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.type = 'dataset'; + return _this; + } + DatasetView.type = 'dataset'; + return DatasetView; + }(ComponentView); + function install$S(registers) { + registers.registerComponentModel(DatasetModel); + registers.registerComponentView(DatasetView); + } + + var CMD$4 = PathProxy.CMD; + function aroundEqual(a, b) { + return Math.abs(a - b) < 1e-5; + } + function pathToBezierCurves(path) { + var data = path.data; + var len = path.len(); + var bezierArrayGroups = []; + var currentSubpath; + var xi = 0; + var yi = 0; + var x0 = 0; + var y0 = 0; + function createNewSubpath(x, y) { + if (currentSubpath && currentSubpath.length > 2) { + bezierArrayGroups.push(currentSubpath); + } + currentSubpath = [x, y]; + } + function addLine(x0, y0, x1, y1) { + if (!(aroundEqual(x0, x1) && aroundEqual(y0, y1))) { + currentSubpath.push(x0, y0, x1, y1, x1, y1); + } + } + function addArc(startAngle, endAngle, cx, cy, rx, ry) { + var delta = Math.abs(endAngle - startAngle); + var len = Math.tan(delta / 4) * 4 / 3; + var dir = endAngle < startAngle ? -1 : 1; + var c1 = Math.cos(startAngle); + var s1 = Math.sin(startAngle); + var c2 = Math.cos(endAngle); + var s2 = Math.sin(endAngle); + var x1 = c1 * rx + cx; + var y1 = s1 * ry + cy; + var x4 = c2 * rx + cx; + var y4 = s2 * ry + cy; + var hx = rx * len * dir; + var hy = ry * len * dir; + currentSubpath.push(x1 - hx * s1, y1 + hy * c1, x4 + hx * s2, y4 - hy * c2, x4, y4); + } + var x1; + var y1; + var x2; + var y2; + for (var i = 0; i < len;) { + var cmd = data[i++]; + var isFirst = i === 1; + if (isFirst) { + xi = data[i]; + yi = data[i + 1]; + x0 = xi; + y0 = yi; + if (cmd === CMD$4.L || cmd === CMD$4.C || cmd === CMD$4.Q) { + currentSubpath = [x0, y0]; + } + } + switch (cmd) { + case CMD$4.M: + xi = x0 = data[i++]; + yi = y0 = data[i++]; + createNewSubpath(x0, y0); + break; + case CMD$4.L: + x1 = data[i++]; + y1 = data[i++]; + addLine(xi, yi, x1, y1); + xi = x1; + yi = y1; + break; + case CMD$4.C: + currentSubpath.push(data[i++], data[i++], data[i++], data[i++], xi = data[i++], yi = data[i++]); + break; + case CMD$4.Q: + x1 = data[i++]; + y1 = data[i++]; + x2 = data[i++]; + y2 = data[i++]; + currentSubpath.push(xi + 2 / 3 * (x1 - xi), yi + 2 / 3 * (y1 - yi), x2 + 2 / 3 * (x1 - x2), y2 + 2 / 3 * (y1 - y2), x2, y2); + xi = x2; + yi = y2; + break; + case CMD$4.A: + var cx = data[i++]; + var cy = data[i++]; + var rx = data[i++]; + var ry = data[i++]; + var startAngle = data[i++]; + var endAngle = data[i++] + startAngle; + i += 1; + var anticlockwise = !data[i++]; + x1 = Math.cos(startAngle) * rx + cx; + y1 = Math.sin(startAngle) * ry + cy; + if (isFirst) { + x0 = x1; + y0 = y1; + createNewSubpath(x0, y0); + } + else { + addLine(xi, yi, x1, y1); + } + xi = Math.cos(endAngle) * rx + cx; + yi = Math.sin(endAngle) * ry + cy; + var step = (anticlockwise ? -1 : 1) * Math.PI / 2; + for (var angle = startAngle; anticlockwise ? angle > endAngle : angle < endAngle; angle += step) { + var nextAngle = anticlockwise ? Math.max(angle + step, endAngle) + : Math.min(angle + step, endAngle); + addArc(angle, nextAngle, cx, cy, rx, ry); + } + break; + case CMD$4.R: + x0 = xi = data[i++]; + y0 = yi = data[i++]; + x1 = x0 + data[i++]; + y1 = y0 + data[i++]; + createNewSubpath(x1, y0); + addLine(x1, y0, x1, y1); + addLine(x1, y1, x0, y1); + addLine(x0, y1, x0, y0); + addLine(x0, y0, x1, y0); + break; + case CMD$4.Z: + currentSubpath && addLine(xi, yi, x0, y0); + xi = x0; + yi = y0; + break; + } + } + if (currentSubpath && currentSubpath.length > 2) { + bezierArrayGroups.push(currentSubpath); + } + return bezierArrayGroups; + } + function adpativeBezier(x0, y0, x1, y1, x2, y2, x3, y3, out, scale) { + if (aroundEqual(x0, x1) && aroundEqual(y0, y1) && aroundEqual(x2, x3) && aroundEqual(y2, y3)) { + out.push(x3, y3); + return; + } + var PIXEL_DISTANCE = 2 / scale; + var PIXEL_DISTANCE_SQR = PIXEL_DISTANCE * PIXEL_DISTANCE; + var dx = x3 - x0; + var dy = y3 - y0; + var d = Math.sqrt(dx * dx + dy * dy); + dx /= d; + dy /= d; + var dx1 = x1 - x0; + var dy1 = y1 - y0; + var dx2 = x2 - x3; + var dy2 = y2 - y3; + var cp1LenSqr = dx1 * dx1 + dy1 * dy1; + var cp2LenSqr = dx2 * dx2 + dy2 * dy2; + if (cp1LenSqr < PIXEL_DISTANCE_SQR && cp2LenSqr < PIXEL_DISTANCE_SQR) { + out.push(x3, y3); + return; + } + var projLen1 = dx * dx1 + dy * dy1; + var projLen2 = -dx * dx2 - dy * dy2; + var d1Sqr = cp1LenSqr - projLen1 * projLen1; + var d2Sqr = cp2LenSqr - projLen2 * projLen2; + if (d1Sqr < PIXEL_DISTANCE_SQR && projLen1 >= 0 + && d2Sqr < PIXEL_DISTANCE_SQR && projLen2 >= 0) { + out.push(x3, y3); + return; + } + var tmpSegX = []; + var tmpSegY = []; + cubicSubdivide(x0, x1, x2, x3, 0.5, tmpSegX); + cubicSubdivide(y0, y1, y2, y3, 0.5, tmpSegY); + adpativeBezier(tmpSegX[0], tmpSegY[0], tmpSegX[1], tmpSegY[1], tmpSegX[2], tmpSegY[2], tmpSegX[3], tmpSegY[3], out, scale); + adpativeBezier(tmpSegX[4], tmpSegY[4], tmpSegX[5], tmpSegY[5], tmpSegX[6], tmpSegY[6], tmpSegX[7], tmpSegY[7], out, scale); + } + function pathToPolygons(path, scale) { + var bezierArrayGroups = pathToBezierCurves(path); + var polygons = []; + scale = scale || 1; + for (var i = 0; i < bezierArrayGroups.length; i++) { + var beziers = bezierArrayGroups[i]; + var polygon = []; + var x0 = beziers[0]; + var y0 = beziers[1]; + polygon.push(x0, y0); + for (var k = 2; k < beziers.length;) { + var x1 = beziers[k++]; + var y1 = beziers[k++]; + var x2 = beziers[k++]; + var y2 = beziers[k++]; + var x3 = beziers[k++]; + var y3 = beziers[k++]; + adpativeBezier(x0, y0, x1, y1, x2, y2, x3, y3, polygon, scale); + x0 = x3; + y0 = y3; + } + polygons.push(polygon); + } + return polygons; + } + + function getDividingGrids(dimSize, rowDim, count) { + var rowSize = dimSize[rowDim]; + var columnSize = dimSize[1 - rowDim]; + var ratio = Math.abs(rowSize / columnSize); + var rowCount = Math.ceil(Math.sqrt(ratio * count)); + var columnCount = Math.floor(count / rowCount); + if (columnCount === 0) { + columnCount = 1; + rowCount = count; + } + var grids = []; + for (var i = 0; i < rowCount; i++) { + grids.push(columnCount); + } + var currentCount = rowCount * columnCount; + var remained = count - currentCount; + if (remained > 0) { + for (var i = 0; i < remained; i++) { + grids[i % rowCount] += 1; + } + } + return grids; + } + function divideSector(sectorShape, count, outShapes) { + var r0 = sectorShape.r0; + var r = sectorShape.r; + var startAngle = sectorShape.startAngle; + var endAngle = sectorShape.endAngle; + var angle = Math.abs(endAngle - startAngle); + var arcLen = angle * r; + var deltaR = r - r0; + var isAngleRow = arcLen > Math.abs(deltaR); + var grids = getDividingGrids([arcLen, deltaR], isAngleRow ? 0 : 1, count); + var rowSize = (isAngleRow ? angle : deltaR) / grids.length; + for (var row = 0; row < grids.length; row++) { + var columnSize = (isAngleRow ? deltaR : angle) / grids[row]; + for (var column = 0; column < grids[row]; column++) { + var newShape = {}; + if (isAngleRow) { + newShape.startAngle = startAngle + rowSize * row; + newShape.endAngle = startAngle + rowSize * (row + 1); + newShape.r0 = r0 + columnSize * column; + newShape.r = r0 + columnSize * (column + 1); + } + else { + newShape.startAngle = startAngle + columnSize * column; + newShape.endAngle = startAngle + columnSize * (column + 1); + newShape.r0 = r0 + rowSize * row; + newShape.r = r0 + rowSize * (row + 1); + } + newShape.clockwise = sectorShape.clockwise; + newShape.cx = sectorShape.cx; + newShape.cy = sectorShape.cy; + outShapes.push(newShape); + } + } + } + function divideRect(rectShape, count, outShapes) { + var width = rectShape.width; + var height = rectShape.height; + var isHorizontalRow = width > height; + var grids = getDividingGrids([width, height], isHorizontalRow ? 0 : 1, count); + var rowSizeDim = isHorizontalRow ? 'width' : 'height'; + var columnSizeDim = isHorizontalRow ? 'height' : 'width'; + var rowDim = isHorizontalRow ? 'x' : 'y'; + var columnDim = isHorizontalRow ? 'y' : 'x'; + var rowSize = rectShape[rowSizeDim] / grids.length; + for (var row = 0; row < grids.length; row++) { + var columnSize = rectShape[columnSizeDim] / grids[row]; + for (var column = 0; column < grids[row]; column++) { + var newShape = {}; + newShape[rowDim] = row * rowSize; + newShape[columnDim] = column * columnSize; + newShape[rowSizeDim] = rowSize; + newShape[columnSizeDim] = columnSize; + newShape.x += rectShape.x; + newShape.y += rectShape.y; + outShapes.push(newShape); + } + } + } + function crossProduct2d$1(x1, y1, x2, y2) { + return x1 * y2 - x2 * y1; + } + function lineLineIntersect$1(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y) { + var mx = a2x - a1x; + var my = a2y - a1y; + var nx = b2x - b1x; + var ny = b2y - b1y; + var nmCrossProduct = crossProduct2d$1(nx, ny, mx, my); + if (Math.abs(nmCrossProduct) < 1e-6) { + return null; + } + var b1a1x = a1x - b1x; + var b1a1y = a1y - b1y; + var p = crossProduct2d$1(b1a1x, b1a1y, nx, ny) / nmCrossProduct; + if (p < 0 || p > 1) { + return null; + } + return new Point(p * mx + a1x, p * my + a1y); + } + function projPtOnLine(pt, lineA, lineB) { + var dir = new Point(); + Point.sub(dir, lineB, lineA); + dir.normalize(); + var dir2 = new Point(); + Point.sub(dir2, pt, lineA); + var len = dir2.dot(dir); + return len; + } + function addToPoly(poly, pt) { + var last = poly[poly.length - 1]; + if (last && last[0] === pt[0] && last[1] === pt[1]) { + return; + } + poly.push(pt); + } + function splitPolygonByLine(points, lineA, lineB) { + var len = points.length; + var intersections = []; + for (var i = 0; i < len; i++) { + var p0 = points[i]; + var p1 = points[(i + 1) % len]; + var intersectionPt = lineLineIntersect$1(p0[0], p0[1], p1[0], p1[1], lineA.x, lineA.y, lineB.x, lineB.y); + if (intersectionPt) { + intersections.push({ + projPt: projPtOnLine(intersectionPt, lineA, lineB), + pt: intersectionPt, + idx: i + }); + } + } + if (intersections.length < 2) { + return [{ points: points }, { points: points }]; + } + intersections.sort(function (a, b) { + return a.projPt - b.projPt; + }); + var splitPt0 = intersections[0]; + var splitPt1 = intersections[intersections.length - 1]; + if (splitPt1.idx < splitPt0.idx) { + var tmp = splitPt0; + splitPt0 = splitPt1; + splitPt1 = tmp; + } + var splitPt0Arr = [splitPt0.pt.x, splitPt0.pt.y]; + var splitPt1Arr = [splitPt1.pt.x, splitPt1.pt.y]; + var newPolyA = [splitPt0Arr]; + var newPolyB = [splitPt1Arr]; + for (var i = splitPt0.idx + 1; i <= splitPt1.idx; i++) { + addToPoly(newPolyA, points[i].slice()); + } + addToPoly(newPolyA, splitPt1Arr); + addToPoly(newPolyA, splitPt0Arr); + for (var i = splitPt1.idx + 1; i <= splitPt0.idx + len; i++) { + addToPoly(newPolyB, points[i % len].slice()); + } + addToPoly(newPolyB, splitPt0Arr); + addToPoly(newPolyB, splitPt1Arr); + return [{ + points: newPolyA + }, { + points: newPolyB + }]; + } + function binaryDividePolygon(polygonShape) { + var points = polygonShape.points; + var min = []; + var max = []; + fromPoints(points, min, max); + var boundingRect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]); + var width = boundingRect.width; + var height = boundingRect.height; + var x = boundingRect.x; + var y = boundingRect.y; + var pt0 = new Point(); + var pt1 = new Point(); + if (width > height) { + pt0.x = pt1.x = x + width / 2; + pt0.y = y; + pt1.y = y + height; + } + else { + pt0.y = pt1.y = y + height / 2; + pt0.x = x; + pt1.x = x + width; + } + return splitPolygonByLine(points, pt0, pt1); + } + function binaryDivideRecursive(divider, shape, count, out) { + if (count === 1) { + out.push(shape); + } + else { + var mid = Math.floor(count / 2); + var sub = divider(shape); + binaryDivideRecursive(divider, sub[0], mid, out); + binaryDivideRecursive(divider, sub[1], count - mid, out); + } + return out; + } + function clone$4(path, count) { + var paths = []; + for (var i = 0; i < count; i++) { + paths.push(clonePath(path)); + } + return paths; + } + function copyPathProps(source, target) { + target.setStyle(source.style); + target.z = source.z; + target.z2 = source.z2; + target.zlevel = source.zlevel; + } + function polygonConvert(points) { + var out = []; + for (var i = 0; i < points.length;) { + out.push([points[i++], points[i++]]); + } + return out; + } + function split(path, count) { + var outShapes = []; + var shape = path.shape; + var OutShapeCtor; + switch (path.type) { + case 'rect': + divideRect(shape, count, outShapes); + OutShapeCtor = Rect; + break; + case 'sector': + divideSector(shape, count, outShapes); + OutShapeCtor = Sector; + break; + case 'circle': + divideSector({ + r0: 0, r: shape.r, startAngle: 0, endAngle: Math.PI * 2, + cx: shape.cx, cy: shape.cy + }, count, outShapes); + OutShapeCtor = Sector; + break; + default: + var m = path.getComputedTransform(); + var scale = m ? Math.sqrt(Math.max(m[0] * m[0] + m[1] * m[1], m[2] * m[2] + m[3] * m[3])) : 1; + var polygons = map(pathToPolygons(path.getUpdatedPathProxy(), scale), function (poly) { return polygonConvert(poly); }); + var polygonCount = polygons.length; + if (polygonCount === 0) { + binaryDivideRecursive(binaryDividePolygon, { + points: polygons[0] + }, count, outShapes); + } + else if (polygonCount === count) { + for (var i = 0; i < polygonCount; i++) { + outShapes.push({ + points: polygons[i] + }); + } + } + else { + var totalArea_1 = 0; + var items = map(polygons, function (poly) { + var min = []; + var max = []; + fromPoints(poly, min, max); + var area = (max[1] - min[1]) * (max[0] - min[0]); + totalArea_1 += area; + return { poly: poly, area: area }; + }); + items.sort(function (a, b) { return b.area - a.area; }); + var left = count; + for (var i = 0; i < polygonCount; i++) { + var item = items[i]; + if (left <= 0) { + break; + } + var selfCount = i === polygonCount - 1 + ? left + : Math.ceil(item.area / totalArea_1 * count); + if (selfCount < 0) { + continue; + } + binaryDivideRecursive(binaryDividePolygon, { + points: item.poly + }, selfCount, outShapes); + left -= selfCount; + } + } + OutShapeCtor = Polygon; + break; + } + if (!OutShapeCtor) { + return clone$4(path, count); + } + var out = []; + for (var i = 0; i < outShapes.length; i++) { + var subPath = new OutShapeCtor(); + subPath.setShape(outShapes[i]); + copyPathProps(path, subPath); + out.push(subPath); + } + return out; + } + + function alignSubpath(subpath1, subpath2) { + var len1 = subpath1.length; + var len2 = subpath2.length; + if (len1 === len2) { + return [subpath1, subpath2]; + } + var tmpSegX = []; + var tmpSegY = []; + var shorterPath = len1 < len2 ? subpath1 : subpath2; + var shorterLen = Math.min(len1, len2); + var diff = Math.abs(len2 - len1) / 6; + var shorterBezierCount = (shorterLen - 2) / 6; + var eachCurveSubDivCount = Math.ceil(diff / shorterBezierCount) + 1; + var newSubpath = [shorterPath[0], shorterPath[1]]; + var remained = diff; + for (var i = 2; i < shorterLen;) { + var x0 = shorterPath[i - 2]; + var y0 = shorterPath[i - 1]; + var x1 = shorterPath[i++]; + var y1 = shorterPath[i++]; + var x2 = shorterPath[i++]; + var y2 = shorterPath[i++]; + var x3 = shorterPath[i++]; + var y3 = shorterPath[i++]; + if (remained <= 0) { + newSubpath.push(x1, y1, x2, y2, x3, y3); + continue; + } + var actualSubDivCount = Math.min(remained, eachCurveSubDivCount - 1) + 1; + for (var k = 1; k <= actualSubDivCount; k++) { + var p = k / actualSubDivCount; + cubicSubdivide(x0, x1, x2, x3, p, tmpSegX); + cubicSubdivide(y0, y1, y2, y3, p, tmpSegY); + x0 = tmpSegX[3]; + y0 = tmpSegY[3]; + newSubpath.push(tmpSegX[1], tmpSegY[1], tmpSegX[2], tmpSegY[2], x0, y0); + x1 = tmpSegX[5]; + y1 = tmpSegY[5]; + x2 = tmpSegX[6]; + y2 = tmpSegY[6]; + } + remained -= actualSubDivCount - 1; + } + return shorterPath === subpath1 ? [newSubpath, subpath2] : [subpath1, newSubpath]; + } + function createSubpath(lastSubpathSubpath, otherSubpath) { + var len = lastSubpathSubpath.length; + var lastX = lastSubpathSubpath[len - 2]; + var lastY = lastSubpathSubpath[len - 1]; + var newSubpath = []; + for (var i = 0; i < otherSubpath.length;) { + newSubpath[i++] = lastX; + newSubpath[i++] = lastY; + } + return newSubpath; + } + function alignBezierCurves(array1, array2) { + var _a; + var lastSubpath1; + var lastSubpath2; + var newArray1 = []; + var newArray2 = []; + for (var i = 0; i < Math.max(array1.length, array2.length); i++) { + var subpath1 = array1[i]; + var subpath2 = array2[i]; + var newSubpath1 = void 0; + var newSubpath2 = void 0; + if (!subpath1) { + newSubpath1 = createSubpath(lastSubpath1 || subpath2, subpath2); + newSubpath2 = subpath2; + } + else if (!subpath2) { + newSubpath2 = createSubpath(lastSubpath2 || subpath1, subpath1); + newSubpath1 = subpath1; + } + else { + _a = alignSubpath(subpath1, subpath2), newSubpath1 = _a[0], newSubpath2 = _a[1]; + lastSubpath1 = newSubpath1; + lastSubpath2 = newSubpath2; + } + newArray1.push(newSubpath1); + newArray2.push(newSubpath2); + } + return [newArray1, newArray2]; + } + function centroid$1(array) { + var signedArea = 0; + var cx = 0; + var cy = 0; + var len = array.length; + for (var i = 0, j = len - 2; i < len; j = i, i += 2) { + var x0 = array[j]; + var y0 = array[j + 1]; + var x1 = array[i]; + var y1 = array[i + 1]; + var a = x0 * y1 - x1 * y0; + signedArea += a; + cx += (x0 + x1) * a; + cy += (y0 + y1) * a; + } + if (signedArea === 0) { + return [array[0] || 0, array[1] || 0]; + } + return [cx / signedArea / 3, cy / signedArea / 3, signedArea]; + } + function findBestRingOffset(fromSubBeziers, toSubBeziers, fromCp, toCp) { + var bezierCount = (fromSubBeziers.length - 2) / 6; + var bestScore = Infinity; + var bestOffset = 0; + var len = fromSubBeziers.length; + var len2 = len - 2; + for (var offset = 0; offset < bezierCount; offset++) { + var cursorOffset = offset * 6; + var score = 0; + for (var k = 0; k < len; k += 2) { + var idx = k === 0 ? cursorOffset : ((cursorOffset + k - 2) % len2 + 2); + var x0 = fromSubBeziers[idx] - fromCp[0]; + var y0 = fromSubBeziers[idx + 1] - fromCp[1]; + var x1 = toSubBeziers[k] - toCp[0]; + var y1 = toSubBeziers[k + 1] - toCp[1]; + var dx = x1 - x0; + var dy = y1 - y0; + score += dx * dx + dy * dy; + } + if (score < bestScore) { + bestScore = score; + bestOffset = offset; + } + } + return bestOffset; + } + function reverse(array) { + var newArr = []; + var len = array.length; + for (var i = 0; i < len; i += 2) { + newArr[i] = array[len - i - 2]; + newArr[i + 1] = array[len - i - 1]; + } + return newArr; + } + function findBestMorphingRotation(fromArr, toArr, searchAngleIteration, searchAngleRange) { + var result = []; + var fromNeedsReverse; + for (var i = 0; i < fromArr.length; i++) { + var fromSubpathBezier = fromArr[i]; + var toSubpathBezier = toArr[i]; + var fromCp = centroid$1(fromSubpathBezier); + var toCp = centroid$1(toSubpathBezier); + if (fromNeedsReverse == null) { + fromNeedsReverse = fromCp[2] < 0 !== toCp[2] < 0; + } + var newFromSubpathBezier = []; + var newToSubpathBezier = []; + var bestAngle = 0; + var bestScore = Infinity; + var tmpArr = []; + var len = fromSubpathBezier.length; + if (fromNeedsReverse) { + fromSubpathBezier = reverse(fromSubpathBezier); + } + var offset = findBestRingOffset(fromSubpathBezier, toSubpathBezier, fromCp, toCp) * 6; + var len2 = len - 2; + for (var k = 0; k < len2; k += 2) { + var idx = (offset + k) % len2 + 2; + newFromSubpathBezier[k + 2] = fromSubpathBezier[idx] - fromCp[0]; + newFromSubpathBezier[k + 3] = fromSubpathBezier[idx + 1] - fromCp[1]; + } + newFromSubpathBezier[0] = fromSubpathBezier[offset] - fromCp[0]; + newFromSubpathBezier[1] = fromSubpathBezier[offset + 1] - fromCp[1]; + if (searchAngleIteration > 0) { + var step = searchAngleRange / searchAngleIteration; + for (var angle = -searchAngleRange / 2; angle <= searchAngleRange / 2; angle += step) { + var sa = Math.sin(angle); + var ca = Math.cos(angle); + var score = 0; + for (var k = 0; k < fromSubpathBezier.length; k += 2) { + var x0 = newFromSubpathBezier[k]; + var y0 = newFromSubpathBezier[k + 1]; + var x1 = toSubpathBezier[k] - toCp[0]; + var y1 = toSubpathBezier[k + 1] - toCp[1]; + var newX1 = x1 * ca - y1 * sa; + var newY1 = x1 * sa + y1 * ca; + tmpArr[k] = newX1; + tmpArr[k + 1] = newY1; + var dx = newX1 - x0; + var dy = newY1 - y0; + score += dx * dx + dy * dy; + } + if (score < bestScore) { + bestScore = score; + bestAngle = angle; + for (var m = 0; m < tmpArr.length; m++) { + newToSubpathBezier[m] = tmpArr[m]; + } + } + } + } + else { + for (var i_1 = 0; i_1 < len; i_1 += 2) { + newToSubpathBezier[i_1] = toSubpathBezier[i_1] - toCp[0]; + newToSubpathBezier[i_1 + 1] = toSubpathBezier[i_1 + 1] - toCp[1]; + } + } + result.push({ + from: newFromSubpathBezier, + to: newToSubpathBezier, + fromCp: fromCp, + toCp: toCp, + rotation: -bestAngle + }); + } + return result; + } + function isCombineMorphing(path) { + return path.__isCombineMorphing; + } + var SAVED_METHOD_PREFIX = '__mOriginal_'; + function saveAndModifyMethod(obj, methodName, modifiers) { + var savedMethodName = SAVED_METHOD_PREFIX + methodName; + var originalMethod = obj[savedMethodName] || obj[methodName]; + if (!obj[savedMethodName]) { + obj[savedMethodName] = obj[methodName]; + } + var replace = modifiers.replace; + var after = modifiers.after; + var before = modifiers.before; + obj[methodName] = function () { + var args = arguments; + var res; + before && before.apply(this, args); + if (replace) { + res = replace.apply(this, args); + } + else { + res = originalMethod.apply(this, args); + } + after && after.apply(this, args); + return res; + }; + } + function restoreMethod(obj, methodName) { + var savedMethodName = SAVED_METHOD_PREFIX + methodName; + if (obj[savedMethodName]) { + obj[methodName] = obj[savedMethodName]; + obj[savedMethodName] = null; + } + } + function applyTransformOnBeziers(bezierCurves, mm) { + for (var i = 0; i < bezierCurves.length; i++) { + var subBeziers = bezierCurves[i]; + for (var k = 0; k < subBeziers.length;) { + var x = subBeziers[k]; + var y = subBeziers[k + 1]; + subBeziers[k++] = mm[0] * x + mm[2] * y + mm[4]; + subBeziers[k++] = mm[1] * x + mm[3] * y + mm[5]; + } + } + } + function prepareMorphPath(fromPath, toPath) { + var fromPathProxy = fromPath.getUpdatedPathProxy(); + var toPathProxy = toPath.getUpdatedPathProxy(); + var _a = alignBezierCurves(pathToBezierCurves(fromPathProxy), pathToBezierCurves(toPathProxy)), fromBezierCurves = _a[0], toBezierCurves = _a[1]; + var fromPathTransform = fromPath.getComputedTransform(); + var toPathTransform = toPath.getComputedTransform(); + function updateIdentityTransform() { + this.transform = null; + } + fromPathTransform && applyTransformOnBeziers(fromBezierCurves, fromPathTransform); + toPathTransform && applyTransformOnBeziers(toBezierCurves, toPathTransform); + saveAndModifyMethod(toPath, 'updateTransform', { replace: updateIdentityTransform }); + toPath.transform = null; + var morphingData = findBestMorphingRotation(fromBezierCurves, toBezierCurves, 10, Math.PI); + var tmpArr = []; + saveAndModifyMethod(toPath, 'buildPath', { replace: function (path) { + var t = toPath.__morphT; + var onet = 1 - t; + var newCp = []; + for (var i = 0; i < morphingData.length; i++) { + var item = morphingData[i]; + var from = item.from; + var to = item.to; + var angle = item.rotation * t; + var fromCp = item.fromCp; + var toCp = item.toCp; + var sa = Math.sin(angle); + var ca = Math.cos(angle); + lerp(newCp, fromCp, toCp, t); + for (var m = 0; m < from.length; m += 2) { + var x0_1 = from[m]; + var y0_1 = from[m + 1]; + var x1 = to[m]; + var y1 = to[m + 1]; + var x = x0_1 * onet + x1 * t; + var y = y0_1 * onet + y1 * t; + tmpArr[m] = (x * ca - y * sa) + newCp[0]; + tmpArr[m + 1] = (x * sa + y * ca) + newCp[1]; + } + var x0 = tmpArr[0]; + var y0 = tmpArr[1]; + path.moveTo(x0, y0); + for (var m = 2; m < from.length;) { + var x1 = tmpArr[m++]; + var y1 = tmpArr[m++]; + var x2 = tmpArr[m++]; + var y2 = tmpArr[m++]; + var x3 = tmpArr[m++]; + var y3 = tmpArr[m++]; + if (x0 === x1 && y0 === y1 && x2 === x3 && y2 === y3) { + path.lineTo(x3, y3); + } + else { + path.bezierCurveTo(x1, y1, x2, y2, x3, y3); + } + x0 = x3; + y0 = y3; + } + } + } }); + } + function morphPath(fromPath, toPath, animationOpts) { + if (!fromPath || !toPath) { + return toPath; + } + var oldDone = animationOpts.done; + var oldDuring = animationOpts.during; + prepareMorphPath(fromPath, toPath); + toPath.__morphT = 0; + function restoreToPath() { + restoreMethod(toPath, 'buildPath'); + restoreMethod(toPath, 'updateTransform'); + toPath.__morphT = -1; + toPath.createPathProxy(); + toPath.dirtyShape(); + } + toPath.animateTo({ + __morphT: 1 + }, defaults({ + during: function (p) { + toPath.dirtyShape(); + oldDuring && oldDuring(p); + }, + done: function () { + restoreToPath(); + oldDone && oldDone(); + } + }, animationOpts)); + return toPath; + } + function hilbert(x, y, minX, minY, maxX, maxY) { + var bits = 16; + x = (maxX === minX) ? 0 : Math.round(32767 * (x - minX) / (maxX - minX)); + y = (maxY === minY) ? 0 : Math.round(32767 * (y - minY) / (maxY - minY)); + var d = 0; + var tmp; + for (var s = (1 << bits) / 2; s > 0; s /= 2) { + var rx = 0; + var ry = 0; + if ((x & s) > 0) { + rx = 1; + } + if ((y & s) > 0) { + ry = 1; + } + d += s * s * ((3 * rx) ^ ry); + if (ry === 0) { + if (rx === 1) { + x = s - 1 - x; + y = s - 1 - y; + } + tmp = x; + x = y; + y = tmp; + } + } + return d; + } + function sortPaths(pathList) { + var xMin = Infinity; + var yMin = Infinity; + var xMax = -Infinity; + var yMax = -Infinity; + var cps = map(pathList, function (path) { + var rect = path.getBoundingRect(); + var m = path.getComputedTransform(); + var x = rect.x + rect.width / 2 + (m ? m[4] : 0); + var y = rect.y + rect.height / 2 + (m ? m[5] : 0); + xMin = Math.min(x, xMin); + yMin = Math.min(y, yMin); + xMax = Math.max(x, xMax); + yMax = Math.max(y, yMax); + return [x, y]; + }); + var items = map(cps, function (cp, idx) { + return { + cp: cp, + z: hilbert(cp[0], cp[1], xMin, yMin, xMax, yMax), + path: pathList[idx] + }; + }); + return items.sort(function (a, b) { return a.z - b.z; }).map(function (item) { return item.path; }); + } + function defaultDividePath(param) { + return split(param.path, param.count); + } + function createEmptyReturn() { + return { + fromIndividuals: [], + toIndividuals: [], + count: 0 + }; + } + function combineMorph(fromList, toPath, animationOpts) { + var fromPathList = []; + function addFromPath(fromList) { + for (var i = 0; i < fromList.length; i++) { + var from = fromList[i]; + if (isCombineMorphing(from)) { + addFromPath(from.childrenRef()); + } + else if (from instanceof Path) { + fromPathList.push(from); + } + } + } + addFromPath(fromList); + var separateCount = fromPathList.length; + if (!separateCount) { + return createEmptyReturn(); + } + var dividePath = animationOpts.dividePath || defaultDividePath; + var toSubPathList = dividePath({ + path: toPath, count: separateCount + }); + if (toSubPathList.length !== separateCount) { + console.error('Invalid morphing: unmatched splitted path'); + return createEmptyReturn(); + } + fromPathList = sortPaths(fromPathList); + toSubPathList = sortPaths(toSubPathList); + var oldDone = animationOpts.done; + var oldDuring = animationOpts.during; + var individualDelay = animationOpts.individualDelay; + var identityTransform = new Transformable(); + for (var i = 0; i < separateCount; i++) { + var from = fromPathList[i]; + var to = toSubPathList[i]; + to.parent = toPath; + to.copyTransform(identityTransform); + if (!individualDelay) { + prepareMorphPath(from, to); + } + } + toPath.__isCombineMorphing = true; + toPath.childrenRef = function () { + return toSubPathList; + }; + function addToSubPathListToZr(zr) { + for (var i = 0; i < toSubPathList.length; i++) { + toSubPathList[i].addSelfToZr(zr); + } + } + saveAndModifyMethod(toPath, 'addSelfToZr', { + after: function (zr) { + addToSubPathListToZr(zr); + } + }); + saveAndModifyMethod(toPath, 'removeSelfFromZr', { + after: function (zr) { + for (var i = 0; i < toSubPathList.length; i++) { + toSubPathList[i].removeSelfFromZr(zr); + } + } + }); + function restoreToPath() { + toPath.__isCombineMorphing = false; + toPath.__morphT = -1; + toPath.childrenRef = null; + restoreMethod(toPath, 'addSelfToZr'); + restoreMethod(toPath, 'removeSelfFromZr'); + } + var toLen = toSubPathList.length; + if (individualDelay) { + var animating_1 = toLen; + var eachDone = function () { + animating_1--; + if (animating_1 === 0) { + restoreToPath(); + oldDone && oldDone(); + } + }; + for (var i = 0; i < toLen; i++) { + var indivdualAnimationOpts = individualDelay ? defaults({ + delay: (animationOpts.delay || 0) + individualDelay(i, toLen, fromPathList[i], toSubPathList[i]), + done: eachDone + }, animationOpts) : animationOpts; + morphPath(fromPathList[i], toSubPathList[i], indivdualAnimationOpts); + } + } + else { + toPath.__morphT = 0; + toPath.animateTo({ + __morphT: 1 + }, defaults({ + during: function (p) { + for (var i = 0; i < toLen; i++) { + var child = toSubPathList[i]; + child.__morphT = toPath.__morphT; + child.dirtyShape(); + } + oldDuring && oldDuring(p); + }, + done: function () { + restoreToPath(); + for (var i = 0; i < fromList.length; i++) { + restoreMethod(fromList[i], 'updateTransform'); + } + oldDone && oldDone(); + } + }, animationOpts)); + } + if (toPath.__zr) { + addToSubPathListToZr(toPath.__zr); + } + return { + fromIndividuals: fromPathList, + toIndividuals: toSubPathList, + count: toLen + }; + } + function separateMorph(fromPath, toPathList, animationOpts) { + var toLen = toPathList.length; + var fromPathList = []; + var dividePath = animationOpts.dividePath || defaultDividePath; + function addFromPath(fromList) { + for (var i = 0; i < fromList.length; i++) { + var from = fromList[i]; + if (isCombineMorphing(from)) { + addFromPath(from.childrenRef()); + } + else if (from instanceof Path) { + fromPathList.push(from); + } + } + } + if (isCombineMorphing(fromPath)) { + addFromPath(fromPath.childrenRef()); + var fromLen = fromPathList.length; + if (fromLen < toLen) { + var k = 0; + for (var i = fromLen; i < toLen; i++) { + fromPathList.push(clonePath(fromPathList[k++ % fromLen])); + } + } + fromPathList.length = toLen; + } + else { + fromPathList = dividePath({ path: fromPath, count: toLen }); + var fromPathTransform = fromPath.getComputedTransform(); + for (var i = 0; i < fromPathList.length; i++) { + fromPathList[i].setLocalTransform(fromPathTransform); + } + if (fromPathList.length !== toLen) { + console.error('Invalid morphing: unmatched splitted path'); + return createEmptyReturn(); + } + } + fromPathList = sortPaths(fromPathList); + toPathList = sortPaths(toPathList); + var individualDelay = animationOpts.individualDelay; + for (var i = 0; i < toLen; i++) { + var indivdualAnimationOpts = individualDelay ? defaults({ + delay: (animationOpts.delay || 0) + individualDelay(i, toLen, fromPathList[i], toPathList[i]) + }, animationOpts) : animationOpts; + morphPath(fromPathList[i], toPathList[i], indivdualAnimationOpts); + } + return { + fromIndividuals: fromPathList, + toIndividuals: toPathList, + count: toPathList.length + }; + } + + function isMultiple(elements) { + return isArray(elements[0]); + } + function prepareMorphBatches(one, many) { + var batches = []; + var batchCount = one.length; + for (var i = 0; i < batchCount; i++) { + batches.push({ + one: one[i], + many: [] + }); + } + for (var i = 0; i < many.length; i++) { + var len = many[i].length; + var k = void 0; + for (k = 0; k < len; k++) { + batches[k % batchCount].many.push(many[i][k]); + } + } + var off = 0; + // If one has more paths than each one of many. average them. + for (var i = batchCount - 1; i >= 0; i--) { + if (!batches[i].many.length) { + var moveFrom = batches[off].many; + if (moveFrom.length <= 1) { + // Not enough + // Start from the first one. + if (off) { + off = 0; + } else { + return batches; + } + } + var len = moveFrom.length; + var mid = Math.ceil(len / 2); + batches[i].many = moveFrom.slice(mid, len); + batches[off].many = moveFrom.slice(0, mid); + off++; + } + } + return batches; + } + var pathDividers = { + clone: function (params) { + var ret = []; + // Fitting the alpha + var approxOpacity = 1 - Math.pow(1 - params.path.style.opacity, 1 / params.count); + for (var i = 0; i < params.count; i++) { + var cloned = clonePath(params.path); + cloned.setStyle('opacity', approxOpacity); + ret.push(cloned); + } + return ret; + }, + // Use the default divider + split: null + }; + function applyMorphAnimation(from, to, divideShape, seriesModel, dataIndex, animateOtherProps) { + if (!from.length || !to.length) { + return; + } + var updateAnimationCfg = getAnimationConfig('update', seriesModel, dataIndex); + if (!(updateAnimationCfg && updateAnimationCfg.duration > 0)) { + return; + } + var animationDelay = seriesModel.getModel('universalTransition').get('delay'); + var animationCfg = Object.assign({ + // Need to setToFinal so the further calculation based on the style can be correct. + // Like emphasis color. + setToFinal: true + }, updateAnimationCfg); + var many; + var one; + if (isMultiple(from)) { + // manyToOne + many = from; + one = to; + } + if (isMultiple(to)) { + // oneToMany + many = to; + one = from; + } + function morphOneBatch(batch, fromIsMany, animateIndex, animateCount, forceManyOne) { + var batchMany = batch.many; + var batchOne = batch.one; + if (batchMany.length === 1 && !forceManyOne) { + // Is one to one + var batchFrom = fromIsMany ? batchMany[0] : batchOne; + var batchTo = fromIsMany ? batchOne : batchMany[0]; + if (isCombineMorphing(batchFrom)) { + // Keep doing combine animation. + morphOneBatch({ + many: [batchFrom], + one: batchTo + }, true, animateIndex, animateCount, true); + } else { + var individualAnimationCfg = animationDelay ? defaults({ + delay: animationDelay(animateIndex, animateCount) + }, animationCfg) : animationCfg; + morphPath(batchFrom, batchTo, individualAnimationCfg); + animateOtherProps(batchFrom, batchTo, batchFrom, batchTo, individualAnimationCfg); + } + } else { + var separateAnimationCfg = defaults({ + dividePath: pathDividers[divideShape], + individualDelay: animationDelay && function (idx, count, fromPath, toPath) { + return animationDelay(idx + animateIndex, animateCount); + } + }, animationCfg); + var _a = fromIsMany ? combineMorph(batchMany, batchOne, separateAnimationCfg) : separateMorph(batchOne, batchMany, separateAnimationCfg), + fromIndividuals = _a.fromIndividuals, + toIndividuals = _a.toIndividuals; + var count = fromIndividuals.length; + for (var k = 0; k < count; k++) { + var individualAnimationCfg = animationDelay ? defaults({ + delay: animationDelay(k, count) + }, animationCfg) : animationCfg; + animateOtherProps(fromIndividuals[k], toIndividuals[k], fromIsMany ? batchMany[k] : batch.one, fromIsMany ? batch.one : batchMany[k], individualAnimationCfg); + } + } + } + var fromIsMany = many ? many === from + // Is one to one. If the path number not match. also needs do merge and separate morphing. + : from.length > to.length; + var morphBatches = many ? prepareMorphBatches(one, many) : prepareMorphBatches(fromIsMany ? to : from, [fromIsMany ? from : to]); + var animateCount = 0; + for (var i = 0; i < morphBatches.length; i++) { + animateCount += morphBatches[i].many.length; + } + var animateIndex = 0; + for (var i = 0; i < morphBatches.length; i++) { + morphOneBatch(morphBatches[i], fromIsMany, animateIndex, animateCount); + animateIndex += morphBatches[i].many.length; + } + } + function getPathList(elements) { + if (!elements) { + return []; + } + if (isArray(elements)) { + var pathList_1 = []; + for (var i = 0; i < elements.length; i++) { + pathList_1.push(getPathList(elements[i])); + } + return pathList_1; + } + var pathList = []; + elements.traverse(function (el) { + if (el instanceof Path && !el.disableMorphing && !el.invisible && !el.ignore) { + pathList.push(el); + } + }); + return pathList; + } + + var DATA_COUNT_THRESHOLD = 1e4; + var TRANSITION_NONE = 0; + var TRANSITION_P2C = 1; + var TRANSITION_C2P = 2; + var getUniversalTransitionGlobalStore = makeInner(); + function getDimension(data, visualDimension) { + var dimensions = data.dimensions; + for (var i = 0; i < dimensions.length; i++) { + var dimInfo = data.getDimensionInfo(dimensions[i]); + if (dimInfo && dimInfo.otherDims[visualDimension] === 0) { + return dimensions[i]; + } + } + } + // get value by dimension. (only get value of itemGroupId or childGroupId, so convert it to string) + function getValueByDimension(data, dataIndex, dimension) { + var dimInfo = data.getDimensionInfo(dimension); + var dimOrdinalMeta = dimInfo && dimInfo.ordinalMeta; + if (dimInfo) { + var value = data.get(dimInfo.name, dataIndex); + if (dimOrdinalMeta) { + return dimOrdinalMeta.categories[value] || value + ''; + } + return value + ''; + } + } + function getGroupId(data, dataIndex, dataGroupId, isChild) { + // try to get groupId from encode + var visualDimension = isChild ? 'itemChildGroupId' : 'itemGroupId'; + var groupIdDim = getDimension(data, visualDimension); + if (groupIdDim) { + var groupId = getValueByDimension(data, dataIndex, groupIdDim); + return groupId; + } + // try to get groupId from raw data item + var rawDataItem = data.getRawDataItem(dataIndex); + var property = isChild ? 'childGroupId' : 'groupId'; + if (rawDataItem && rawDataItem[property]) { + return rawDataItem[property] + ''; + } + // fallback + if (isChild) { + return; + } + // try to use series.dataGroupId as groupId, otherwise use dataItem's id as groupId + return dataGroupId || data.getId(dataIndex); + } + // flatten all data items from different serieses into one arrary + function flattenDataDiffItems(list) { + var items = []; + each(list, function (seriesInfo) { + var data = seriesInfo.data; + var dataGroupId = seriesInfo.dataGroupId; + if (data.count() > DATA_COUNT_THRESHOLD) { + if ("development" !== 'production') { + warn('Universal transition is disabled on large data > 10k.'); + } + return; + } + var indices = data.getIndices(); + for (var dataIndex = 0; dataIndex < indices.length; dataIndex++) { + items.push({ + data: data, + groupId: getGroupId(data, dataIndex, dataGroupId, false), + childGroupId: getGroupId(data, dataIndex, dataGroupId, true), + divide: seriesInfo.divide, + dataIndex: dataIndex + }); + } + }); + return items; + } + function fadeInElement(newEl, newSeries, newIndex) { + newEl.traverse(function (el) { + if (el instanceof Path) { + // TODO use fade in animation for target element. + initProps(el, { + style: { + opacity: 0 + } + }, newSeries, { + dataIndex: newIndex, + isFrom: true + }); + } + }); + } + function removeEl$1(el) { + if (el.parent) { + // Bake parent transform to element. + // So it can still have proper transform to transition after it's removed. + var computedTransform = el.getComputedTransform(); + el.setLocalTransform(computedTransform); + el.parent.remove(el); + } + } + function stopAnimation(el) { + el.stopAnimation(); + if (el.isGroup) { + el.traverse(function (child) { + child.stopAnimation(); + }); + } + } + function animateElementStyles(el, dataIndex, seriesModel) { + var animationConfig = getAnimationConfig('update', seriesModel, dataIndex); + animationConfig && el.traverse(function (child) { + if (child instanceof Displayable) { + var oldStyle = getOldStyle(child); + if (oldStyle) { + child.animateFrom({ + style: oldStyle + }, animationConfig); + } + } + }); + } + function isAllIdSame(oldDiffItems, newDiffItems) { + var len = oldDiffItems.length; + if (len !== newDiffItems.length) { + return false; + } + for (var i = 0; i < len; i++) { + var oldItem = oldDiffItems[i]; + var newItem = newDiffItems[i]; + if (oldItem.data.getId(oldItem.dataIndex) !== newItem.data.getId(newItem.dataIndex)) { + return false; + } + } + return true; + } + function transitionBetween(oldList, newList, api) { + var oldDiffItems = flattenDataDiffItems(oldList); + var newDiffItems = flattenDataDiffItems(newList); + function updateMorphingPathProps(from, to, rawFrom, rawTo, animationCfg) { + if (rawFrom || from) { + to.animateFrom({ + style: rawFrom && rawFrom !== from + // dividingMethod like clone may override the style(opacity) + // So extend it to raw style. + ? extend(extend({}, rawFrom.style), from.style) : from.style + }, animationCfg); + } + } + var hasMorphAnimation = false; + /** + * With groupId and childGroupId, we can build parent-child relationships between dataItems. + * However, we should mind the parent-child "direction" between old and new options. + * + * For example, suppose we have two dataItems from two series.data: + * + * dataA: [ dataB: [ + * { { + * value: 5, value: 3, + * groupId: 'creatures', groupId: 'animals', + * childGroupId: 'animals' childGroupId: 'dogs' + * }, }, + * ... ... + * ] ] + * + * where dataA is belong to optionA and dataB is belong to optionB. + * + * When we `setOption(optionB)` from optionA, we choose childGroupId of dataItemA and groupId of + * dataItemB as keys so the two keys are matched (both are 'animals'), then universalTransition + * will work. This derection is "parent -> child". + * + * If we `setOption(optionA)` from optionB, we also choose groupId of dataItemB and childGroupId + * of dataItemA as keys and universalTransition will work. This derection is "child -> parent". + * + * If there is no childGroupId specified, which means no multiLevelDrillDown/Up is needed and no + * parent-child relationship exists. This direction is "none". + * + * So we need to know whether to use groupId or childGroupId as the key when we call the keyGetter + * functions. Thus, we need to decide the direction first. + * + * The rule is: + * + * if (all childGroupIds in oldDiffItems and all groupIds in newDiffItems have common value) { + * direction = 'parent -> child'; + * } else if (all groupIds in oldDiffItems and all childGroupIds in newDiffItems have common value) { + * direction = 'child -> parent'; + * } else { + * direction = 'none'; + * } + */ + var direction = TRANSITION_NONE; + // find all groupIds and childGroupIds from oldDiffItems + var oldGroupIds = createHashMap(); + var oldChildGroupIds = createHashMap(); + oldDiffItems.forEach(function (item) { + item.groupId && oldGroupIds.set(item.groupId, true); + item.childGroupId && oldChildGroupIds.set(item.childGroupId, true); + }); + // traverse newDiffItems and decide the direction according to the rule + for (var i = 0; i < newDiffItems.length; i++) { + var newGroupId = newDiffItems[i].groupId; + if (oldChildGroupIds.get(newGroupId)) { + direction = TRANSITION_P2C; + break; + } + var newChildGroupId = newDiffItems[i].childGroupId; + if (newChildGroupId && oldGroupIds.get(newChildGroupId)) { + direction = TRANSITION_C2P; + break; + } + } + function createKeyGetter(isOld, onlyGetId) { + return function (diffItem) { + var data = diffItem.data; + var dataIndex = diffItem.dataIndex; + // TODO if specified dim + if (onlyGetId) { + return data.getId(dataIndex); + } + if (isOld) { + return direction === TRANSITION_P2C ? diffItem.childGroupId : diffItem.groupId; + } else { + return direction === TRANSITION_C2P ? diffItem.childGroupId : diffItem.groupId; + } + }; + } + // Use id if it's very likely to be an one to one animation + // It's more robust than groupId + // TODO Check if key dimension is specified. + var useId = isAllIdSame(oldDiffItems, newDiffItems); + var isElementStillInChart = {}; + if (!useId) { + // We may have different diff strategy with basicTransition if we use other dimension as key. + // If so, we can't simply check if oldEl is same with newEl. We need a map to check if oldEl is still being used in the new chart. + // We can't use the elements that already being morphed. Let it keep it's original basic transition. + for (var i = 0; i < newDiffItems.length; i++) { + var newItem = newDiffItems[i]; + var el = newItem.data.getItemGraphicEl(newItem.dataIndex); + if (el) { + isElementStillInChart[el.id] = true; + } + } + } + function updateOneToOne(newIndex, oldIndex) { + var oldItem = oldDiffItems[oldIndex]; + var newItem = newDiffItems[newIndex]; + var newSeries = newItem.data.hostModel; + // TODO Mark this elements is morphed and don't morph them anymore + var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex); + var newEl = newItem.data.getItemGraphicEl(newItem.dataIndex); + // Can't handle same elements. + if (oldEl === newEl) { + newEl && animateElementStyles(newEl, newItem.dataIndex, newSeries); + return; + } + if ( + // We can't use the elements that already being morphed + oldEl && isElementStillInChart[oldEl.id]) { + return; + } + if (newEl) { + // TODO: If keep animating the group in case + // some of the elements don't want to be morphed. + // TODO Label? + stopAnimation(newEl); + if (oldEl) { + stopAnimation(oldEl); + // If old element is doing leaving animation. stop it and remove it immediately. + removeEl$1(oldEl); + hasMorphAnimation = true; + applyMorphAnimation(getPathList(oldEl), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps); + } else { + fadeInElement(newEl, newSeries, newIndex); + } + } + // else keep oldEl leaving animation. + } + + new DataDiffer(oldDiffItems, newDiffItems, createKeyGetter(true, useId), createKeyGetter(false, useId), null, 'multiple').update(updateOneToOne).updateManyToOne(function (newIndex, oldIndices) { + var newItem = newDiffItems[newIndex]; + var newData = newItem.data; + var newSeries = newData.hostModel; + var newEl = newData.getItemGraphicEl(newItem.dataIndex); + var oldElsList = filter(map(oldIndices, function (idx) { + return oldDiffItems[idx].data.getItemGraphicEl(oldDiffItems[idx].dataIndex); + }), function (oldEl) { + return oldEl && oldEl !== newEl && !isElementStillInChart[oldEl.id]; + }); + if (newEl) { + stopAnimation(newEl); + if (oldElsList.length) { + // If old element is doing leaving animation. stop it and remove it immediately. + each(oldElsList, function (oldEl) { + stopAnimation(oldEl); + removeEl$1(oldEl); + }); + hasMorphAnimation = true; + applyMorphAnimation(getPathList(oldElsList), getPathList(newEl), newItem.divide, newSeries, newIndex, updateMorphingPathProps); + } else { + fadeInElement(newEl, newSeries, newItem.dataIndex); + } + } + // else keep oldEl leaving animation. + }).updateOneToMany(function (newIndices, oldIndex) { + var oldItem = oldDiffItems[oldIndex]; + var oldEl = oldItem.data.getItemGraphicEl(oldItem.dataIndex); + // We can't use the elements that already being morphed + if (oldEl && isElementStillInChart[oldEl.id]) { + return; + } + var newElsList = filter(map(newIndices, function (idx) { + return newDiffItems[idx].data.getItemGraphicEl(newDiffItems[idx].dataIndex); + }), function (el) { + return el && el !== oldEl; + }); + var newSeris = newDiffItems[newIndices[0]].data.hostModel; + if (newElsList.length) { + each(newElsList, function (newEl) { + return stopAnimation(newEl); + }); + if (oldEl) { + stopAnimation(oldEl); + // If old element is doing leaving animation. stop it and remove it immediately. + removeEl$1(oldEl); + hasMorphAnimation = true; + applyMorphAnimation(getPathList(oldEl), getPathList(newElsList), oldItem.divide, + // Use divide on old. + newSeris, newIndices[0], updateMorphingPathProps); + } else { + each(newElsList, function (newEl) { + return fadeInElement(newEl, newSeris, newIndices[0]); + }); + } + } + // else keep oldEl leaving animation. + }).updateManyToMany(function (newIndices, oldIndices) { + // If two data are same and both have groupId. + // Normally they should be diff by id. + new DataDiffer(oldIndices, newIndices, function (rawIdx) { + return oldDiffItems[rawIdx].data.getId(oldDiffItems[rawIdx].dataIndex); + }, function (rawIdx) { + return newDiffItems[rawIdx].data.getId(newDiffItems[rawIdx].dataIndex); + }).update(function (newIndex, oldIndex) { + // Use the original index + updateOneToOne(newIndices[newIndex], oldIndices[oldIndex]); + }).execute(); + }).execute(); + if (hasMorphAnimation) { + each(newList, function (_a) { + var data = _a.data; + var seriesModel = data.hostModel; + var view = seriesModel && api.getViewOfSeriesModel(seriesModel); + var animationCfg = getAnimationConfig('update', seriesModel, 0); // use 0 index. + if (view && seriesModel.isAnimationEnabled() && animationCfg && animationCfg.duration > 0) { + view.group.traverse(function (el) { + if (el instanceof Path && !el.animators.length) { + // We can't accept there still exists element that has no animation + // if universalTransition is enabled + el.animateFrom({ + style: { + opacity: 0 + } + }, animationCfg); + } + }); + } + }); + } + } + function getSeriesTransitionKey(series) { + var seriesKey = series.getModel('universalTransition').get('seriesKey'); + if (!seriesKey) { + // Use series id by default. + return series.id; + } + return seriesKey; + } + function convertArraySeriesKeyToString(seriesKey) { + if (isArray(seriesKey)) { + // Order independent. + return seriesKey.sort().join(','); + } + return seriesKey; + } + function getDivideShapeFromData(data) { + if (data.hostModel) { + return data.hostModel.getModel('universalTransition').get('divideShape'); + } + } + function findTransitionSeriesBatches(globalStore, params) { + var updateBatches = createHashMap(); + var oldDataMap = createHashMap(); + // Map that only store key in array seriesKey. + // Which is used to query the old data when transition from one to multiple series. + var oldDataMapForSplit = createHashMap(); + each(globalStore.oldSeries, function (series, idx) { + var oldDataGroupId = globalStore.oldDataGroupIds[idx]; + var oldData = globalStore.oldData[idx]; + var transitionKey = getSeriesTransitionKey(series); + var transitionKeyStr = convertArraySeriesKeyToString(transitionKey); + oldDataMap.set(transitionKeyStr, { + dataGroupId: oldDataGroupId, + data: oldData + }); + if (isArray(transitionKey)) { + // Same key can't in different array seriesKey. + each(transitionKey, function (key) { + oldDataMapForSplit.set(key, { + key: transitionKeyStr, + dataGroupId: oldDataGroupId, + data: oldData + }); + }); + } + }); + function checkTransitionSeriesKeyDuplicated(transitionKeyStr) { + if (updateBatches.get(transitionKeyStr)) { + warn("Duplicated seriesKey in universalTransition " + transitionKeyStr); + } + } + each(params.updatedSeries, function (series) { + if (series.isUniversalTransitionEnabled() && series.isAnimationEnabled()) { + var newDataGroupId = series.get('dataGroupId'); + var newData = series.getData(); + var transitionKey = getSeriesTransitionKey(series); + var transitionKeyStr = convertArraySeriesKeyToString(transitionKey); + // Only transition between series with same id. + var oldData = oldDataMap.get(transitionKeyStr); + // string transition key is the best match. + if (oldData) { + if ("development" !== 'production') { + checkTransitionSeriesKeyDuplicated(transitionKeyStr); + } + // TODO check if data is same? + updateBatches.set(transitionKeyStr, { + oldSeries: [{ + dataGroupId: oldData.dataGroupId, + divide: getDivideShapeFromData(oldData.data), + data: oldData.data + }], + newSeries: [{ + dataGroupId: newDataGroupId, + divide: getDivideShapeFromData(newData), + data: newData + }] + }); + } else { + // Transition from multiple series. + // e.g. 'female', 'male' -> ['female', 'male'] + if (isArray(transitionKey)) { + if ("development" !== 'production') { + checkTransitionSeriesKeyDuplicated(transitionKeyStr); + } + var oldSeries_1 = []; + each(transitionKey, function (key) { + var oldData = oldDataMap.get(key); + if (oldData.data) { + oldSeries_1.push({ + dataGroupId: oldData.dataGroupId, + divide: getDivideShapeFromData(oldData.data), + data: oldData.data + }); + } + }); + if (oldSeries_1.length) { + updateBatches.set(transitionKeyStr, { + oldSeries: oldSeries_1, + newSeries: [{ + dataGroupId: newDataGroupId, + data: newData, + divide: getDivideShapeFromData(newData) + }] + }); + } + } else { + // Try transition to multiple series. + // e.g. ['female', 'male'] -> 'female', 'male' + var oldData_1 = oldDataMapForSplit.get(transitionKey); + if (oldData_1) { + var batch = updateBatches.get(oldData_1.key); + if (!batch) { + batch = { + oldSeries: [{ + dataGroupId: oldData_1.dataGroupId, + data: oldData_1.data, + divide: getDivideShapeFromData(oldData_1.data) + }], + newSeries: [] + }; + updateBatches.set(oldData_1.key, batch); + } + batch.newSeries.push({ + dataGroupId: newDataGroupId, + data: newData, + divide: getDivideShapeFromData(newData) + }); + } + } + } + } + }); + return updateBatches; + } + function querySeries(series, finder) { + for (var i = 0; i < series.length; i++) { + var found = finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id; + if (found) { + return i; + } + } + } + function transitionSeriesFromOpt(transitionOpt, globalStore, params, api) { + var from = []; + var to = []; + each(normalizeToArray(transitionOpt.from), function (finder) { + var idx = querySeries(globalStore.oldSeries, finder); + if (idx >= 0) { + from.push({ + dataGroupId: globalStore.oldDataGroupIds[idx], + data: globalStore.oldData[idx], + // TODO can specify divideShape in transition. + divide: getDivideShapeFromData(globalStore.oldData[idx]), + groupIdDim: finder.dimension + }); + } + }); + each(normalizeToArray(transitionOpt.to), function (finder) { + var idx = querySeries(params.updatedSeries, finder); + if (idx >= 0) { + var data = params.updatedSeries[idx].getData(); + to.push({ + dataGroupId: globalStore.oldDataGroupIds[idx], + data: data, + divide: getDivideShapeFromData(data), + groupIdDim: finder.dimension + }); + } + }); + if (from.length > 0 && to.length > 0) { + transitionBetween(from, to, api); + } + } + function installUniversalTransition(registers) { + registers.registerUpdateLifecycle('series:beforeupdate', function (ecMOdel, api, params) { + each(normalizeToArray(params.seriesTransition), function (transOpt) { + each(normalizeToArray(transOpt.to), function (finder) { + var series = params.updatedSeries; + for (var i = 0; i < series.length; i++) { + if (finder.seriesIndex != null && finder.seriesIndex === series[i].seriesIndex || finder.seriesId != null && finder.seriesId === series[i].id) { + series[i][SERIES_UNIVERSAL_TRANSITION_PROP] = true; + } + } + }); + }); + }); + registers.registerUpdateLifecycle('series:transition', function (ecModel, api, params) { + // TODO api provide an namespace that can save stuff per instance + var globalStore = getUniversalTransitionGlobalStore(api); + // TODO multiple to multiple series. + if (globalStore.oldSeries && params.updatedSeries && params.optionChanged) { + // TODO transitionOpt was used in an old implementation and can be removed now + // Use give transition config if its' give; + var transitionOpt = params.seriesTransition; + if (transitionOpt) { + each(normalizeToArray(transitionOpt), function (opt) { + transitionSeriesFromOpt(opt, globalStore, params, api); + }); + } else { + // Else guess from series based on transition series key. + var updateBatches_1 = findTransitionSeriesBatches(globalStore, params); + each(updateBatches_1.keys(), function (key) { + var batch = updateBatches_1.get(key); + transitionBetween(batch.oldSeries, batch.newSeries, api); + }); + } + // Reset + each(params.updatedSeries, function (series) { + // Reset; + if (series[SERIES_UNIVERSAL_TRANSITION_PROP]) { + series[SERIES_UNIVERSAL_TRANSITION_PROP] = false; + } + }); + } + // Save all series of current update. Not only the updated one. + var allSeries = ecModel.getSeries(); + var savedSeries = globalStore.oldSeries = []; + var savedDataGroupIds = globalStore.oldDataGroupIds = []; + var savedData = globalStore.oldData = []; + for (var i = 0; i < allSeries.length; i++) { + var data = allSeries[i].getData(); + // Only save the data that can have transition. + // Avoid large data costing too much extra memory + if (data.count() < DATA_COUNT_THRESHOLD) { + savedSeries.push(allSeries[i]); + savedDataGroupIds.push(allSeries[i].get('dataGroupId')); + savedData.push(data); + } + } + }); + } + + // ----------------- + // Render engines + // ----------------- + // Render via Canvas. + // echarts.init(dom, null, { renderer: 'canvas' }) + use([install$1]); + // Render via SVG. + // echarts.init(dom, null, { renderer: 'svg' }) + use([install]); + // ---------------- + // Charts (series) + // ---------------- + // All of the series types, for example: + // chart.setOption({ + // series: [{ + // type: 'line' // or 'bar', 'pie', ... + // }] + // }); + use([install$2, install$3, install$4, install$6, install$8, install$a, install$b, install$c, install$d, install$e, install$f, install$h, install$i, install$j, install$k, install$l, install$m, install$n, install$o, install$p, install$q, install$r]); + // ------------------- + // Coordinate systems + // ------------------- + // All of the axis modules have been included in the + // coordinate system module below, do not need to + // make extra import. + // `cartesian` coordinate system. For some historical + // reasons, it is named as grid, for example: + // chart.setOption({ + // grid: {...}, + // xAxis: {...}, + // yAxis: {...}, + // series: [{...}] + // }); + use(install$t); + // `polar` coordinate system, for example: + // chart.setOption({ + // polar: {...}, + // radiusAxis: {...}, + // angleAxis: {...}, + // series: [{ + // coordinateSystem: 'polar' + // }] + // }); + use(install$u); + // `geo` coordinate system, for example: + // chart.setOption({ + // geo: {...}, + // series: [{ + // coordinateSystem: 'geo' + // }] + // }); + use(install$9); + // `singleAxis` coordinate system (notice, it is a coordinate system + // with only one axis, work for chart like theme river), for example: + // chart.setOption({ + // singleAxis: {...} + // series: [{type: 'themeRiver', ...}] + // }); + use(install$v); + // `parallel` coordinate system, only work for parallel series, for example: + // chart.setOption({ + // parallel: {...}, + // parallelAxis: [{...}, ...], + // series: [{ + // type: 'parallel' + // }] + // }); + use(install$g); + // `calendar` coordinate system. for example, + // chart.setOption({ + // calendar: {...}, + // series: [{ + // coordinateSystem: 'calendar' + // }] + // ); + use(install$w); + // ------------------ + // Other components + // ------------------ + // `graphic` component, for example: + // chart.setOption({ + // graphic: {...} + // }); + use(install$x); + // `toolbox` component, for example: + // chart.setOption({ + // toolbox: {...} + // }); + use(install$z); + // `tooltip` component, for example: + // chart.setOption({ + // tooltip: {...} + // }); + use(install$A); + // `axisPointer` component, for example: + // chart.setOption({ + // tooltip: {axisPointer: {...}, ...} + // }); + // Or + // chart.setOption({ + // axisPointer: {...} + // }); + use(install$s); + // `brush` component, for example: + // chart.setOption({ + // brush: {...} + // }); + // Or + // chart.setOption({ + // tooltip: {feature: {brush: {...}} + // }) + use(install$B); + // `title` component, for example: + // chart.setOption({ + // title: {...} + // }); + use(install$C); + // `timeline` component, for example: + // chart.setOption({ + // timeline: {...} + // }); + use(install$D); + // `markPoint` component, for example: + // chart.setOption({ + // series: [{markPoint: {...}}] + // }); + use(install$E); + // `markLine` component, for example: + // chart.setOption({ + // series: [{markLine: {...}}] + // }); + use(install$F); + // `markArea` component, for example: + // chart.setOption({ + // series: [{markArea: {...}}] + // }); + use(install$G); + // `legend` component not scrollable. for example: + // chart.setOption({ + // legend: {...} + // }); + use(install$J); + // `dataZoom` component including both `dataZoomInside` and `dataZoomSlider`. + use(install$M); + // `dataZoom` component providing drag, pinch, wheel behaviors + // inside coordinate system, for example: + // chart.setOption({ + // dataZoom: {type: 'inside'} + // }); + use(install$K); + // `dataZoom` component providing a slider bar, for example: + // chart.setOption({ + // dataZoom: {type: 'slider'} + // }); + use(install$L); + // `visualMap` component including both `visualMapContinuous` and `visualMapPiecewise`. + use(install$P); + // `visualMap` component providing continuous bar, for example: + // chart.setOption({ + // visualMap: {type: 'continuous'} + // }); + use(install$N); + // `visualMap` component providing pieces bar, for example: + // chart.setOption({ + // visualMap: {type: 'piecewise'} + // }); + use(install$O); + // `aria` component providing aria, for example: + // chart.setOption({ + // aria: {...} + // }); + use(install$Q); + // dataset transform + // chart.setOption({ + // dataset: { + // transform: [] + // } + // }); + use(install$R); + use(install$S); + // universal transition + // chart.setOption({ + // series: { + // universalTransition: { enabled: true } + // } + // }) + use(installUniversalTransition); + // label layout + // chart.setOption({ + // series: { + // labelLayout: { hideOverlap: true } + // } + // }) + use(installLabelLayout); + + exports.Axis = Axis; + exports.ChartView = ChartView; + exports.ComponentModel = ComponentModel; + exports.ComponentView = ComponentView; + exports.List = SeriesData; + exports.Model = Model; + exports.PRIORITY = PRIORITY; + exports.SeriesModel = SeriesModel; + exports.color = color; + exports.connect = connect; + exports.dataTool = dataTool; + exports.dependencies = dependencies; + exports.disConnect = disConnect; + exports.disconnect = disconnect; + exports.dispose = dispose$1; + exports.env = env; + exports.extendChartView = extendChartView; + exports.extendComponentModel = extendComponentModel; + exports.extendComponentView = extendComponentView; + exports.extendSeriesModel = extendSeriesModel; + exports.format = format$1; + exports.getCoordinateSystemDimensions = getCoordinateSystemDimensions; + exports.getInstanceByDom = getInstanceByDom; + exports.getInstanceById = getInstanceById; + exports.getMap = getMap; + exports.graphic = graphic$1; + exports.helper = helper; + exports.init = init$1; + exports.innerDrawElementOnCanvas = brushSingle; + exports.matrix = matrix; + exports.number = number; + exports.parseGeoJSON = parseGeoJSON; + exports.parseGeoJson = parseGeoJSON; + exports.registerAction = registerAction; + exports.registerCoordinateSystem = registerCoordinateSystem; + exports.registerLayout = registerLayout; + exports.registerLoading = registerLoading; + exports.registerLocale = registerLocale; + exports.registerMap = registerMap; + exports.registerPostInit = registerPostInit; + exports.registerPostUpdate = registerPostUpdate; + exports.registerPreprocessor = registerPreprocessor; + exports.registerProcessor = registerProcessor; + exports.registerTheme = registerTheme; + exports.registerTransform = registerTransform; + exports.registerUpdateLifecycle = registerUpdateLifecycle; + exports.registerVisual = registerVisual; + exports.setCanvasCreator = setCanvasCreator; + exports.setPlatformAPI = setPlatformAPI; + exports.throttle = throttle; + exports.time = time; + exports.use = use; + exports.util = util$1; + exports.vector = vector; + exports.version = version$1; + exports.zrUtil = util; + exports.zrender = zrender; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); +//# sourceMappingURL=echarts.js.map diff --git a/assets/echarts.min.js b/assets/echarts.min.js new file mode 100644 index 0000000..80094ac --- /dev/null +++ b/assets/echarts.min.js @@ -0,0 +1,45 @@ + +/* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ + +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).echarts={})}(this,(function(t){"use strict"; +/*! ***************************************************************************** + Copyright (c) Microsoft Corporation. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THIS SOFTWARE. + ***************************************************************************** */var e=function(t,n){return(e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n])})(t,n)};function n(t,n){if("function"!=typeof n&&null!==n)throw new TypeError("Class extends value "+String(n)+" is not a constructor or null");function i(){this.constructor=t}e(t,n),t.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}var i=function(){this.firefox=!1,this.ie=!1,this.edge=!1,this.newEdge=!1,this.weChat=!1},r=new function(){this.browser=new i,this.node=!1,this.wxa=!1,this.worker=!1,this.svgSupported=!1,this.touchEventsSupported=!1,this.pointerEventsSupported=!1,this.domSupported=!1,this.transformSupported=!1,this.transform3dSupported=!1,this.hasGlobalWindow="undefined"!=typeof window};"object"==typeof wx&&"function"==typeof wx.getSystemInfoSync?(r.wxa=!0,r.touchEventsSupported=!0):"undefined"==typeof document&&"undefined"!=typeof self?r.worker=!0:"undefined"==typeof navigator?(r.node=!0,r.svgSupported=!0):function(t,e){var n=e.browser,i=t.match(/Firefox\/([\d.]+)/),r=t.match(/MSIE\s([\d.]+)/)||t.match(/Trident\/.+?rv:(([\d.]+))/),o=t.match(/Edge?\/([\d.]+)/),a=/micromessenger/i.test(t);i&&(n.firefox=!0,n.version=i[1]);r&&(n.ie=!0,n.version=r[1]);o&&(n.edge=!0,n.version=o[1],n.newEdge=+o[1].split(".")[0]>18);a&&(n.weChat=!0);e.svgSupported="undefined"!=typeof SVGRect,e.touchEventsSupported="ontouchstart"in window&&!n.ie&&!n.edge,e.pointerEventsSupported="onpointerdown"in window&&(n.edge||n.ie&&+n.version>=11),e.domSupported="undefined"!=typeof document;var s=document.documentElement.style;e.transform3dSupported=(n.ie&&"transition"in s||n.edge||"WebKitCSSMatrix"in window&&"m11"in new WebKitCSSMatrix||"MozPerspective"in s)&&!("OTransition"in s),e.transformSupported=e.transform3dSupported||n.ie&&+n.version>=9}(navigator.userAgent,r);var o="sans-serif",a="12px sans-serif";var s,l,u=function(t){var e={};if("undefined"==typeof JSON)return e;for(var n=0;n=0)o=r*t.length;else for(var c=0;c>1)%2;a.style.cssText=["position: absolute","visibility: hidden","padding: 0","margin: 0","border-width: 0","user-select: none","width:0","height:0",i[s]+":0",r[l]+":0",i[1-s]+":auto",r[1-l]+":auto",""].join("!important;"),t.appendChild(a),n.push(a)}return n}(e,a),a,o);if(s)return s(t,n,i),!0}return!1}function Jt(t){return"CANVAS"===t.nodeName.toUpperCase()}var Qt=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,te=[],ee=r.browser.firefox&&+r.browser.version.split(".")[0]<39;function ne(t,e,n,i){return n=n||{},i?ie(t,e,n):ee&&null!=e.layerX&&e.layerX!==e.offsetX?(n.zrX=e.layerX,n.zrY=e.layerY):null!=e.offsetX?(n.zrX=e.offsetX,n.zrY=e.offsetY):ie(t,e,n),n}function ie(t,e,n){if(r.domSupported&&t.getBoundingClientRect){var i=e.clientX,o=e.clientY;if(Jt(t)){var a=t.getBoundingClientRect();return n.zrX=i-a.left,void(n.zrY=o-a.top)}if($t(te,t,i,o))return n.zrX=te[0],void(n.zrY=te[1])}n.zrX=n.zrY=0}function re(t){return t||window.event}function oe(t,e,n){if(null!=(e=re(e)).zrX)return e;var i=e.type;if(i&&i.indexOf("touch")>=0){var r="touchend"!==i?e.targetTouches[0]:e.changedTouches[0];r&&ne(t,r,e,n)}else{ne(t,e,e,n);var o=function(t){var e=t.wheelDelta;if(e)return e;var n=t.deltaX,i=t.deltaY;if(null==n||null==i)return e;return 3*(0!==i?Math.abs(i):Math.abs(n))*(i>0?-1:i<0?1:n>0?-1:1)}(e);e.zrDelta=o?o/120:-(e.detail||0)/3}var a=e.button;return null==e.which&&void 0!==a&&Qt.test(e.type)&&(e.which=1&a?1:2&a?3:4&a?2:0),e}function ae(t,e,n,i){t.addEventListener(e,n,i)}var se=function(t){t.preventDefault(),t.stopPropagation(),t.cancelBubble=!0};function le(t){return 2===t.which||3===t.which}var ue=function(){function t(){this._track=[]}return t.prototype.recognize=function(t,e,n){return this._doTrack(t,e,n),this._recognize(t)},t.prototype.clear=function(){return this._track.length=0,this},t.prototype._doTrack=function(t,e,n){var i=t.touches;if(i){for(var r={points:[],touches:[],target:e,event:t},o=0,a=i.length;o1&&r&&r.length>1){var a=he(r)/he(o);!isFinite(a)&&(a=1),e.pinchScale=a;var s=[((i=r)[0][0]+i[1][0])/2,(i[0][1]+i[1][1])/2];return e.pinchX=s[0],e.pinchY=s[1],{type:"pinch",target:t[0].target,event:e}}}}},pe="silent";function de(){se(this.event)}var fe=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.handler=null,e}return n(e,t),e.prototype.dispose=function(){},e.prototype.setCursor=function(){},e}(Xt),ge=function(t,e){this.x=t,this.y=e},ye=["click","dblclick","mousewheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],ve=function(t){function e(e,n,i,r){var o=t.call(this)||this;return o._hovered=new ge(0,0),o.storage=e,o.painter=n,o.painterRoot=r,i=i||new fe,o.proxy=null,o.setHandlerProxy(i),o._draggingMgr=new Ut(o),o}return n(e,t),e.prototype.setHandlerProxy=function(t){this.proxy&&this.proxy.dispose(),t&&(E(ye,(function(e){t.on&&t.on(e,this[e],this)}),this),t.handler=this),this.proxy=t},e.prototype.mousemove=function(t){var e=t.zrX,n=t.zrY,i=xe(this,e,n),r=this._hovered,o=r.target;o&&!o.__zr&&(o=(r=this.findHover(r.x,r.y)).target);var a=this._hovered=i?new ge(e,n):this.findHover(e,n),s=a.target,l=this.proxy;l.setCursor&&l.setCursor(s?s.cursor:"default"),o&&s!==o&&this.dispatchToElement(r,"mouseout",t),this.dispatchToElement(a,"mousemove",t),s&&s!==o&&this.dispatchToElement(a,"mouseover",t)},e.prototype.mouseout=function(t){var e=t.zrEventControl;"only_globalout"!==e&&this.dispatchToElement(this._hovered,"mouseout",t),"no_globalout"!==e&&this.trigger("globalout",{type:"globalout",event:t})},e.prototype.resize=function(){this._hovered=new ge(0,0)},e.prototype.dispatch=function(t,e){var n=this[t];n&&n.call(this,e)},e.prototype.dispose=function(){this.proxy.dispose(),this.storage=null,this.proxy=null,this.painter=null},e.prototype.setCursorStyle=function(t){var e=this.proxy;e.setCursor&&e.setCursor(t)},e.prototype.dispatchToElement=function(t,e,n){var i=(t=t||{}).target;if(!i||!i.silent){for(var r="on"+e,o=function(t,e,n){return{type:t,event:n,target:e.target,topTarget:e.topTarget,cancelBubble:!1,offsetX:n.zrX,offsetY:n.zrY,gestureEvent:n.gestureEvent,pinchX:n.pinchX,pinchY:n.pinchY,pinchScale:n.pinchScale,wheelDelta:n.zrDelta,zrByTouch:n.zrByTouch,which:n.which,stop:de}}(e,t,n);i&&(i[r]&&(o.cancelBubble=!!i[r].call(i,o)),i.trigger(e,o),i=i.__hostTarget?i.__hostTarget:i.parent,!o.cancelBubble););o.cancelBubble||(this.trigger(e,o),this.painter&&this.painter.eachOtherLayer&&this.painter.eachOtherLayer((function(t){"function"==typeof t[r]&&t[r].call(t,o),t.trigger&&t.trigger(e,o)})))}},e.prototype.findHover=function(t,e,n){for(var i=this.storage.getDisplayList(),r=new ge(t,e),o=i.length-1;o>=0;o--){var a=void 0;if(i[o]!==n&&!i[o].ignore&&(a=me(i[o],t,e))&&(!r.topTarget&&(r.topTarget=i[o]),a!==pe)){r.target=i[o];break}}return r},e.prototype.processGesture=function(t,e){this._gestureMgr||(this._gestureMgr=new ue);var n=this._gestureMgr;"start"===e&&n.clear();var i=n.recognize(t,this.findHover(t.zrX,t.zrY,null).target,this.proxy.dom);if("end"===e&&n.clear(),i){var r=i.type;t.gestureEvent=r;var o=new ge;o.target=i.target,this.dispatchToElement(o,r,i.event)}},e}(Xt);function me(t,e,n){if(t[t.rectHover?"rectContain":"contain"](e,n)){for(var i=t,r=void 0,o=!1;i;){if(i.ignoreClip&&(o=!0),!o){var a=i.getClipPath();if(a&&!a.contain(e,n))return!1;i.silent&&(r=!0)}var s=i.__hostTarget;i=s||i.parent}return!r||pe}return!1}function xe(t,e,n){var i=t.painter;return e<0||e>i.getWidth()||n<0||n>i.getHeight()}E(["click","mousedown","mouseup","mousewheel","dblclick","contextmenu"],(function(t){ve.prototype[t]=function(e){var n,i,r=e.zrX,o=e.zrY,a=xe(this,r,o);if("mouseup"===t&&a||(i=(n=this.findHover(r,o)).target),"mousedown"===t)this._downEl=i,this._downPoint=[e.zrX,e.zrY],this._upEl=i;else if("mouseup"===t)this._upEl=i;else if("click"===t){if(this._downEl!==this._upEl||!this._downPoint||Et(this._downPoint,[e.zrX,e.zrY])>4)return;this._downPoint=null}this.dispatchToElement(n,t,e)}}));function _e(t,e,n,i){var r=e+1;if(r===n)return 1;if(i(t[r++],t[e])<0){for(;r=0;)r++;return r-e}function be(t,e,n,i,r){for(i===e&&i++;i>>1])<0?l=o:s=o+1;var u=i-s;switch(u){case 3:t[s+3]=t[s+2];case 2:t[s+2]=t[s+1];case 1:t[s+1]=t[s];break;default:for(;u>0;)t[s+u]=t[s+u-1],u--}t[s]=a}}function we(t,e,n,i,r,o){var a=0,s=0,l=1;if(o(t,e[n+r])>0){for(s=i-r;l0;)a=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}else{for(s=r+1;ls&&(l=s);var u=a;a=r-l,l=r-u}for(a++;a>>1);o(t,e[n+h])>0?a=h+1:l=h}return l}function Se(t,e,n,i,r,o){var a=0,s=0,l=1;if(o(t,e[n+r])<0){for(s=r+1;ls&&(l=s);var u=a;a=r-l,l=r-u}else{for(s=i-r;l=0;)a=l,(l=1+(l<<1))<=0&&(l=s);l>s&&(l=s),a+=r,l+=r}for(a++;a>>1);o(t,e[n+h])<0?l=h:a=h+1}return l}function Me(t,e){var n,i,r=7,o=0;t.length;var a=[];function s(s){var l=n[s],u=i[s],h=n[s+1],c=i[s+1];i[s]=u+c,s===o-3&&(n[s+1]=n[s+2],i[s+1]=i[s+2]),o--;var p=Se(t[h],t,l,u,0,e);l+=p,0!==(u-=p)&&0!==(c=we(t[l+u-1],t,h,c,c-1,e))&&(u<=c?function(n,i,o,s){var l=0;for(l=0;l=7||d>=7);if(f)break;g<0&&(g=0),g+=2}if((r=g)<1&&(r=1),1===i){for(l=0;l=0;l--)t[d+l]=t[p+l];return void(t[c]=a[h])}var f=r;for(;;){var g=0,y=0,v=!1;do{if(e(a[h],t[u])<0){if(t[c--]=t[u--],g++,y=0,0==--i){v=!0;break}}else if(t[c--]=a[h--],y++,g=0,1==--s){v=!0;break}}while((g|y)=0;l--)t[d+l]=t[p+l];if(0===i){v=!0;break}}if(t[c--]=a[h--],1==--s){v=!0;break}if(0!==(y=s-we(t[u],a,0,s,s-1,e))){for(s-=y,d=(c-=y)+1,p=(h-=y)+1,l=0;l=7||y>=7);if(v)break;f<0&&(f=0),f+=2}(r=f)<1&&(r=1);if(1===s){for(d=(c-=i)+1,p=(u-=i)+1,l=i-1;l>=0;l--)t[d+l]=t[p+l];t[c]=a[h]}else{if(0===s)throw new Error;for(p=c-(s-1),l=0;l1;){var t=o-2;if(t>=1&&i[t-1]<=i[t]+i[t+1]||t>=2&&i[t-2]<=i[t]+i[t-1])i[t-1]i[t+1])break;s(t)}},forceMergeRuns:function(){for(;o>1;){var t=o-2;t>0&&i[t-1]=32;)e|=1&t,t>>=1;return t+e}(r);do{if((o=_e(t,n,i,e))s&&(l=s),be(t,n,n+l,n+o,e),o=l}a.pushRun(n,o),a.mergeRuns(),r-=o,n+=o}while(0!==r);a.forceMergeRuns()}}}var Te=!1;function Ce(){Te||(Te=!0,console.warn("z / z2 / zlevel of displayable is invalid, which may cause unexpected errors"))}function De(t,e){return t.zlevel===e.zlevel?t.z===e.z?t.z2-e.z2:t.z-e.z:t.zlevel-e.zlevel}var Ae=function(){function t(){this._roots=[],this._displayList=[],this._displayListLen=0,this.displayableSortFunc=De}return t.prototype.traverse=function(t,e){for(var n=0;n0&&(u.__clipPaths=[]),isNaN(u.z)&&(Ce(),u.z=0),isNaN(u.z2)&&(Ce(),u.z2=0),isNaN(u.zlevel)&&(Ce(),u.zlevel=0),this._displayList[this._displayListLen++]=u}var h=t.getDecalElement&&t.getDecalElement();h&&this._updateAndAddDisplayable(h,e,n);var c=t.getTextGuideLine();c&&this._updateAndAddDisplayable(c,e,n);var p=t.getTextContent();p&&this._updateAndAddDisplayable(p,e,n)}},t.prototype.addRoot=function(t){t.__zr&&t.__zr.storage===this||this._roots.push(t)},t.prototype.delRoot=function(t){if(t instanceof Array)for(var e=0,n=t.length;e=0&&this._roots.splice(i,1)}},t.prototype.delAllRoots=function(){this._roots=[],this._displayList=[],this._displayListLen=0},t.prototype.getRoots=function(){return this._roots},t.prototype.dispose=function(){this._displayList=null,this._roots=null},t}(),ke=r.hasGlobalWindow&&(window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.msRequestAnimationFrame&&window.msRequestAnimationFrame.bind(window)||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame)||function(t){return setTimeout(t,16)},Le={linear:function(t){return t},quadraticIn:function(t){return t*t},quadraticOut:function(t){return t*(2-t)},quadraticInOut:function(t){return(t*=2)<1?.5*t*t:-.5*(--t*(t-2)-1)},cubicIn:function(t){return t*t*t},cubicOut:function(t){return--t*t*t+1},cubicInOut:function(t){return(t*=2)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},quarticIn:function(t){return t*t*t*t},quarticOut:function(t){return 1- --t*t*t*t},quarticInOut:function(t){return(t*=2)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},quinticIn:function(t){return t*t*t*t*t},quinticOut:function(t){return--t*t*t*t*t+1},quinticInOut:function(t){return(t*=2)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},sinusoidalIn:function(t){return 1-Math.cos(t*Math.PI/2)},sinusoidalOut:function(t){return Math.sin(t*Math.PI/2)},sinusoidalInOut:function(t){return.5*(1-Math.cos(Math.PI*t))},exponentialIn:function(t){return 0===t?0:Math.pow(1024,t-1)},exponentialOut:function(t){return 1===t?1:1-Math.pow(2,-10*t)},exponentialInOut:function(t){return 0===t?0:1===t?1:(t*=2)<1?.5*Math.pow(1024,t-1):.5*(2-Math.pow(2,-10*(t-1)))},circularIn:function(t){return 1-Math.sqrt(1-t*t)},circularOut:function(t){return Math.sqrt(1- --t*t)},circularInOut:function(t){return(t*=2)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},elasticIn:function(t){var e,n=.1;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=.4*Math.asin(1/n)/(2*Math.PI),-n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/.4))},elasticOut:function(t){var e,n=.1;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=.4*Math.asin(1/n)/(2*Math.PI),n*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/.4)+1)},elasticInOut:function(t){var e,n=.1,i=.4;return 0===t?0:1===t?1:(!n||n<1?(n=1,e=.1):e=i*Math.asin(1/n)/(2*Math.PI),(t*=2)<1?n*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*-.5:n*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/i)*.5+1)},backIn:function(t){var e=1.70158;return t*t*((e+1)*t-e)},backOut:function(t){var e=1.70158;return--t*t*((e+1)*t+e)+1},backInOut:function(t){var e=2.5949095;return(t*=2)<1?t*t*((e+1)*t-e)*.5:.5*((t-=2)*t*((e+1)*t+e)+2)},bounceIn:function(t){return 1-Le.bounceOut(1-t)},bounceOut:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},bounceInOut:function(t){return t<.5?.5*Le.bounceIn(2*t):.5*Le.bounceOut(2*t-1)+.5}},Pe=Math.pow,Oe=Math.sqrt,Re=1e-8,Ne=1e-4,Ee=Oe(3),ze=1/3,Ve=wt(),Be=wt(),Fe=wt();function Ge(t){return t>-1e-8&&tRe||t<-1e-8}function He(t,e,n,i,r){var o=1-r;return o*o*(o*t+3*r*e)+r*r*(r*i+3*o*n)}function Ye(t,e,n,i,r){var o=1-r;return 3*(((e-t)*o+2*(n-e)*r)*o+(i-n)*r*r)}function Ue(t,e,n,i,r,o){var a=i+3*(e-n)-t,s=3*(n-2*e+t),l=3*(e-t),u=t-r,h=s*s-3*a*l,c=s*l-9*a*u,p=l*l-3*s*u,d=0;if(Ge(h)&&Ge(c)){if(Ge(s))o[0]=0;else(M=-l/s)>=0&&M<=1&&(o[d++]=M)}else{var f=c*c-4*h*p;if(Ge(f)){var g=c/h,y=-g/2;(M=-s/a+g)>=0&&M<=1&&(o[d++]=M),y>=0&&y<=1&&(o[d++]=y)}else if(f>0){var v=Oe(f),m=h*s+1.5*a*(-c+v),x=h*s+1.5*a*(-c-v);(M=(-s-((m=m<0?-Pe(-m,ze):Pe(m,ze))+(x=x<0?-Pe(-x,ze):Pe(x,ze))))/(3*a))>=0&&M<=1&&(o[d++]=M)}else{var _=(2*h*s-3*a*c)/(2*Oe(h*h*h)),b=Math.acos(_)/3,w=Oe(h),S=Math.cos(b),M=(-s-2*w*S)/(3*a),I=(y=(-s+w*(S+Ee*Math.sin(b)))/(3*a),(-s+w*(S-Ee*Math.sin(b)))/(3*a));M>=0&&M<=1&&(o[d++]=M),y>=0&&y<=1&&(o[d++]=y),I>=0&&I<=1&&(o[d++]=I)}}return d}function Xe(t,e,n,i,r){var o=6*n-12*e+6*t,a=9*e+3*i-3*t-9*n,s=3*e-3*t,l=0;if(Ge(a)){if(We(o))(h=-s/o)>=0&&h<=1&&(r[l++]=h)}else{var u=o*o-4*a*s;if(Ge(u))r[0]=-o/(2*a);else if(u>0){var h,c=Oe(u),p=(-o-c)/(2*a);(h=(-o+c)/(2*a))>=0&&h<=1&&(r[l++]=h),p>=0&&p<=1&&(r[l++]=p)}}return l}function Ze(t,e,n,i,r,o){var a=(e-t)*r+t,s=(n-e)*r+e,l=(i-n)*r+n,u=(s-a)*r+a,h=(l-s)*r+s,c=(h-u)*r+u;o[0]=t,o[1]=a,o[2]=u,o[3]=c,o[4]=c,o[5]=h,o[6]=l,o[7]=i}function je(t,e,n,i,r,o,a,s,l,u,h){var c,p,d,f,g,y=.005,v=1/0;Ve[0]=l,Ve[1]=u;for(var m=0;m<1;m+=.05)Be[0]=He(t,n,r,a,m),Be[1]=He(e,i,o,s,m),(f=Vt(Ve,Be))=0&&f=0&&y=1?1:Ue(0,i,o,1,t,s)&&He(0,r,a,1,s[0])}}}var on=function(){function t(t){this._inited=!1,this._startTime=0,this._pausedTime=0,this._paused=!1,this._life=t.life||1e3,this._delay=t.delay||0,this.loop=t.loop||!1,this.onframe=t.onframe||xt,this.ondestroy=t.ondestroy||xt,this.onrestart=t.onrestart||xt,t.easing&&this.setEasing(t.easing)}return t.prototype.step=function(t,e){if(this._inited||(this._startTime=t+this._delay,this._inited=!0),!this._paused){var n=this._life,i=t-this._startTime-this._pausedTime,r=i/n;r<0&&(r=0),r=Math.min(r,1);var o=this.easingFunc,a=o?o(r):r;if(this.onframe(a),1===r){if(!this.loop)return!0;var s=i%n;this._startTime=t-s,this._pausedTime=0,this.onrestart()}return!1}this._pausedTime+=e},t.prototype.pause=function(){this._paused=!0},t.prototype.resume=function(){this._paused=!1},t.prototype.setEasing=function(t){this.easing=t,this.easingFunc=U(t)?t:Le[t]||rn(t)},t}(),an=function(t){this.value=t},sn=function(){function t(){this._len=0}return t.prototype.insert=function(t){var e=new an(t);return this.insertEntry(e),e},t.prototype.insertEntry=function(t){this.head?(this.tail.next=t,t.prev=this.tail,t.next=null,this.tail=t):this.head=this.tail=t,this._len++},t.prototype.remove=function(t){var e=t.prev,n=t.next;e?e.next=n:this.head=n,n?n.prev=e:this.tail=e,t.next=t.prev=null,this._len--},t.prototype.len=function(){return this._len},t.prototype.clear=function(){this.head=this.tail=null,this._len=0},t}(),ln=function(){function t(t){this._list=new sn,this._maxSize=10,this._map={},this._maxSize=t}return t.prototype.put=function(t,e){var n=this._list,i=this._map,r=null;if(null==i[t]){var o=n.len(),a=this._lastRemovedEntry;if(o>=this._maxSize&&o>0){var s=n.head;n.remove(s),delete i[s.key],r=s.value,this._lastRemovedEntry=s}a?a.value=e:a=new an(e),a.key=t,n.insertEntry(a),i[t]=a}return r},t.prototype.get=function(t){var e=this._map[t],n=this._list;if(null!=e)return e!==n.tail&&(n.remove(e),n.insertEntry(e)),e.value},t.prototype.clear=function(){this._list.clear(),this._map={}},t.prototype.len=function(){return this._list.len()},t}(),un={transparent:[0,0,0,0],aliceblue:[240,248,255,1],antiquewhite:[250,235,215,1],aqua:[0,255,255,1],aquamarine:[127,255,212,1],azure:[240,255,255,1],beige:[245,245,220,1],bisque:[255,228,196,1],black:[0,0,0,1],blanchedalmond:[255,235,205,1],blue:[0,0,255,1],blueviolet:[138,43,226,1],brown:[165,42,42,1],burlywood:[222,184,135,1],cadetblue:[95,158,160,1],chartreuse:[127,255,0,1],chocolate:[210,105,30,1],coral:[255,127,80,1],cornflowerblue:[100,149,237,1],cornsilk:[255,248,220,1],crimson:[220,20,60,1],cyan:[0,255,255,1],darkblue:[0,0,139,1],darkcyan:[0,139,139,1],darkgoldenrod:[184,134,11,1],darkgray:[169,169,169,1],darkgreen:[0,100,0,1],darkgrey:[169,169,169,1],darkkhaki:[189,183,107,1],darkmagenta:[139,0,139,1],darkolivegreen:[85,107,47,1],darkorange:[255,140,0,1],darkorchid:[153,50,204,1],darkred:[139,0,0,1],darksalmon:[233,150,122,1],darkseagreen:[143,188,143,1],darkslateblue:[72,61,139,1],darkslategray:[47,79,79,1],darkslategrey:[47,79,79,1],darkturquoise:[0,206,209,1],darkviolet:[148,0,211,1],deeppink:[255,20,147,1],deepskyblue:[0,191,255,1],dimgray:[105,105,105,1],dimgrey:[105,105,105,1],dodgerblue:[30,144,255,1],firebrick:[178,34,34,1],floralwhite:[255,250,240,1],forestgreen:[34,139,34,1],fuchsia:[255,0,255,1],gainsboro:[220,220,220,1],ghostwhite:[248,248,255,1],gold:[255,215,0,1],goldenrod:[218,165,32,1],gray:[128,128,128,1],green:[0,128,0,1],greenyellow:[173,255,47,1],grey:[128,128,128,1],honeydew:[240,255,240,1],hotpink:[255,105,180,1],indianred:[205,92,92,1],indigo:[75,0,130,1],ivory:[255,255,240,1],khaki:[240,230,140,1],lavender:[230,230,250,1],lavenderblush:[255,240,245,1],lawngreen:[124,252,0,1],lemonchiffon:[255,250,205,1],lightblue:[173,216,230,1],lightcoral:[240,128,128,1],lightcyan:[224,255,255,1],lightgoldenrodyellow:[250,250,210,1],lightgray:[211,211,211,1],lightgreen:[144,238,144,1],lightgrey:[211,211,211,1],lightpink:[255,182,193,1],lightsalmon:[255,160,122,1],lightseagreen:[32,178,170,1],lightskyblue:[135,206,250,1],lightslategray:[119,136,153,1],lightslategrey:[119,136,153,1],lightsteelblue:[176,196,222,1],lightyellow:[255,255,224,1],lime:[0,255,0,1],limegreen:[50,205,50,1],linen:[250,240,230,1],magenta:[255,0,255,1],maroon:[128,0,0,1],mediumaquamarine:[102,205,170,1],mediumblue:[0,0,205,1],mediumorchid:[186,85,211,1],mediumpurple:[147,112,219,1],mediumseagreen:[60,179,113,1],mediumslateblue:[123,104,238,1],mediumspringgreen:[0,250,154,1],mediumturquoise:[72,209,204,1],mediumvioletred:[199,21,133,1],midnightblue:[25,25,112,1],mintcream:[245,255,250,1],mistyrose:[255,228,225,1],moccasin:[255,228,181,1],navajowhite:[255,222,173,1],navy:[0,0,128,1],oldlace:[253,245,230,1],olive:[128,128,0,1],olivedrab:[107,142,35,1],orange:[255,165,0,1],orangered:[255,69,0,1],orchid:[218,112,214,1],palegoldenrod:[238,232,170,1],palegreen:[152,251,152,1],paleturquoise:[175,238,238,1],palevioletred:[219,112,147,1],papayawhip:[255,239,213,1],peachpuff:[255,218,185,1],peru:[205,133,63,1],pink:[255,192,203,1],plum:[221,160,221,1],powderblue:[176,224,230,1],purple:[128,0,128,1],red:[255,0,0,1],rosybrown:[188,143,143,1],royalblue:[65,105,225,1],saddlebrown:[139,69,19,1],salmon:[250,128,114,1],sandybrown:[244,164,96,1],seagreen:[46,139,87,1],seashell:[255,245,238,1],sienna:[160,82,45,1],silver:[192,192,192,1],skyblue:[135,206,235,1],slateblue:[106,90,205,1],slategray:[112,128,144,1],slategrey:[112,128,144,1],snow:[255,250,250,1],springgreen:[0,255,127,1],steelblue:[70,130,180,1],tan:[210,180,140,1],teal:[0,128,128,1],thistle:[216,191,216,1],tomato:[255,99,71,1],turquoise:[64,224,208,1],violet:[238,130,238,1],wheat:[245,222,179,1],white:[255,255,255,1],whitesmoke:[245,245,245,1],yellow:[255,255,0,1],yellowgreen:[154,205,50,1]};function hn(t){return(t=Math.round(t))<0?0:t>255?255:t}function cn(t){return t<0?0:t>1?1:t}function pn(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?hn(parseFloat(e)/100*255):hn(parseInt(e,10))}function dn(t){var e=t;return e.length&&"%"===e.charAt(e.length-1)?cn(parseFloat(e)/100):cn(parseFloat(e))}function fn(t,e,n){return n<0?n+=1:n>1&&(n-=1),6*n<1?t+(e-t)*n*6:2*n<1?e:3*n<2?t+(e-t)*(2/3-n)*6:t}function gn(t,e,n){return t+(e-t)*n}function yn(t,e,n,i,r){return t[0]=e,t[1]=n,t[2]=i,t[3]=r,t}function vn(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t}var mn=new ln(20),xn=null;function _n(t,e){xn&&vn(xn,e),xn=mn.put(t,xn||e.slice())}function bn(t,e){if(t){e=e||[];var n=mn.get(t);if(n)return vn(e,n);var i=(t+="").replace(/ /g,"").toLowerCase();if(i in un)return vn(e,un[i]),_n(t,e),e;var r,o=i.length;if("#"===i.charAt(0))return 4===o||5===o?(r=parseInt(i.slice(1,4),16))>=0&&r<=4095?(yn(e,(3840&r)>>4|(3840&r)>>8,240&r|(240&r)>>4,15&r|(15&r)<<4,5===o?parseInt(i.slice(4),16)/15:1),_n(t,e),e):void yn(e,0,0,0,1):7===o||9===o?(r=parseInt(i.slice(1,7),16))>=0&&r<=16777215?(yn(e,(16711680&r)>>16,(65280&r)>>8,255&r,9===o?parseInt(i.slice(7),16)/255:1),_n(t,e),e):void yn(e,0,0,0,1):void 0;var a=i.indexOf("("),s=i.indexOf(")");if(-1!==a&&s+1===o){var l=i.substr(0,a),u=i.substr(a+1,s-(a+1)).split(","),h=1;switch(l){case"rgba":if(4!==u.length)return 3===u.length?yn(e,+u[0],+u[1],+u[2],1):yn(e,0,0,0,1);h=dn(u.pop());case"rgb":return 3!==u.length?void yn(e,0,0,0,1):(yn(e,pn(u[0]),pn(u[1]),pn(u[2]),h),_n(t,e),e);case"hsla":return 4!==u.length?void yn(e,0,0,0,1):(u[3]=dn(u[3]),wn(u,e),_n(t,e),e);case"hsl":return 3!==u.length?void yn(e,0,0,0,1):(wn(u,e),_n(t,e),e);default:return}}yn(e,0,0,0,1)}}function wn(t,e){var n=(parseFloat(t[0])%360+360)%360/360,i=dn(t[1]),r=dn(t[2]),o=r<=.5?r*(i+1):r+i-r*i,a=2*r-o;return yn(e=e||[],hn(255*fn(a,o,n+1/3)),hn(255*fn(a,o,n)),hn(255*fn(a,o,n-1/3)),1),4===t.length&&(e[3]=t[3]),e}function Sn(t,e){var n=bn(t);if(n){for(var i=0;i<3;i++)n[i]=e<0?n[i]*(1-e)|0:(255-n[i])*e+n[i]|0,n[i]>255?n[i]=255:n[i]<0&&(n[i]=0);return kn(n,4===n.length?"rgba":"rgb")}}function Mn(t,e,n){if(e&&e.length&&t>=0&&t<=1){n=n||[];var i=t*(e.length-1),r=Math.floor(i),o=Math.ceil(i),a=e[r],s=e[o],l=i-r;return n[0]=hn(gn(a[0],s[0],l)),n[1]=hn(gn(a[1],s[1],l)),n[2]=hn(gn(a[2],s[2],l)),n[3]=cn(gn(a[3],s[3],l)),n}}var In=Mn;function Tn(t,e,n){if(e&&e.length&&t>=0&&t<=1){var i=t*(e.length-1),r=Math.floor(i),o=Math.ceil(i),a=bn(e[r]),s=bn(e[o]),l=i-r,u=kn([hn(gn(a[0],s[0],l)),hn(gn(a[1],s[1],l)),hn(gn(a[2],s[2],l)),cn(gn(a[3],s[3],l))],"rgba");return n?{color:u,leftIndex:r,rightIndex:o,value:i}:u}}var Cn=Tn;function Dn(t,e,n,i){var r=bn(t);if(t)return r=function(t){if(t){var e,n,i=t[0]/255,r=t[1]/255,o=t[2]/255,a=Math.min(i,r,o),s=Math.max(i,r,o),l=s-a,u=(s+a)/2;if(0===l)e=0,n=0;else{n=u<.5?l/(s+a):l/(2-s-a);var h=((s-i)/6+l/2)/l,c=((s-r)/6+l/2)/l,p=((s-o)/6+l/2)/l;i===s?e=p-c:r===s?e=1/3+h-p:o===s&&(e=2/3+c-h),e<0&&(e+=1),e>1&&(e-=1)}var d=[360*e,n,u];return null!=t[3]&&d.push(t[3]),d}}(r),null!=e&&(r[0]=function(t){return(t=Math.round(t))<0?0:t>360?360:t}(e)),null!=n&&(r[1]=dn(n)),null!=i&&(r[2]=dn(i)),kn(wn(r),"rgba")}function An(t,e){var n=bn(t);if(n&&null!=e)return n[3]=cn(e),kn(n,"rgba")}function kn(t,e){if(t&&t.length){var n=t[0]+","+t[1]+","+t[2];return"rgba"!==e&&"hsva"!==e&&"hsla"!==e||(n+=","+t[3]),e+"("+n+")"}}function Ln(t,e){var n=bn(t);return n?(.299*n[0]+.587*n[1]+.114*n[2])*n[3]/255+(1-n[3])*e:0}var Pn=Object.freeze({__proto__:null,parse:bn,lift:Sn,toHex:function(t){var e=bn(t);if(e)return((1<<24)+(e[0]<<16)+(e[1]<<8)+ +e[2]).toString(16).slice(1)},fastLerp:Mn,fastMapToColor:In,lerp:Tn,mapToColor:Cn,modifyHSL:Dn,modifyAlpha:An,stringify:kn,lum:Ln,random:function(){return kn([Math.round(255*Math.random()),Math.round(255*Math.random()),Math.round(255*Math.random())],"rgb")}}),On=Math.round;function Rn(t){var e;if(t&&"transparent"!==t){if("string"==typeof t&&t.indexOf("rgba")>-1){var n=bn(t);n&&(t="rgb("+n[0]+","+n[1]+","+n[2]+")",e=n[3])}}else t="none";return{color:t,opacity:null==e?1:e}}var Nn=1e-4;function En(t){return t-1e-4}function zn(t){return On(1e3*t)/1e3}function Vn(t){return On(1e4*t)/1e4}var Bn={left:"start",right:"end",center:"middle",middle:"middle"};function Fn(t){return t&&!!t.image}function Gn(t){return"linear"===t.type}function Wn(t){return"radial"===t.type}function Hn(t){return"url(#"+t+")"}function Yn(t){var e=t.getGlobalScale(),n=Math.max(e[0],e[1]);return Math.max(Math.ceil(Math.log(n)/Math.log(10)),1)}function Un(t){var e=t.x||0,n=t.y||0,i=(t.rotation||0)*_t,r=rt(t.scaleX,1),o=rt(t.scaleY,1),a=t.skewX||0,s=t.skewY||0,l=[];return(e||n)&&l.push("translate("+e+"px,"+n+"px)"),i&&l.push("rotate("+i+")"),1===r&&1===o||l.push("scale("+r+","+o+")"),(a||s)&&l.push("skew("+On(a*_t)+"deg, "+On(s*_t)+"deg)"),l.join(" ")}var Xn=r.hasGlobalWindow&&U(window.btoa)?function(t){return window.btoa(unescape(t))}:"undefined"!=typeof Buffer?function(t){return Buffer.from(t).toString("base64")}:function(t){return null},Zn=Array.prototype.slice;function jn(t,e,n){return(e-t)*n+t}function qn(t,e,n,i){for(var r=e.length,o=0;oi?e:t,o=Math.min(n,i),a=r[o-1]||{color:[0,0,0,0],offset:0},s=o;sa)i.length=a;else for(var s=o;s=1},t.prototype.getAdditiveTrack=function(){return this._additiveTrack},t.prototype.addKeyframe=function(t,e,n){this._needsSort=!0;var i=this.keyframes,r=i.length,o=!1,a=6,s=e;if(N(e)){var l=function(t){return N(t&&t[0])?2:1}(e);a=l,(1===l&&!j(e[0])||2===l&&!j(e[0][0]))&&(o=!0)}else if(j(e)&&!nt(e))a=0;else if(X(e))if(isNaN(+e)){var u=bn(e);u&&(s=u,a=3)}else a=0;else if(Q(e)){var h=A({},s);h.colorStops=z(e.colorStops,(function(t){return{offset:t.offset,color:bn(t.color)}})),Gn(e)?a=4:Wn(e)&&(a=5),s=h}0===r?this.valType=a:a===this.valType&&6!==a||(o=!0),this.discrete=this.discrete||o;var c={time:t,value:s,rawValue:e,percent:0};return n&&(c.easing=n,c.easingFunc=U(n)?n:Le[n]||rn(n)),i.push(c),c},t.prototype.prepare=function(t,e){var n=this.keyframes;this._needsSort&&n.sort((function(t,e){return t.time-e.time}));for(var i=this.valType,r=n.length,o=n[r-1],a=this.discrete,s=ii(i),l=ni(i),u=0;u=0&&!(l[n].percent<=e);n--);n=d(n,u-2)}else{for(n=p;ne);n++);n=d(n-1,u-2)}r=l[n+1],i=l[n]}if(i&&r){this._lastFr=n,this._lastFrP=e;var f=r.percent-i.percent,g=0===f?1:d((e-i.percent)/f,1);r.easingFunc&&(g=r.easingFunc(g));var y=o?this._additiveValue:c?ri:t[h];if(!ii(s)&&!c||y||(y=this._additiveValue=[]),this.discrete)t[h]=g<1?i.rawValue:r.rawValue;else if(ii(s))1===s?qn(y,i[a],r[a],g):function(t,e,n,i){for(var r=e.length,o=r&&e[0].length,a=0;a0&&s.addKeyframe(0,ti(l),i),this._trackKeys.push(a)}s.addKeyframe(t,ti(e[a]),i)}return this._maxTime=Math.max(this._maxTime,t),this},t.prototype.pause=function(){this._clip.pause(),this._paused=!0},t.prototype.resume=function(){this._clip.resume(),this._paused=!1},t.prototype.isPaused=function(){return!!this._paused},t.prototype.duration=function(t){return this._maxTime=t,this._force=!0,this},t.prototype._doneCallback=function(){this._setTracksFinished(),this._clip=null;var t=this._doneCbs;if(t)for(var e=t.length,n=0;n0)){this._started=1;for(var e=this,n=[],i=this._maxTime||0,r=0;r1){var a=o.pop();r.addKeyframe(a.time,t[i]),r.prepare(this._maxTime,r.getAdditiveTrack())}}}},t}();function si(){return(new Date).getTime()}var li,ui,hi=function(t){function e(e){var n=t.call(this)||this;return n._running=!1,n._time=0,n._pausedTime=0,n._pauseStart=0,n._paused=!1,e=e||{},n.stage=e.stage||{},n}return n(e,t),e.prototype.addClip=function(t){t.animation&&this.removeClip(t),this._head?(this._tail.next=t,t.prev=this._tail,t.next=null,this._tail=t):this._head=this._tail=t,t.animation=this},e.prototype.addAnimator=function(t){t.animation=this;var e=t.getClip();e&&this.addClip(e)},e.prototype.removeClip=function(t){if(t.animation){var e=t.prev,n=t.next;e?e.next=n:this._head=n,n?n.prev=e:this._tail=e,t.next=t.prev=t.animation=null}},e.prototype.removeAnimator=function(t){var e=t.getClip();e&&this.removeClip(e),t.animation=null},e.prototype.update=function(t){for(var e=si()-this._pausedTime,n=e-this._time,i=this._head;i;){var r=i.next;i.step(e,n)?(i.ondestroy(),this.removeClip(i),i=r):i=r}this._time=e,t||(this.trigger("frame",n),this.stage.update&&this.stage.update())},e.prototype._startLoop=function(){var t=this;this._running=!0,ke((function e(){t._running&&(ke(e),!t._paused&&t.update())}))},e.prototype.start=function(){this._running||(this._time=si(),this._pausedTime=0,this._startLoop())},e.prototype.stop=function(){this._running=!1},e.prototype.pause=function(){this._paused||(this._pauseStart=si(),this._paused=!0)},e.prototype.resume=function(){this._paused&&(this._pausedTime+=si()-this._pauseStart,this._paused=!1)},e.prototype.clear=function(){for(var t=this._head;t;){var e=t.next;t.prev=t.next=t.animation=null,t=e}this._head=this._tail=null},e.prototype.isFinished=function(){return null==this._head},e.prototype.animate=function(t,e){e=e||{},this.start();var n=new ai(t,e.loop);return this.addAnimator(n),n},e}(Xt),ci=r.domSupported,pi=(ui={pointerdown:1,pointerup:1,pointermove:1,pointerout:1},{mouse:li=["click","dblclick","mousewheel","wheel","mouseout","mouseup","mousedown","mousemove","contextmenu"],touch:["touchstart","touchend","touchmove"],pointer:z(li,(function(t){var e=t.replace("mouse","pointer");return ui.hasOwnProperty(e)?e:t}))}),di=["mousemove","mouseup"],fi=["pointermove","pointerup"],gi=!1;function yi(t){var e=t.pointerType;return"pen"===e||"touch"===e}function vi(t){t&&(t.zrByTouch=!0)}function mi(t,e){for(var n=e,i=!1;n&&9!==n.nodeType&&!(i=n.domBelongToZr||n!==e&&n===t.painterRoot);)n=n.parentNode;return i}var xi=function(t,e){this.stopPropagation=xt,this.stopImmediatePropagation=xt,this.preventDefault=xt,this.type=e.type,this.target=this.currentTarget=t.dom,this.pointerType=e.pointerType,this.clientX=e.clientX,this.clientY=e.clientY},_i={mousedown:function(t){t=oe(this.dom,t),this.__mayPointerCapture=[t.zrX,t.zrY],this.trigger("mousedown",t)},mousemove:function(t){t=oe(this.dom,t);var e=this.__mayPointerCapture;!e||t.zrX===e[0]&&t.zrY===e[1]||this.__togglePointerCapture(!0),this.trigger("mousemove",t)},mouseup:function(t){t=oe(this.dom,t),this.__togglePointerCapture(!1),this.trigger("mouseup",t)},mouseout:function(t){mi(this,(t=oe(this.dom,t)).toElement||t.relatedTarget)||(this.__pointerCapturing&&(t.zrEventControl="no_globalout"),this.trigger("mouseout",t))},wheel:function(t){gi=!0,t=oe(this.dom,t),this.trigger("mousewheel",t)},mousewheel:function(t){gi||(t=oe(this.dom,t),this.trigger("mousewheel",t))},touchstart:function(t){vi(t=oe(this.dom,t)),this.__lastTouchMoment=new Date,this.handler.processGesture(t,"start"),_i.mousemove.call(this,t),_i.mousedown.call(this,t)},touchmove:function(t){vi(t=oe(this.dom,t)),this.handler.processGesture(t,"change"),_i.mousemove.call(this,t)},touchend:function(t){vi(t=oe(this.dom,t)),this.handler.processGesture(t,"end"),_i.mouseup.call(this,t),+new Date-+this.__lastTouchMoment<300&&_i.click.call(this,t)},pointerdown:function(t){_i.mousedown.call(this,t)},pointermove:function(t){yi(t)||_i.mousemove.call(this,t)},pointerup:function(t){_i.mouseup.call(this,t)},pointerout:function(t){yi(t)||_i.mouseout.call(this,t)}};E(["click","dblclick","contextmenu"],(function(t){_i[t]=function(e){e=oe(this.dom,e),this.trigger(t,e)}}));var bi={pointermove:function(t){yi(t)||bi.mousemove.call(this,t)},pointerup:function(t){bi.mouseup.call(this,t)},mousemove:function(t){this.trigger("mousemove",t)},mouseup:function(t){var e=this.__pointerCapturing;this.__togglePointerCapture(!1),this.trigger("mouseup",t),e&&(t.zrEventControl="only_globalout",this.trigger("mouseout",t))}};function wi(t,e){var n=e.domHandlers;r.pointerEventsSupported?E(pi.pointer,(function(i){Mi(e,i,(function(e){n[i].call(t,e)}))})):(r.touchEventsSupported&&E(pi.touch,(function(i){Mi(e,i,(function(r){n[i].call(t,r),function(t){t.touching=!0,null!=t.touchTimer&&(clearTimeout(t.touchTimer),t.touchTimer=null),t.touchTimer=setTimeout((function(){t.touching=!1,t.touchTimer=null}),700)}(e)}))})),E(pi.mouse,(function(i){Mi(e,i,(function(r){r=re(r),e.touching||n[i].call(t,r)}))})))}function Si(t,e){function n(n){Mi(e,n,(function(i){i=re(i),mi(t,i.target)||(i=function(t,e){return oe(t.dom,new xi(t,e),!0)}(t,i),e.domHandlers[n].call(t,i))}),{capture:!0})}r.pointerEventsSupported?E(fi,n):r.touchEventsSupported||E(di,n)}function Mi(t,e,n,i){t.mounted[e]=n,t.listenerOpts[e]=i,ae(t.domTarget,e,n,i)}function Ii(t){var e,n,i,r,o=t.mounted;for(var a in o)o.hasOwnProperty(a)&&(e=t.domTarget,n=a,i=o[a],r=t.listenerOpts[a],e.removeEventListener(n,i,r));t.mounted={}}var Ti=function(t,e){this.mounted={},this.listenerOpts={},this.touching=!1,this.domTarget=t,this.domHandlers=e},Ci=function(t){function e(e,n){var i=t.call(this)||this;return i.__pointerCapturing=!1,i.dom=e,i.painterRoot=n,i._localHandlerScope=new Ti(e,_i),ci&&(i._globalHandlerScope=new Ti(document,bi)),wi(i,i._localHandlerScope),i}return n(e,t),e.prototype.dispose=function(){Ii(this._localHandlerScope),ci&&Ii(this._globalHandlerScope)},e.prototype.setCursor=function(t){this.dom.style&&(this.dom.style.cursor=t||"default")},e.prototype.__togglePointerCapture=function(t){if(this.__mayPointerCapture=null,ci&&+this.__pointerCapturing^+t){this.__pointerCapturing=t;var e=this._globalHandlerScope;t?Si(this,e):Ii(e)}},e}(Xt),Di=1;r.hasGlobalWindow&&(Di=Math.max(window.devicePixelRatio||window.screen&&window.screen.deviceXDPI/window.screen.logicalXDPI||1,1));var Ai=Di,ki="#333",Li="#ccc";function Pi(){return[1,0,0,1,0,0]}function Oi(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t}function Ri(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t}function Ni(t,e,n){var i=e[0]*n[0]+e[2]*n[1],r=e[1]*n[0]+e[3]*n[1],o=e[0]*n[2]+e[2]*n[3],a=e[1]*n[2]+e[3]*n[3],s=e[0]*n[4]+e[2]*n[5]+e[4],l=e[1]*n[4]+e[3]*n[5]+e[5];return t[0]=i,t[1]=r,t[2]=o,t[3]=a,t[4]=s,t[5]=l,t}function Ei(t,e,n){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4]+n[0],t[5]=e[5]+n[1],t}function zi(t,e,n){var i=e[0],r=e[2],o=e[4],a=e[1],s=e[3],l=e[5],u=Math.sin(n),h=Math.cos(n);return t[0]=i*h+a*u,t[1]=-i*u+a*h,t[2]=r*h+s*u,t[3]=-r*u+h*s,t[4]=h*o+u*l,t[5]=h*l-u*o,t}function Vi(t,e,n){var i=n[0],r=n[1];return t[0]=e[0]*i,t[1]=e[1]*r,t[2]=e[2]*i,t[3]=e[3]*r,t[4]=e[4]*i,t[5]=e[5]*r,t}function Bi(t,e){var n=e[0],i=e[2],r=e[4],o=e[1],a=e[3],s=e[5],l=n*a-o*i;return l?(l=1/l,t[0]=a*l,t[1]=-o*l,t[2]=-i*l,t[3]=n*l,t[4]=(i*s-a*r)*l,t[5]=(o*r-n*s)*l,t):null}function Fi(t){var e=[1,0,0,1,0,0];return Ri(e,t),e}var Gi=Object.freeze({__proto__:null,create:Pi,identity:Oi,copy:Ri,mul:Ni,translate:Ei,rotate:zi,scale:Vi,invert:Bi,clone:Fi}),Wi=Oi,Hi=5e-5;function Yi(t){return t>Hi||t<-5e-5}var Ui=[],Xi=[],Zi=[1,0,0,1,0,0],ji=Math.abs,qi=function(){function t(){}return t.prototype.getLocalTransform=function(e){return t.getLocalTransform(this,e)},t.prototype.setPosition=function(t){this.x=t[0],this.y=t[1]},t.prototype.setScale=function(t){this.scaleX=t[0],this.scaleY=t[1]},t.prototype.setSkew=function(t){this.skewX=t[0],this.skewY=t[1]},t.prototype.setOrigin=function(t){this.originX=t[0],this.originY=t[1]},t.prototype.needLocalTransform=function(){return Yi(this.rotation)||Yi(this.x)||Yi(this.y)||Yi(this.scaleX-1)||Yi(this.scaleY-1)||Yi(this.skewX)||Yi(this.skewY)},t.prototype.updateTransform=function(){var t=this.parent&&this.parent.transform,e=this.needLocalTransform(),n=this.transform;e||t?(n=n||[1,0,0,1,0,0],e?this.getLocalTransform(n):Wi(n),t&&(e?Ni(n,t,n):Ri(n,t)),this.transform=n,this._resolveGlobalScaleRatio(n)):n&&Wi(n)},t.prototype._resolveGlobalScaleRatio=function(t){var e=this.globalScaleRatio;if(null!=e&&1!==e){this.getGlobalScale(Ui);var n=Ui[0]<0?-1:1,i=Ui[1]<0?-1:1,r=((Ui[0]-n)*e+n)/Ui[0]||0,o=((Ui[1]-i)*e+i)/Ui[1]||0;t[0]*=r,t[1]*=r,t[2]*=o,t[3]*=o}this.invTransform=this.invTransform||[1,0,0,1,0,0],Bi(this.invTransform,t)},t.prototype.getComputedTransform=function(){for(var t=this,e=[];t;)e.push(t),t=t.parent;for(;t=e.pop();)t.updateTransform();return this.transform},t.prototype.setLocalTransform=function(t){if(t){var e=t[0]*t[0]+t[1]*t[1],n=t[2]*t[2]+t[3]*t[3],i=Math.atan2(t[1],t[0]),r=Math.PI/2+i-Math.atan2(t[3],t[2]);n=Math.sqrt(n)*Math.cos(r),e=Math.sqrt(e),this.skewX=r,this.skewY=0,this.rotation=-i,this.x=+t[4],this.y=+t[5],this.scaleX=e,this.scaleY=n,this.originX=0,this.originY=0}},t.prototype.decomposeTransform=function(){if(this.transform){var t=this.parent,e=this.transform;t&&t.transform&&(Ni(Xi,t.invTransform,e),e=Xi);var n=this.originX,i=this.originY;(n||i)&&(Zi[4]=n,Zi[5]=i,Ni(Xi,e,Zi),Xi[4]-=n,Xi[5]-=i,e=Xi),this.setLocalTransform(e)}},t.prototype.getGlobalScale=function(t){var e=this.transform;return t=t||[],e?(t[0]=Math.sqrt(e[0]*e[0]+e[1]*e[1]),t[1]=Math.sqrt(e[2]*e[2]+e[3]*e[3]),e[0]<0&&(t[0]=-t[0]),e[3]<0&&(t[1]=-t[1]),t):(t[0]=1,t[1]=1,t)},t.prototype.transformCoordToLocal=function(t,e){var n=[t,e],i=this.invTransform;return i&&Ft(n,n,i),n},t.prototype.transformCoordToGlobal=function(t,e){var n=[t,e],i=this.transform;return i&&Ft(n,n,i),n},t.prototype.getLineScale=function(){var t=this.transform;return t&&ji(t[0]-1)>1e-10&&ji(t[3]-1)>1e-10?Math.sqrt(ji(t[0]*t[3]-t[2]*t[1])):1},t.prototype.copyTransform=function(t){$i(this,t)},t.getLocalTransform=function(t,e){e=e||[];var n=t.originX||0,i=t.originY||0,r=t.scaleX,o=t.scaleY,a=t.anchorX,s=t.anchorY,l=t.rotation||0,u=t.x,h=t.y,c=t.skewX?Math.tan(t.skewX):0,p=t.skewY?Math.tan(-t.skewY):0;if(n||i||a||s){var d=n+a,f=i+s;e[4]=-d*r-c*f*o,e[5]=-f*o-p*d*r}else e[4]=e[5]=0;return e[0]=r,e[3]=o,e[1]=p*r,e[2]=c*o,l&&zi(e,e,l),e[4]+=n+u,e[5]+=i+h,e},t.initDefaultProps=function(){var e=t.prototype;e.scaleX=e.scaleY=e.globalScaleRatio=1,e.x=e.y=e.originX=e.originY=e.skewX=e.skewY=e.rotation=e.anchorX=e.anchorY=0}(),t}(),Ki=["x","y","originX","originY","anchorX","anchorY","rotation","scaleX","scaleY","skewX","skewY"];function $i(t,e){for(var n=0;nf&&(f=x,gf&&(f=_,v=n.x&&t<=n.x+n.width&&e>=n.y&&e<=n.y+n.height},t.prototype.clone=function(){return new t(this.x,this.y,this.width,this.height)},t.prototype.copy=function(e){t.copy(this,e)},t.prototype.plain=function(){return{x:this.x,y:this.y,width:this.width,height:this.height}},t.prototype.isFinite=function(){return isFinite(this.x)&&isFinite(this.y)&&isFinite(this.width)&&isFinite(this.height)},t.prototype.isZero=function(){return 0===this.width||0===this.height},t.create=function(e){return new t(e.x,e.y,e.width,e.height)},t.copy=function(t,e){t.x=e.x,t.y=e.y,t.width=e.width,t.height=e.height},t.applyTransform=function(e,n,i){if(i){if(i[1]<1e-5&&i[1]>-1e-5&&i[2]<1e-5&&i[2]>-1e-5){var r=i[0],o=i[3],a=i[4],s=i[5];return e.x=n.x*r+a,e.y=n.y*o+s,e.width=n.width*r,e.height=n.height*o,e.width<0&&(e.x+=e.width,e.width=-e.width),void(e.height<0&&(e.y+=e.height,e.height=-e.height))}er.x=ir.x=n.x,er.y=rr.y=n.y,nr.x=rr.x=n.x+n.width,nr.y=ir.y=n.y+n.height,er.transform(i),rr.transform(i),nr.transform(i),ir.transform(i),e.x=Qi(er.x,nr.x,ir.x,rr.x),e.y=Qi(er.y,nr.y,ir.y,rr.y);var l=tr(er.x,nr.x,ir.x,rr.x),u=tr(er.y,nr.y,ir.y,rr.y);e.width=l-e.x,e.height=u-e.y}else e!==n&&t.copy(e,n)},t}(),lr={};function ur(t,e){var n=lr[e=e||a];n||(n=lr[e]=new ln(500));var i=n.get(t);return null==i&&(i=h.measureText(t,e).width,n.put(t,i)),i}function hr(t,e,n,i){var r=ur(t,e),o=fr(e),a=pr(0,r,n),s=dr(0,o,i);return new sr(a,s,r,o)}function cr(t,e,n,i){var r=((t||"")+"").split("\n");if(1===r.length)return hr(r[0],e,n,i);for(var o=new sr(0,0,0,0),a=0;a=0?parseFloat(t)/100*e:parseFloat(t):t}function yr(t,e,n){var i=e.position||"inside",r=null!=e.distance?e.distance:5,o=n.height,a=n.width,s=o/2,l=n.x,u=n.y,h="left",c="top";if(i instanceof Array)l+=gr(i[0],n.width),u+=gr(i[1],n.height),h=null,c=null;else switch(i){case"left":l-=r,u+=s,h="right",c="middle";break;case"right":l+=r+a,u+=s,c="middle";break;case"top":l+=a/2,u-=r,h="center",c="bottom";break;case"bottom":l+=a/2,u+=o+r,h="center";break;case"inside":l+=a/2,u+=s,h="center",c="middle";break;case"insideLeft":l+=r,u+=s,c="middle";break;case"insideRight":l+=a-r,u+=s,h="right",c="middle";break;case"insideTop":l+=a/2,u+=r,h="center";break;case"insideBottom":l+=a/2,u+=o-r,h="center",c="bottom";break;case"insideTopLeft":l+=r,u+=r;break;case"insideTopRight":l+=a-r,u+=r,h="right";break;case"insideBottomLeft":l+=r,u+=o-r,c="bottom";break;case"insideBottomRight":l+=a-r,u+=o-r,h="right",c="bottom"}return(t=t||{}).x=l,t.y=u,t.align=h,t.verticalAlign=c,t}var vr="__zr_normal__",mr=Ki.concat(["ignore"]),xr=V(Ki,(function(t,e){return t[e]=!0,t}),{ignore:!1}),_r={},br=new sr(0,0,0,0),wr=function(){function t(t){this.id=M(),this.animators=[],this.currentStates=[],this.states={},this._init(t)}return t.prototype._init=function(t){this.attr(t)},t.prototype.drift=function(t,e,n){switch(this.draggable){case"horizontal":e=0;break;case"vertical":t=0}var i=this.transform;i||(i=this.transform=[1,0,0,1,0,0]),i[4]+=t,i[5]+=e,this.decomposeTransform(),this.markRedraw()},t.prototype.beforeUpdate=function(){},t.prototype.afterUpdate=function(){},t.prototype.update=function(){this.updateTransform(),this.__dirty&&this.updateInnerText()},t.prototype.updateInnerText=function(t){var e=this._textContent;if(e&&(!e.ignore||t)){this.textConfig||(this.textConfig={});var n=this.textConfig,i=n.local,r=e.innerTransformable,o=void 0,a=void 0,s=!1;r.parent=i?this:null;var l=!1;if(r.copyTransform(e),null!=n.position){var u=br;n.layoutRect?u.copy(n.layoutRect):u.copy(this.getBoundingRect()),i||u.applyTransform(this.transform),this.calculateTextPosition?this.calculateTextPosition(_r,n,u):yr(_r,n,u),r.x=_r.x,r.y=_r.y,o=_r.align,a=_r.verticalAlign;var h=n.origin;if(h&&null!=n.rotation){var c=void 0,p=void 0;"center"===h?(c=.5*u.width,p=.5*u.height):(c=gr(h[0],u.width),p=gr(h[1],u.height)),l=!0,r.originX=-r.x+c+(i?0:u.x),r.originY=-r.y+p+(i?0:u.y)}}null!=n.rotation&&(r.rotation=n.rotation);var d=n.offset;d&&(r.x+=d[0],r.y+=d[1],l||(r.originX=-d[0],r.originY=-d[1]));var f=null==n.inside?"string"==typeof n.position&&n.position.indexOf("inside")>=0:n.inside,g=this._innerTextDefaultStyle||(this._innerTextDefaultStyle={}),y=void 0,v=void 0,m=void 0;f&&this.canBeInsideText()?(y=n.insideFill,v=n.insideStroke,null!=y&&"auto"!==y||(y=this.getInsideTextFill()),null!=v&&"auto"!==v||(v=this.getInsideTextStroke(y),m=!0)):(y=n.outsideFill,v=n.outsideStroke,null!=y&&"auto"!==y||(y=this.getOutsideFill()),null!=v&&"auto"!==v||(v=this.getOutsideStroke(y),m=!0)),(y=y||"#000")===g.fill&&v===g.stroke&&m===g.autoStroke&&o===g.align&&a===g.verticalAlign||(s=!0,g.fill=y,g.stroke=v,g.autoStroke=m,g.align=o,g.verticalAlign=a,e.setDefaultTextStyle(g)),e.__dirty|=1,s&&e.dirtyStyle(!0)}},t.prototype.canBeInsideText=function(){return!0},t.prototype.getInsideTextFill=function(){return"#fff"},t.prototype.getInsideTextStroke=function(t){return"#000"},t.prototype.getOutsideFill=function(){return this.__zr&&this.__zr.isDarkMode()?Li:ki},t.prototype.getOutsideStroke=function(t){var e=this.__zr&&this.__zr.getBackgroundColor(),n="string"==typeof e&&bn(e);n||(n=[255,255,255,1]);for(var i=n[3],r=this.__zr.isDarkMode(),o=0;o<3;o++)n[o]=n[o]*i+(r?0:255)*(1-i);return n[3]=1,kn(n,"rgba")},t.prototype.traverse=function(t,e){},t.prototype.attrKV=function(t,e){"textConfig"===t?this.setTextConfig(e):"textContent"===t?this.setTextContent(e):"clipPath"===t?this.setClipPath(e):"extra"===t?(this.extra=this.extra||{},A(this.extra,e)):this[t]=e},t.prototype.hide=function(){this.ignore=!0,this.markRedraw()},t.prototype.show=function(){this.ignore=!1,this.markRedraw()},t.prototype.attr=function(t,e){if("string"==typeof t)this.attrKV(t,e);else if(q(t))for(var n=G(t),i=0;i0},t.prototype.getState=function(t){return this.states[t]},t.prototype.ensureState=function(t){var e=this.states;return e[t]||(e[t]={}),e[t]},t.prototype.clearStates=function(t){this.useState(vr,!1,t)},t.prototype.useState=function(t,e,n,i){var r=t===vr;if(this.hasState()||!r){var o=this.currentStates,a=this.stateTransition;if(!(P(o,t)>=0)||!e&&1!==o.length){var s;if(this.stateProxy&&!r&&(s=this.stateProxy(t)),s||(s=this.states&&this.states[t]),s||r){r||this.saveCurrentToNormalState(s);var l=!!(s&&s.hoverLayer||i);l&&this._toggleHoverLayerFlag(!0),this._applyStateObj(t,s,this._normalState,e,!n&&!this.__inHover&&a&&a.duration>0,a);var u=this._textContent,h=this._textGuide;return u&&u.useState(t,e,n,l),h&&h.useState(t,e,n,l),r?(this.currentStates=[],this._normalState={}):e?this.currentStates.push(t):this.currentStates=[t],this._updateAnimationTargets(),this.markRedraw(),!l&&this.__inHover&&(this._toggleHoverLayerFlag(!1),this.__dirty&=-2),s}I("State "+t+" not exists.")}}},t.prototype.useStates=function(t,e,n){if(t.length){var i=[],r=this.currentStates,o=t.length,a=o===r.length;if(a)for(var s=0;s0,d);var f=this._textContent,g=this._textGuide;f&&f.useStates(t,e,c),g&&g.useStates(t,e,c),this._updateAnimationTargets(),this.currentStates=t.slice(),this.markRedraw(),!c&&this.__inHover&&(this._toggleHoverLayerFlag(!1),this.__dirty&=-2)}else this.clearStates()},t.prototype._updateAnimationTargets=function(){for(var t=0;t=0){var n=this.currentStates.slice();n.splice(e,1),this.useStates(n)}},t.prototype.replaceState=function(t,e,n){var i=this.currentStates.slice(),r=P(i,t),o=P(i,e)>=0;r>=0?o?i.splice(r,1):i[r]=e:n&&!o&&i.push(e),this.useStates(i)},t.prototype.toggleState=function(t,e){e?this.useState(t,!0):this.removeState(t)},t.prototype._mergeStates=function(t){for(var e,n={},i=0;i=0&&e.splice(n,1)})),this.animators.push(t),n&&n.animation.addAnimator(t),n&&n.wakeUp()},t.prototype.updateDuringAnimation=function(t){this.markRedraw()},t.prototype.stopAnimation=function(t,e){for(var n=this.animators,i=n.length,r=[],o=0;o0&&n.during&&o[0].during((function(t,e){n.during(e)}));for(var p=0;p0||r.force&&!a.length){var w,S=void 0,M=void 0,I=void 0;if(s){M={},p&&(S={});for(_=0;_=0&&(n.splice(i,0,t),this._doAdd(t))}return this},e.prototype.replace=function(t,e){var n=P(this._children,t);return n>=0&&this.replaceAt(e,n),this},e.prototype.replaceAt=function(t,e){var n=this._children,i=n[e];if(t&&t!==this&&t.parent!==this&&t!==i){n[e]=t,i.parent=null;var r=this.__zr;r&&i.removeSelfFromZr(r),this._doAdd(t)}return this},e.prototype._doAdd=function(t){t.parent&&t.parent.remove(t),t.parent=this;var e=this.__zr;e&&e!==t.__zr&&t.addSelfToZr(e),e&&e.refresh()},e.prototype.remove=function(t){var e=this.__zr,n=this._children,i=P(n,t);return i<0||(n.splice(i,1),t.parent=null,e&&t.removeSelfFromZr(e),e&&e.refresh()),this},e.prototype.removeAll=function(){for(var t=this._children,e=this.__zr,n=0;n0&&(this._stillFrameAccum++,this._stillFrameAccum>this._sleepAfterStill&&this.animation.stop())},t.prototype.setSleepAfterStill=function(t){this._sleepAfterStill=t},t.prototype.wakeUp=function(){this.animation.start(),this._stillFrameAccum=0},t.prototype.refreshHover=function(){this._needsRefreshHover=!0},t.prototype.refreshHoverImmediately=function(){this._needsRefreshHover=!1,this.painter.refreshHover&&"canvas"===this.painter.getType()&&this.painter.refreshHover()},t.prototype.resize=function(t){t=t||{},this.painter.resize(t.width,t.height),this.handler.resize()},t.prototype.clearAnimation=function(){this.animation.clear()},t.prototype.getWidth=function(){return this.painter.getWidth()},t.prototype.getHeight=function(){return this.painter.getHeight()},t.prototype.setCursorStyle=function(t){this.handler.setCursorStyle(t)},t.prototype.findHover=function(t,e){return this.handler.findHover(t,e)},t.prototype.on=function(t,e,n){return this.handler.on(t,e,n),this},t.prototype.off=function(t,e){this.handler.off(t,e)},t.prototype.trigger=function(t,e){this.handler.trigger(t,e)},t.prototype.clear=function(){for(var t=this.storage.getRoots(),e=0;e0){if(t<=r)return a;if(t>=o)return s}else{if(t>=r)return a;if(t<=o)return s}else{if(t===r)return a;if(t===o)return s}return(t-r)/l*u+a}function Er(t,e){switch(t){case"center":case"middle":t="50%";break;case"left":case"top":t="0%";break;case"right":case"bottom":t="100%"}return X(t)?(n=t,n.replace(/^\s+|\s+$/g,"")).match(/%$/)?parseFloat(t)/100*e:parseFloat(t):null==t?NaN:+t;var n}function zr(t,e,n){return null==e&&(e=10),e=Math.min(Math.max(0,e),20),t=(+t).toFixed(e),n?t:+t}function Vr(t){return t.sort((function(t,e){return t-e})),t}function Br(t){if(t=+t,isNaN(t))return 0;if(t>1e-14)for(var e=1,n=0;n<15;n++,e*=10)if(Math.round(t*e)/e===t)return n;return Fr(t)}function Fr(t){var e=t.toString().toLowerCase(),n=e.indexOf("e"),i=n>0?+e.slice(n+1):0,r=n>0?n:e.length,o=e.indexOf("."),a=o<0?0:r-1-o;return Math.max(0,a-i)}function Gr(t,e){var n=Math.log,i=Math.LN10,r=Math.floor(n(t[1]-t[0])/i),o=Math.round(n(Math.abs(e[1]-e[0]))/i),a=Math.min(Math.max(-r+o,0),20);return isFinite(a)?a:20}function Wr(t,e,n){if(!t[e])return 0;var i=V(t,(function(t,e){return t+(isNaN(e)?0:e)}),0);if(0===i)return 0;for(var r=Math.pow(10,n),o=z(t,(function(t){return(isNaN(t)?0:t)/i*r*100})),a=100*r,s=z(o,(function(t){return Math.floor(t)})),l=V(s,(function(t,e){return t+e}),0),u=z(o,(function(t,e){return t-s[e]}));lh&&(h=u[p],c=p);++s[c],u[c]=0,++l}return s[e]/r}function Hr(t,e){var n=Math.max(Br(t),Br(e)),i=t+e;return n>20?i:zr(i,n)}var Yr=9007199254740991;function Ur(t){var e=2*Math.PI;return(t%e+e)%e}function Xr(t){return t>-1e-4&&t=10&&e++,e}function $r(t,e){var n=Kr(t),i=Math.pow(10,n),r=t/i;return t=(e?r<1.5?1:r<2.5?2:r<4?3:r<7?5:10:r<1?1:r<2?2:r<3?3:r<5?5:10)*i,n>=-20?+t.toFixed(n<0?-n:0):t}function Jr(t,e){var n=(t.length-1)*e+1,i=Math.floor(n),r=+t[i-1],o=n-i;return o?r+o*(t[i]-r):r}function Qr(t){t.sort((function(t,e){return s(t,e,0)?-1:1}));for(var e=-1/0,n=1,i=0;i=0||r&&P(r,s)<0)){var l=n.getShallow(s,e);null!=l&&(o[t[a][0]]=l)}}return o}}var Ho=Wo([["fill","color"],["shadowBlur"],["shadowOffsetX"],["shadowOffsetY"],["opacity"],["shadowColor"]]),Yo=function(){function t(){}return t.prototype.getAreaStyle=function(t,e){return Ho(this,t,e)},t}(),Uo=new ln(50);function Xo(t){if("string"==typeof t){var e=Uo.get(t);return e&&e.image}return t}function Zo(t,e,n,i,r){if(t){if("string"==typeof t){if(e&&e.__zrImageSrc===t||!n)return e;var o=Uo.get(t),a={hostEl:n,cb:i,cbPayload:r};if(o)!qo(e=o.image)&&o.pending.push(a);else{var s=h.loadImage(t,jo,jo);s.__zrImageSrc=t,Uo.put(t,s.__cachedImgObj={image:s,pending:[a]})}return e}return t}return e}function jo(){var t=this.__cachedImgObj;this.onload=this.onerror=this.__cachedImgObj=null;for(var e=0;e=a;l++)s-=a;var u=ur(n,e);return u>s&&(n="",u=0),s=t-u,r.ellipsis=n,r.ellipsisWidth=u,r.contentWidth=s,r.containerWidth=t,r}function Qo(t,e){var n=e.containerWidth,i=e.font,r=e.contentWidth;if(!n)return"";var o=ur(t,i);if(o<=n)return t;for(var a=0;;a++){if(o<=r||a>=e.maxIterations){t+=e.ellipsis;break}var s=0===a?ta(t,r,e.ascCharWidth,e.cnCharWidth):o>0?Math.floor(t.length*r/o):0;o=ur(t=t.substr(0,s),i)}return""===t&&(t=e.placeholder),t}function ta(t,e,n,i){for(var r=0,o=0,a=t.length;o0&&f+i.accumWidth>i.width&&(o=e.split("\n"),c=!0),i.accumWidth=f}else{var g=sa(e,h,i.width,i.breakAll,i.accumWidth);i.accumWidth=g.accumWidth+d,a=g.linesWidths,o=g.lines}}else o=e.split("\n");for(var y=0;y=33&&e<=383}(t)||!!oa[t]}function sa(t,e,n,i,r){for(var o=[],a=[],s="",l="",u=0,h=0,c=0;cn:r+h+d>n)?h?(s||l)&&(f?(s||(s=l,l="",h=u=0),o.push(s),a.push(h-u),l+=p,s="",h=u+=d):(l&&(s+=l,l="",u=0),o.push(s),a.push(h),s=p,h=d)):f?(o.push(l),a.push(u),l=p,u=d):(o.push(p),a.push(d)):(h+=d,f?(l+=p,u+=d):(l&&(s+=l,l="",u=0),s+=p))}else l&&(s+=l,h+=u),o.push(s),a.push(h),s="",l="",u=0,h=0}return o.length||s||(s=t,l="",u=0),l&&(s+=l),s&&(o.push(s),a.push(h)),1===o.length&&(h+=r),{accumWidth:h,lines:o,linesWidths:a}}var la="__zr_style_"+Math.round(10*Math.random()),ua={shadowBlur:0,shadowOffsetX:0,shadowOffsetY:0,shadowColor:"#000",opacity:1,blend:"source-over"},ha={style:{shadowBlur:!0,shadowOffsetX:!0,shadowOffsetY:!0,shadowColor:!0,opacity:!0}};ua[la]=!0;var ca=["z","z2","invisible"],pa=["invisible"],da=function(t){function e(e){return t.call(this,e)||this}var i;return n(e,t),e.prototype._init=function(e){for(var n=G(e),i=0;i1e-4)return s[0]=t-n,s[1]=e-i,l[0]=t+n,void(l[1]=e+i);if(ba[0]=xa(r)*n+t,ba[1]=ma(r)*i+e,wa[0]=xa(o)*n+t,wa[1]=ma(o)*i+e,u(s,ba,wa),h(l,ba,wa),(r%=_a)<0&&(r+=_a),(o%=_a)<0&&(o+=_a),r>o&&!a?o+=_a:rr&&(Sa[0]=xa(d)*n+t,Sa[1]=ma(d)*i+e,u(s,Sa,s),h(l,Sa,l))}var La={M:1,L:2,C:3,Q:4,A:5,Z:6,R:7},Pa=[],Oa=[],Ra=[],Na=[],Ea=[],za=[],Va=Math.min,Ba=Math.max,Fa=Math.cos,Ga=Math.sin,Wa=Math.abs,Ha=Math.PI,Ya=2*Ha,Ua="undefined"!=typeof Float32Array,Xa=[];function Za(t){return Math.round(t/Ha*1e8)/1e8%2*Ha}var ja=function(){function t(t){this.dpr=1,this._xi=0,this._yi=0,this._x0=0,this._y0=0,this._len=0,t&&(this._saveData=!1),this._saveData&&(this.data=[])}return t.prototype.increaseVersion=function(){this._version++},t.prototype.getVersion=function(){return this._version},t.prototype.setScale=function(t,e,n){(n=n||0)>0&&(this._ux=Wa(n/Ai/t)||0,this._uy=Wa(n/Ai/e)||0)},t.prototype.setDPR=function(t){this.dpr=t},t.prototype.setContext=function(t){this._ctx=t},t.prototype.getContext=function(){return this._ctx},t.prototype.beginPath=function(){return this._ctx&&this._ctx.beginPath(),this.reset(),this},t.prototype.reset=function(){this._saveData&&(this._len=0),this._pathSegLen&&(this._pathSegLen=null,this._pathLen=0),this._version++},t.prototype.moveTo=function(t,e){return this._drawPendingPt(),this.addData(La.M,t,e),this._ctx&&this._ctx.moveTo(t,e),this._x0=t,this._y0=e,this._xi=t,this._yi=e,this},t.prototype.lineTo=function(t,e){var n=Wa(t-this._xi),i=Wa(e-this._yi),r=n>this._ux||i>this._uy;if(this.addData(La.L,t,e),this._ctx&&r&&this._ctx.lineTo(t,e),r)this._xi=t,this._yi=e,this._pendingPtDist=0;else{var o=n*n+i*i;o>this._pendingPtDist&&(this._pendingPtX=t,this._pendingPtY=e,this._pendingPtDist=o)}return this},t.prototype.bezierCurveTo=function(t,e,n,i,r,o){return this._drawPendingPt(),this.addData(La.C,t,e,n,i,r,o),this._ctx&&this._ctx.bezierCurveTo(t,e,n,i,r,o),this._xi=r,this._yi=o,this},t.prototype.quadraticCurveTo=function(t,e,n,i){return this._drawPendingPt(),this.addData(La.Q,t,e,n,i),this._ctx&&this._ctx.quadraticCurveTo(t,e,n,i),this._xi=n,this._yi=i,this},t.prototype.arc=function(t,e,n,i,r,o){this._drawPendingPt(),Xa[0]=i,Xa[1]=r,function(t,e){var n=Za(t[0]);n<0&&(n+=Ya);var i=n-t[0],r=t[1];r+=i,!e&&r-n>=Ya?r=n+Ya:e&&n-r>=Ya?r=n-Ya:!e&&n>r?r=n+(Ya-Za(n-r)):e&&nu.length&&(this._expandData(),u=this.data);for(var h=0;h0&&(this._ctx&&this._ctx.lineTo(this._pendingPtX,this._pendingPtY),this._pendingPtDist=0)},t.prototype._expandData=function(){if(!(this.data instanceof Array)){for(var t=[],e=0;e11&&(this.data=new Float32Array(t)))}},t.prototype.getBoundingRect=function(){Ra[0]=Ra[1]=Ea[0]=Ea[1]=Number.MAX_VALUE,Na[0]=Na[1]=za[0]=za[1]=-Number.MAX_VALUE;var t,e=this.data,n=0,i=0,r=0,o=0;for(t=0;tn||Wa(y)>i||c===e-1)&&(f=Math.sqrt(A*A+y*y),r=g,o=x);break;case La.C:var v=t[c++],m=t[c++],x=(g=t[c++],t[c++]),_=t[c++],b=t[c++];f=qe(r,o,v,m,g,x,_,b,10),r=_,o=b;break;case La.Q:f=en(r,o,v=t[c++],m=t[c++],g=t[c++],x=t[c++],10),r=g,o=x;break;case La.A:var w=t[c++],S=t[c++],M=t[c++],I=t[c++],T=t[c++],C=t[c++],D=C+T;c+=1;t[c++];d&&(a=Fa(T)*M+w,s=Ga(T)*I+S),f=Ba(M,I)*Va(Ya,Math.abs(C)),r=Fa(D)*M+w,o=Ga(D)*I+S;break;case La.R:a=r=t[c++],s=o=t[c++],f=2*t[c++]+2*t[c++];break;case La.Z:var A=a-r;y=s-o;f=Math.sqrt(A*A+y*y),r=a,o=s}f>=0&&(l[h++]=f,u+=f)}return this._pathLen=u,u},t.prototype.rebuildPath=function(t,e){var n,i,r,o,a,s,l,u,h,c,p=this.data,d=this._ux,f=this._uy,g=this._len,y=e<1,v=0,m=0,x=0;if(!y||(this._pathSegLen||this._calculateLength(),l=this._pathSegLen,u=e*this._pathLen))t:for(var _=0;_0&&(t.lineTo(h,c),x=0),b){case La.M:n=r=p[_++],i=o=p[_++],t.moveTo(r,o);break;case La.L:a=p[_++],s=p[_++];var S=Wa(a-r),M=Wa(s-o);if(S>d||M>f){if(y){if(v+(j=l[m++])>u){var I=(u-v)/j;t.lineTo(r*(1-I)+a*I,o*(1-I)+s*I);break t}v+=j}t.lineTo(a,s),r=a,o=s,x=0}else{var T=S*S+M*M;T>x&&(h=a,c=s,x=T)}break;case La.C:var C=p[_++],D=p[_++],A=p[_++],k=p[_++],L=p[_++],P=p[_++];if(y){if(v+(j=l[m++])>u){Ze(r,C,A,L,I=(u-v)/j,Pa),Ze(o,D,k,P,I,Oa),t.bezierCurveTo(Pa[1],Oa[1],Pa[2],Oa[2],Pa[3],Oa[3]);break t}v+=j}t.bezierCurveTo(C,D,A,k,L,P),r=L,o=P;break;case La.Q:C=p[_++],D=p[_++],A=p[_++],k=p[_++];if(y){if(v+(j=l[m++])>u){Qe(r,C,A,I=(u-v)/j,Pa),Qe(o,D,k,I,Oa),t.quadraticCurveTo(Pa[1],Oa[1],Pa[2],Oa[2]);break t}v+=j}t.quadraticCurveTo(C,D,A,k),r=A,o=k;break;case La.A:var O=p[_++],R=p[_++],N=p[_++],E=p[_++],z=p[_++],V=p[_++],B=p[_++],F=!p[_++],G=N>E?N:E,W=Wa(N-E)>.001,H=z+V,Y=!1;if(y)v+(j=l[m++])>u&&(H=z+V*(u-v)/j,Y=!0),v+=j;if(W&&t.ellipse?t.ellipse(O,R,N,E,B,z,H,F):t.arc(O,R,G,z,H,F),Y)break t;w&&(n=Fa(z)*N+O,i=Ga(z)*E+R),r=Fa(H)*N+O,o=Ga(H)*E+R;break;case La.R:n=r=p[_],i=o=p[_+1],a=p[_++],s=p[_++];var U=p[_++],X=p[_++];if(y){if(v+(j=l[m++])>u){var Z=u-v;t.moveTo(a,s),t.lineTo(a+Va(Z,U),s),(Z-=U)>0&&t.lineTo(a+U,s+Va(Z,X)),(Z-=X)>0&&t.lineTo(a+Ba(U-Z,0),s+X),(Z-=U)>0&&t.lineTo(a,s+Ba(X-Z,0));break t}v+=j}t.rect(a,s,U,X);break;case La.Z:if(y){var j;if(v+(j=l[m++])>u){I=(u-v)/j;t.lineTo(r*(1-I)+n*I,o*(1-I)+i*I);break t}v+=j}t.closePath(),r=n,o=i}}},t.prototype.clone=function(){var e=new t,n=this.data;return e.data=n.slice?n.slice():Array.prototype.slice.call(n),e._len=this._len,e},t.CMD=La,t.initDefaultProps=function(){var e=t.prototype;e._saveData=!0,e._ux=0,e._uy=0,e._pendingPtDist=0,e._version=0}(),t}();function qa(t,e,n,i,r,o,a){if(0===r)return!1;var s=r,l=0;if(a>e+s&&a>i+s||at+s&&o>n+s||oe+c&&h>i+c&&h>o+c&&h>s+c||ht+c&&u>n+c&&u>r+c&&u>a+c||ue+u&&l>i+u&&l>o+u||lt+u&&s>n+u&&s>r+u||sn||h+ur&&(r+=ts);var p=Math.atan2(l,s);return p<0&&(p+=ts),p>=i&&p<=r||p+ts>=i&&p+ts<=r}function ns(t,e,n,i,r,o){if(o>e&&o>i||or?s:0}var is=ja.CMD,rs=2*Math.PI;var os=[-1,-1,-1],as=[-1,-1];function ss(t,e,n,i,r,o,a,s,l,u){if(u>e&&u>i&&u>o&&u>s||u1&&(h=void 0,h=as[0],as[0]=as[1],as[1]=h),f=He(e,i,o,s,as[0]),d>1&&(g=He(e,i,o,s,as[1]))),2===d?ve&&s>i&&s>o||s=0&&h<=1&&(r[l++]=h);else{var u=a*a-4*o*s;if(Ge(u))(h=-a/(2*o))>=0&&h<=1&&(r[l++]=h);else if(u>0){var h,c=Oe(u),p=(-a-c)/(2*o);(h=(-a+c)/(2*o))>=0&&h<=1&&(r[l++]=h),p>=0&&p<=1&&(r[l++]=p)}}return l}(e,i,o,s,os);if(0===l)return 0;var u=Je(e,i,o);if(u>=0&&u<=1){for(var h=0,c=Ke(e,i,o,u),p=0;pn||s<-n)return 0;var l=Math.sqrt(n*n-s*s);os[0]=-l,os[1]=l;var u=Math.abs(i-r);if(u<1e-4)return 0;if(u>=rs-1e-4){i=0,r=rs;var h=o?1:-1;return a>=os[0]+t&&a<=os[1]+t?h:0}if(i>r){var c=i;i=r,r=c}i<0&&(i+=rs,r+=rs);for(var p=0,d=0;d<2;d++){var f=os[d];if(f+t>a){var g=Math.atan2(s,f);h=o?1:-1;g<0&&(g=rs+g),(g>=i&&g<=r||g+rs>=i&&g+rs<=r)&&(g>Math.PI/2&&g<1.5*Math.PI&&(h=-h),p+=h)}}return p}function hs(t,e,n,i,r){for(var o,a,s,l,u=t.data,h=t.len(),c=0,p=0,d=0,f=0,g=0,y=0;y1&&(n||(c+=ns(p,d,f,g,i,r))),m&&(f=p=u[y],g=d=u[y+1]),v){case is.M:p=f=u[y++],d=g=u[y++];break;case is.L:if(n){if(qa(p,d,u[y],u[y+1],e,i,r))return!0}else c+=ns(p,d,u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case is.C:if(n){if(Ka(p,d,u[y++],u[y++],u[y++],u[y++],u[y],u[y+1],e,i,r))return!0}else c+=ss(p,d,u[y++],u[y++],u[y++],u[y++],u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case is.Q:if(n){if($a(p,d,u[y++],u[y++],u[y],u[y+1],e,i,r))return!0}else c+=ls(p,d,u[y++],u[y++],u[y],u[y+1],i,r)||0;p=u[y++],d=u[y++];break;case is.A:var x=u[y++],_=u[y++],b=u[y++],w=u[y++],S=u[y++],M=u[y++];y+=1;var I=!!(1-u[y++]);o=Math.cos(S)*b+x,a=Math.sin(S)*w+_,m?(f=o,g=a):c+=ns(p,d,o,a,i,r);var T=(i-x)*w/b+x;if(n){if(es(x,_,w,S,S+M,I,e,T,r))return!0}else c+=us(x,_,w,S,S+M,I,T,r);p=Math.cos(S+M)*b+x,d=Math.sin(S+M)*w+_;break;case is.R:if(f=p=u[y++],g=d=u[y++],o=f+u[y++],a=g+u[y++],n){if(qa(f,g,o,g,e,i,r)||qa(o,g,o,a,e,i,r)||qa(o,a,f,a,e,i,r)||qa(f,a,f,g,e,i,r))return!0}else c+=ns(o,g,o,a,i,r),c+=ns(f,a,f,g,i,r);break;case is.Z:if(n){if(qa(p,d,f,g,e,i,r))return!0}else c+=ns(p,d,f,g,i,r);p=f,d=g}}return n||(s=d,l=g,Math.abs(s-l)<1e-4)||(c+=ns(p,d,f,g,i,r)||0),0!==c}var cs=k({fill:"#000",stroke:null,strokePercent:1,fillOpacity:1,strokeOpacity:1,lineDashOffset:0,lineWidth:1,lineCap:"butt",miterLimit:10,strokeNoScale:!1,strokeFirst:!1},ua),ps={style:k({fill:!0,stroke:!0,strokePercent:!0,fillOpacity:!0,strokeOpacity:!0,lineDashOffset:!0,lineWidth:!0,miterLimit:!0},ha.style)},ds=Ki.concat(["invisible","culling","z","z2","zlevel","parent"]),fs=function(t){function e(e){return t.call(this,e)||this}var i;return n(e,t),e.prototype.update=function(){var n=this;t.prototype.update.call(this);var i=this.style;if(i.decal){var r=this._decalEl=this._decalEl||new e;r.buildPath===e.prototype.buildPath&&(r.buildPath=function(t){n.buildPath(t,n.shape)}),r.silent=!0;var o=r.style;for(var a in i)o[a]!==i[a]&&(o[a]=i[a]);o.fill=i.fill?i.decal:null,o.decal=null,o.shadowColor=null,i.strokeFirst&&(o.stroke=null);for(var s=0;s.5?ki:e>.2?"#eee":Li}if(t)return Li}return ki},e.prototype.getInsideTextStroke=function(t){var e=this.style.fill;if(X(e)){var n=this.__zr;if(!(!n||!n.isDarkMode())===Ln(t,0)<.4)return e}},e.prototype.buildPath=function(t,e,n){},e.prototype.pathUpdated=function(){this.__dirty&=-5},e.prototype.getUpdatedPathProxy=function(t){return!this.path&&this.createPathProxy(),this.path.beginPath(),this.buildPath(this.path,this.shape,t),this.path},e.prototype.createPathProxy=function(){this.path=new ja(!1)},e.prototype.hasStroke=function(){var t=this.style,e=t.stroke;return!(null==e||"none"===e||!(t.lineWidth>0))},e.prototype.hasFill=function(){var t=this.style.fill;return null!=t&&"none"!==t},e.prototype.getBoundingRect=function(){var t=this._rect,e=this.style,n=!t;if(n){var i=!1;this.path||(i=!0,this.createPathProxy());var r=this.path;(i||4&this.__dirty)&&(r.beginPath(),this.buildPath(r,this.shape,!1),this.pathUpdated()),t=r.getBoundingRect()}if(this._rect=t,this.hasStroke()&&this.path&&this.path.len()>0){var o=this._rectStroke||(this._rectStroke=t.clone());if(this.__dirty||n){o.copy(t);var a=e.strokeNoScale?this.getLineScale():1,s=e.lineWidth;if(!this.hasFill()){var l=this.strokeContainThreshold;s=Math.max(s,null==l?4:l)}a>1e-10&&(o.width+=s/a,o.height+=s/a,o.x-=s/a/2,o.y-=s/a/2)}return o}return t},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect(),r=this.style;if(t=n[0],e=n[1],i.contain(t,e)){var o=this.path;if(this.hasStroke()){var a=r.lineWidth,s=r.strokeNoScale?this.getLineScale():1;if(s>1e-10&&(this.hasFill()||(a=Math.max(a,this.strokeContainThreshold)),function(t,e,n,i){return hs(t,e,!0,n,i)}(o,a/s,t,e)))return!0}if(this.hasFill())return function(t,e,n){return hs(t,0,!1,e,n)}(o,t,e)}return!1},e.prototype.dirtyShape=function(){this.__dirty|=4,this._rect&&(this._rect=null),this._decalEl&&this._decalEl.dirtyShape(),this.markRedraw()},e.prototype.dirty=function(){this.dirtyStyle(),this.dirtyShape()},e.prototype.animateShape=function(t){return this.animate("shape",t)},e.prototype.updateDuringAnimation=function(t){"style"===t?this.dirtyStyle():"shape"===t?this.dirtyShape():this.markRedraw()},e.prototype.attrKV=function(e,n){"shape"===e?this.setShape(n):t.prototype.attrKV.call(this,e,n)},e.prototype.setShape=function(t,e){var n=this.shape;return n||(n=this.shape={}),"string"==typeof t?n[t]=e:A(n,t),this.dirtyShape(),this},e.prototype.shapeChanged=function(){return!!(4&this.__dirty)},e.prototype.createStyle=function(t){return yt(cs,t)},e.prototype._innerSaveToNormal=function(e){t.prototype._innerSaveToNormal.call(this,e);var n=this._normalState;e.shape&&!n.shape&&(n.shape=A({},this.shape))},e.prototype._applyStateObj=function(e,n,i,r,o,a){t.prototype._applyStateObj.call(this,e,n,i,r,o,a);var s,l=!(n&&r);if(n&&n.shape?o?r?s=n.shape:(s=A({},i.shape),A(s,n.shape)):(s=A({},r?this.shape:i.shape),A(s,n.shape)):l&&(s=i.shape),s)if(o){this.shape=A({},this.shape);for(var u={},h=G(s),c=0;c0},e.prototype.hasFill=function(){var t=this.style.fill;return null!=t&&"none"!==t},e.prototype.createStyle=function(t){return yt(gs,t)},e.prototype.setBoundingRect=function(t){this._rect=t},e.prototype.getBoundingRect=function(){var t=this.style;if(!this._rect){var e=t.text;null!=e?e+="":e="";var n=cr(e,t.font,t.textAlign,t.textBaseline);if(n.x+=t.x||0,n.y+=t.y||0,this.hasStroke()){var i=t.lineWidth;n.x-=i/2,n.y-=i/2,n.width+=i,n.height+=i}this._rect=n}return this._rect},e.initDefaultProps=void(e.prototype.dirtyRectTolerance=10),e}(da);ys.prototype.type="tspan";var vs=k({x:0,y:0},ua),ms={style:k({x:!0,y:!0,width:!0,height:!0,sx:!0,sy:!0,sWidth:!0,sHeight:!0},ha.style)};var xs=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.createStyle=function(t){return yt(vs,t)},e.prototype._getSize=function(t){var e=this.style,n=e[t];if(null!=n)return n;var i,r=(i=e.image)&&"string"!=typeof i&&i.width&&i.height?e.image:this.__image;if(!r)return 0;var o="width"===t?"height":"width",a=e[o];return null==a?r[t]:r[t]/r[o]*a},e.prototype.getWidth=function(){return this._getSize("width")},e.prototype.getHeight=function(){return this._getSize("height")},e.prototype.getAnimationStyleProps=function(){return ms},e.prototype.getBoundingRect=function(){var t=this.style;return this._rect||(this._rect=new sr(t.x||0,t.y||0,this.getWidth(),this.getHeight())),this._rect},e}(da);xs.prototype.type="image";var _s=Math.round;function bs(t,e,n){if(e){var i=e.x1,r=e.x2,o=e.y1,a=e.y2;t.x1=i,t.x2=r,t.y1=o,t.y2=a;var s=n&&n.lineWidth;return s?(_s(2*i)===_s(2*r)&&(t.x1=t.x2=Ss(i,s,!0)),_s(2*o)===_s(2*a)&&(t.y1=t.y2=Ss(o,s,!0)),t):t}}function ws(t,e,n){if(e){var i=e.x,r=e.y,o=e.width,a=e.height;t.x=i,t.y=r,t.width=o,t.height=a;var s=n&&n.lineWidth;return s?(t.x=Ss(i,s,!0),t.y=Ss(r,s,!0),t.width=Math.max(Ss(i+o,s,!1)-t.x,0===o?0:1),t.height=Math.max(Ss(r+a,s,!1)-t.y,0===a?0:1),t):t}}function Ss(t,e,n){if(!e)return t;var i=_s(2*t);return(i+_s(e))%2==0?i/2:(i+(n?1:-1))/2}var Ms=function(){this.x=0,this.y=0,this.width=0,this.height=0},Is={},Ts=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Ms},e.prototype.buildPath=function(t,e){var n,i,r,o;if(this.subPixelOptimize){var a=ws(Is,e,this.style);n=a.x,i=a.y,r=a.width,o=a.height,a.r=e.r,e=a}else n=e.x,i=e.y,r=e.width,o=e.height;e.r?function(t,e){var n,i,r,o,a,s=e.x,l=e.y,u=e.width,h=e.height,c=e.r;u<0&&(s+=u,u=-u),h<0&&(l+=h,h=-h),"number"==typeof c?n=i=r=o=c:c instanceof Array?1===c.length?n=i=r=o=c[0]:2===c.length?(n=r=c[0],i=o=c[1]):3===c.length?(n=c[0],i=o=c[1],r=c[2]):(n=c[0],i=c[1],r=c[2],o=c[3]):n=i=r=o=0,n+i>u&&(n*=u/(a=n+i),i*=u/a),r+o>u&&(r*=u/(a=r+o),o*=u/a),i+r>h&&(i*=h/(a=i+r),r*=h/a),n+o>h&&(n*=h/(a=n+o),o*=h/a),t.moveTo(s+n,l),t.lineTo(s+u-i,l),0!==i&&t.arc(s+u-i,l+i,i,-Math.PI/2,0),t.lineTo(s+u,l+h-r),0!==r&&t.arc(s+u-r,l+h-r,r,0,Math.PI/2),t.lineTo(s+o,l+h),0!==o&&t.arc(s+o,l+h-o,o,Math.PI/2,Math.PI),t.lineTo(s,l+n),0!==n&&t.arc(s+n,l+n,n,Math.PI,1.5*Math.PI)}(t,e):t.rect(n,i,r,o)},e.prototype.isZeroArea=function(){return!this.shape.width||!this.shape.height},e}(fs);Ts.prototype.type="rect";var Cs={fill:"#000"},Ds={style:k({fill:!0,stroke:!0,fillOpacity:!0,strokeOpacity:!0,lineWidth:!0,fontSize:!0,lineHeight:!0,width:!0,height:!0,textShadowColor:!0,textShadowBlur:!0,textShadowOffsetX:!0,textShadowOffsetY:!0,backgroundColor:!0,padding:!0,borderColor:!0,borderWidth:!0,borderRadius:!0},ha.style)},As=function(t){function e(e){var n=t.call(this)||this;return n.type="text",n._children=[],n._defaultStyle=Cs,n.attr(e),n}return n(e,t),e.prototype.childrenRef=function(){return this._children},e.prototype.update=function(){t.prototype.update.call(this),this.styleChanged()&&this._updateSubTexts();for(var e=0;ed&&h){var f=Math.floor(d/l);n=n.slice(0,f)}if(t&&a&&null!=c)for(var g=Jo(c,o,e.ellipsis,{minChar:e.truncateMinChar,placeholder:e.placeholder}),y=0;y0,T=null!=t.width&&("truncate"===t.overflow||"break"===t.overflow||"breakAll"===t.overflow),C=i.calculatedLineHeight,D=0;Dl&&ra(n,t.substring(l,u),e,s),ra(n,i[2],e,s,i[1]),l=Ko.lastIndex}lo){b>0?(m.tokens=m.tokens.slice(0,b),y(m,_,x),n.lines=n.lines.slice(0,v+1)):n.lines=n.lines.slice(0,v);break t}var C=w.width,D=null==C||"auto"===C;if("string"==typeof C&&"%"===C.charAt(C.length-1))P.percentWidth=C,h.push(P),P.contentWidth=ur(P.text,I);else{if(D){var A=w.backgroundColor,k=A&&A.image;k&&qo(k=Xo(k))&&(P.width=Math.max(P.width,k.width*T/k.height))}var L=f&&null!=r?r-_:null;null!=L&&L=0&&"right"===(C=x[T]).align;)this._placeToken(C,t,b,f,I,"right",y),w-=C.width,I-=C.width,T--;for(M+=(n-(M-d)-(g-I)-w)/2;S<=T;)C=x[S],this._placeToken(C,t,b,f,M+C.width/2,"center",y),M+=C.width,S++;f+=b}},e.prototype._placeToken=function(t,e,n,i,r,o,s){var l=e.rich[t.styleName]||{};l.text=t.text;var u=t.verticalAlign,h=i+n/2;"top"===u?h=i+t.height/2:"bottom"===u&&(h=i+n-t.height/2),!t.isLineHolder&&Gs(l)&&this._renderBackground(l,e,"right"===o?r-t.width:"center"===o?r-t.width/2:r,h-t.height/2,t.width,t.height);var c=!!l.backgroundColor,p=t.textPadding;p&&(r=Bs(r,o,p),h-=t.height/2-p[0]-t.innerHeight/2);var d=this._getOrCreateChild(ys),f=d.createStyle();d.useStyle(f);var g=this._defaultStyle,y=!1,v=0,m=Vs("fill"in l?l.fill:"fill"in e?e.fill:(y=!0,g.fill)),x=zs("stroke"in l?l.stroke:"stroke"in e?e.stroke:c||s||g.autoStroke&&!y?null:(v=2,g.stroke)),_=l.textShadowBlur>0||e.textShadowBlur>0;f.text=t.text,f.x=r,f.y=h,_&&(f.shadowBlur=l.textShadowBlur||e.textShadowBlur||0,f.shadowColor=l.textShadowColor||e.textShadowColor||"transparent",f.shadowOffsetX=l.textShadowOffsetX||e.textShadowOffsetX||0,f.shadowOffsetY=l.textShadowOffsetY||e.textShadowOffsetY||0),f.textAlign=o,f.textBaseline="middle",f.font=t.font||a,f.opacity=ot(l.opacity,e.opacity,1),Rs(f,l),x&&(f.lineWidth=ot(l.lineWidth,e.lineWidth,v),f.lineDash=rt(l.lineDash,e.lineDash),f.lineDashOffset=e.lineDashOffset||0,f.stroke=x),m&&(f.fill=m);var b=t.contentWidth,w=t.contentHeight;d.setBoundingRect(new sr(pr(f.x,b,f.textAlign),dr(f.y,w,f.textBaseline),b,w))},e.prototype._renderBackground=function(t,e,n,i,r,o){var a,s,l,u=t.backgroundColor,h=t.borderWidth,c=t.borderColor,p=u&&u.image,d=u&&!p,f=t.borderRadius,g=this;if(d||t.lineHeight||h&&c){(a=this._getOrCreateChild(Ts)).useStyle(a.createStyle()),a.style.fill=null;var y=a.shape;y.x=n,y.y=i,y.width=r,y.height=o,y.r=f,a.dirtyShape()}if(d)(l=a.style).fill=u||null,l.fillOpacity=rt(t.fillOpacity,1);else if(p){(s=this._getOrCreateChild(xs)).onload=function(){g.dirtyStyle()};var v=s.style;v.image=u.image,v.x=n,v.y=i,v.width=r,v.height=o}h&&c&&((l=a.style).lineWidth=h,l.stroke=c,l.strokeOpacity=rt(t.strokeOpacity,1),l.lineDash=t.borderDash,l.lineDashOffset=t.borderDashOffset||0,a.strokeContainThreshold=0,a.hasFill()&&a.hasStroke()&&(l.strokeFirst=!0,l.lineWidth*=2));var m=(a||s).style;m.shadowBlur=t.shadowBlur||0,m.shadowColor=t.shadowColor||"transparent",m.shadowOffsetX=t.shadowOffsetX||0,m.shadowOffsetY=t.shadowOffsetY||0,m.opacity=ot(t.opacity,e.opacity,1)},e.makeFont=function(t){var e="";return Ns(t)&&(e=[t.fontStyle,t.fontWeight,Os(t.fontSize),t.fontFamily||"sans-serif"].join(" ")),e&&ut(e)||t.textFont||t.font},e}(da),ks={left:!0,right:1,center:1},Ls={top:1,bottom:1,middle:1},Ps=["fontStyle","fontWeight","fontSize","fontFamily"];function Os(t){return"string"!=typeof t||-1===t.indexOf("px")&&-1===t.indexOf("rem")&&-1===t.indexOf("em")?isNaN(+t)?"12px":t+"px":t}function Rs(t,e){for(var n=0;n=0,o=!1;if(t instanceof fs){var a=Xs(t),s=r&&a.selectFill||a.normalFill,l=r&&a.selectStroke||a.normalStroke;if(nl(s)||nl(l)){var u=(i=i||{}).style||{};"inherit"===u.fill?(o=!0,i=A({},i),(u=A({},u)).fill=s):!nl(u.fill)&&nl(s)?(o=!0,i=A({},i),(u=A({},u)).fill=rl(s)):!nl(u.stroke)&&nl(l)&&(o||(i=A({},i),u=A({},u)),u.stroke=rl(l)),i.style=u}}if(i&&null==i.z2){o||(i=A({},i));var h=t.z2EmphasisLift;i.z2=t.z2+(null!=h?h:Ks)}return i}(this,0,e,n);if("blur"===t)return function(t,e,n){var i=P(t.currentStates,e)>=0,r=t.style.opacity,o=i?null:function(t,e,n,i){for(var r=t.style,o={},a=0;a0){var o={dataIndex:r,seriesIndex:t.seriesIndex};null!=i&&(o.dataType=i),e.push(o)}}))})),e}function Pl(t,e,n){Vl(t,!0),dl(t,yl),Rl(t,e,n)}function Ol(t,e,n,i){i?function(t){Vl(t,!1)}(t):Pl(t,e,n)}function Rl(t,e,n){var i=Ws(t);null!=e?(i.focus=e,i.blurScope=n):i.focus&&(i.focus=null)}var Nl=["emphasis","blur","select"],El={itemStyle:"getItemStyle",lineStyle:"getLineStyle",areaStyle:"getAreaStyle"};function zl(t,e,n,i){n=n||"itemStyle";for(var r=0;r1&&(a*=Zl(f),s*=Zl(f));var g=(r===o?-1:1)*Zl((a*a*(s*s)-a*a*(d*d)-s*s*(p*p))/(a*a*(d*d)+s*s*(p*p)))||0,y=g*a*d/s,v=g*-s*p/a,m=(t+n)/2+ql(c)*y-jl(c)*v,x=(e+i)/2+jl(c)*y+ql(c)*v,_=Ql([1,0],[(p-y)/a,(d-v)/s]),b=[(p-y)/a,(d-v)/s],w=[(-1*p-y)/a,(-1*d-v)/s],S=Ql(b,w);if(Jl(b,w)<=-1&&(S=Kl),Jl(b,w)>=1&&(S=0),S<0){var M=Math.round(S/Kl*1e6)/1e6;S=2*Kl+M%2*Kl}h.addData(u,m,x,a,s,_,S,c,o)}var eu=/([mlvhzcqtsa])([^mlvhzcqtsa]*)/gi,nu=/-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;var iu=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.applyTransform=function(t){},e}(fs);function ru(t){return null!=t.setData}function ou(t,e){var n=function(t){var e=new ja;if(!t)return e;var n,i=0,r=0,o=i,a=r,s=ja.CMD,l=t.match(eu);if(!l)return e;for(var u=0;uk*k+L*L&&(M=T,I=C),{cx:M,cy:I,x0:-h,y0:-c,x1:M*(r/b-1),y1:I*(r/b-1)}}function Mu(t,e){var n,i=_u(e.r,0),r=_u(e.r0||0,0),o=i>0;if(o||r>0){if(o||(i=r,r=0),r>i){var a=i;i=r,r=a}var s=e.startAngle,l=e.endAngle;if(!isNaN(s)&&!isNaN(l)){var u=e.cx,h=e.cy,c=!!e.clockwise,p=mu(l-s),d=p>du&&p%du;if(d>wu&&(p=d),i>wu)if(p>du-wu)t.moveTo(u+i*gu(s),h+i*fu(s)),t.arc(u,h,i,s,l,!c),r>wu&&(t.moveTo(u+r*gu(l),h+r*fu(l)),t.arc(u,h,r,l,s,c));else{var f=void 0,g=void 0,y=void 0,v=void 0,m=void 0,x=void 0,_=void 0,b=void 0,w=void 0,S=void 0,M=void 0,I=void 0,T=void 0,C=void 0,D=void 0,A=void 0,k=i*gu(s),L=i*fu(s),P=r*gu(l),O=r*fu(l),R=p>wu;if(R){var N=e.cornerRadius;N&&(f=(n=function(t){var e;if(Y(t)){var n=t.length;if(!n)return t;e=1===n?[t[0],t[0],0,0]:2===n?[t[0],t[0],t[1],t[1]]:3===n?t.concat(t[2]):t}else e=[t,t,t,t];return e}(N))[0],g=n[1],y=n[2],v=n[3]);var E=mu(i-r)/2;if(m=bu(E,y),x=bu(E,v),_=bu(E,f),b=bu(E,g),M=w=_u(m,x),I=S=_u(_,b),(w>wu||S>wu)&&(T=i*gu(l),C=i*fu(l),D=r*gu(s),A=r*fu(s),pwu){var U=bu(y,M),X=bu(v,M),Z=Su(D,A,k,L,i,U,c),j=Su(T,C,P,O,i,X,c);t.moveTo(u+Z.cx+Z.x0,h+Z.cy+Z.y0),M0&&t.arc(u+Z.cx,h+Z.cy,U,vu(Z.y0,Z.x0),vu(Z.y1,Z.x1),!c),t.arc(u,h,i,vu(Z.cy+Z.y1,Z.cx+Z.x1),vu(j.cy+j.y1,j.cx+j.x1),!c),X>0&&t.arc(u+j.cx,h+j.cy,X,vu(j.y1,j.x1),vu(j.y0,j.x0),!c))}else t.moveTo(u+k,h+L),t.arc(u,h,i,s,l,!c);else t.moveTo(u+k,h+L);if(r>wu&&R)if(I>wu){U=bu(f,I),Z=Su(P,O,T,C,r,-(X=bu(g,I)),c),j=Su(k,L,D,A,r,-U,c);t.lineTo(u+Z.cx+Z.x0,h+Z.cy+Z.y0),I0&&t.arc(u+Z.cx,h+Z.cy,X,vu(Z.y0,Z.x0),vu(Z.y1,Z.x1),!c),t.arc(u,h,r,vu(Z.cy+Z.y1,Z.cx+Z.x1),vu(j.cy+j.y1,j.cx+j.x1),c),U>0&&t.arc(u+j.cx,h+j.cy,U,vu(j.y1,j.x1),vu(j.y0,j.x0),!c))}else t.lineTo(u+P,h+O),t.arc(u,h,r,l,s,c);else t.lineTo(u+P,h+O)}else t.moveTo(u,h);t.closePath()}}}var Iu=function(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=2*Math.PI,this.clockwise=!0,this.cornerRadius=0},Tu=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Iu},e.prototype.buildPath=function(t,e){Mu(t,e)},e.prototype.isZeroArea=function(){return this.shape.startAngle===this.shape.endAngle||this.shape.r===this.shape.r0},e}(fs);Tu.prototype.type="sector";var Cu=function(){this.cx=0,this.cy=0,this.r=0,this.r0=0},Du=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultShape=function(){return new Cu},e.prototype.buildPath=function(t,e){var n=e.cx,i=e.cy,r=2*Math.PI;t.moveTo(n+e.r,i),t.arc(n,i,e.r,0,r,!1),t.moveTo(n+e.r0,i),t.arc(n,i,e.r0,0,r,!0)},e}(fs);function Au(t,e,n){var i=e.smooth,r=e.points;if(r&&r.length>=2){if(i){var o=function(t,e,n,i){var r,o,a,s,l=[],u=[],h=[],c=[];if(i){a=[1/0,1/0],s=[-1/0,-1/0];for(var p=0,d=t.length;pju[1]){if(a=!1,r)return a;var u=Math.abs(ju[0]-Zu[1]),h=Math.abs(Zu[0]-ju[1]);Math.min(u,h)>i.len()&&(u0){var c={duration:h.duration,delay:h.delay||0,easing:h.easing,done:o,force:!!o||!!a,setToFinal:!u,scope:t,during:a};l?e.animateFrom(n,c):e.animateTo(n,c)}else e.stopAnimation(),!l&&e.attr(n),a&&a(1),o&&o()}function ih(t,e,n,i,r,o){nh("update",t,e,n,i,r,o)}function rh(t,e,n,i,r,o){nh("enter",t,e,n,i,r,o)}function oh(t){if(!t.__zr)return!0;for(var e=0;eMath.abs(o[1])?o[0]>0?"right":"left":o[1]>0?"bottom":"top"}function Ch(t){return!t.isGroup}function Dh(t,e,n){if(t&&e){var i,r=(i={},t.traverse((function(t){Ch(t)&&t.anid&&(i[t.anid]=t)})),i);e.traverse((function(t){if(Ch(t)&&t.anid){var e=r[t.anid];if(e){var i=o(t);t.attr(o(e)),ih(t,i,n,Ws(t).dataIndex)}}}))}function o(t){var e={x:t.x,y:t.y,rotation:t.rotation};return function(t){return null!=t.shape}(t)&&(e.shape=A({},t.shape)),e}}function Ah(t,e){return z(t,(function(t){var n=t[0];n=hh(n,e.x),n=ch(n,e.x+e.width);var i=t[1];return i=hh(i,e.y),[n,i=ch(i,e.y+e.height)]}))}function kh(t,e){var n=hh(t.x,e.x),i=ch(t.x+t.width,e.x+e.width),r=hh(t.y,e.y),o=ch(t.y+t.height,e.y+e.height);if(i>=n&&o>=r)return{x:n,y:r,width:i-n,height:o-r}}function Lh(t,e,n){var i=A({rectHover:!0},e),r=i.style={strokeNoScale:!0};if(n=n||{x:-1,y:-1,width:2,height:2},t)return 0===t.indexOf("image://")?(r.image=t.slice(8),k(r,n),new xs(i)):mh(t.replace("path://",""),i,n,"center")}function Ph(t,e,n,i,r){for(var o=0,a=r[r.length-1];o=-1e-6)return!1;var f=t-r,g=e-o,y=Rh(f,g,u,h)/d;if(y<0||y>1)return!1;var v=Rh(f,g,c,p)/d;return!(v<0||v>1)}function Rh(t,e,n,i){return t*i-n*e}function Nh(t){var e=t.itemTooltipOption,n=t.componentModel,i=t.itemName,r=X(e)?{formatter:e}:e,o=n.mainType,a=n.componentIndex,s={componentType:o,name:i,$vars:["name"]};s[o+"Index"]=a;var l=t.formatterParamsExtra;l&&E(G(l),(function(t){mt(s,t)||(s[t]=l[t],s.$vars.push(t))}));var u=Ws(t.el);u.componentMainType=o,u.componentIndex=a,u.tooltipConfig={name:i,option:k({content:i,formatterParams:s},r)}}function Eh(t,e){var n;t.isGroup&&(n=e(t)),n||t.traverse(e)}function zh(t,e){if(t)if(Y(t))for(var n=0;n-1?yc:mc;function wc(t,e){t=t.toUpperCase(),_c[t]=new pc(e),xc[t]=e}function Sc(t){return _c[t]}wc(vc,{time:{month:["January","February","March","April","May","June","July","August","September","October","November","December"],monthAbbr:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayOfWeek:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayOfWeekAbbr:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]},legend:{selector:{all:"All",inverse:"Inv"}},toolbox:{brush:{title:{rect:"Box Select",polygon:"Lasso Select",lineX:"Horizontally Select",lineY:"Vertically Select",keep:"Keep Selections",clear:"Clear Selections"}},dataView:{title:"Data View",lang:["Data View","Close","Refresh"]},dataZoom:{title:{zoom:"Zoom",back:"Zoom Reset"}},magicType:{title:{line:"Switch to Line Chart",bar:"Switch to Bar Chart",stack:"Stack",tiled:"Tile"}},restore:{title:"Restore"},saveAsImage:{title:"Save as Image",lang:["Right Click to Save Image"]}},series:{typeNames:{pie:"Pie chart",bar:"Bar chart",line:"Line chart",scatter:"Scatter plot",effectScatter:"Ripple scatter plot",radar:"Radar chart",tree:"Tree",treemap:"Treemap",boxplot:"Boxplot",candlestick:"Candlestick",k:"K line chart",heatmap:"Heat map",map:"Map",parallel:"Parallel coordinate map",lines:"Line graph",graph:"Relationship graph",sankey:"Sankey diagram",funnel:"Funnel chart",gauge:"Gauge",pictorialBar:"Pictorial bar",themeRiver:"Theme River Map",sunburst:"Sunburst"}},aria:{general:{withTitle:'This is a chart about "{title}"',withoutTitle:"This is a chart"},series:{single:{prefix:"",withName:" with type {seriesType} named {seriesName}.",withoutName:" with type {seriesType}."},multiple:{prefix:". It consists of {seriesCount} series count.",withName:" The {seriesId} series is a {seriesType} representing {seriesName}.",withoutName:" The {seriesId} series is a {seriesType}.",separator:{middle:"",end:""}}},data:{allData:"The data is as follows: ",partialData:"The first {displayCnt} items are: ",withName:"the data for {name} is {value}",withoutName:"{value}",separator:{middle:", ",end:". "}}}}),wc(yc,{time:{month:["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],monthAbbr:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],dayOfWeek:["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],dayOfWeekAbbr:["日","一","二","三","四","五","六"]},legend:{selector:{all:"全选",inverse:"反选"}},toolbox:{brush:{title:{rect:"矩形选择",polygon:"圈选",lineX:"横向选择",lineY:"纵向选择",keep:"保持选择",clear:"清除选择"}},dataView:{title:"数据视图",lang:["数据视图","关闭","刷新"]},dataZoom:{title:{zoom:"区域缩放",back:"区域缩放还原"}},magicType:{title:{line:"切换为折线图",bar:"切换为柱状图",stack:"切换为堆叠",tiled:"切换为平铺"}},restore:{title:"还原"},saveAsImage:{title:"保存为图片",lang:["右键另存为图片"]}},series:{typeNames:{pie:"饼图",bar:"柱状图",line:"折线图",scatter:"散点图",effectScatter:"涟漪散点图",radar:"雷达图",tree:"树图",treemap:"矩形树图",boxplot:"箱型图",candlestick:"K线图",k:"K线图",heatmap:"热力图",map:"地图",parallel:"平行坐标图",lines:"线图",graph:"关系图",sankey:"桑基图",funnel:"漏斗图",gauge:"仪表盘图",pictorialBar:"象形柱图",themeRiver:"主题河流图",sunburst:"旭日图"}},aria:{general:{withTitle:"这是一个关于“{title}”的图表。",withoutTitle:"这是一个图表,"},series:{single:{prefix:"",withName:"图表类型是{seriesType},表示{seriesName}。",withoutName:"图表类型是{seriesType}。"},multiple:{prefix:"它由{seriesCount}个图表系列组成。",withName:"第{seriesId}个系列是一个表示{seriesName}的{seriesType},",withoutName:"第{seriesId}个系列是一个{seriesType},",separator:{middle:";",end:"。"}}},data:{allData:"其数据是——",partialData:"其中,前{displayCnt}项是——",withName:"{name}的数据是{value}",withoutName:"{value}",separator:{middle:",",end:""}}}});var Mc=1e3,Ic=6e4,Tc=36e5,Cc=864e5,Dc=31536e6,Ac={year:"{yyyy}",month:"{MMM}",day:"{d}",hour:"{HH}:{mm}",minute:"{HH}:{mm}",second:"{HH}:{mm}:{ss}",millisecond:"{HH}:{mm}:{ss} {SSS}",none:"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss} {SSS}"},kc="{yyyy}-{MM}-{dd}",Lc={year:"{yyyy}",month:"{yyyy}-{MM}",day:kc,hour:"{yyyy}-{MM}-{dd} "+Ac.hour,minute:"{yyyy}-{MM}-{dd} "+Ac.minute,second:"{yyyy}-{MM}-{dd} "+Ac.second,millisecond:Ac.none},Pc=["year","month","day","hour","minute","second","millisecond"],Oc=["year","half-year","quarter","month","week","half-week","day","half-day","quarter-day","hour","minute","second","millisecond"];function Rc(t,e){return"0000".substr(0,e-(t+="").length)+t}function Nc(t){switch(t){case"half-year":case"quarter":return"month";case"week":case"half-week":return"day";case"half-day":case"quarter-day":return"hour";default:return t}}function Ec(t){return t===Nc(t)}function zc(t,e,n,i){var r=jr(t),o=r[Fc(n)](),a=r[Gc(n)]()+1,s=Math.floor((a-1)/4)+1,l=r[Wc(n)](),u=r["get"+(n?"UTC":"")+"Day"](),h=r[Hc(n)](),c=(h-1)%12+1,p=r[Yc(n)](),d=r[Uc(n)](),f=r[Xc(n)](),g=(i instanceof pc?i:Sc(i||bc)||_c.EN).getModel("time"),y=g.get("month"),v=g.get("monthAbbr"),m=g.get("dayOfWeek"),x=g.get("dayOfWeekAbbr");return(e||"").replace(/{yyyy}/g,o+"").replace(/{yy}/g,o%100+"").replace(/{Q}/g,s+"").replace(/{MMMM}/g,y[a-1]).replace(/{MMM}/g,v[a-1]).replace(/{MM}/g,Rc(a,2)).replace(/{M}/g,a+"").replace(/{dd}/g,Rc(l,2)).replace(/{d}/g,l+"").replace(/{eeee}/g,m[u]).replace(/{ee}/g,x[u]).replace(/{e}/g,u+"").replace(/{HH}/g,Rc(h,2)).replace(/{H}/g,h+"").replace(/{hh}/g,Rc(c+"",2)).replace(/{h}/g,c+"").replace(/{mm}/g,Rc(p,2)).replace(/{m}/g,p+"").replace(/{ss}/g,Rc(d,2)).replace(/{s}/g,d+"").replace(/{SSS}/g,Rc(f,3)).replace(/{S}/g,f+"")}function Vc(t,e){var n=jr(t),i=n[Gc(e)]()+1,r=n[Wc(e)](),o=n[Hc(e)](),a=n[Yc(e)](),s=n[Uc(e)](),l=0===n[Xc(e)](),u=l&&0===s,h=u&&0===a,c=h&&0===o,p=c&&1===r;return p&&1===i?"year":p?"month":c?"day":h?"hour":u?"minute":l?"second":"millisecond"}function Bc(t,e,n){var i=j(t)?jr(t):t;switch(e=e||Vc(t,n)){case"year":return i[Fc(n)]();case"half-year":return i[Gc(n)]()>=6?1:0;case"quarter":return Math.floor((i[Gc(n)]()+1)/4);case"month":return i[Gc(n)]();case"day":return i[Wc(n)]();case"half-day":return i[Hc(n)]()/24;case"hour":return i[Hc(n)]();case"minute":return i[Yc(n)]();case"second":return i[Uc(n)]();case"millisecond":return i[Xc(n)]()}}function Fc(t){return t?"getUTCFullYear":"getFullYear"}function Gc(t){return t?"getUTCMonth":"getMonth"}function Wc(t){return t?"getUTCDate":"getDate"}function Hc(t){return t?"getUTCHours":"getHours"}function Yc(t){return t?"getUTCMinutes":"getMinutes"}function Uc(t){return t?"getUTCSeconds":"getSeconds"}function Xc(t){return t?"getUTCMilliseconds":"getMilliseconds"}function Zc(t){return t?"setUTCFullYear":"setFullYear"}function jc(t){return t?"setUTCMonth":"setMonth"}function qc(t){return t?"setUTCDate":"setDate"}function Kc(t){return t?"setUTCHours":"setHours"}function $c(t){return t?"setUTCMinutes":"setMinutes"}function Jc(t){return t?"setUTCSeconds":"setSeconds"}function Qc(t){return t?"setUTCMilliseconds":"setMilliseconds"}function tp(t){if(!eo(t))return X(t)?t:"-";var e=(t+"").split(".");return e[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g,"$1,")+(e.length>1?"."+e[1]:"")}function ep(t,e){return t=(t||"").toLowerCase().replace(/-(.)/g,(function(t,e){return e.toUpperCase()})),e&&t&&(t=t.charAt(0).toUpperCase()+t.slice(1)),t}var np=st,ip=/([&<>"'])/g,rp={"&":"&","<":"<",">":">",'"':""","'":"'"};function op(t){return null==t?"":(t+"").replace(ip,(function(t,e){return rp[e]}))}function ap(t,e,n){function i(t){return t&&ut(t)?t:"-"}function r(t){return!(null==t||isNaN(t)||!isFinite(t))}var o="time"===e,a=t instanceof Date;if(o||a){var s=o?jr(t):t;if(!isNaN(+s))return zc(s,"{yyyy}-{MM}-{dd} {HH}:{mm}:{ss}",n);if(a)return"-"}if("ordinal"===e)return Z(t)?i(t):j(t)&&r(t)?t+"":"-";var l=to(t);return r(l)?tp(l):Z(t)?i(t):"boolean"==typeof t?t+"":"-"}var sp=["a","b","c","d","e","f","g"],lp=function(t,e){return"{"+t+(null==e?"":e)+"}"};function up(t,e,n){Y(e)||(e=[e]);var i=e.length;if(!i)return"";for(var r=e[0].$vars||[],o=0;o':'':{renderMode:o,content:"{"+(n.markerId||"markerX")+"|} ",style:"subItem"===r?{width:4,height:4,borderRadius:2,backgroundColor:i}:{width:10,height:10,borderRadius:5,backgroundColor:i}}:""}function cp(t,e){return e=e||"transparent",X(t)?t:q(t)&&t.colorStops&&(t.colorStops[0]||{}).color||e}function pp(t,e){if("_blank"===e||"blank"===e){var n=window.open();n.opener=null,n.location.href=t}else window.open(t,e)}var dp=E,fp=["left","right","top","bottom","width","height"],gp=[["width","left","right"],["height","top","bottom"]];function yp(t,e,n,i,r){var o=0,a=0;null==i&&(i=1/0),null==r&&(r=1/0);var s=0;e.eachChild((function(l,u){var h,c,p=l.getBoundingRect(),d=e.childAt(u+1),f=d&&d.getBoundingRect();if("horizontal"===t){var g=p.width+(f?-f.x+p.x:0);(h=o+g)>i||l.newline?(o=0,h=g,a+=s+n,s=p.height):s=Math.max(s,p.height)}else{var y=p.height+(f?-f.y+p.y:0);(c=a+y)>r||l.newline?(o+=s+n,a=0,c=y,s=p.width):s=Math.max(s,p.width)}l.newline||(l.x=o,l.y=a,l.markRedraw(),"horizontal"===t?o=h+n:a=c+n)}))}var vp=yp;H(yp,"vertical"),H(yp,"horizontal");function mp(t,e,n){n=np(n||0);var i=e.width,r=e.height,o=Er(t.left,i),a=Er(t.top,r),s=Er(t.right,i),l=Er(t.bottom,r),u=Er(t.width,i),h=Er(t.height,r),c=n[2]+n[0],p=n[1]+n[3],d=t.aspect;switch(isNaN(u)&&(u=i-s-p-o),isNaN(h)&&(h=r-l-c-a),null!=d&&(isNaN(u)&&isNaN(h)&&(d>i/r?u=.8*i:h=.8*r),isNaN(u)&&(u=d*h),isNaN(h)&&(h=u/d)),isNaN(o)&&(o=i-s-u-p),isNaN(a)&&(a=r-l-h-c),t.left||t.right){case"center":o=i/2-u/2-n[3];break;case"right":o=i-u-p}switch(t.top||t.bottom){case"middle":case"center":a=r/2-h/2-n[0];break;case"bottom":a=r-h-c}o=o||0,a=a||0,isNaN(u)&&(u=i-p-o-(s||0)),isNaN(h)&&(h=r-c-a-(l||0));var f=new sr(o+n[3],a+n[0],u,h);return f.margin=n,f}function xp(t,e,n,i,r,o){var a,s=!r||!r.hv||r.hv[0],l=!r||!r.hv||r.hv[1],u=r&&r.boundingMode||"all";if((o=o||t).x=t.x,o.y=t.y,!s&&!l)return!1;if("raw"===u)a="group"===t.type?new sr(0,0,+e.width||0,+e.height||0):t.getBoundingRect();else if(a=t.getBoundingRect(),t.needLocalTransform()){var h=t.getLocalTransform();(a=a.clone()).applyTransform(h)}var c=mp(k({width:a.width,height:a.height},e),n,i),p=s?c.x-a.x:0,d=l?c.y-a.y:0;return"raw"===u?(o.x=p,o.y=d):(o.x+=p,o.y+=d),o===t&&t.markRedraw(),!0}function _p(t){var e=t.layoutMode||t.constructor.layoutMode;return q(e)?e:e?{type:e}:null}function bp(t,e,n){var i=n&&n.ignoreSize;!Y(i)&&(i=[i,i]);var r=a(gp[0],0),o=a(gp[1],1);function a(n,r){var o={},a=0,u={},h=0;if(dp(n,(function(e){u[e]=t[e]})),dp(n,(function(t){s(e,t)&&(o[t]=u[t]=e[t]),l(o,t)&&a++,l(u,t)&&h++})),i[r])return l(e,n[1])?u[n[2]]=null:l(e,n[2])&&(u[n[1]]=null),u;if(2!==h&&a){if(a>=2)return o;for(var c=0;c=0;a--)o=C(o,n[a],!0);e.defaultOption=o}return e.defaultOption},e.prototype.getReferringComponents=function(t,e){var n=t+"Index",i=t+"Id";return Ao(this.ecModel,t,{index:this.get(n,!0),id:this.get(i,!0)},e)},e.prototype.getBoxLayoutParams=function(){var t=this;return{left:t.get("left"),top:t.get("top"),right:t.get("right"),bottom:t.get("bottom"),width:t.get("width"),height:t.get("height")}},e.prototype.getZLevelKey=function(){return""},e.prototype.setZLevel=function(t){this.option.zlevel=t},e.protoInitialize=function(){var t=e.prototype;t.type="component",t.id="",t.name="",t.mainType="",t.subType="",t.componentIndex=0}(),e}(pc);zo(Ip,pc),Go(Ip),function(t){var e={};t.registerSubTypeDefaulter=function(t,n){var i=No(t);e[i.main]=n},t.determineSubType=function(n,i){var r=i.type;if(!r){var o=No(n).main;t.hasSubTypes(n)&&e[o]&&(r=e[o](i))}return r}}(Ip),function(t,e){function n(t,e){return t[e]||(t[e]={predecessor:[],successor:[]}),t[e]}t.topologicalTravel=function(t,i,r,o){if(t.length){var a=function(t){var i={},r=[];return E(t,(function(o){var a=n(i,o),s=function(t,e){var n=[];return E(t,(function(t){P(e,t)>=0&&n.push(t)})),n}(a.originalDeps=e(o),t);a.entryCount=s.length,0===a.entryCount&&r.push(o),E(s,(function(t){P(a.predecessor,t)<0&&a.predecessor.push(t);var e=n(i,t);P(e.successor,t)<0&&e.successor.push(o)}))})),{graph:i,noEntryList:r}}(i),s=a.graph,l=a.noEntryList,u={};for(E(t,(function(t){u[t]=!0}));l.length;){var h=l.pop(),c=s[h],p=!!u[h];p&&(r.call(o,h,c.originalDeps.slice()),delete u[h]),E(c.successor,p?f:d)}E(u,(function(){var t="";throw new Error(t)}))}function d(t){s[t].entryCount--,0===s[t].entryCount&&l.push(t)}function f(t){u[t]=!0,d(t)}}}(Ip,(function(t){var e=[];E(Ip.getClassesByMainType(t),(function(t){e=e.concat(t.dependencies||t.prototype.dependencies||[])})),e=z(e,(function(t){return No(t).main})),"dataset"!==t&&P(e,"dataset")<=0&&e.unshift("dataset");return e}));var Tp="";"undefined"!=typeof navigator&&(Tp=navigator.platform||"");var Cp="rgba(0, 0, 0, 0.2)",Dp={darkMode:"auto",colorBy:"series",color:["#5470c6","#91cc75","#fac858","#ee6666","#73c0de","#3ba272","#fc8452","#9a60b4","#ea7ccc"],gradientColor:["#f6efa6","#d88273","#bf444c"],aria:{decal:{decals:[{color:Cp,dashArrayX:[1,0],dashArrayY:[2,5],symbolSize:1,rotation:Math.PI/6},{color:Cp,symbol:"circle",dashArrayX:[[8,8],[0,8,8,0]],dashArrayY:[6,0],symbolSize:.8},{color:Cp,dashArrayX:[1,0],dashArrayY:[4,3],rotation:-Math.PI/4},{color:Cp,dashArrayX:[[6,6],[0,6,6,0]],dashArrayY:[6,0]},{color:Cp,dashArrayX:[[1,0],[1,6]],dashArrayY:[1,0,6,0],rotation:Math.PI/4},{color:Cp,symbol:"triangle",dashArrayX:[[9,9],[0,9,9,0]],dashArrayY:[7,2],symbolSize:.75}]}},textStyle:{fontFamily:Tp.match(/^Win/)?"Microsoft YaHei":"sans-serif",fontSize:12,fontStyle:"normal",fontWeight:"normal"},blendMode:null,stateAnimation:{duration:300,easing:"cubicOut"},animation:"auto",animationDuration:1e3,animationDurationUpdate:500,animationEasing:"cubicInOut",animationEasingUpdate:"cubicInOut",animationThreshold:2e3,progressiveThreshold:3e3,progressive:400,hoverLayerThreshold:3e3,useUTC:!1},Ap=ft(["tooltip","label","itemName","itemId","itemGroupId","seriesName"]),kp="original",Lp="arrayRows",Pp="objectRows",Op="keyedColumns",Rp="typedArray",Np="unknown",Ep="column",zp="row",Vp=1,Bp=2,Fp=3,Gp=So();function Wp(t,e,n){var i={},r=Yp(e);if(!r||!t)return i;var o,a,s=[],l=[],u=e.ecModel,h=Gp(u).datasetMap,c=r.uid+"_"+n.seriesLayoutBy;E(t=t.slice(),(function(e,n){var r=q(e)?e:t[n]={name:e};"ordinal"===r.type&&null==o&&(o=n,a=f(r)),i[r.name]=[]}));var p=h.get(c)||h.set(c,{categoryWayDim:a,valueWayDim:0});function d(t,e,n){for(var i=0;ie)return t[i];return t[n-1]}(i,a):n;if((h=h||n)&&h.length){var c=h[l];return r&&(u[r]=c),s.paletteIdx=(l+1)%h.length,c}}var nd=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.init=function(t,e,n,i,r,o){i=i||{},this.option=null,this._theme=new pc(i),this._locale=new pc(r),this._optionManager=o},e.prototype.setOption=function(t,e,n){var i=od(e);this._optionManager.setOption(t,n,i),this._resetOption(null,i)},e.prototype.resetOption=function(t,e){return this._resetOption(t,od(e))},e.prototype._resetOption=function(t,e){var n=!1,i=this._optionManager;if(!t||"recreate"===t){var r=i.mountOption("recreate"===t);0,this.option&&"recreate"!==t?(this.restoreData(),this._mergeOption(r,e)):Kp(this,r),n=!0}if("timeline"!==t&&"media"!==t||this.restoreData(),!t||"recreate"===t||"timeline"===t){var o=i.getTimelineOption(this);o&&(n=!0,this._mergeOption(o,e))}if(!t||"recreate"===t||"media"===t){var a=i.getMediaOption(this);a.length&&E(a,(function(t){n=!0,this._mergeOption(t,e)}),this)}return n},e.prototype.mergeOption=function(t){this._mergeOption(t,null)},e.prototype._mergeOption=function(t,e){var n=this.option,i=this._componentsMap,r=this._componentsCount,o=[],a=ft(),s=e&&e.replaceMergeMainTypeMap;Gp(this).datasetMap=ft(),E(t,(function(t,e){null!=t&&(Ip.hasClass(e)?e&&(o.push(e),a.set(e,!0)):n[e]=null==n[e]?T(t):C(n[e],t,!0))})),s&&s.each((function(t,e){Ip.hasClass(e)&&!a.get(e)&&(o.push(e),a.set(e,!0))})),Ip.topologicalTravel(o,Ip.getAllClassMainTypes(),(function(e){var o=function(t,e,n){var i=Zp.get(e);if(!i)return n;var r=i(t);return r?n.concat(r):n}(this,e,ho(t[e])),a=i.get(e),l=a?s&&s.get(e)?"replaceMerge":"normalMerge":"replaceAll",u=yo(a,o,l);(function(t,e,n){E(t,(function(t){var i=t.newOption;q(i)&&(t.keyInfo.mainType=e,t.keyInfo.subType=function(t,e,n,i){return e.type?e.type:n?n.subType:i.determineSubType(t,e)}(e,i,t.existing,n))}))})(u,e,Ip),n[e]=null,i.set(e,null),r.set(e,0);var h,c=[],p=[],d=0;E(u,(function(t,n){var i=t.existing,r=t.newOption;if(r){var o="series"===e,a=Ip.getClass(e,t.keyInfo.subType,!o);if(!a)return;if("tooltip"===e){if(h)return void 0;h=!0}if(i&&i.constructor===a)i.name=t.keyInfo.name,i.mergeOption(r,this),i.optionUpdated(r,!1);else{var s=A({componentIndex:n},t.keyInfo);A(i=new a(r,this,this,s),s),t.brandNew&&(i.__requireNewView=!0),i.init(r,this,this),i.optionUpdated(null,!0)}}else i&&(i.mergeOption({},this),i.optionUpdated({},!1));i?(c.push(i.option),p.push(i),d++):(c.push(void 0),p.push(void 0))}),this),n[e]=c,i.set(e,p),r.set(e,d),"series"===e&&jp(this)}),this),this._seriesIndices||jp(this)},e.prototype.getOption=function(){var t=T(this.option);return E(t,(function(e,n){if(Ip.hasClass(n)){for(var i=ho(e),r=i.length,o=!1,a=r-1;a>=0;a--)i[a]&&!bo(i[a])?o=!0:(i[a]=null,!o&&r--);i.length=r,t[n]=i}})),delete t["\0_ec_inner"],t},e.prototype.getTheme=function(){return this._theme},e.prototype.getLocaleModel=function(){return this._locale},e.prototype.setUpdatePayload=function(t){this._payload=t},e.prototype.getUpdatePayload=function(){return this._payload},e.prototype.getComponent=function(t,e){var n=this._componentsMap.get(t);if(n){var i=n[e||0];if(i)return i;if(null==e)for(var r=0;r=e:"max"===n?t<=e:t===e})(i[a],t,o)||(r=!1)}})),r}var dd=E,fd=q,gd=["areaStyle","lineStyle","nodeStyle","linkStyle","chordStyle","label","labelLine"];function yd(t){var e=t&&t.itemStyle;if(e)for(var n=0,i=gd.length;n=0;f--){var g=t[f];if(s||(c=g.data.rawIndexOf(g.stackedByDimension,h)),c>=0){var y=g.data.getByRawIndex(g.stackResultDimension,c);if(p>=0&&y>0||p<=0&&y<0){p=Hr(p,y),d=y;break}}}return i[0]=p,i[1]=d,i}))}))}var Rd,Nd,Ed,zd,Vd,Bd=function(t){this.data=t.data||(t.sourceFormat===Op?{}:[]),this.sourceFormat=t.sourceFormat||Np,this.seriesLayoutBy=t.seriesLayoutBy||Ep,this.startIndex=t.startIndex||0,this.dimensionsDetectedCount=t.dimensionsDetectedCount,this.metaRawOption=t.metaRawOption;var e=this.dimensionsDefine=t.dimensionsDefine;if(e)for(var n=0;nu&&(u=d)}s[0]=l,s[1]=u}},i=function(){return this._data?this._data.length/this._dimSize:0};function r(t){for(var e=0;e=0&&(s=o.interpolatedValue[l])}return null!=s?s+"":""})):void 0},t.prototype.getRawValue=function(t,e){return of(this.getData(e),t)},t.prototype.formatTooltip=function(t,e,n){},t}();function lf(t){var e,n;return q(t)?t.type&&(n=t):e=t,{text:e,frag:n}}function uf(t){return new hf(t)}var hf=function(){function t(t){t=t||{},this._reset=t.reset,this._plan=t.plan,this._count=t.count,this._onDirty=t.onDirty,this._dirty=!0}return t.prototype.perform=function(t){var e,n=this._upstream,i=t&&t.skip;if(this._dirty&&n){var r=this.context;r.data=r.outputData=n.context.outputData}this.__pipeline&&(this.__pipeline.currentTask=this),this._plan&&!i&&(e=this._plan(this.context));var o,a=h(this._modBy),s=this._modDataCount||0,l=h(t&&t.modBy),u=t&&t.modDataCount||0;function h(t){return!(t>=1)&&(t=1),t}a===l&&s===u||(e="reset"),(this._dirty||"reset"===e)&&(this._dirty=!1,o=this._doReset(i)),this._modBy=l,this._modDataCount=u;var c=t&&t.step;if(this._dueEnd=n?n._outputDueEnd:this._count?this._count(this.context):1/0,this._progress){var p=this._dueIndex,d=Math.min(null!=c?this._dueIndex+c:1/0,this._dueEnd);if(!i&&(o||p1&&i>0?s:a}};return o;function a(){return e=t?null:oe},gte:function(t,e){return t>=e}},yf=function(){function t(t,e){if(!j(e)){var n="";0,ao(n)}this._opFn=gf[t],this._rvalFloat=to(e)}return t.prototype.evaluate=function(t){return j(t)?this._opFn(t,this._rvalFloat):this._opFn(to(t),this._rvalFloat)},t}(),vf=function(){function t(t,e){var n="desc"===t;this._resultLT=n?1:-1,null==e&&(e=n?"min":"max"),this._incomparable="min"===e?-1/0:1/0}return t.prototype.evaluate=function(t,e){var n=j(t)?t:to(t),i=j(e)?e:to(e),r=isNaN(n),o=isNaN(i);if(r&&(n=this._incomparable),o&&(i=this._incomparable),r&&o){var a=X(t),s=X(e);a&&(n=s?t:0),s&&(i=a?e:0)}return ni?-this._resultLT:0},t}(),mf=function(){function t(t,e){this._rval=e,this._isEQ=t,this._rvalTypeof=typeof e,this._rvalFloat=to(e)}return t.prototype.evaluate=function(t){var e=t===this._rval;if(!e){var n=typeof t;n===this._rvalTypeof||"number"!==n&&"number"!==this._rvalTypeof||(e=to(t)===this._rvalFloat)}return this._isEQ?e:!e},t}();function xf(t,e){return"eq"===t||"ne"===t?new mf("eq"===t,e):mt(gf,t)?new yf(t,e):null}var _f=function(){function t(){}return t.prototype.getRawData=function(){throw new Error("not supported")},t.prototype.getRawDataItem=function(t){throw new Error("not supported")},t.prototype.cloneRawData=function(){},t.prototype.getDimensionInfo=function(t){},t.prototype.cloneAllDimensionInfo=function(){},t.prototype.count=function(){},t.prototype.retrieveValue=function(t,e){},t.prototype.retrieveValueFromItem=function(t,e){},t.prototype.convertValue=function(t,e){return pf(t,e)},t}();function bf(t){var e=t.sourceFormat;if(!Cf(e)){var n="";0,ao(n)}return t.data}function wf(t){var e=t.sourceFormat,n=t.data;if(!Cf(e)){var i="";0,ao(i)}if(e===Lp){for(var r=[],o=0,a=n.length;o65535?kf:Lf}function Ef(t,e,n,i,r){var o=Rf[n||"float"];if(r){var a=t[e],s=a&&a.length;if(s!==i){for(var l=new o(i),u=0;ug[1]&&(g[1]=f)}return this._rawCount=this._count=s,{start:a,end:s}},t.prototype._initDataFromProvider=function(t,e,n){for(var i=this._provider,r=this._chunks,o=this._dimensions,a=o.length,s=this._rawExtent,l=z(o,(function(t){return t.property})),u=0;uy[1]&&(y[1]=g)}}!i.persistent&&i.clean&&i.clean(),this._rawCount=this._count=e,this._extent=[]},t.prototype.count=function(){return this._count},t.prototype.get=function(t,e){if(!(e>=0&&e=0&&e=this._rawCount||t<0)return-1;if(!this._indices)return t;var e=this._indices,n=e[t];if(null!=n&&nt))return o;r=o-1}}return-1},t.prototype.indicesOfNearest=function(t,e,n){var i=this._chunks[t],r=[];if(!i)return r;null==n&&(n=1/0);for(var o=1/0,a=-1,s=0,l=0,u=this.count();l=0&&a<0)&&(o=c,a=h,s=0),h===a&&(r[s++]=l))}return r.length=s,r},t.prototype.getIndices=function(){var t,e=this._indices;if(e){var n=e.constructor,i=this._count;if(n===Array){t=new n(i);for(var r=0;r=u&&x<=h||isNaN(x))&&(a[s++]=d),d++}p=!0}else if(2===r){f=c[i[0]];var y=c[i[1]],v=t[i[1]][0],m=t[i[1]][1];for(g=0;g=u&&x<=h||isNaN(x))&&(_>=v&&_<=m||isNaN(_))&&(a[s++]=d),d++}p=!0}}if(!p)if(1===r)for(g=0;g=u&&x<=h||isNaN(x))&&(a[s++]=b)}else for(g=0;gt[M][1])&&(w=!1)}w&&(a[s++]=e.getRawIndex(g))}return sy[1]&&(y[1]=g)}}}},t.prototype.lttbDownSample=function(t,e){var n,i,r,o=this.clone([t],!0),a=o._chunks[t],s=this.count(),l=0,u=Math.floor(1/e),h=this.getRawIndex(0),c=new(Nf(this._rawCount))(Math.min(2*(Math.ceil(s/u)+2),s));c[l++]=h;for(var p=1;pn&&(n=i,r=I)}M>0&&M<_-x&&(c[l++]=Math.min(S,r),r=Math.max(S,r)),c[l++]=r,h=r}return c[l++]=this.getRawIndex(s-1),o._count=l,o._indices=c,o.getRawIndex=this._getRawIdx,o},t.prototype.downSample=function(t,e,n,i){for(var r=this.clone([t],!0),o=r._chunks,a=[],s=Math.floor(1/e),l=o[t],u=this.count(),h=r._rawExtent[t]=[1/0,-1/0],c=new(Nf(this._rawCount))(Math.ceil(u/s)),p=0,d=0;du-d&&(s=u-d,a.length=s);for(var f=0;fh[1]&&(h[1]=y),c[p++]=v}return r._count=p,r._indices=c,r._updateGetRawIdx(),r},t.prototype.each=function(t,e){if(this._count)for(var n=t.length,i=this._chunks,r=0,o=this.count();ra&&(a=l)}return i=[o,a],this._extent[t]=i,i},t.prototype.getRawDataItem=function(t){var e=this.getRawIndex(t);if(this._provider.persistent)return this._provider.getItem(e);for(var n=[],i=this._chunks,r=0;r=0?this._indices[t]:-1},t.prototype._updateGetRawIdx=function(){this.getRawIndex=this._indices?this._getRawIdx:this._getRawIdxIdentity},t.internalField=function(){function t(t,e,n,i){return pf(t[i],this._dimensions[i])}Df={arrayRows:t,objectRows:function(t,e,n,i){return pf(t[e],this._dimensions[i])},keyedColumns:t,original:function(t,e,n,i){var r=t&&(null==t.value?t:t.value);return pf(r instanceof Array?r[i]:r,this._dimensions[i])},typedArray:function(t,e,n,i){return t[i]}}}(),t}(),Vf=function(){function t(t){this._sourceList=[],this._storeList=[],this._upstreamSignList=[],this._versionSignBase=0,this._dirty=!0,this._sourceHost=t}return t.prototype.dirty=function(){this._setLocalSource([],[]),this._storeList=[],this._dirty=!0},t.prototype._setLocalSource=function(t,e){this._sourceList=t,this._upstreamSignList=e,this._versionSignBase++,this._versionSignBase>9e10&&(this._versionSignBase=0)},t.prototype._getVersionSign=function(){return this._sourceHost.uid+"_"+this._versionSignBase},t.prototype.prepareSource=function(){this._isDirty()&&(this._createSource(),this._dirty=!1)},t.prototype._createSource=function(){this._setLocalSource([],[]);var t,e,n=this._sourceHost,i=this._getUpstreamSourceManagers(),r=!!i.length;if(Ff(n)){var o=n,a=void 0,s=void 0,l=void 0;if(r){var u=i[0];u.prepareSource(),a=(l=u.getSource()).data,s=l.sourceFormat,e=[u._getVersionSign()]}else s=$(a=o.get("data",!0))?Rp:kp,e=[];var h=this._getSourceMetaRawOption()||{},c=l&&l.metaRawOption||{},p=rt(h.seriesLayoutBy,c.seriesLayoutBy)||null,d=rt(h.sourceHeader,c.sourceHeader),f=rt(h.dimensions,c.dimensions);t=p!==c.seriesLayoutBy||!!d!=!!c.sourceHeader||f?[Gd(a,{seriesLayoutBy:p,sourceHeader:d,dimensions:f},s)]:[]}else{var g=n;if(r){var y=this._applyTransform(i);t=y.sourceList,e=y.upstreamSignList}else{t=[Gd(g.get("source",!0),this._getSourceMetaRawOption(),null)],e=[]}}this._setLocalSource(t,e)},t.prototype._applyTransform=function(t){var e,n=this._sourceHost,i=n.get("transform",!0),r=n.get("fromTransformResult",!0);if(null!=r){var o="";1!==t.length&&Gf(o)}var a,s=[],l=[];return E(t,(function(t){t.prepareSource();var e=t.getSource(r||0),n="";null==r||e||Gf(n),s.push(e),l.push(t._getVersionSign())})),i?e=function(t,e,n){var i=ho(t),r=i.length,o="";r||ao(o);for(var a=0,s=r;a1||n>0&&!t.noHeader;return E(t.blocks,(function(t){var n=jf(t);n>=e&&(e=n+ +(i&&(!n||Xf(t)&&!t.noHeader)))})),e}return 0}function qf(t,e,n,i){var r,o=e.noHeader,a=(r=jf(e),{html:Hf[r],richText:Yf[r]}),s=[],l=e.blocks||[];lt(!l||Y(l)),l=l||[];var u=t.orderMode;if(e.sortBlocks&&u){l=l.slice();var h={valueAsc:"asc",valueDesc:"desc"};if(mt(h,u)){var c=new vf(h[u],null);l.sort((function(t,e){return c.evaluate(t.sortParam,e.sortParam)}))}else"seriesDesc"===u&&l.reverse()}E(l,(function(n,r){var o=e.valueFormatter,l=Zf(n)(o?A(A({},t),{valueFormatter:o}):t,n,r>0?a.html:0,i);null!=l&&s.push(l)}));var p="richText"===t.renderMode?s.join(a.richText):Jf(s.join(""),o?n:a.html);if(o)return p;var d=ap(e.header,"ordinal",t.useUTC),f=Wf(i,t.renderMode).nameStyle;return"richText"===t.renderMode?Qf(t,d,f)+a.richText+p:Jf('
    '+op(d)+"
    "+p,n)}function Kf(t,e,n,i){var r=t.renderMode,o=e.noName,a=e.noValue,s=!e.markerType,l=e.name,u=t.useUTC,h=e.valueFormatter||t.valueFormatter||function(t){return z(t=Y(t)?t:[t],(function(t,e){return ap(t,Y(d)?d[e]:d,u)}))};if(!o||!a){var c=s?"":t.markupStyleCreator.makeTooltipMarker(e.markerType,e.markerColor||"#333",r),p=o?"":ap(l,"ordinal",u),d=e.valueType,f=a?[]:h(e.value),g=!s||!o,y=!s&&o,v=Wf(i,r),m=v.nameStyle,x=v.valueStyle;return"richText"===r?(s?"":c)+(o?"":Qf(t,p,m))+(a?"":function(t,e,n,i,r){var o=[r],a=i?10:20;return n&&o.push({padding:[0,0,0,a],align:"right"}),t.markupStyleCreator.wrapRichTextStyle(Y(e)?e.join(" "):e,o)}(t,f,g,y,x)):Jf((s?"":c)+(o?"":function(t,e,n){return''+op(t)+""}(p,!s,m))+(a?"":function(t,e,n,i){var r=n?"10px":"20px",o=e?"float:right;margin-left:"+r:"";return t=Y(t)?t:[t],''+z(t,(function(t){return op(t)})).join("  ")+""}(f,g,y,x)),n)}}function $f(t,e,n,i,r,o){if(t)return Zf(t)({useUTC:r,renderMode:n,orderMode:i,markupStyleCreator:e,valueFormatter:t.valueFormatter},t,0,o)}function Jf(t,e){return'
    '+t+'
    '}function Qf(t,e,n){return t.markupStyleCreator.wrapRichTextStyle(e,n)}function tg(t,e){return cp(t.getData().getItemVisual(e,"style")[t.visualDrawType])}function eg(t,e){var n=t.get("padding");return null!=n?n:"richText"===e?[8,10]:10}var ng=function(){function t(){this.richTextStyles={},this._nextStyleNameId=no()}return t.prototype._generateStyleName=function(){return"__EC_aUTo_"+this._nextStyleNameId++},t.prototype.makeTooltipMarker=function(t,e,n){var i="richText"===n?this._generateStyleName():null,r=hp({color:e,type:t,renderMode:n,markerId:i});return X(r)?r:(this.richTextStyles[i]=r.style,r.content)},t.prototype.wrapRichTextStyle=function(t,e){var n={};Y(e)?E(e,(function(t){return A(n,t)})):A(n,e);var i=this._generateStyleName();return this.richTextStyles[i]=n,"{"+i+"|"+t+"}"},t}();function ig(t){var e,n,i,r,o=t.series,a=t.dataIndex,s=t.multipleSeries,l=o.getData(),u=l.mapDimensionsAll("defaultedTooltip"),h=u.length,c=o.getRawValue(a),p=Y(c),d=tg(o,a);if(h>1||p&&!h){var f=function(t,e,n,i,r){var o=e.getData(),a=V(t,(function(t,e,n){var i=o.getDimensionInfo(n);return t||i&&!1!==i.tooltip&&null!=i.displayName}),!1),s=[],l=[],u=[];function h(t,e){var n=o.getDimensionInfo(e);n&&!1!==n.otherDims.tooltip&&(a?u.push(Uf("nameValue",{markerType:"subItem",markerColor:r,name:n.displayName,value:t,valueType:n.type})):(s.push(t),l.push(n.type)))}return i.length?E(i,(function(t){h(of(o,n,t),t)})):E(t,h),{inlineValues:s,inlineValueTypes:l,blocks:u}}(c,o,a,u,d);e=f.inlineValues,n=f.inlineValueTypes,i=f.blocks,r=f.inlineValues[0]}else if(h){var g=l.getDimensionInfo(u[0]);r=e=of(l,a,u[0]),n=g.type}else r=e=p?c[0]:c;var y=_o(o),v=y&&o.name||"",m=l.getName(a),x=s?v:m;return Uf("section",{header:v,noHeader:s||!y,sortParam:r,blocks:[Uf("nameValue",{markerType:"item",markerColor:d,name:x,noName:!ut(x),value:e,valueType:n})].concat(i||[])})}var rg=So();function og(t,e){return t.getName(e)||t.getId(e)}var ag=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._selectedDataIndicesMap={},e}return n(e,t),e.prototype.init=function(t,e,n){this.seriesIndex=this.componentIndex,this.dataTask=uf({count:lg,reset:ug}),this.dataTask.context={model:this},this.mergeDefaultAndTheme(t,n),(rg(this).sourceManager=new Vf(this)).prepareSource();var i=this.getInitialData(t,n);cg(i,this),this.dataTask.context.data=i,rg(this).dataBeforeProcessed=i,sg(this),this._initSelectedMapFromData(i)},e.prototype.mergeDefaultAndTheme=function(t,e){var n=_p(this),i=n?wp(t):{},r=this.subType;Ip.hasClass(r)&&(r+="Series"),C(t,e.getTheme().get(this.subType)),C(t,this.getDefaultOption()),co(t,"label",["show"]),this.fillDataTextStyle(t.data),n&&bp(t,i,n)},e.prototype.mergeOption=function(t,e){t=C(this.option,t,!0),this.fillDataTextStyle(t.data);var n=_p(this);n&&bp(this.option,t,n);var i=rg(this).sourceManager;i.dirty(),i.prepareSource();var r=this.getInitialData(t,e);cg(r,this),this.dataTask.dirty(),this.dataTask.context.data=r,rg(this).dataBeforeProcessed=r,sg(this),this._initSelectedMapFromData(r)},e.prototype.fillDataTextStyle=function(t){if(t&&!$(t))for(var e=["show"],n=0;nthis.getShallow("animationThreshold")&&(e=!1),!!e},e.prototype.restoreData=function(){this.dataTask.dirty()},e.prototype.getColorFromPalette=function(t,e,n){var i=this.ecModel,r=Qp.prototype.getColorFromPalette.call(this,t,e,n);return r||(r=i.getColorFromPalette(t,e,n)),r},e.prototype.coordDimToDataDim=function(t){return this.getRawData().mapDimensionsAll(t)},e.prototype.getProgressive=function(){return this.get("progressive")},e.prototype.getProgressiveThreshold=function(){return this.get("progressiveThreshold")},e.prototype.select=function(t,e){this._innerSelect(this.getData(e),t)},e.prototype.unselect=function(t,e){var n=this.option.selectedMap;if(n){var i=this.option.selectedMode,r=this.getData(e);if("series"===i||"all"===n)return this.option.selectedMap={},void(this._selectedDataIndicesMap={});for(var o=0;o=0&&n.push(r)}return n},e.prototype.isSelected=function(t,e){var n=this.option.selectedMap;if(!n)return!1;var i=this.getData(e);return("all"===n||n[og(i,t)])&&!i.getItemModel(t).get(["select","disabled"])},e.prototype.isUniversalTransitionEnabled=function(){if(this.__universalTransitionEnabled)return!0;var t=this.option.universalTransition;return!!t&&(!0===t||t&&t.enabled)},e.prototype._innerSelect=function(t,e){var n,i,r=this.option,o=r.selectedMode,a=e.length;if(o&&a)if("series"===o)r.selectedMap="all";else if("multiple"===o){q(r.selectedMap)||(r.selectedMap={});for(var s=r.selectedMap,l=0;l0&&this._innerSelect(t,e)}},e.registerClass=function(t){return Ip.registerClass(t)},e.protoInitialize=function(){var t=e.prototype;t.type="series.__base__",t.seriesIndex=0,t.ignoreStyleOnData=!1,t.hasSymbolVisual=!1,t.defaultSymbol="circle",t.visualStyleAccessPath="itemStyle",t.visualDrawType="fill"}(),e}(Ip);function sg(t){var e=t.name;_o(t)||(t.name=function(t){var e=t.getRawData(),n=e.mapDimensionsAll("seriesName"),i=[];return E(n,(function(t){var n=e.getDimensionInfo(t);n.displayName&&i.push(n.displayName)})),i.join(" ")}(t)||e)}function lg(t){return t.model.getRawData().count()}function ug(t){var e=t.model;return e.setData(e.getRawData().cloneShallow()),hg}function hg(t,e){e.outputData&&t.end>e.outputData.count()&&e.model.getRawData().cloneShallow(e.outputData)}function cg(t,e){E(gt(t.CHANGABLE_METHODS,t.DOWNSAMPLE_METHODS),(function(n){t.wrapMethod(n,H(pg,e))}))}function pg(t,e){var n=dg(t);return n&&n.setOutputEnd((e||this).count()),e}function dg(t){var e=(t.ecModel||{}).scheduler,n=e&&e.getPipeline(t.uid);if(n){var i=n.currentTask;if(i){var r=i.agentStubMap;r&&(i=r.get(t.uid))}return i}}R(ag,sf),R(ag,Qp),zo(ag,Ip);var fg=function(){function t(){this.group=new Cr,this.uid=fc("viewComponent")}return t.prototype.init=function(t,e){},t.prototype.render=function(t,e,n,i){},t.prototype.dispose=function(t,e){},t.prototype.updateView=function(t,e,n,i){},t.prototype.updateLayout=function(t,e,n,i){},t.prototype.updateVisual=function(t,e,n,i){},t.prototype.blurSeries=function(t,e){},t.prototype.eachRendered=function(t){var e=this.group;e&&e.traverse(t)},t}();function gg(){var t=So();return function(e){var n=t(e),i=e.pipelineContext,r=!!n.large,o=!!n.progressiveRender,a=n.large=!(!i||!i.large),s=n.progressiveRender=!(!i||!i.progressiveRender);return!(r===a&&o===s)&&"reset"}}Eo(fg),Go(fg);var yg=So(),vg=gg(),mg=function(){function t(){this.group=new Cr,this.uid=fc("viewChart"),this.renderTask=uf({plan:bg,reset:wg}),this.renderTask.context={view:this}}return t.prototype.init=function(t,e){},t.prototype.render=function(t,e,n,i){0},t.prototype.highlight=function(t,e,n,i){var r=t.getData(i&&i.dataType);r&&_g(r,i,"emphasis")},t.prototype.downplay=function(t,e,n,i){var r=t.getData(i&&i.dataType);r&&_g(r,i,"normal")},t.prototype.remove=function(t,e){this.group.removeAll()},t.prototype.dispose=function(t,e){},t.prototype.updateView=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.updateLayout=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.updateVisual=function(t,e,n,i){this.render(t,e,n,i)},t.prototype.eachRendered=function(t){zh(this.group,t)},t.markUpdateMethod=function(t,e){yg(t).updateMethod=e},t.protoInitialize=void(t.prototype.type="chart"),t}();function xg(t,e,n){t&&Bl(t)&&("emphasis"===e?xl:_l)(t,n)}function _g(t,e,n){var i=wo(t,e),r=e&&null!=e.highlightKey?function(t){var e=Us[t];return null==e&&Ys<=32&&(e=Us[t]=Ys++),e}(e.highlightKey):null;null!=i?E(ho(i),(function(e){xg(t.getItemGraphicEl(e),n,r)})):t.eachItemGraphicEl((function(t){xg(t,n,r)}))}function bg(t){return vg(t.model)}function wg(t){var e=t.model,n=t.ecModel,i=t.api,r=t.payload,o=e.pipelineContext.progressiveRender,a=t.view,s=r&&yg(r).updateMethod,l=o?"incrementalPrepareRender":s&&a[s]?s:"render";return"render"!==l&&a[l](e,n,i,r),Sg[l]}Eo(mg),Go(mg);var Sg={incrementalPrepareRender:{progress:function(t,e){e.view.incrementalRender(t,e.model,e.ecModel,e.api,e.payload)}},render:{forceFirstProgress:!0,progress:function(t,e){e.view.render(e.model,e.ecModel,e.api,e.payload)}}},Mg="\0__throttleOriginMethod",Ig="\0__throttleRate",Tg="\0__throttleType";function Cg(t,e,n){var i,r,o,a,s,l=0,u=0,h=null;function c(){u=(new Date).getTime(),h=null,t.apply(o,a||[])}e=e||0;var p=function(){for(var t=[],p=0;p=0?c():h=setTimeout(c,-r),l=i};return p.clear=function(){h&&(clearTimeout(h),h=null)},p.debounceNextCall=function(t){s=t},p}function Dg(t,e,n,i){var r=t[e];if(r){var o=r[Mg]||r,a=r[Tg];if(r[Ig]!==n||a!==i){if(null==n||!i)return t[e]=o;(r=t[e]=Cg(o,n,"debounce"===i))[Mg]=o,r[Tg]=i,r[Ig]=n}return r}}function Ag(t,e){var n=t[e];n&&n[Mg]&&(n.clear&&n.clear(),t[e]=n[Mg])}var kg=So(),Lg={itemStyle:Wo(uc,!0),lineStyle:Wo(ac,!0)},Pg={lineStyle:"stroke",itemStyle:"fill"};function Og(t,e){var n=t.visualStyleMapper||Lg[e];return n||(console.warn("Unkown style type '"+e+"'."),Lg.itemStyle)}function Rg(t,e){var n=t.visualDrawType||Pg[e];return n||(console.warn("Unkown style type '"+e+"'."),"fill")}var Ng={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var n=t.getData(),i=t.visualStyleAccessPath||"itemStyle",r=t.getModel(i),o=Og(t,i)(r),a=r.getShallow("decal");a&&(n.setVisual("decal",a),a.dirty=!0);var s=Rg(t,i),l=o[s],u=U(l)?l:null,h="auto"===o.fill||"auto"===o.stroke;if(!o[s]||u||h){var c=t.getColorFromPalette(t.name,null,e.getSeriesCount());o[s]||(o[s]=c,n.setVisual("colorFromPalette",!0)),o.fill="auto"===o.fill||U(o.fill)?c:o.fill,o.stroke="auto"===o.stroke||U(o.stroke)?c:o.stroke}if(n.setVisual("style",o),n.setVisual("drawType",s),!e.isSeriesFiltered(t)&&u)return n.setVisual("colorFromPalette",!1),{dataEach:function(e,n){var i=t.getDataParams(n),r=A({},o);r[s]=u(i),e.setItemVisual(n,"style",r)}}}},Eg=new pc,zg={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){if(!t.ignoreStyleOnData&&!e.isSeriesFiltered(t)){var n=t.getData(),i=t.visualStyleAccessPath||"itemStyle",r=Og(t,i),o=n.getVisual("drawType");return{dataEach:n.hasItemOption?function(t,e){var n=t.getRawDataItem(e);if(n&&n[i]){Eg.option=n[i];var a=r(Eg);A(t.ensureUniqueItemVisual(e,"style"),a),Eg.option.decal&&(t.setItemVisual(e,"decal",Eg.option.decal),Eg.option.decal.dirty=!0),o in a&&t.setItemVisual(e,"colorFromPalette",!1)}}:null}}}},Vg={performRawSeries:!0,overallReset:function(t){var e=ft();t.eachSeries((function(t){var n=t.getColorBy();if(!t.isColorBySeries()){var i=t.type+"-"+n,r=e.get(i);r||(r={},e.set(i,r)),kg(t).scope=r}})),t.eachSeries((function(e){if(!e.isColorBySeries()&&!t.isSeriesFiltered(e)){var n=e.getRawData(),i={},r=e.getData(),o=kg(e).scope,a=e.visualStyleAccessPath||"itemStyle",s=Rg(e,a);r.each((function(t){var e=r.getRawIndex(t);i[e]=t})),n.each((function(t){var a=i[t];if(r.getItemVisual(a,"colorFromPalette")){var l=r.ensureUniqueItemVisual(a,"style"),u=n.getName(t)||t+"",h=n.count();l[s]=e.getColorFromPalette(u,o,h)}}))}}))}},Bg=Math.PI;var Fg=function(){function t(t,e,n,i){this._stageTaskMap=ft(),this.ecInstance=t,this.api=e,n=this._dataProcessorHandlers=n.slice(),i=this._visualHandlers=i.slice(),this._allHandlers=n.concat(i)}return t.prototype.restoreData=function(t,e){t.restoreData(e),this._stageTaskMap.each((function(t){var e=t.overallTask;e&&e.dirty()}))},t.prototype.getPerformArgs=function(t,e){if(t.__pipeline){var n=this._pipelineMap.get(t.__pipeline.id),i=n.context,r=!e&&n.progressiveEnabled&&(!i||i.progressiveRender)&&t.__idxInPipeline>n.blockIndex?n.step:null,o=i&&i.modDataCount;return{step:r,modBy:null!=o?Math.ceil(o/r):null,modDataCount:o}}},t.prototype.getPipeline=function(t){return this._pipelineMap.get(t)},t.prototype.updateStreamModes=function(t,e){var n=this._pipelineMap.get(t.uid),i=t.getData().count(),r=n.progressiveEnabled&&e.incrementalPrepareRender&&i>=n.threshold,o=t.get("large")&&i>=t.get("largeThreshold"),a="mod"===t.get("progressiveChunkMode")?i:null;t.pipelineContext=n.context={progressiveRender:r,modDataCount:a,large:o}},t.prototype.restorePipelines=function(t){var e=this,n=e._pipelineMap=ft();t.eachSeries((function(t){var i=t.getProgressive(),r=t.uid;n.set(r,{id:r,head:null,tail:null,threshold:t.getProgressiveThreshold(),progressiveEnabled:i&&!(t.preventIncremental&&t.preventIncremental()),blockIndex:-1,step:Math.round(i||700),count:0}),e._pipe(t,t.dataTask)}))},t.prototype.prepareStageTasks=function(){var t=this._stageTaskMap,e=this.api.getModel(),n=this.api;E(this._allHandlers,(function(i){var r=t.get(i.uid)||t.set(i.uid,{}),o="";lt(!(i.reset&&i.overallReset),o),i.reset&&this._createSeriesStageTask(i,r,e,n),i.overallReset&&this._createOverallStageTask(i,r,e,n)}),this)},t.prototype.prepareView=function(t,e,n,i){var r=t.renderTask,o=r.context;o.model=e,o.ecModel=n,o.api=i,r.__block=!t.incrementalPrepareRender,this._pipe(e,r)},t.prototype.performDataProcessorTasks=function(t,e){this._performStageTasks(this._dataProcessorHandlers,t,e,{block:!0})},t.prototype.performVisualTasks=function(t,e,n){this._performStageTasks(this._visualHandlers,t,e,n)},t.prototype._performStageTasks=function(t,e,n,i){i=i||{};var r=!1,o=this;function a(t,e){return t.setDirty&&(!t.dirtyMap||t.dirtyMap.get(e.__pipeline.id))}E(t,(function(t,s){if(!i.visualType||i.visualType===t.visualType){var l=o._stageTaskMap.get(t.uid),u=l.seriesTaskMap,h=l.overallTask;if(h){var c,p=h.agentStubMap;p.each((function(t){a(i,t)&&(t.dirty(),c=!0)})),c&&h.dirty(),o.updatePayload(h,n);var d=o.getPerformArgs(h,i.block);p.each((function(t){t.perform(d)})),h.perform(d)&&(r=!0)}else u&&u.each((function(s,l){a(i,s)&&s.dirty();var u=o.getPerformArgs(s,i.block);u.skip=!t.performRawSeries&&e.isSeriesFiltered(s.context.model),o.updatePayload(s,n),s.perform(u)&&(r=!0)}))}})),this.unfinished=r||this.unfinished},t.prototype.performSeriesTasks=function(t){var e;t.eachSeries((function(t){e=t.dataTask.perform()||e})),this.unfinished=e||this.unfinished},t.prototype.plan=function(){this._pipelineMap.each((function(t){var e=t.tail;do{if(e.__block){t.blockIndex=e.__idxInPipeline;break}e=e.getUpstream()}while(e)}))},t.prototype.updatePayload=function(t,e){"remain"!==e&&(t.context.payload=e)},t.prototype._createSeriesStageTask=function(t,e,n,i){var r=this,o=e.seriesTaskMap,a=e.seriesTaskMap=ft(),s=t.seriesType,l=t.getTargetSeries;function u(e){var s=e.uid,l=a.set(s,o&&o.get(s)||uf({plan:Ug,reset:Xg,count:qg}));l.context={model:e,ecModel:n,api:i,useClearVisual:t.isVisual&&!t.isLayout,plan:t.plan,reset:t.reset,scheduler:r},r._pipe(e,l)}t.createOnAllSeries?n.eachRawSeries(u):s?n.eachRawSeriesByType(s,u):l&&l(n,i).each(u)},t.prototype._createOverallStageTask=function(t,e,n,i){var r=this,o=e.overallTask=e.overallTask||uf({reset:Gg});o.context={ecModel:n,api:i,overallReset:t.overallReset,scheduler:r};var a=o.agentStubMap,s=o.agentStubMap=ft(),l=t.seriesType,u=t.getTargetSeries,h=!0,c=!1,p="";function d(t){var e=t.uid,n=s.set(e,a&&a.get(e)||(c=!0,uf({reset:Wg,onDirty:Yg})));n.context={model:t,overallProgress:h},n.agent=o,n.__block=h,r._pipe(t,n)}lt(!t.createOnAllSeries,p),l?n.eachRawSeriesByType(l,d):u?u(n,i).each(d):(h=!1,E(n.getSeries(),d)),c&&o.dirty()},t.prototype._pipe=function(t,e){var n=t.uid,i=this._pipelineMap.get(n);!i.head&&(i.head=e),i.tail&&i.tail.pipe(e),i.tail=e,e.__idxInPipeline=i.count++,e.__pipeline=i},t.wrapStageHandler=function(t,e){return U(t)&&(t={overallReset:t,seriesType:Kg(t)}),t.uid=fc("stageHandler"),e&&(t.visualType=e),t},t}();function Gg(t){t.overallReset(t.ecModel,t.api,t.payload)}function Wg(t){return t.overallProgress&&Hg}function Hg(){this.agent.dirty(),this.getDownstream().dirty()}function Yg(){this.agent&&this.agent.dirty()}function Ug(t){return t.plan?t.plan(t.model,t.ecModel,t.api,t.payload):null}function Xg(t){t.useClearVisual&&t.data.clearAllVisual();var e=t.resetDefines=ho(t.reset(t.model,t.ecModel,t.api,t.payload));return e.length>1?z(e,(function(t,e){return jg(e)})):Zg}var Zg=jg(0);function jg(t){return function(e,n){var i=n.data,r=n.resetDefines[t];if(r&&r.dataEach)for(var o=e.start;o0&&h===r.length-u.length){var c=r.slice(0,h);"data"!==c&&(e.mainType=c,e[u.toLowerCase()]=t,s=!0)}}a.hasOwnProperty(r)&&(n[r]=t,s=!0),s||(i[r]=t)}))}return{cptQuery:e,dataQuery:n,otherQuery:i}},t.prototype.filter=function(t,e){var n=this.eventInfo;if(!n)return!0;var i=n.targetEl,r=n.packedEvent,o=n.model,a=n.view;if(!o||!a)return!0;var s=e.cptQuery,l=e.dataQuery;return u(s,o,"mainType")&&u(s,o,"subType")&&u(s,o,"index","componentIndex")&&u(s,o,"name")&&u(s,o,"id")&&u(l,r,"name")&&u(l,r,"dataIndex")&&u(l,r,"dataType")&&(!a.filterForExposedEvent||a.filterForExposedEvent(t,e.otherQuery,i,r));function u(t,e,n,i){return null==t[n]||e[i||n]===t[n]}},t.prototype.afterTrigger=function(){this.eventInfo=null},t}(),uy=["symbol","symbolSize","symbolRotate","symbolOffset"],hy=uy.concat(["symbolKeepAspect"]),cy={createOnAllSeries:!0,performRawSeries:!0,reset:function(t,e){var n=t.getData();if(t.legendIcon&&n.setVisual("legendIcon",t.legendIcon),t.hasSymbolVisual){for(var i={},r={},o=!1,a=0;a0&&(e=i.lineDash,n=i.lineWidth,e&&"solid"!==e&&n>0?"dashed"===e?[4*n,2*n]:"dotted"===e?[n]:j(e)?[e]:Y(e)?e:null:null),o=i.lineDashOffset;if(r){var a=i.strokeNoScale&&t.getLineScale?t.getLineScale():1;a&&1!==a&&(r=z(r,(function(t){return t/a})),o/=a)}return[r,o]}var zy=new ja(!0);function Vy(t){var e=t.stroke;return!(null==e||"none"===e||!(t.lineWidth>0))}function By(t){return"string"==typeof t&&"none"!==t}function Fy(t){var e=t.fill;return null!=e&&"none"!==e}function Gy(t,e){if(null!=e.fillOpacity&&1!==e.fillOpacity){var n=t.globalAlpha;t.globalAlpha=e.fillOpacity*e.opacity,t.fill(),t.globalAlpha=n}else t.fill()}function Wy(t,e){if(null!=e.strokeOpacity&&1!==e.strokeOpacity){var n=t.globalAlpha;t.globalAlpha=e.strokeOpacity*e.opacity,t.stroke(),t.globalAlpha=n}else t.stroke()}function Hy(t,e,n){var i=Zo(e.image,e.__image,n);if(qo(i)){var r=t.createPattern(i,e.repeat||"repeat");if("function"==typeof DOMMatrix&&r&&r.setTransform){var o=new DOMMatrix;o.translateSelf(e.x||0,e.y||0),o.rotateSelf(0,0,(e.rotation||0)*_t),o.scaleSelf(e.scaleX||1,e.scaleY||1),r.setTransform(o)}return r}}var Yy=["shadowBlur","shadowOffsetX","shadowOffsetY"],Uy=[["lineCap","butt"],["lineJoin","miter"],["miterLimit",10]];function Xy(t,e,n,i,r){var o=!1;if(!i&&e===(n=n||{}))return!1;if(i||e.opacity!==n.opacity){qy(t,r),o=!0;var a=Math.max(Math.min(e.opacity,1),0);t.globalAlpha=isNaN(a)?ua.opacity:a}(i||e.blend!==n.blend)&&(o||(qy(t,r),o=!0),t.globalCompositeOperation=e.blend||ua.blend);for(var s=0;s0&&t.unfinished);t.unfinished||this._zr.flush()}}},e.prototype.getDom=function(){return this._dom},e.prototype.getId=function(){return this.id},e.prototype.getZr=function(){return this._zr},e.prototype.isSSR=function(){return this._ssr},e.prototype.setOption=function(t,e,n){if(!this.__flagInMainProcess)if(this._disposed)Gv(this.id);else{var i,r,o;if(q(e)&&(n=e.lazyUpdate,i=e.silent,r=e.replaceMerge,o=e.transition,e=e.notMerge),this.__flagInMainProcess=!0,!this._model||e){var a=new cd(this._api),s=this._theme,l=this._model=new nd;l.scheduler=this._scheduler,l.ssr=this._ssr,l.init(null,null,null,s,this._locale,a)}this._model.setOption(t,{replaceMerge:r},Uv);var u={seriesTransition:o,optionChanged:!0};if(n)this.__pendingUpdate={silent:i,updateParams:u},this.__flagInMainProcess=!1,this.getZr().wakeUp();else{try{mv(this),bv.update.call(this,null,u)}catch(t){throw this.__pendingUpdate=null,this.__flagInMainProcess=!1,t}this._ssr||this._zr.flush(),this.__pendingUpdate=null,this.__flagInMainProcess=!1,Iv.call(this,i),Tv.call(this,i)}}},e.prototype.setTheme=function(){oo()},e.prototype.getModel=function(){return this._model},e.prototype.getOption=function(){return this._model&&this._model.getOption()},e.prototype.getWidth=function(){return this._zr.getWidth()},e.prototype.getHeight=function(){return this._zr.getHeight()},e.prototype.getDevicePixelRatio=function(){return this._zr.painter.dpr||uv&&window.devicePixelRatio||1},e.prototype.getRenderedCanvas=function(t){return this.renderToCanvas(t)},e.prototype.renderToCanvas=function(t){t=t||{};var e=this._zr.painter;return e.getRenderedCanvas({backgroundColor:t.backgroundColor||this._model.get("backgroundColor"),pixelRatio:t.pixelRatio||this.getDevicePixelRatio()})},e.prototype.renderToSVGString=function(t){t=t||{};var e=this._zr.painter;return e.renderToString({useViewBox:t.useViewBox})},e.prototype.getSvgDataURL=function(){if(r.svgSupported){var t=this._zr;return E(t.storage.getDisplayList(),(function(t){t.stopAnimation(null,!0)})),t.painter.toDataURL()}},e.prototype.getDataURL=function(t){if(!this._disposed){var e=(t=t||{}).excludeComponents,n=this._model,i=[],r=this;E(e,(function(t){n.eachComponent({mainType:t},(function(t){var e=r._componentsMap[t.__viewId];e.group.ignore||(i.push(e),e.group.ignore=!0)}))}));var o="svg"===this._zr.painter.getType()?this.getSvgDataURL():this.renderToCanvas(t).toDataURL("image/"+(t&&t.type||"png"));return E(i,(function(t){t.group.ignore=!1})),o}Gv(this.id)},e.prototype.getConnectedDataURL=function(t){if(!this._disposed){var e="svg"===t.type,n=this.group,i=Math.min,r=Math.max,o=1/0;if(Kv[n]){var a=o,s=o,l=-1/0,u=-1/0,c=[],p=t&&t.pixelRatio||this.getDevicePixelRatio();E(qv,(function(o,h){if(o.group===n){var p=e?o.getZr().painter.getSvgDom().innerHTML:o.renderToCanvas(T(t)),d=o.getDom().getBoundingClientRect();a=i(d.left,a),s=i(d.top,s),l=r(d.right,l),u=r(d.bottom,u),c.push({dom:p,left:d.left,top:d.top})}}));var d=(l*=p)-(a*=p),f=(u*=p)-(s*=p),g=h.createCanvas(),y=Lr(g,{renderer:e?"svg":"canvas"});if(y.resize({width:d,height:f}),e){var v="";return E(c,(function(t){var e=t.left-a,n=t.top-s;v+=''+t.dom+""})),y.painter.getSvgRoot().innerHTML=v,t.connectedBackgroundColor&&y.painter.setBackgroundColor(t.connectedBackgroundColor),y.refreshImmediately(),y.painter.toDataURL()}return t.connectedBackgroundColor&&y.add(new Ts({shape:{x:0,y:0,width:d,height:f},style:{fill:t.connectedBackgroundColor}})),E(c,(function(t){var e=new xs({style:{x:t.left*p-a,y:t.top*p-s,image:t.dom}});y.add(e)})),y.refreshImmediately(),g.toDataURL("image/"+(t&&t.type||"png"))}return this.getDataURL(t)}Gv(this.id)},e.prototype.convertToPixel=function(t,e){return wv(this,"convertToPixel",t,e)},e.prototype.convertFromPixel=function(t,e){return wv(this,"convertFromPixel",t,e)},e.prototype.containPixel=function(t,e){var n;if(!this._disposed)return E(Io(this._model,t),(function(t,i){i.indexOf("Models")>=0&&E(t,(function(t){var r=t.coordinateSystem;if(r&&r.containPoint)n=n||!!r.containPoint(e);else if("seriesModels"===i){var o=this._chartsMap[t.__viewId];o&&o.containPoint&&(n=n||o.containPoint(e,t))}else 0}),this)}),this),!!n;Gv(this.id)},e.prototype.getVisual=function(t,e){var n=Io(this._model,t,{defaultMainType:"series"}),i=n.seriesModel;var r=i.getData(),o=n.hasOwnProperty("dataIndexInside")?n.dataIndexInside:n.hasOwnProperty("dataIndex")?r.indexOfRawIndex(n.dataIndex):null;return null!=o?dy(r,o,e):fy(r,e)},e.prototype.getViewOfComponentModel=function(t){return this._componentsMap[t.__viewId]},e.prototype.getViewOfSeriesModel=function(t){return this._chartsMap[t.__viewId]},e.prototype._initEvents=function(){var t,e,n,i=this;E(Fv,(function(t){var e=function(e){var n,r=i.getModel(),o=e.target,a="globalout"===t;if(a?n={}:o&&my(o,(function(t){var e=Ws(t);if(e&&null!=e.dataIndex){var i=e.dataModel||r.getSeriesByIndex(e.seriesIndex);return n=i&&i.getDataParams(e.dataIndex,e.dataType)||{},!0}if(e.eventData)return n=A({},e.eventData),!0}),!0),n){var s=n.componentType,l=n.componentIndex;"markLine"!==s&&"markPoint"!==s&&"markArea"!==s||(s="series",l=n.seriesIndex);var u=s&&null!=l&&r.getComponent(s,l),h=u&&i["series"===u.mainType?"_chartsMap":"_componentsMap"][u.__viewId];0,n.event=e,n.type=t,i._$eventProcessor.eventInfo={targetEl:o,packedEvent:n,model:u,view:h},i.trigger(t,n)}};e.zrEventfulCallAtLast=!0,i._zr.on(t,e,i)})),E(Hv,(function(t,e){i._messageCenter.on(e,(function(t){this.trigger(e,t)}),i)})),E(["selectchanged"],(function(t){i._messageCenter.on(t,(function(e){this.trigger(t,e)}),i)})),t=this._messageCenter,e=this,n=this._api,t.on("selectchanged",(function(t){var i=n.getModel();t.isFromClick?(vy("map","selectchanged",e,i,t),vy("pie","selectchanged",e,i,t)):"select"===t.fromAction?(vy("map","selected",e,i,t),vy("pie","selected",e,i,t)):"unselect"===t.fromAction&&(vy("map","unselected",e,i,t),vy("pie","unselected",e,i,t))}))},e.prototype.isDisposed=function(){return this._disposed},e.prototype.clear=function(){this._disposed?Gv(this.id):this.setOption({series:[]},!0)},e.prototype.dispose=function(){if(this._disposed)Gv(this.id);else{this._disposed=!0,this.getDom()&&ko(this.getDom(),Qv,"");var t=this,e=t._api,n=t._model;E(t._componentsViews,(function(t){t.dispose(n,e)})),E(t._chartsViews,(function(t){t.dispose(n,e)})),t._zr.dispose(),t._dom=t._model=t._chartsMap=t._componentsMap=t._chartsViews=t._componentsViews=t._scheduler=t._api=t._zr=t._throttledZrFlush=t._theme=t._coordSysMgr=t._messageCenter=null,delete qv[t.id]}},e.prototype.resize=function(t){if(!this.__flagInMainProcess)if(this._disposed)Gv(this.id);else{this._zr.resize(t);var e=this._model;if(this._loadingFX&&this._loadingFX.resize(),e){var n=e.resetOption("media"),i=t&&t.silent;this.__pendingUpdate&&(null==i&&(i=this.__pendingUpdate.silent),n=!0,this.__pendingUpdate=null),this.__flagInMainProcess=!0;try{n&&mv(this),bv.update.call(this,{type:"resize",animation:A({duration:0},t&&t.animation)})}catch(t){throw this.__flagInMainProcess=!1,t}this.__flagInMainProcess=!1,Iv.call(this,i),Tv.call(this,i)}}},e.prototype.showLoading=function(t,e){if(this._disposed)Gv(this.id);else if(q(t)&&(e=t,t=""),t=t||"default",this.hideLoading(),jv[t]){var n=jv[t](this._api,e),i=this._zr;this._loadingFX=n,i.add(n)}},e.prototype.hideLoading=function(){this._disposed?Gv(this.id):(this._loadingFX&&this._zr.remove(this._loadingFX),this._loadingFX=null)},e.prototype.makeActionFromEvent=function(t){var e=A({},t);return e.type=Hv[t.type],e},e.prototype.dispatchAction=function(t,e){if(this._disposed)Gv(this.id);else if(q(e)||(e={silent:!!e}),Wv[t.type]&&this._model)if(this.__flagInMainProcess)this._pendingActions.push(t);else{var n=e.silent;Mv.call(this,t,n);var i=e.flush;i?this._zr.flush():!1!==i&&r.browser.weChat&&this._throttledZrFlush(),Iv.call(this,n),Tv.call(this,n)}},e.prototype.updateLabelLayout=function(){av.trigger("series:layoutlabels",this._model,this._api,{updatedSeries:[]})},e.prototype.appendData=function(t){if(this._disposed)Gv(this.id);else{var e=t.seriesIndex,n=this.getModel().getSeriesByIndex(e);0,n.appendData(t),this._scheduler.unfinished=!0,this.getZr().wakeUp()}},e.internalField=function(){function t(t){t.clearColorPalette(),t.eachSeries((function(t){t.clearColorPalette()}))}function e(t){for(var e=[],n=t.currentStates,i=0;i0?{duration:o,delay:i.get("delay"),easing:i.get("easing")}:null;n.eachRendered((function(t){if(t.states&&t.states.emphasis){if(oh(t))return;if(t instanceof fs&&function(t){var e=Xs(t);e.normalFill=t.style.fill,e.normalStroke=t.style.stroke;var n=t.states.select||{};e.selectFill=n.style&&n.style.fill||null,e.selectStroke=n.style&&n.style.stroke||null}(t),t.__dirty){var n=t.prevStates;n&&t.useStates(n)}if(r){t.stateTransition=a;var i=t.getTextContent(),o=t.getTextGuideLine();i&&(i.stateTransition=a),o&&(o.stateTransition=a)}t.__dirty&&e(t)}}))}mv=function(t){var e=t._scheduler;e.restorePipelines(t._model),e.prepareStageTasks(),xv(t,!0),xv(t,!1),e.plan()},xv=function(t,e){for(var n=t._model,i=t._scheduler,r=e?t._componentsViews:t._chartsViews,o=e?t._componentsMap:t._chartsMap,a=t._zr,s=t._api,l=0;le.get("hoverLayerThreshold")&&!r.node&&!r.worker&&e.eachSeries((function(e){if(!e.preventUsingHoverLayer){var n=t._chartsMap[e.__viewId];n.__alive&&n.eachRendered((function(t){t.states.emphasis&&(t.states.emphasis.hoverLayer=!0)}))}}))}(t,e),av.trigger("series:afterupdate",e,n,l)},Rv=function(t){t.__needsUpdateStatus=!0,t.getZr().wakeUp()},Nv=function(t){t.__needsUpdateStatus&&(t.getZr().storage.traverse((function(t){oh(t)||e(t)})),t.__needsUpdateStatus=!1)},Pv=function(t){return new(function(e){function i(){return null!==e&&e.apply(this,arguments)||this}return n(i,e),i.prototype.getCoordinateSystems=function(){return t._coordSysMgr.getCoordinateSystems()},i.prototype.getComponentByElement=function(e){for(;e;){var n=e.__ecComponentInfo;if(null!=n)return t._model.getComponent(n.mainType,n.index);e=e.parent}},i.prototype.enterEmphasis=function(e,n){xl(e,n),Rv(t)},i.prototype.leaveEmphasis=function(e,n){_l(e,n),Rv(t)},i.prototype.enterBlur=function(e){bl(e),Rv(t)},i.prototype.leaveBlur=function(e){wl(e),Rv(t)},i.prototype.enterSelect=function(e){Sl(e),Rv(t)},i.prototype.leaveSelect=function(e){Ml(e),Rv(t)},i.prototype.getModel=function(){return t.getModel()},i.prototype.getViewOfComponentModel=function(e){return t.getViewOfComponentModel(e)},i.prototype.getViewOfSeriesModel=function(e){return t.getViewOfSeriesModel(e)},i}(sd))(t)},Ov=function(t){function e(t,e){for(var n=0;n=0)){dm.push(n);var o=Fg.wrapStageHandler(n,r);o.__prio=e,o.__raw=n,t.push(o)}}function gm(t,e){jv[t]=e}function ym(t,e,n){var i=lv("registerMap");i&&i(t,e,n)}var vm=function(t){var e=(t=T(t)).type,n="";e||ao(n);var i=e.split(":");2!==i.length&&ao(n);var r=!1;"echarts"===i[0]&&(e=i[1],r=!0),t.__isBuiltIn=r,If.set(e,t)};pm(hv,Ng),pm(cv,zg),pm(cv,Vg),pm(hv,cy),pm(cv,py),pm(7e3,(function(t,e){t.eachRawSeries((function(n){if(!t.isSeriesFiltered(n)){var i=n.getData();i.hasItemVisual()&&i.each((function(t){var n=i.getItemVisual(t,"decal");n&&(i.ensureUniqueItemVisual(t,"style").decal=nv(n,e))}));var r=i.getVisual("decal");if(r)i.getVisual("style").decal=nv(r,e)}}))})),rm(Pd),om(900,(function(t){var e=ft();t.eachSeries((function(t){var n=t.get("stack");if(n){var i=e.get(n)||e.set(n,[]),r=t.getData(),o={stackResultDimension:r.getCalculationInfo("stackResultDimension"),stackedOverDimension:r.getCalculationInfo("stackedOverDimension"),stackedDimension:r.getCalculationInfo("stackedDimension"),stackedByDimension:r.getCalculationInfo("stackedByDimension"),isStackedByIndex:r.getCalculationInfo("isStackedByIndex"),data:r,seriesModel:t};if(!o.stackedDimension||!o.isStackedByIndex&&!o.stackedByDimension)return;i.length&&r.setCalculationInfo("stackedOnSeries",i[i.length-1].seriesModel),i.push(o)}})),e.each(Od)})),gm("default",(function(t,e){k(e=e||{},{text:"loading",textColor:"#000",fontSize:12,fontWeight:"normal",fontStyle:"normal",fontFamily:"sans-serif",maskColor:"rgba(255, 255, 255, 0.8)",showSpinner:!0,color:"#5470c6",spinnerRadius:10,lineWidth:5,zlevel:0});var n=new Cr,i=new Ts({style:{fill:e.maskColor},zlevel:e.zlevel,z:1e4});n.add(i);var r,o=new As({style:{text:e.text,fill:e.textColor,fontSize:e.fontSize,fontWeight:e.fontWeight,fontStyle:e.fontStyle,fontFamily:e.fontFamily},zlevel:e.zlevel,z:10001}),a=new Ts({style:{fill:"none"},textContent:o,textConfig:{position:"right",distance:10},zlevel:e.zlevel,z:10001});return n.add(a),e.showSpinner&&((r=new Wu({shape:{startAngle:-Bg/2,endAngle:-Bg/2+.1,r:e.spinnerRadius},style:{stroke:e.color,lineCap:"round",lineWidth:e.lineWidth},zlevel:e.zlevel,z:10001})).animateShape(!0).when(1e3,{endAngle:3*Bg/2}).start("circularInOut"),r.animateShape(!0).when(1e3,{startAngle:3*Bg/2}).delay(300).start("circularInOut"),n.add(r)),n.resize=function(){var n=o.getBoundingRect().width,s=e.showSpinner?e.spinnerRadius:0,l=(t.getWidth()-2*s-(e.showSpinner&&n?10:0)-n)/2-(e.showSpinner&&n?0:5+n/2)+(e.showSpinner?0:n/2)+(n?0:s),u=t.getHeight()/2;e.showSpinner&&r.setShape({cx:l,cy:u}),a.setShape({x:l-s,y:u-s,width:2*s,height:2*s}),i.setShape({x:0,y:0,width:t.getWidth(),height:t.getHeight()})},n.resize(),n})),um({type:$s,event:$s,update:$s},xt),um({type:Js,event:Js,update:Js},xt),um({type:Qs,event:Qs,update:Qs},xt),um({type:tl,event:tl,update:tl},xt),um({type:el,event:el,update:el},xt),im("light",ny),im("dark",sy);var mm=[],xm={registerPreprocessor:rm,registerProcessor:om,registerPostInit:am,registerPostUpdate:sm,registerUpdateLifecycle:lm,registerAction:um,registerCoordinateSystem:hm,registerLayout:cm,registerVisual:pm,registerTransform:vm,registerLoading:gm,registerMap:ym,registerImpl:function(t,e){sv[t]=e},PRIORITY:pv,ComponentModel:Ip,ComponentView:fg,SeriesModel:ag,ChartView:mg,registerComponentModel:function(t){Ip.registerClass(t)},registerComponentView:function(t){fg.registerClass(t)},registerSeriesModel:function(t){ag.registerClass(t)},registerChartView:function(t){mg.registerClass(t)},registerSubTypeDefaulter:function(t,e){Ip.registerSubTypeDefaulter(t,e)},registerPainter:function(t,e){Pr(t,e)}};function _m(t){Y(t)?E(t,(function(t){_m(t)})):P(mm,t)>=0||(mm.push(t),U(t)&&(t={install:t}),t.install(xm))}function bm(t){return null==t?0:t.length||1}function wm(t){return t}var Sm=function(){function t(t,e,n,i,r,o){this._old=t,this._new=e,this._oldKeyGetter=n||wm,this._newKeyGetter=i||wm,this.context=r,this._diffModeMultiple="multiple"===o}return t.prototype.add=function(t){return this._add=t,this},t.prototype.update=function(t){return this._update=t,this},t.prototype.updateManyToOne=function(t){return this._updateManyToOne=t,this},t.prototype.updateOneToMany=function(t){return this._updateOneToMany=t,this},t.prototype.updateManyToMany=function(t){return this._updateManyToMany=t,this},t.prototype.remove=function(t){return this._remove=t,this},t.prototype.execute=function(){this[this._diffModeMultiple?"_executeMultiple":"_executeOneToOne"]()},t.prototype._executeOneToOne=function(){var t=this._old,e=this._new,n={},i=new Array(t.length),r=new Array(e.length);this._initIndexMap(t,null,i,"_oldKeyGetter"),this._initIndexMap(e,n,r,"_newKeyGetter");for(var o=0;o1){var u=s.shift();1===s.length&&(n[a]=s[0]),this._update&&this._update(u,o)}else 1===l?(n[a]=null,this._update&&this._update(s,o)):this._remove&&this._remove(o)}this._performRestAdd(r,n)},t.prototype._executeMultiple=function(){var t=this._old,e=this._new,n={},i={},r=[],o=[];this._initIndexMap(t,n,r,"_oldKeyGetter"),this._initIndexMap(e,i,o,"_newKeyGetter");for(var a=0;a1&&1===c)this._updateManyToOne&&this._updateManyToOne(u,l),i[s]=null;else if(1===h&&c>1)this._updateOneToMany&&this._updateOneToMany(u,l),i[s]=null;else if(1===h&&1===c)this._update&&this._update(u,l),i[s]=null;else if(h>1&&c>1)this._updateManyToMany&&this._updateManyToMany(u,l),i[s]=null;else if(h>1)for(var p=0;p1)for(var a=0;a30}var Nm,Em,zm,Vm,Bm,Fm,Gm,Wm=q,Hm=z,Ym="undefined"==typeof Int32Array?Array:Int32Array,Um=["hasItemOption","_nameList","_idList","_invertedIndicesMap","_dimSummary","userOutput","_rawData","_dimValueGetter","_nameDimIdx","_idDimIdx","_nameRepeatCount"],Xm=["_approximateExtent"],Zm=function(){function t(t,e){var n;this.type="list",this._dimOmitted=!1,this._nameList=[],this._idList=[],this._visual={},this._layout={},this._itemVisuals=[],this._itemLayouts=[],this._graphicEls=[],this._approximateExtent={},this._calculationInfo={},this.hasItemOption=!1,this.TRANSFERABLE_METHODS=["cloneShallow","downSample","lttbDownSample","map"],this.CHANGABLE_METHODS=["filterSelf","selectRange"],this.DOWNSAMPLE_METHODS=["downSample","lttbDownSample"];var i=!1;Lm(t)?(n=t.dimensions,this._dimOmitted=t.isDimensionOmitted(),this._schema=t):(i=!0,n=t),n=n||["x","y"];for(var r={},o=[],a={},s=!1,l={},u=0;u=e)){var n=this._store.getProvider();this._updateOrdinalMeta();var i=this._nameList,r=this._idList;if(n.getSource().sourceFormat===kp&&!n.pure)for(var o=[],a=t;a0},t.prototype.ensureUniqueItemVisual=function(t,e){var n=this._itemVisuals,i=n[t];i||(i=n[t]={});var r=i[e];return null==r&&(Y(r=this.getVisual(e))?r=r.slice():Wm(r)&&(r=A({},r)),i[e]=r),r},t.prototype.setItemVisual=function(t,e,n){var i=this._itemVisuals[t]||{};this._itemVisuals[t]=i,Wm(e)?A(i,e):i[e]=n},t.prototype.clearAllVisual=function(){this._visual={},this._itemVisuals=[]},t.prototype.setLayout=function(t,e){Wm(t)?A(this._layout,t):this._layout[t]=e},t.prototype.getLayout=function(t){return this._layout[t]},t.prototype.getItemLayout=function(t){return this._itemLayouts[t]},t.prototype.setItemLayout=function(t,e,n){this._itemLayouts[t]=n?A(this._itemLayouts[t]||{},e):e},t.prototype.clearItemLayouts=function(){this._itemLayouts.length=0},t.prototype.setItemGraphicEl=function(t,e){var n=this.hostModel&&this.hostModel.seriesIndex;Hs(n,this.dataType,t,e),this._graphicEls[t]=e},t.prototype.getItemGraphicEl=function(t){return this._graphicEls[t]},t.prototype.eachItemGraphicEl=function(t,e){E(this._graphicEls,(function(n,i){n&&t&&t.call(e,n,i)}))},t.prototype.cloneShallow=function(e){return e||(e=new t(this._schema?this._schema:Hm(this.dimensions,this._getDimInfo,this),this.hostModel)),Bm(e,this),e._store=this._store,e},t.prototype.wrapMethod=function(t,e){var n=this[t];U(n)&&(this.__wrappedMethods=this.__wrappedMethods||[],this.__wrappedMethods.push(t),this[t]=function(){var t=n.apply(this,arguments);return e.apply(this,[t].concat(at(arguments)))})},t.internalField=(Nm=function(t){var e=t._invertedIndicesMap;E(e,(function(n,i){var r=t._dimInfos[i],o=r.ordinalMeta,a=t._store;if(o){n=e[i]=new Ym(o.categories.length);for(var s=0;s1&&(s+="__ec__"+u),i[e]=s}})),t}();function jm(t,e){Fd(t)||(t=Wd(t));var n=(e=e||{}).coordDimensions||[],i=e.dimensionsDefine||t.dimensionsDefine||[],r=ft(),o=[],a=function(t,e,n,i){var r=Math.max(t.dimensionsDetectedCount||1,e.length,n.length,i||0);return E(e,(function(t){var e;q(t)&&(e=t.dimsDef)&&(r=Math.max(r,e.length))})),r}(t,n,i,e.dimensionsCount),s=e.canOmitUnusedDimensions&&Rm(a),l=i===t.dimensionsDefine,u=l?Om(t):Pm(i),h=e.encodeDefine;!h&&e.encodeDefaulter&&(h=e.encodeDefaulter(t,a));for(var c=ft(h),p=new Pf(a),d=0;d0&&(i.name=r+(o-1)),o++,e.set(r,o)}}(o),new km({source:t,dimensions:o,fullDimensionCount:a,dimensionOmitted:s})}function qm(t,e,n){var i=e.data;if(n||i.hasOwnProperty(t)){for(var r=0;i.hasOwnProperty(t+r);)r++;t+=r}return e.set(t,!0),t}var Km=function(t){this.coordSysDims=[],this.axisMap=ft(),this.categoryAxisMap=ft(),this.coordSysName=t};var $m={cartesian2d:function(t,e,n,i){var r=t.getReferringComponents("xAxis",Co).models[0],o=t.getReferringComponents("yAxis",Co).models[0];e.coordSysDims=["x","y"],n.set("x",r),n.set("y",o),Jm(r)&&(i.set("x",r),e.firstCategoryDimIndex=0),Jm(o)&&(i.set("y",o),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=1))},singleAxis:function(t,e,n,i){var r=t.getReferringComponents("singleAxis",Co).models[0];e.coordSysDims=["single"],n.set("single",r),Jm(r)&&(i.set("single",r),e.firstCategoryDimIndex=0)},polar:function(t,e,n,i){var r=t.getReferringComponents("polar",Co).models[0],o=r.findAxisModel("radiusAxis"),a=r.findAxisModel("angleAxis");e.coordSysDims=["radius","angle"],n.set("radius",o),n.set("angle",a),Jm(o)&&(i.set("radius",o),e.firstCategoryDimIndex=0),Jm(a)&&(i.set("angle",a),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=1))},geo:function(t,e,n,i){e.coordSysDims=["lng","lat"]},parallel:function(t,e,n,i){var r=t.ecModel,o=r.getComponent("parallel",t.get("parallelIndex")),a=e.coordSysDims=o.dimensions.slice();E(o.parallelAxisIndex,(function(t,o){var s=r.getComponent("parallelAxis",t),l=a[o];n.set(l,s),Jm(s)&&(i.set(l,s),null==e.firstCategoryDimIndex&&(e.firstCategoryDimIndex=o))}))}};function Jm(t){return"category"===t.get("type")}function Qm(t,e,n){var i,r,o,a=(n=n||{}).byIndex,s=n.stackedCoordDimension;!function(t){return!Lm(t.schema)}(e)?(r=e.schema,i=r.dimensions,o=e.store):i=e;var l,u,h,c,p=!(!t||!t.get("stack"));if(E(i,(function(t,e){X(t)&&(i[e]=t={name:t}),p&&!t.isExtraCoord&&(a||l||!t.ordinalMeta||(l=t),u||"ordinal"===t.type||"time"===t.type||s&&s!==t.coordDim||(u=t))})),!u||a||l||(a=!0),u){h="__\0ecstackresult_"+t.id,c="__\0ecstackedover_"+t.id,l&&(l.createInvertedIndices=!0);var d=u.coordDim,f=u.type,g=0;E(i,(function(t){t.coordDim===d&&g++}));var y={name:h,coordDim:d,coordDimIndex:g,type:f,isExtraCoord:!0,isCalculationCoord:!0,storeDimIndex:i.length},v={name:c,coordDim:c,coordDimIndex:g+1,type:f,isExtraCoord:!0,isCalculationCoord:!0,storeDimIndex:i.length+1};r?(o&&(y.storeDimIndex=o.ensureCalculationDimension(c,f),v.storeDimIndex=o.ensureCalculationDimension(h,f)),r.appendCalculationDimension(y),r.appendCalculationDimension(v)):(i.push(y),i.push(v))}return{stackedDimension:u&&u.name,stackedByDimension:l&&l.name,isStackedByIndex:a,stackedOverDimension:c,stackResultDimension:h}}function tx(t,e){return!!e&&e===t.getCalculationInfo("stackedDimension")}function ex(t,e){return tx(t,e)?t.getCalculationInfo("stackResultDimension"):e}function nx(t,e,n){n=n||{};var i,r=e.getSourceManager(),o=!1;t?(o=!0,i=Wd(t)):o=(i=r.getSource()).sourceFormat===kp;var a=function(t){var e=t.get("coordinateSystem"),n=new Km(e),i=$m[e];if(i)return i(t,n,n.axisMap,n.categoryAxisMap),n}(e),s=function(t,e){var n,i=t.get("coordinateSystem"),r=ud.get(i);return e&&e.coordSysDims&&(n=z(e.coordSysDims,(function(t){var n={name:t},i=e.axisMap.get(t);if(i){var r=i.get("type");n.type=Tm(r)}return n}))),n||(n=r&&(r.getDimensionsInfo?r.getDimensionsInfo():r.dimensions.slice())||["x","y"]),n}(e,a),l=n.useEncodeDefaulter,u=U(l)?l:l?H(Wp,s,e):null,h=jm(i,{coordDimensions:s,generateCoord:n.generateCoord,encodeDefine:e.getEncode(),encodeDefaulter:u,canOmitUnusedDimensions:!o}),c=function(t,e,n){var i,r;return n&&E(t,(function(t,o){var a=t.coordDim,s=n.categoryAxisMap.get(a);s&&(null==i&&(i=o),t.ordinalMeta=s.getOrdinalMeta(),e&&(t.createInvertedIndices=!0)),null!=t.otherDims.itemName&&(r=!0)})),r||null==i||(t[i].otherDims.itemName=0),i}(h.dimensions,n.createInvertedIndices,a),p=o?null:r.getSharedDataStore(h),d=Qm(e,{schema:h,store:p}),f=new Zm(h,e);f.setCalculationInfo(d);var g=null!=c&&function(t){if(t.sourceFormat===kp){return!Y(fo(function(t){var e=0;for(;ee[1]&&(e[1]=t[1])},t.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},t.prototype.getExtent=function(){return this._extent.slice()},t.prototype.setExtent=function(t,e){var n=this._extent;isNaN(t)||(n[0]=t),isNaN(e)||(n[1]=e)},t.prototype.isInExtentRange=function(t){return this._extent[0]<=t&&this._extent[1]>=t},t.prototype.isBlank=function(){return this._isBlank},t.prototype.setBlank=function(t){this._isBlank=t},t}();Go(ix);var rx=0,ox=function(){function t(t){this.categories=t.categories||[],this._needCollect=t.needCollect,this._deduplication=t.deduplication,this.uid=++rx}return t.createByAxisModel=function(e){var n=e.option,i=n.data,r=i&&z(i,ax);return new t({categories:r,needCollect:!r,deduplication:!1!==n.dedplication})},t.prototype.getOrdinal=function(t){return this._getOrCreateMap().get(t)},t.prototype.parseAndCollect=function(t){var e,n=this._needCollect;if(!X(t)&&!n)return t;if(n&&!this._deduplication)return e=this.categories.length,this.categories[e]=t,e;var i=this._getOrCreateMap();return null==(e=i.get(t))&&(n?(e=this.categories.length,this.categories[e]=t,i.set(t,e)):e=NaN),e},t.prototype._getOrCreateMap=function(){return this._map||(this._map=ft(this.categories))},t}();function ax(t){return q(t)&&null!=t.value?t.value:t+""}function sx(t){return"interval"===t.type||"log"===t.type}function lx(t,e,n,i){var r={},o=t[1]-t[0],a=r.interval=$r(o/e,!0);null!=n&&ai&&(a=r.interval=i);var s=r.intervalPrecision=hx(a);return function(t,e){!isFinite(t[0])&&(t[0]=e[0]),!isFinite(t[1])&&(t[1]=e[1]),cx(t,0,e),cx(t,1,e),t[0]>t[1]&&(t[0]=t[1])}(r.niceTickExtent=[zr(Math.ceil(t[0]/a)*a,s),zr(Math.floor(t[1]/a)*a,s)],t),r}function ux(t){var e=Math.pow(10,Kr(t)),n=t/e;return n?2===n?n=3:3===n?n=5:n*=2:n=1,zr(n*e)}function hx(t){return Br(t)+2}function cx(t,e,n){t[e]=Math.max(Math.min(t[e],n[1]),n[0])}function px(t,e){return t>=e[0]&&t<=e[1]}function dx(t,e){return e[1]===e[0]?.5:(t-e[0])/(e[1]-e[0])}function fx(t,e){return t*(e[1]-e[0])+e[0]}var gx=function(t){function e(e){var n=t.call(this,e)||this;n.type="ordinal";var i=n.getSetting("ordinalMeta");return i||(i=new ox({})),Y(i)&&(i=new ox({categories:z(i,(function(t){return q(t)?t.value:t}))})),n._ordinalMeta=i,n._extent=n.getSetting("extent")||[0,i.categories.length-1],n}return n(e,t),e.prototype.parse=function(t){return X(t)?this._ordinalMeta.getOrdinal(t):Math.round(t)},e.prototype.contain=function(t){return px(t=this.parse(t),this._extent)&&null!=this._ordinalMeta.categories[t]},e.prototype.normalize=function(t){return dx(t=this._getTickNumber(this.parse(t)),this._extent)},e.prototype.scale=function(t){return t=Math.round(fx(t,this._extent)),this.getRawOrdinalNumber(t)},e.prototype.getTicks=function(){for(var t=[],e=this._extent,n=e[0];n<=e[1];)t.push({value:n}),n++;return t},e.prototype.getMinorTicks=function(t){},e.prototype.setSortInfo=function(t){if(null!=t){for(var e=t.ordinalNumbers,n=this._ordinalNumbersByTick=[],i=this._ticksByOrdinalNumber=[],r=0,o=this._ordinalMeta.categories.length,a=Math.min(o,e.length);r=0&&t=0&&t=t},e.prototype.getOrdinalMeta=function(){return this._ordinalMeta},e.prototype.calcNiceTicks=function(){},e.prototype.calcNiceExtent=function(){},e.type="ordinal",e}(ix);ix.registerClass(gx);var yx=zr,vx=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="interval",e._interval=0,e._intervalPrecision=2,e}return n(e,t),e.prototype.parse=function(t){return t},e.prototype.contain=function(t){return px(t,this._extent)},e.prototype.normalize=function(t){return dx(t,this._extent)},e.prototype.scale=function(t){return fx(t,this._extent)},e.prototype.setExtent=function(t,e){var n=this._extent;isNaN(t)||(n[0]=parseFloat(t)),isNaN(e)||(n[1]=parseFloat(e))},e.prototype.unionExtent=function(t){var e=this._extent;t[0]e[1]&&(e[1]=t[1]),this.setExtent(e[0],e[1])},e.prototype.getInterval=function(){return this._interval},e.prototype.setInterval=function(t){this._interval=t,this._niceExtent=this._extent.slice(),this._intervalPrecision=hx(t)},e.prototype.getTicks=function(t){var e=this._interval,n=this._extent,i=this._niceExtent,r=this._intervalPrecision,o=[];if(!e)return o;n[0]1e4)return[];var s=o.length?o[o.length-1].value:i[1];return n[1]>s&&(t?o.push({value:yx(s+e,r)}):o.push({value:n[1]})),o},e.prototype.getMinorTicks=function(t){for(var e=this.getTicks(!0),n=[],i=this.getExtent(),r=1;ri[0]&&h0&&(o=null===o?s:Math.min(o,s))}n[i]=o}}return n}(t),n=[];return E(t,(function(t){var i,r=t.coordinateSystem.getBaseAxis(),o=r.getExtent();if("category"===r.type)i=r.getBandWidth();else if("value"===r.type||"time"===r.type){var a=r.dim+"_"+r.index,s=e[a],l=Math.abs(o[1]-o[0]),u=r.scale.getExtent(),h=Math.abs(u[1]-u[0]);i=s?l/h*s:l}else{var c=t.getData();i=Math.abs(o[1]-o[0])/c.count()}var p=Er(t.get("barWidth"),i),d=Er(t.get("barMaxWidth"),i),f=Er(t.get("barMinWidth")||(Lx(t)?.5:1),i),g=t.get("barGap"),y=t.get("barCategoryGap");n.push({bandWidth:i,barWidth:p,barMaxWidth:d,barMinWidth:f,barGap:g,barCategoryGap:y,axisKey:Mx(r),stackId:Sx(t)})})),Cx(n)}function Cx(t){var e={};E(t,(function(t,n){var i=t.axisKey,r=t.bandWidth,o=e[i]||{bandWidth:r,remainedWidth:r,autoWidthCount:0,categoryGap:null,gap:"20%",stacks:{}},a=o.stacks;e[i]=o;var s=t.stackId;a[s]||o.autoWidthCount++,a[s]=a[s]||{width:0,maxWidth:0};var l=t.barWidth;l&&!a[s].width&&(a[s].width=l,l=Math.min(o.remainedWidth,l),o.remainedWidth-=l);var u=t.barMaxWidth;u&&(a[s].maxWidth=u);var h=t.barMinWidth;h&&(a[s].minWidth=h);var c=t.barGap;null!=c&&(o.gap=c);var p=t.barCategoryGap;null!=p&&(o.categoryGap=p)}));var n={};return E(e,(function(t,e){n[e]={};var i=t.stacks,r=t.bandWidth,o=t.categoryGap;if(null==o){var a=G(i).length;o=Math.max(35-4*a,15)+"%"}var s=Er(o,r),l=Er(t.gap,1),u=t.remainedWidth,h=t.autoWidthCount,c=(u-s)/(h+(h-1)*l);c=Math.max(c,0),E(i,(function(t){var e=t.maxWidth,n=t.minWidth;if(t.width){i=t.width;e&&(i=Math.min(i,e)),n&&(i=Math.max(i,n)),t.width=i,u-=i+l*i,h--}else{var i=c;e&&ei&&(i=n),i!==c&&(t.width=i,u-=i+l*i,h--)}})),c=(u-s)/(h+(h-1)*l),c=Math.max(c,0);var p,d=0;E(i,(function(t,e){t.width||(t.width=c),p=t,d+=t.width*(1+l)})),p&&(d-=p.width*l);var f=-d/2;E(i,(function(t,i){n[e][i]=n[e][i]||{bandWidth:r,offset:f,width:t.width},f+=t.width*(1+l)}))})),n}function Dx(t,e){var n=Ix(t,e),i=Tx(n);E(n,(function(t){var e=t.getData(),n=t.coordinateSystem.getBaseAxis(),r=Sx(t),o=i[Mx(n)][r],a=o.offset,s=o.width;e.setLayout({bandWidth:o.bandWidth,offset:a,size:s})}))}function Ax(t){return{seriesType:t,plan:gg(),reset:function(t){if(kx(t)){var e=t.getData(),n=t.coordinateSystem,i=n.getBaseAxis(),r=n.getOtherAxis(i),o=e.getDimensionIndex(e.mapDimension(r.dim)),a=e.getDimensionIndex(e.mapDimension(i.dim)),s=t.get("showBackground",!0),l=e.mapDimension(r.dim),u=e.getCalculationInfo("stackResultDimension"),h=tx(e,l)&&!!e.getCalculationInfo("stackedOnSeries"),c=r.isHorizontal(),p=function(t,e){return e.toGlobalCoord(e.dataToCoord("log"===e.type?1:0))}(0,r),d=Lx(t),f=t.get("barMinHeight")||0,g=u&&e.getDimensionIndex(u),y=e.getLayout("size"),v=e.getLayout("offset");return{progress:function(t,e){for(var i,r=t.count,l=d&&_x(3*r),u=d&&s&&_x(3*r),m=d&&_x(r),x=n.master.getRect(),_=c?x.width:x.height,b=e.getStore(),w=0;null!=(i=t.next());){var S=b.get(h?g:o,i),M=b.get(a,i),I=p,T=void 0;h&&(T=+S-b.get(o,i));var C=void 0,D=void 0,A=void 0,k=void 0;if(c){var L=n.dataToPoint([S,M]);if(h)I=n.dataToPoint([T,M])[0];C=I,D=L[1]+v,A=L[0]-I,k=y,Math.abs(A)0)for(var s=0;s=0;--s)if(l[u]){o=l[u];break}o=o||a.none}if(Y(o)){var h=null==t.level?0:t.level>=0?t.level:o.length+t.level;o=o[h=Math.min(h,o.length-1)]}}return zc(new Date(t.value),o,r,i)}(t,e,n,this.getSetting("locale"),i)},e.prototype.getTicks=function(){var t=this._interval,e=this._extent,n=[];if(!t)return n;n.push({value:e[0],level:0});var i=this.getSetting("useUTC"),r=function(t,e,n,i){var r=1e4,o=Oc,a=0;function s(t,e,n,r,o,a,s){for(var l=new Date(e),u=e,h=l[r]();u1&&0===u&&o.unshift({value:o[0].value-p})}}for(u=0;u=i[0]&&v<=i[1]&&c++)}var m=(i[1]-i[0])/e;if(c>1.5*m&&p>m/1.5)break;if(u.push(g),c>m||t===o[d])break}h=[]}}0;var x=B(z(u,(function(t){return B(t,(function(t){return t.value>=i[0]&&t.value<=i[1]&&!t.notAdd}))})),(function(t){return t.length>0})),_=[],b=x.length-1;for(d=0;dn&&(this._approxInterval=n);var o=Ox.length,a=Math.min(function(t,e,n,i){for(;n>>1;t[r][1]16?16:t>7.5?7:t>3.5?4:t>1.5?2:1}function Nx(t){return(t/=2592e6)>6?6:t>3?3:t>2?2:1}function Ex(t){return(t/=Tc)>12?12:t>6?6:t>3.5?4:t>2?2:1}function zx(t,e){return(t/=e?Ic:Mc)>30?30:t>20?20:t>15?15:t>10?10:t>5?5:t>2?2:1}function Vx(t){return $r(t,!0)}function Bx(t,e,n){var i=new Date(t);switch(Nc(e)){case"year":case"month":i[jc(n)](0);case"day":i[qc(n)](1);case"hour":i[Kc(n)](0);case"minute":i[$c(n)](0);case"second":i[Jc(n)](0),i[Qc(n)](0)}return i.getTime()}ix.registerClass(Px);var Fx=ix.prototype,Gx=vx.prototype,Wx=zr,Hx=Math.floor,Yx=Math.ceil,Ux=Math.pow,Xx=Math.log,Zx=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="log",e.base=10,e._originalScale=new vx,e._interval=0,e}return n(e,t),e.prototype.getTicks=function(t){var e=this._originalScale,n=this._extent,i=e.getExtent();return z(Gx.getTicks.call(this,t),(function(t){var e=t.value,r=zr(Ux(this.base,e));return r=e===n[0]&&this._fixMin?qx(r,i[0]):r,{value:r=e===n[1]&&this._fixMax?qx(r,i[1]):r}}),this)},e.prototype.setExtent=function(t,e){var n=this.base;t=Xx(t)/Xx(n),e=Xx(e)/Xx(n),Gx.setExtent.call(this,t,e)},e.prototype.getExtent=function(){var t=this.base,e=Fx.getExtent.call(this);e[0]=Ux(t,e[0]),e[1]=Ux(t,e[1]);var n=this._originalScale.getExtent();return this._fixMin&&(e[0]=qx(e[0],n[0])),this._fixMax&&(e[1]=qx(e[1],n[1])),e},e.prototype.unionExtent=function(t){this._originalScale.unionExtent(t);var e=this.base;t[0]=Xx(t[0])/Xx(e),t[1]=Xx(t[1])/Xx(e),Fx.unionExtent.call(this,t)},e.prototype.unionExtentFromData=function(t,e){this.unionExtent(t.getApproximateExtent(e))},e.prototype.calcNiceTicks=function(t){t=t||10;var e=this._extent,n=e[1]-e[0];if(!(n===1/0||n<=0)){var i=qr(n);for(t/n*i<=.5&&(i*=10);!isNaN(i)&&Math.abs(i)<1&&Math.abs(i)>0;)i*=10;var r=[zr(Yx(e[0]/i)*i),zr(Hx(e[1]/i)*i)];this._interval=i,this._niceExtent=r}},e.prototype.calcNiceExtent=function(t){Gx.calcNiceExtent.call(this,t),this._fixMin=t.fixMin,this._fixMax=t.fixMax},e.prototype.parse=function(t){return t},e.prototype.contain=function(t){return px(t=Xx(t)/Xx(this.base),this._extent)},e.prototype.normalize=function(t){return dx(t=Xx(t)/Xx(this.base),this._extent)},e.prototype.scale=function(t){return t=fx(t,this._extent),Ux(this.base,t)},e.type="log",e}(ix),jx=Zx.prototype;function qx(t,e){return Wx(t,Br(e))}jx.getMinorTicks=Gx.getMinorTicks,jx.getLabel=Gx.getLabel,ix.registerClass(Zx);var Kx=function(){function t(t,e,n){this._prepareParams(t,e,n)}return t.prototype._prepareParams=function(t,e,n){n[1]0&&s>0&&!l&&(a=0),a<0&&s<0&&!u&&(s=0));var c=this._determinedMin,p=this._determinedMax;return null!=c&&(a=c,l=!0),null!=p&&(s=p,u=!0),{min:a,max:s,minFixed:l,maxFixed:u,isBlank:h}},t.prototype.modifyDataMinMax=function(t,e){this[Jx[t]]=e},t.prototype.setDeterminedMinMax=function(t,e){var n=$x[t];this[n]=e},t.prototype.freeze=function(){this.frozen=!0},t}(),$x={min:"_determinedMin",max:"_determinedMax"},Jx={min:"_dataMin",max:"_dataMax"};function Qx(t,e,n){var i=t.rawExtentInfo;return i||(i=new Kx(t,e,n),t.rawExtentInfo=i,i)}function t_(t,e){return null==e?null:nt(e)?NaN:t.parse(e)}function e_(t,e){var n=t.type,i=Qx(t,e,t.getExtent()).calculate();t.setBlank(i.isBlank);var r=i.min,o=i.max,a=e.ecModel;if(a&&"time"===n){var s=Ix("bar",a),l=!1;if(E(s,(function(t){l=l||t.getBaseAxis()===e.axis})),l){var u=Tx(s),h=function(t,e,n,i){var r=n.axis.getExtent(),o=r[1]-r[0],a=function(t,e,n){if(t&&e){var i=t[Mx(e)];return null!=i&&null!=n?i[Sx(n)]:i}}(i,n.axis);if(void 0===a)return{min:t,max:e};var s=1/0;E(a,(function(t){s=Math.min(t.offset,s)}));var l=-1/0;E(a,(function(t){l=Math.max(t.offset+t.width,l)})),s=Math.abs(s),l=Math.abs(l);var u=s+l,h=e-t,c=h/(1-(s+l)/o)-h;return{min:t-=c*(s/u),max:e+=c*(l/u)}}(r,o,e,u);r=h.min,o=h.max}}return{extent:[r,o],fixMin:i.minFixed,fixMax:i.maxFixed}}function n_(t,e){var n=e,i=e_(t,n),r=i.extent,o=n.get("splitNumber");t instanceof Zx&&(t.base=n.get("logBase"));var a=t.type,s=n.get("interval"),l="interval"===a||"time"===a;t.setExtent(r[0],r[1]),t.calcNiceExtent({splitNumber:o,fixMin:i.fixMin,fixMax:i.fixMax,minInterval:l?n.get("minInterval"):null,maxInterval:l?n.get("maxInterval"):null}),null!=s&&t.setInterval&&t.setInterval(s)}function i_(t,e){if(e=e||t.get("type"))switch(e){case"category":return new gx({ordinalMeta:t.getOrdinalMeta?t.getOrdinalMeta():t.getCategories(),extent:[1/0,-1/0]});case"time":return new Px({locale:t.ecModel.getLocaleModel(),useUTC:t.ecModel.get("useUTC")});default:return new(ix.getClass(e)||vx)}}function r_(t){var e,n,i=t.getLabelModel().get("formatter"),r="category"===t.type?t.scale.getExtent()[0]:null;return"time"===t.scale.type?(n=i,function(e,i){return t.scale.getFormattedLabel(e,i,n)}):X(i)?function(e){return function(n){var i=t.scale.getLabel(n);return e.replace("{value}",null!=i?i:"")}}(i):U(i)?(e=i,function(n,i){return null!=r&&(i=n.value-r),e(o_(t,n),i,null!=n.level?{level:n.level}:null)}):function(e){return t.scale.getLabel(e)}}function o_(t,e){return"category"===t.type?t.scale.getLabel(e):e.value}function a_(t,e){var n=e*Math.PI/180,i=t.width,r=t.height,o=i*Math.abs(Math.cos(n))+Math.abs(r*Math.sin(n)),a=i*Math.abs(Math.sin(n))+Math.abs(r*Math.cos(n));return new sr(t.x,t.y,o,a)}function s_(t){var e=t.get("interval");return null==e?"auto":e}function l_(t){return"category"===t.type&&0===s_(t.getLabelModel())}function u_(t,e){var n={};return E(t.mapDimensionsAll(e),(function(e){n[ex(t,e)]=!0})),G(n)}var h_=function(){function t(){}return t.prototype.getNeedCrossZero=function(){return!this.option.scale},t.prototype.getCoordSysModel=function(){},t}();var c_={isDimensionStacked:tx,enableDataStack:Qm,getStackedDimension:ex};var p_=Object.freeze({__proto__:null,createList:function(t){return nx(null,t)},getLayoutRect:mp,dataStack:c_,createScale:function(t,e){var n=e;e instanceof pc||(n=new pc(e));var i=i_(n);return i.setExtent(t[0],t[1]),n_(i,n),i},mixinAxisModelCommonMethods:function(t){R(t,h_)},getECData:Ws,createTextStyle:function(t,e){return Yh(t,null,null,"normal"!==(e=e||{}).state)},createDimensions:function(t,e){return jm(t,e).dimensions},createSymbol:ky,enableHoverEmphasis:Pl});function d_(t,e){return Math.abs(t-e)<1e-8}function f_(t,e,n){var i=0,r=t[0];if(!r)return!1;for(var o=1;on&&(t=r,n=a)}if(t)return function(t){for(var e=0,n=0,i=0,r=t.length,o=t[r-1][0],a=t[r-1][1],s=0;s>1^-(1&s),l=l>>1^-(1&l),r=s+=r,o=l+=o,i.push([s/n,l/n])}return i}function I_(t,e){return z(B((t=function(t){if(!t.UTF8Encoding)return t;var e=t,n=e.UTF8Scale;return null==n&&(n=1024),E(e.features,(function(t){var e=t.geometry,i=e.encodeOffsets,r=e.coordinates;if(i)switch(e.type){case"LineString":e.coordinates=M_(r,i,n);break;case"Polygon":case"MultiLineString":S_(r,i,n);break;case"MultiPolygon":E(r,(function(t,e){return S_(t,i[e],n)}))}})),e.UTF8Encoding=!1,e}(t)).features,(function(t){return t.geometry&&t.properties&&t.geometry.coordinates.length>0})),(function(t){var n=t.properties,i=t.geometry,r=[];switch(i.type){case"Polygon":var o=i.coordinates;r.push(new x_(o[0],o.slice(1)));break;case"MultiPolygon":E(i.coordinates,(function(t){t[0]&&r.push(new x_(t[0],t.slice(1)))}));break;case"LineString":r.push(new __([i.coordinates]));break;case"MultiLineString":r.push(new __(i.coordinates))}var a=new b_(n[e||"name"],r,n.cp);return a.properties=n,a}))}var T_=Object.freeze({__proto__:null,linearMap:Nr,round:zr,asc:Vr,getPrecision:Br,getPrecisionSafe:Fr,getPixelPrecision:Gr,getPercentWithPrecision:Wr,MAX_SAFE_INTEGER:Yr,remRadian:Ur,isRadianAroundZero:Xr,parseDate:jr,quantity:qr,quantityExponent:Kr,nice:$r,quantile:Jr,reformIntervals:Qr,isNumeric:eo,numericToNumber:to}),C_=Object.freeze({__proto__:null,parse:jr,format:zc}),D_=Object.freeze({__proto__:null,extendShape:dh,extendPath:gh,makePath:mh,makeImage:xh,mergePath:bh,resizePath:wh,createIcon:Lh,updateProps:ih,initProps:rh,getTransform:Mh,clipPointsByRect:Ah,clipRectByRect:kh,registerShape:yh,getShapeClass:vh,Group:Cr,Image:xs,Text:As,Circle:uu,Ellipse:cu,Sector:Tu,Ring:Du,Polygon:Lu,Polyline:Ou,Rect:Ts,Line:Eu,BezierCurve:Fu,Arc:Wu,IncrementalDisplayable:Qu,CompoundPath:Hu,LinearGradient:Uu,RadialGradient:Xu,BoundingRect:sr}),A_=Object.freeze({__proto__:null,addCommas:tp,toCamelCase:ep,normalizeCssArray:np,encodeHTML:op,formatTpl:up,getTooltipMarker:hp,formatTime:function(t,e,n){"week"!==t&&"month"!==t&&"quarter"!==t&&"half-year"!==t&&"year"!==t||(t="MM-dd\nyyyy");var i=jr(e),r=n?"getUTC":"get",o=i[r+"FullYear"](),a=i[r+"Month"]()+1,s=i[r+"Date"](),l=i[r+"Hours"](),u=i[r+"Minutes"](),h=i[r+"Seconds"](),c=i[r+"Milliseconds"]();return t=t.replace("MM",Rc(a,2)).replace("M",a).replace("yyyy",o).replace("yy",o%100+"").replace("dd",Rc(s,2)).replace("d",s).replace("hh",Rc(l,2)).replace("h",l).replace("mm",Rc(u,2)).replace("m",u).replace("ss",Rc(h,2)).replace("s",h).replace("SSS",Rc(c,3))},capitalFirst:function(t){return t?t.charAt(0).toUpperCase()+t.substr(1):t},truncateText:$o,getTextRect:function(t,e,n,i,r,o,a,s){return new As({style:{text:t,font:e,align:n,verticalAlign:i,padding:r,rich:o,overflow:a?"truncate":null,lineHeight:s}}).getBoundingRect()}}),k_=Object.freeze({__proto__:null,map:z,each:E,indexOf:P,inherits:O,reduce:V,filter:B,bind:W,curry:H,isArray:Y,isString:X,isObject:q,isFunction:U,extend:A,defaults:k,clone:T,merge:C}),L_=So();function P_(t){return"category"===t.type?function(t){var e=t.getLabelModel(),n=R_(t,e);return!e.get("show")||t.scale.isBlank()?{labels:[],labelCategoryInterval:n.labelCategoryInterval}:n}(t):function(t){var e=t.scale.getTicks(),n=r_(t);return{labels:z(e,(function(e,i){return{level:e.level,formattedLabel:n(e,i),rawLabel:t.scale.getLabel(e),tickValue:e.value}}))}}(t)}function O_(t,e){return"category"===t.type?function(t,e){var n,i,r=N_(t,"ticks"),o=s_(e),a=E_(r,o);if(a)return a;e.get("show")&&!t.scale.isBlank()||(n=[]);if(U(o))n=B_(t,o,!0);else if("auto"===o){var s=R_(t,t.getLabelModel());i=s.labelCategoryInterval,n=z(s.labels,(function(t){return t.tickValue}))}else n=V_(t,i=o,!0);return z_(r,o,{ticks:n,tickCategoryInterval:i})}(t,e):{ticks:z(t.scale.getTicks(),(function(t){return t.value}))}}function R_(t,e){var n,i,r=N_(t,"labels"),o=s_(e),a=E_(r,o);return a||(U(o)?n=B_(t,o):(i="auto"===o?function(t){var e=L_(t).autoInterval;return null!=e?e:L_(t).autoInterval=t.calculateCategoryInterval()}(t):o,n=V_(t,i)),z_(r,o,{labels:n,labelCategoryInterval:i}))}function N_(t,e){return L_(t)[e]||(L_(t)[e]=[])}function E_(t,e){for(var n=0;n1&&h/l>2&&(u=Math.round(Math.ceil(u/l)*l));var c=l_(t),p=a.get("showMinLabel")||c,d=a.get("showMaxLabel")||c;p&&u!==o[0]&&g(o[0]);for(var f=u;f<=o[1];f+=l)g(f);function g(t){var e={value:t};s.push(n?t:{formattedLabel:i(e),rawLabel:r.getLabel(e),tickValue:t})}return d&&f-l!==o[1]&&g(o[1]),s}function B_(t,e,n){var i=t.scale,r=r_(t),o=[];return E(i.getTicks(),(function(t){var a=i.getLabel(t),s=t.value;e(t.value,a)&&o.push(n?s:{formattedLabel:r(t),rawLabel:a,tickValue:s})})),o}var F_=[0,1],G_=function(){function t(t,e,n){this.onBand=!1,this.inverse=!1,this.dim=t,this.scale=e,this._extent=n||[0,0]}return t.prototype.contain=function(t){var e=this._extent,n=Math.min(e[0],e[1]),i=Math.max(e[0],e[1]);return t>=n&&t<=i},t.prototype.containData=function(t){return this.scale.contain(t)},t.prototype.getExtent=function(){return this._extent.slice()},t.prototype.getPixelPrecision=function(t){return Gr(t||this.scale.getExtent(),this._extent)},t.prototype.setExtent=function(t,e){var n=this._extent;n[0]=t,n[1]=e},t.prototype.dataToCoord=function(t,e){var n=this._extent,i=this.scale;return t=i.normalize(t),this.onBand&&"ordinal"===i.type&&W_(n=n.slice(),i.count()),Nr(t,F_,n,e)},t.prototype.coordToData=function(t,e){var n=this._extent,i=this.scale;this.onBand&&"ordinal"===i.type&&W_(n=n.slice(),i.count());var r=Nr(t,n,F_,e);return this.scale.scale(r)},t.prototype.pointToData=function(t,e){},t.prototype.getTicksCoords=function(t){var e=(t=t||{}).tickModel||this.getTickModel(),n=z(O_(this,e).ticks,(function(t){return{coord:this.dataToCoord("ordinal"===this.scale.type?this.scale.getRawOrdinalNumber(t):t),tickValue:t}}),this);return function(t,e,n,i){var r=e.length;if(!t.onBand||n||!r)return;var o,a,s=t.getExtent();if(1===r)e[0].coord=s[0],o=e[1]={coord:s[0]};else{var l=e[r-1].tickValue-e[0].tickValue,u=(e[r-1].coord-e[0].coord)/l;E(e,(function(t){t.coord-=u/2})),a=1+t.scale.getExtent()[1]-e[r-1].tickValue,o={coord:e[r-1].coord+u*a},e.push(o)}var h=s[0]>s[1];c(e[0].coord,s[0])&&(i?e[0].coord=s[0]:e.shift());i&&c(s[0],e[0].coord)&&e.unshift({coord:s[0]});c(s[1],o.coord)&&(i?o.coord=s[1]:e.pop());i&&c(o.coord,s[1])&&e.push({coord:s[1]});function c(t,e){return t=zr(t),e=zr(e),h?t>e:t0&&t<100||(t=5),z(this.scale.getMinorTicks(t),(function(t){return z(t,(function(t){return{coord:this.dataToCoord(t),tickValue:t}}),this)}),this)},t.prototype.getViewLabels=function(){return P_(this).labels},t.prototype.getLabelModel=function(){return this.model.getModel("axisLabel")},t.prototype.getTickModel=function(){return this.model.getModel("axisTick")},t.prototype.getBandWidth=function(){var t=this._extent,e=this.scale.getExtent(),n=e[1]-e[0]+(this.onBand?1:0);0===n&&(n=1);var i=Math.abs(t[1]-t[0]);return Math.abs(i)/n},t.prototype.calculateCategoryInterval=function(){return function(t){var e=function(t){var e=t.getLabelModel();return{axisRotate:t.getRotate?t.getRotate():t.isHorizontal&&!t.isHorizontal()?90:0,labelRotate:e.get("rotate")||0,font:e.getFont()}}(t),n=r_(t),i=(e.axisRotate-e.labelRotate)/180*Math.PI,r=t.scale,o=r.getExtent(),a=r.count();if(o[1]-o[0]<1)return 0;var s=1;a>40&&(s=Math.max(1,Math.floor(a/40)));for(var l=o[0],u=t.dataToCoord(l+1)-t.dataToCoord(l),h=Math.abs(u*Math.cos(i)),c=Math.abs(u*Math.sin(i)),p=0,d=0;l<=o[1];l+=s){var f,g,y=cr(n({value:l}),e.font,"center","top");f=1.3*y.width,g=1.3*y.height,p=Math.max(p,f,7),d=Math.max(d,g,7)}var v=p/h,m=d/c;isNaN(v)&&(v=1/0),isNaN(m)&&(m=1/0);var x=Math.max(0,Math.floor(Math.min(v,m))),_=L_(t.model),b=t.getExtent(),w=_.lastAutoInterval,S=_.lastTickCount;return null!=w&&null!=S&&Math.abs(w-x)<=1&&Math.abs(S-a)<=1&&w>x&&_.axisExtent0===b[0]&&_.axisExtent1===b[1]?x=w:(_.lastTickCount=a,_.lastAutoInterval=x,_.axisExtent0=b[0],_.axisExtent1=b[1]),x}(this)},t}();function W_(t,e){var n=(t[1]-t[0])/e/2;t[0]+=n,t[1]-=n}var H_=2*Math.PI,Y_=ja.CMD,U_=["top","right","bottom","left"];function X_(t,e,n,i,r){var o=n.width,a=n.height;switch(t){case"top":i.set(n.x+o/2,n.y-e),r.set(0,-1);break;case"bottom":i.set(n.x+o/2,n.y+a+e),r.set(0,1);break;case"left":i.set(n.x-e,n.y+a/2),r.set(-1,0);break;case"right":i.set(n.x+o+e,n.y+a/2),r.set(1,0)}}function Z_(t,e,n,i,r,o,a,s,l){a-=t,s-=e;var u=Math.sqrt(a*a+s*s),h=(a/=u)*n+t,c=(s/=u)*n+e;if(Math.abs(i-r)%H_<1e-4)return l[0]=h,l[1]=c,u-n;if(o){var p=i;i=Qa(r),r=Qa(p)}else i=Qa(i),r=Qa(r);i>r&&(r+=H_);var d=Math.atan2(s,a);if(d<0&&(d+=H_),d>=i&&d<=r||d+H_>=i&&d+H_<=r)return l[0]=h,l[1]=c,u-n;var f=n*Math.cos(i)+t,g=n*Math.sin(i)+e,y=n*Math.cos(r)+t,v=n*Math.sin(r)+e,m=(f-a)*(f-a)+(g-s)*(g-s),x=(y-a)*(y-a)+(v-s)*(v-s);return m0){e=e/180*Math.PI,Q_.fromArray(t[0]),tb.fromArray(t[1]),eb.fromArray(t[2]),Ji.sub(nb,Q_,tb),Ji.sub(ib,eb,tb);var n=nb.len(),i=ib.len();if(!(n<.001||i<.001)){nb.scale(1/n),ib.scale(1/i);var r=nb.dot(ib);if(Math.cos(e)1&&Ji.copy(ab,eb),ab.toArray(t[1])}}}}function lb(t,e,n){if(n<=180&&n>0){n=n/180*Math.PI,Q_.fromArray(t[0]),tb.fromArray(t[1]),eb.fromArray(t[2]),Ji.sub(nb,tb,Q_),Ji.sub(ib,eb,tb);var i=nb.len(),r=ib.len();if(!(i<.001||r<.001))if(nb.scale(1/i),ib.scale(1/r),nb.dot(e)=a)Ji.copy(ab,eb);else{ab.scaleAndAdd(ib,o/Math.tan(Math.PI/2-s));var l=eb.x!==tb.x?(ab.x-tb.x)/(eb.x-tb.x):(ab.y-tb.y)/(eb.y-tb.y);if(isNaN(l))return;l<0?Ji.copy(ab,tb):l>1&&Ji.copy(ab,eb)}ab.toArray(t[1])}}}function ub(t,e,n,i){var r="normal"===n,o=r?t:t.ensureState(n);o.ignore=e;var a=i.get("smooth");a&&!0===a&&(a=.3),o.shape=o.shape||{},a>0&&(o.shape.smooth=a);var s=i.getModel("lineStyle").getLineStyle();r?t.useStyle(s):o.style=s}function hb(t,e){var n=e.smooth,i=e.points;if(i)if(t.moveTo(i[0][0],i[0][1]),n>0&&i.length>=3){var r=Et(i[0],i[1]),o=Et(i[1],i[2]);if(!r||!o)return t.lineTo(i[1][0],i[1][1]),void t.lineTo(i[2][0],i[2][1]);var a=Math.min(r,o)*n,s=Bt([],i[1],i[0],a/r),l=Bt([],i[1],i[2],a/o),u=Bt([],s,l,.5);t.bezierCurveTo(s[0],s[1],s[0],s[1],u[0],u[1]),t.bezierCurveTo(l[0],l[1],l[0],l[1],i[2][0],i[2][1])}else for(var h=1;h0&&o&&_(-h/a,0,a);var f,g,y=t[0],v=t[a-1];return m(),f<0&&b(-f,.8),g<0&&b(g,.8),m(),x(f,g,1),x(g,f,-1),m(),f<0&&w(-f),g<0&&w(g),u}function m(){f=y.rect[e]-i,g=r-v.rect[e]-v.rect[n]}function x(t,e,n){if(t<0){var i=Math.min(e,-t);if(i>0){_(i*n,0,a);var r=i+t;r<0&&b(-r*n,1)}else b(-t*n,1)}}function _(n,i,r){0!==n&&(u=!0);for(var o=i;o0)for(l=0;l0;l--){_(-(o[l-1]*c),l,a)}}}function w(t){var e=t<0?-1:1;t=Math.abs(t);for(var n=Math.ceil(t/(a-1)),i=0;i0?_(n,0,i+1):_(-n,a-i-1,a),(t-=n)<=0)return}}function gb(t,e,n,i){return fb(t,"y","height",e,n,i)}function yb(t){var e=[];t.sort((function(t,e){return e.priority-t.priority}));var n=new sr(0,0,0,0);function i(t){if(!t.ignore){var e=t.ensureState("emphasis");null==e.ignore&&(e.ignore=!1)}t.ignore=!0}for(var r=0;r=0&&n.attr(d.oldLayoutSelect),P(u,"emphasis")>=0&&n.attr(d.oldLayoutEmphasis)),ih(n,s,e,a)}else if(n.attr(s),!$h(n).valueAnimation){var h=rt(n.style.opacity,1);n.style.opacity=0,rh(n,{style:{opacity:h}},e,a)}if(d.oldLayout=s,n.states.select){var c=d.oldLayoutSelect={};Sb(c,s,Mb),Sb(c,n.states.select,Mb)}if(n.states.emphasis){var p=d.oldLayoutEmphasis={};Sb(p,s,Mb),Sb(p,n.states.emphasis,Mb)}Qh(n,a,l,e,e)}if(i&&!i.ignore&&!i.invisible){r=(d=wb(i)).oldLayout;var d,f={points:i.shape.points};r?(i.attr({shape:r}),ih(i,{shape:f},e)):(i.setShape(f),i.style.strokePercent=0,rh(i,{style:{strokePercent:1}},e)),d.oldLayout=f}},t}(),Tb=So();var Cb=Math.sin,Db=Math.cos,Ab=Math.PI,kb=2*Math.PI,Lb=180/Ab,Pb=function(){function t(){}return t.prototype.reset=function(t){this._start=!0,this._d=[],this._str="",this._p=Math.pow(10,t||4)},t.prototype.moveTo=function(t,e){this._add("M",t,e)},t.prototype.lineTo=function(t,e){this._add("L",t,e)},t.prototype.bezierCurveTo=function(t,e,n,i,r,o){this._add("C",t,e,n,i,r,o)},t.prototype.quadraticCurveTo=function(t,e,n,i){this._add("Q",t,e,n,i)},t.prototype.arc=function(t,e,n,i,r,o){this.ellipse(t,e,n,n,0,i,r,o)},t.prototype.ellipse=function(t,e,n,i,r,o,a,s){var l=a-o,u=!s,h=Math.abs(l),c=En(h-kb)||(u?l>=kb:-l>=kb),p=l>0?l%kb:l%kb+kb,d=!1;d=!!c||!En(h)&&p>=Ab==!!u;var f=t+n*Db(o),g=e+i*Cb(o);this._start&&this._add("M",f,g);var y=Math.round(r*Lb);if(c){var v=1/this._p,m=(u?1:-1)*(kb-v);this._add("A",n,i,y,1,+u,t+n*Db(o+m),e+i*Cb(o+m)),v>.01&&this._add("A",n,i,y,0,+u,f,g)}else{var x=t+n*Db(a),_=e+i*Cb(a);this._add("A",n,i,y,+d,+u,x,_)}},t.prototype.rect=function(t,e,n,i){this._add("M",t,e),this._add("l",n,0),this._add("l",0,i),this._add("l",-n,0),this._add("Z")},t.prototype.closePath=function(){this._d.length>0&&this._add("Z")},t.prototype._add=function(t,e,n,i,r,o,a,s,l){for(var u=[],h=this._p,c=1;c"}(r,e.attrs)+(e.text||"")+(i?""+n+z(i,(function(e){return t(e)})).join(n)+n:"")+("")}(t)}function Hb(t){return{zrId:t,shadowCache:{},patternCache:{},gradientCache:{},clipPathCache:{},defs:{},cssNodes:{},cssAnims:{},cssClassIdx:0,cssAnimIdx:0,shadowIdx:0,gradientIdx:0,patternIdx:0,clipPathIdx:0}}function Yb(t,e,n,i){return Gb("svg","root",{width:t,height:e,xmlns:Vb,"xmlns:xlink":Bb,version:"1.1",baseProfile:"full",viewBox:!!i&&"0 0 "+t+" "+e},n)}var Ub={cubicIn:"0.32,0,0.67,0",cubicOut:"0.33,1,0.68,1",cubicInOut:"0.65,0,0.35,1",quadraticIn:"0.11,0,0.5,0",quadraticOut:"0.5,1,0.89,1",quadraticInOut:"0.45,0,0.55,1",quarticIn:"0.5,0,0.75,0",quarticOut:"0.25,1,0.5,1",quarticInOut:"0.76,0,0.24,1",quinticIn:"0.64,0,0.78,0",quinticOut:"0.22,1,0.36,1",quinticInOut:"0.83,0,0.17,1",sinusoidalIn:"0.12,0,0.39,0",sinusoidalOut:"0.61,1,0.88,1",sinusoidalInOut:"0.37,0,0.63,1",exponentialIn:"0.7,0,0.84,0",exponentialOut:"0.16,1,0.3,1",exponentialInOut:"0.87,0,0.13,1",circularIn:"0.55,0,1,0.45",circularOut:"0,0.55,0.45,1",circularInOut:"0.85,0,0.15,1"},Xb="transform-origin";function Zb(t,e,n){var i=A({},t.shape);A(i,e),t.buildPath(n,i);var r=new Pb;return r.reset(Yn(t)),n.rebuildPath(r,1),r.generateStr(),r.getStr()}function jb(t,e){var n=e.originX,i=e.originY;(n||i)&&(t[Xb]=n+"px "+i+"px")}var qb={fill:"fill",opacity:"opacity",lineWidth:"stroke-width",lineDashOffset:"stroke-dashoffset"};function Kb(t,e){var n=e.zrId+"-ani-"+e.cssAnimIdx++;return e.cssAnims[n]=t,n}function $b(t){return X(t)?Ub[t]?"cubic-bezier("+Ub[t]+")":rn(t)?t:"":""}function Jb(t,e,n,i){var r=t.animators,o=r.length,a=[];if(t instanceof Hu){if(y=function(t,e,n){var i,r,o=t.shape.paths,a={};if(E(o,(function(t){var e=Hb(n.zrId);e.animation=!0,Jb(t,{},e,!0);var o=e.cssAnims,s=e.cssNodes,l=G(o),u=l.length;if(u){var h=o[r=l[u-1]];for(var c in h){var p=h[c];a[c]=a[c]||{d:""},a[c].d+=p.d||""}for(var d in s){var f=s[d].animation;f.indexOf(r)>=0&&(i=f)}}})),i){e.d=!1;var s=Kb(a,n);return i.replace(r,s)}}(t,e,n))a.push(y);else if(!o)return}else if(!o)return;for(var s={},l=0;l0})).length)return Kb(h,n)+" "+r[0]+" both"}for(var g in s){var y;(y=f(s[g]))&&a.push(y)}if(a.length){var v=n.zrId+"-cls-"+n.cssClassIdx++;n.cssNodes["."+v]={animation:a.join(",")},e.class=v}}var Qb=Math.round;function tw(t){return t&&X(t.src)}function ew(t){return t&&U(t.toDataURL)}function nw(t,e,n,i){zb((function(r,o){var a="fill"===r||"stroke"===r;a&&function(t){return t&&("linear"===t.type||"radial"===t.type)}(o)?function(t,e,n,i){var r,o=t[n],a={gradientUnits:o.global?"userSpaceOnUse":"objectBoundingBox"};if(Gn(o))r="linearGradient",a.x1=o.x,a.y1=o.y,a.x2=o.x2,a.y2=o.y2;else{if(!Wn(o))return void 0;r="radialGradient",a.cx=rt(o.x,.5),a.cy=rt(o.y,.5),a.r=rt(o.r,.5)}for(var s=o.colorStops,l=[],u=0,h=s.length;ul?Tw(t,null==n[c+1]?null:n[c+1].elm,n,s,c):Cw(t,e,a,l))}(n,i,r):ww(r)?(ww(t.text)&&xw(n,""),Tw(n,null,r,0,r.length-1)):ww(i)?Cw(n,i,0,i.length-1):ww(t.text)&&xw(n,""):t.text!==e.text&&(ww(i)&&Cw(n,i,0,i.length-1),xw(n,e.text)))}var kw=0,Lw=function(){function t(t,e,n){if(this.type="svg",this.refreshHover=Pw("refreshHover"),this.configLayer=Pw("configLayer"),this.storage=e,this._opts=n=A({},n),this.root=t,this._id="zr"+kw++,this._oldVNode=Yb(n.width,n.height),t&&!n.ssr){var i=this._viewport=document.createElement("div");i.style.cssText="position:relative;overflow:hidden";var r=this._svgDom=this._oldVNode.elm=Fb("svg");Dw(null,this._oldVNode),i.appendChild(r),t.appendChild(i)}this.resize(n.width,n.height)}return t.prototype.getType=function(){return this.type},t.prototype.getViewportRoot=function(){return this._viewport},t.prototype.getViewportRootOffset=function(){var t=this.getViewportRoot();if(t)return{offsetLeft:t.offsetLeft||0,offsetTop:t.offsetTop||0}},t.prototype.getSvgDom=function(){return this._svgDom},t.prototype.refresh=function(){if(this.root){var t=this.renderToVNode({willUpdate:!0});t.attrs.style="position:absolute;left:0;top:0;user-select:none",function(t,e){if(Mw(t,e))Aw(t,e);else{var n=t.elm,i=vw(n);Iw(e),null!==i&&(fw(i,e.elm,mw(n)),Cw(i,[t],0,0))}}(this._oldVNode,t),this._oldVNode=t}},t.prototype.renderOneToVNode=function(t){return cw(t,Hb(this._id))},t.prototype.renderToVNode=function(t){t=t||{};var e=this.storage.getDisplayList(!0),n=this._backgroundColor,i=this._width,r=this._height,o=Hb(this._id);o.animation=t.animation,o.willUpdate=t.willUpdate,o.compress=t.compress;var a=[];if(n&&"none"!==n){var s=Rn(n),l=s.color,u=s.opacity;this._bgVNode=Gb("rect","bg",{width:i,height:r,x:"0",y:"0",id:"0",fill:l,"fill-opacity":u}),a.push(this._bgVNode)}else this._bgVNode=null;var h=t.compress?null:this._mainVNode=Gb("g","main",{},[]);this._paintList(e,o,h?h.children:a),h&&a.push(h);var c=z(G(o.defs),(function(t){return o.defs[t]}));if(c.length&&a.push(Gb("defs","defs",{},c)),t.animation){var p=function(t,e,n){var i=(n=n||{}).newline?"\n":"",r=" {"+i,o=i+"}",a=z(G(t),(function(e){return e+r+z(G(t[e]),(function(n){return n+":"+t[e][n]+";"})).join(i)+o})).join(i),s=z(G(e),(function(t){return"@keyframes "+t+r+z(G(e[t]),(function(n){return n+r+z(G(e[t][n]),(function(i){var r=e[t][n][i];return"d"===i&&(r='path("'+r+'")'),i+":"+r+";"})).join(i)+o})).join(i)+o})).join(i);return a||s?[""].join(i):""}(o.cssNodes,o.cssAnims,{newline:!0});if(p){var d=Gb("style","stl",{},[],p);a.push(d)}}return Yb(i,r,a,t.useViewBox)},t.prototype.renderToString=function(t){return t=t||{},Wb(this.renderToVNode({animation:rt(t.cssAnimation,!0),willUpdate:!1,compress:!0,useViewBox:rt(t.useViewBox,!0)}),{newline:!0})},t.prototype.setBackgroundColor=function(t){this._backgroundColor=t;var e=this._bgVNode;if(e&&e.elm){var n=Rn(t),i=n.color,r=n.opacity;e.elm.setAttribute("fill",i),r<1&&e.elm.setAttribute("fill-opacity",r)}},t.prototype.getSvgRoot=function(){return this._mainVNode&&this._mainVNode.elm},t.prototype._paintList=function(t,e,n){for(var i,r,o=t.length,a=[],s=0,l=0,u=0;u=0&&(!c||!r||c[f]!==r[f]);f--);for(var g=d-1;g>f;g--)i=a[--s-1];for(var y=f+1;y=a)}}for(var h=this.__startIndex;h15)break}n.prevElClipPaths&&u.restore()};if(p)if(0===p.length)s=l.__endIndex;else for(var _=d.dpr,b=0;b0&&t>i[0]){for(s=0;st);s++);a=n[i[s]]}if(i.splice(s+1,0,t),n[t]=e,!e.virtual)if(a){var l=a.dom;l.nextSibling?o.insertBefore(e.dom,l.nextSibling):o.appendChild(e.dom)}else o.firstChild?o.insertBefore(e.dom,o.firstChild):o.appendChild(e.dom);e.__painter=this}},t.prototype.eachLayer=function(t,e){for(var n=this._zlevelList,i=0;i0?zw:0),this._needsManuallyCompositing),u.__builtin__||I("ZLevel "+l+" has been used by unkown layer "+u.id),u!==o&&(u.__used=!0,u.__startIndex!==r&&(u.__dirty=!0),u.__startIndex=r,u.incremental?u.__drawIndex=-1:u.__drawIndex=r,e(r),o=u),1&s.__dirty&&!s.__inHover&&(u.__dirty=!0,u.incremental&&u.__drawIndex<0&&(u.__drawIndex=r))}e(r),this.eachBuiltinLayer((function(t,e){!t.__used&&t.getElementCount()>0&&(t.__dirty=!0,t.__startIndex=t.__endIndex=t.__drawIndex=0),t.__dirty&&t.__drawIndex<0&&(t.__drawIndex=t.__startIndex)}))},t.prototype.clear=function(){return this.eachBuiltinLayer(this._clearLayer),this},t.prototype._clearLayer=function(t){t.clear()},t.prototype.setBackgroundColor=function(t){this._backgroundColor=t,E(this._layers,(function(t){t.setUnpainted()}))},t.prototype.configLayer=function(t,e){if(e){var n=this._layerConfig;n[t]?C(n[t],e,!0):n[t]=e;for(var i=0;i-1&&(s.style.stroke=s.style.fill,s.style.fill="#fff",s.style.lineWidth=2),e},e.type="series.line",e.dependencies=["grid","polar"],e.defaultOption={z:3,coordinateSystem:"cartesian2d",legendHoverLink:!0,clip:!0,label:{position:"top"},endLabel:{show:!1,valueAnimation:!0,distance:8},lineStyle:{width:2,type:"solid"},emphasis:{scale:!0},step:!1,smooth:!1,smoothMonotone:null,symbol:"emptyCircle",symbolSize:4,symbolRotate:null,showSymbol:!0,showAllSymbol:"auto",connectNulls:!1,sampling:"none",animationEasing:"linear",progressive:0,hoverLayerThreshold:1/0,universalTransition:{divideShape:"clone"},triggerLineEvent:!1},e}(ag);function Fw(t,e){var n=t.mapDimensionsAll("defaultedLabel"),i=n.length;if(1===i){var r=of(t,e,n[0]);return null!=r?r+"":null}if(i){for(var o=[],a=0;a=0&&i.push(e[o])}return i.join(" ")}var Ww=function(t){function e(e,n,i,r){var o=t.call(this)||this;return o.updateData(e,n,i,r),o}return n(e,t),e.prototype._createSymbol=function(t,e,n,i,r){this.removeAll();var o=ky(t,-1,-1,2,2,null,r);o.attr({z2:100,culling:!0,scaleX:i[0]/2,scaleY:i[1]/2}),o.drift=Hw,this._symbolType=t,this.add(o)},e.prototype.stopSymbolAnimation=function(t){this.childAt(0).stopAnimation(null,t)},e.prototype.getSymbolType=function(){return this._symbolType},e.prototype.getSymbolPath=function(){return this.childAt(0)},e.prototype.highlight=function(){xl(this.childAt(0))},e.prototype.downplay=function(){_l(this.childAt(0))},e.prototype.setZ=function(t,e){var n=this.childAt(0);n.zlevel=t,n.z=e},e.prototype.setDraggable=function(t){var e=this.childAt(0);e.draggable=t,e.cursor=t?"move":e.cursor},e.prototype.updateData=function(t,n,i,r){this.silent=!1;var o=t.getItemVisual(n,"symbol")||"circle",a=t.hostModel,s=e.getSymbolSize(t,n),l=o!==this._symbolType,u=r&&r.disableAnimation;if(l){var h=t.getItemVisual(n,"symbolKeepAspect");this._createSymbol(o,t,n,s,h)}else{(p=this.childAt(0)).silent=!1;var c={scaleX:s[0]/2,scaleY:s[1]/2};u?p.attr(c):ih(p,c,a,n),uh(p)}if(this._updateCommon(t,n,s,i,r),l){var p=this.childAt(0);if(!u){c={scaleX:this._sizeX,scaleY:this._sizeY,style:{opacity:p.style.opacity}};p.scaleX=p.scaleY=0,p.style.opacity=0,rh(p,c,a,n)}}u&&this.childAt(0).stopAnimation("leave")},e.prototype._updateCommon=function(t,e,n,i,r){var o,a,s,l,u,h,c,p,d,f=this.childAt(0),g=t.hostModel;if(i&&(o=i.emphasisItemStyle,a=i.blurItemStyle,s=i.selectItemStyle,l=i.focus,u=i.blurScope,c=i.labelStatesModels,p=i.hoverScale,d=i.cursorStyle,h=i.emphasisDisabled),!i||t.hasItemOption){var y=i&&i.itemModel?i.itemModel:t.getItemModel(e),v=y.getModel("emphasis");o=v.getModel("itemStyle").getItemStyle(),s=y.getModel(["select","itemStyle"]).getItemStyle(),a=y.getModel(["blur","itemStyle"]).getItemStyle(),l=v.get("focus"),u=v.get("blurScope"),h=v.get("disabled"),c=Hh(y),p=v.getShallow("scale"),d=y.getShallow("cursor")}var m=t.getItemVisual(e,"symbolRotate");f.attr("rotation",(m||0)*Math.PI/180||0);var x=Py(t.getItemVisual(e,"symbolOffset"),n);x&&(f.x=x[0],f.y=x[1]),d&&f.attr("cursor",d);var _=t.getItemVisual(e,"style"),b=_.fill;if(f instanceof xs){var w=f.style;f.useStyle(A({image:w.image,x:w.x,y:w.y,width:w.width,height:w.height},_))}else f.__isEmptyBrush?f.useStyle(A({},_)):f.useStyle(_),f.style.decal=null,f.setColor(b,r&&r.symbolInnerColor),f.style.strokeNoScale=!0;var S=t.getItemVisual(e,"liftZ"),M=this._z2;null!=S?null==M&&(this._z2=f.z2,f.z2+=S):null!=M&&(f.z2=M,this._z2=null);var I=r&&r.useNameLabel;Wh(f,c,{labelFetcher:g,labelDataIndex:e,defaultText:function(e){return I?t.getName(e):Fw(t,e)},inheritColor:b,defaultOpacity:_.opacity}),this._sizeX=n[0]/2,this._sizeY=n[1]/2;var T=f.ensureState("emphasis");if(T.style=o,f.ensureState("select").style=s,f.ensureState("blur").style=a,p){var C=Math.max(1.1,3/this._sizeY);T.scaleX=this._sizeX*C,T.scaleY=this._sizeY*C}this.setSymbolScale(1),Ol(this,l,u,h)},e.prototype.setSymbolScale=function(t){this.scaleX=this.scaleY=t},e.prototype.fadeOut=function(t,e,n){var i=this.childAt(0),r=Ws(this).dataIndex,o=n&&n.animation;if(this.silent=i.silent=!0,n&&n.fadeLabel){var a=i.getTextContent();a&&ah(a,{style:{opacity:0}},e,{dataIndex:r,removeOpt:o,cb:function(){i.removeTextContent()}})}else i.removeTextContent();ah(i,{style:{opacity:0},scaleX:0,scaleY:0},e,{dataIndex:r,cb:t,removeOpt:o})},e.getSymbolSize=function(t,e){return Ly(t.getItemVisual(e,"symbolSize"))},e}(Cr);function Hw(t,e){this.parent.drift(t,e)}function Yw(t,e,n,i){return e&&!isNaN(e[0])&&!isNaN(e[1])&&!(i.isIgnore&&i.isIgnore(n))&&!(i.clipShape&&!i.clipShape.contain(e[0],e[1]))&&"none"!==t.getItemVisual(n,"symbol")}function Uw(t){return null==t||q(t)||(t={isIgnore:t}),t||{}}function Xw(t){var e=t.hostModel,n=e.getModel("emphasis");return{emphasisItemStyle:n.getModel("itemStyle").getItemStyle(),blurItemStyle:e.getModel(["blur","itemStyle"]).getItemStyle(),selectItemStyle:e.getModel(["select","itemStyle"]).getItemStyle(),focus:n.get("focus"),blurScope:n.get("blurScope"),emphasisDisabled:n.get("disabled"),hoverScale:n.get("scale"),labelStatesModels:Hh(e),cursorStyle:e.get("cursor")}}var Zw=function(){function t(t){this.group=new Cr,this._SymbolCtor=t||Ww}return t.prototype.updateData=function(t,e){this._progressiveEls=null,e=Uw(e);var n=this.group,i=t.hostModel,r=this._data,o=this._SymbolCtor,a=e.disableAnimation,s=Xw(t),l={disableAnimation:a},u=e.getSymbolPoint||function(e){return t.getItemLayout(e)};r||n.removeAll(),t.diff(r).add((function(i){var r=u(i);if(Yw(t,r,i,e)){var a=new o(t,i,s,l);a.setPosition(r),t.setItemGraphicEl(i,a),n.add(a)}})).update((function(h,c){var p=r.getItemGraphicEl(c),d=u(h);if(Yw(t,d,h,e)){var f=t.getItemVisual(h,"symbol")||"circle",g=p&&p.getSymbolType&&p.getSymbolType();if(!p||g&&g!==f)n.remove(p),(p=new o(t,h,s,l)).setPosition(d);else{p.updateData(t,h,s,l);var y={x:d[0],y:d[1]};a?p.attr(y):ih(p,y,i)}n.add(p),t.setItemGraphicEl(h,p)}else n.remove(p)})).remove((function(t){var e=r.getItemGraphicEl(t);e&&e.fadeOut((function(){n.remove(e)}),i)})).execute(),this._getSymbolPoint=u,this._data=t},t.prototype.updateLayout=function(){var t=this,e=this._data;e&&e.eachItemGraphicEl((function(e,n){var i=t._getSymbolPoint(n);e.setPosition(i),e.markRedraw()}))},t.prototype.incrementalPrepareUpdate=function(t){this._seriesScope=Xw(t),this._data=null,this.group.removeAll()},t.prototype.incrementalUpdate=function(t,e,n){function i(t){t.isGroup||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}this._progressiveEls=[],n=Uw(n);for(var r=t.start;r0?n=i[0]:i[1]<0&&(n=i[1]);return n}(r,n),a=i.dim,s=r.dim,l=e.mapDimension(s),u=e.mapDimension(a),h="x"===s||"radius"===s?1:0,c=z(t.dimensions,(function(t){return e.mapDimension(t)})),p=!1,d=e.getCalculationInfo("stackResultDimension");return tx(e,c[0])&&(p=!0,c[0]=d),tx(e,c[1])&&(p=!0,c[1]=d),{dataDimsForPoint:c,valueStart:o,valueAxisDim:s,baseAxisDim:a,stacked:!!p,valueDim:l,baseDim:u,baseDataOffset:h,stackedOverDimension:e.getCalculationInfo("stackedOverDimension")}}function qw(t,e,n,i){var r=NaN;t.stacked&&(r=n.get(n.getCalculationInfo("stackedOverDimension"),i)),isNaN(r)&&(r=t.valueStart);var o=t.baseDataOffset,a=[];return a[o]=n.get(t.baseDim,i),a[1-o]=r,e.dataToPoint(a)}var Kw=Math.min,$w=Math.max;function Jw(t,e){return isNaN(t)||isNaN(e)}function Qw(t,e,n,i,r,o,a,s,l){for(var u,h,c,p,d,f,g=n,y=0;y=r||g<0)break;if(Jw(v,m)){if(l){g+=o;continue}break}if(g===n)t[o>0?"moveTo":"lineTo"](v,m),c=v,p=m;else{var x=v-u,_=m-h;if(x*x+_*_<.5){g+=o;continue}if(a>0){for(var b=g+o,w=e[2*b],S=e[2*b+1];w===v&&S===m&&y=i||Jw(w,S))d=v,f=m;else{T=w-u,C=S-h;var k=v-u,L=w-v,P=m-h,O=S-m,R=void 0,N=void 0;if("x"===s){var E=T>0?1:-1;d=v-E*(R=Math.abs(k))*a,f=m,D=v+E*(N=Math.abs(L))*a,A=m}else if("y"===s){var z=C>0?1:-1;d=v,f=m-z*(R=Math.abs(P))*a,D=v,A=m+z*(N=Math.abs(O))*a}else R=Math.sqrt(k*k+P*P),d=v-T*a*(1-(I=(N=Math.sqrt(L*L+O*O))/(N+R))),f=m-C*a*(1-I),A=m+C*a*I,D=Kw(D=v+T*a*I,$w(w,v)),A=Kw(A,$w(S,m)),D=$w(D,Kw(w,v)),f=m-(C=(A=$w(A,Kw(S,m)))-m)*R/N,d=Kw(d=v-(T=D-v)*R/N,$w(u,v)),f=Kw(f,$w(h,m)),D=v+(T=v-(d=$w(d,Kw(u,v))))*N/R,A=m+(C=m-(f=$w(f,Kw(h,m))))*N/R}t.bezierCurveTo(c,p,d,f,v,m),c=D,p=A}else t.lineTo(v,m)}u=v,h=m,g+=o}return y}var tS=function(){this.smooth=0,this.smoothConstraint=!0},eS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="ec-polyline",n}return n(e,t),e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new tS},e.prototype.buildPath=function(t,e){var n=e.points,i=0,r=n.length/2;if(e.connectNulls){for(;r>0&&Jw(n[2*r-2],n[2*r-1]);r--);for(;i=0){var y=a?(h-i)*g+i:(u-n)*g+n;return a?[t,y]:[y,t]}n=u,i=h;break;case o.C:u=r[l++],h=r[l++],c=r[l++],p=r[l++],d=r[l++],f=r[l++];var v=a?Ue(n,u,c,d,t,s):Ue(i,h,p,f,t,s);if(v>0)for(var m=0;m=0){y=a?He(i,h,p,f,x):He(n,u,c,d,x);return a?[t,y]:[y,t]}}n=d,i=f}}},e}(fs),nS=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e}(tS),iS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="ec-polygon",n}return n(e,t),e.prototype.getDefaultShape=function(){return new nS},e.prototype.buildPath=function(t,e){var n=e.points,i=e.stackedOnPoints,r=0,o=n.length/2,a=e.smoothMonotone;if(e.connectNulls){for(;o>0&&Jw(n[2*o-2],n[2*o-1]);o--);for(;r=0;a--){var s=t.getDimensionInfo(i[a].dimension);if("x"===(r=s&&s.coordDim)||"y"===r){o=i[a];break}}if(o){var l=e.getAxis(r),u=z(o.stops,(function(t){return{coord:l.toGlobalCoord(l.dataToCoord(t.value)),color:t.color}})),h=u.length,c=o.outerColors.slice();h&&u[0].coord>u[h-1].coord&&(u.reverse(),c.reverse());var p=function(t,e){var n,i,r=[],o=t.length;function a(t,e,n){var i=t.coord;return{coord:n,color:Tn((n-i)/(e.coord-i),[t.color,e.color])}}for(var s=0;se){i?r.push(a(i,l,e)):n&&r.push(a(n,l,0),a(n,l,e));break}n&&(r.push(a(n,l,0)),n=null),r.push(l),i=l}}return r}(u,"x"===r?n.getWidth():n.getHeight()),d=p.length;if(!d&&h)return u[0].coord<0?c[1]?c[1]:u[h-1].color:c[0]?c[0]:u[0].color;var f=p[0].coord-10,g=p[d-1].coord+10,y=g-f;if(y<.001)return"transparent";E(p,(function(t){t.offset=(t.coord-f)/y})),p.push({offset:d?p[d-1].offset:.5,color:c[1]||"transparent"}),p.unshift({offset:d?p[0].offset:.5,color:c[0]||"transparent"});var v=new Uu(0,0,0,0,p,!0);return v[r]=f,v[r+"2"]=g,v}}}function fS(t,e,n){var i=t.get("showAllSymbol"),r="auto"===i;if(!i||r){var o=n.getAxesByScale("ordinal")[0];if(o&&(!r||!function(t,e){var n=t.getExtent(),i=Math.abs(n[1]-n[0])/t.scale.count();isNaN(i)&&(i=0);for(var r=e.count(),o=Math.max(1,Math.round(r/5)),a=0;ai)return!1;return!0}(o,e))){var a=e.mapDimension(o.dim),s={};return E(o.getViewLabels(),(function(t){var e=o.scale.getRawOrdinalNumber(t.tickValue);s[e]=1})),function(t){return!s.hasOwnProperty(e.get(a,t))}}}}function gS(t,e){return[t[2*e],t[2*e+1]]}function yS(t){if(t.get(["endLabel","show"]))return!0;for(var e=0;e0&&"bolder"===t.get(["emphasis","lineStyle","width"]))&&(d.getState("emphasis").style.lineWidth=+d.style.lineWidth+1);Ws(d).seriesIndex=t.seriesIndex,Ol(d,L,P,O);var R=cS(t.get("smooth")),N=t.get("smoothMonotone");if(d.setShape({smooth:R,smoothMonotone:N,connectNulls:w}),f){var E=a.getCalculationInfo("stackedOnSeries"),z=0;f.useStyle(k(l.getAreaStyle(),{fill:C,opacity:.7,lineJoin:"bevel",decal:a.getVisual("style").decal})),E&&(z=cS(E.get("smooth"))),f.setShape({smooth:R,stackedOnSmooth:z,smoothMonotone:N,connectNulls:w}),zl(f,t,"areaStyle"),Ws(f).seriesIndex=t.seriesIndex,Ol(f,L,P,O)}var V=function(t){i._changePolyState(t)};a.eachItemGraphicEl((function(t){t&&(t.onHoverStateChange=V)})),this._polyline.onHoverStateChange=V,this._data=a,this._coordSys=r,this._stackedOnPoints=_,this._points=u,this._step=T,this._valueOrigin=m,t.get("triggerLineEvent")&&(this.packEventData(t,d),f&&this.packEventData(t,f))},e.prototype.packEventData=function(t,e){Ws(e).eventData={componentType:"series",componentSubType:"line",componentIndex:t.componentIndex,seriesIndex:t.seriesIndex,seriesName:t.name,seriesType:"line"}},e.prototype.highlight=function(t,e,n,i){var r=t.getData(),o=wo(r,i);if(this._changePolyState("emphasis"),!(o instanceof Array)&&null!=o&&o>=0){var a=r.getLayout("points"),s=r.getItemGraphicEl(o);if(!s){var l=a[2*o],u=a[2*o+1];if(isNaN(l)||isNaN(u))return;if(this._clipShapeForSymbol&&!this._clipShapeForSymbol.contain(l,u))return;var h=t.get("zlevel"),c=t.get("z");(s=new Ww(r,o)).x=l,s.y=u,s.setZ(h,c);var p=s.getSymbolPath().getTextContent();p&&(p.zlevel=h,p.z=c,p.z2=this._polyline.z2+1),s.__temp=!0,r.setItemGraphicEl(o,s),s.stopSymbolAnimation(!0),this.group.add(s)}s.highlight()}else mg.prototype.highlight.call(this,t,e,n,i)},e.prototype.downplay=function(t,e,n,i){var r=t.getData(),o=wo(r,i);if(this._changePolyState("normal"),null!=o&&o>=0){var a=r.getItemGraphicEl(o);a&&(a.__temp?(r.setItemGraphicEl(o,null),this.group.remove(a)):a.downplay())}else mg.prototype.downplay.call(this,t,e,n,i)},e.prototype._changePolyState=function(t){var e=this._polygon;fl(this._polyline,t),e&&fl(e,t)},e.prototype._newPolyline=function(t){var e=this._polyline;return e&&this._lineGroup.remove(e),e=new eS({shape:{points:t},segmentIgnoreThreshold:2,z2:10}),this._lineGroup.add(e),this._polyline=e,e},e.prototype._newPolygon=function(t,e){var n=this._polygon;return n&&this._lineGroup.remove(n),n=new iS({shape:{points:t,stackedOnPoints:e},segmentIgnoreThreshold:2}),this._lineGroup.add(n),this._polygon=n,n},e.prototype._initSymbolLabelAnimation=function(t,e,n){var i,r,o=e.getBaseAxis(),a=o.inverse;"cartesian2d"===e.type?(i=o.isHorizontal(),r=!1):"polar"===e.type&&(i="angle"===o.dim,r=!0);var s=t.hostModel,l=s.get("animationDuration");U(l)&&(l=l(null));var u=s.get("animationDelay")||0,h=U(u)?u(null):u;t.eachItemGraphicEl((function(t,o){var s=t;if(s){var c=[t.x,t.y],p=void 0,d=void 0,f=void 0;if(n)if(r){var g=n,y=e.pointToCoord(c);i?(p=g.startAngle,d=g.endAngle,f=-y[1]/180*Math.PI):(p=g.r0,d=g.r,f=y[0])}else{var v=n;i?(p=v.x,d=v.x+v.width,f=t.x):(p=v.y+v.height,d=v.y,f=t.y)}var m=d===p?0:(f-p)/(d-p);a&&(m=1-m);var x=U(u)?u(o):l*m+h,_=s.getSymbolPath(),b=_.getTextContent();s.attr({scaleX:0,scaleY:0}),s.animateTo({scaleX:1,scaleY:1},{duration:200,setToFinal:!0,delay:x}),b&&b.animateFrom({style:{opacity:0}},{duration:300,delay:x}),_.disableLabelAnimation=!0}}))},e.prototype._initOrUpdateEndLabel=function(t,e,n){var i=t.getModel("endLabel");if(yS(t)){var r=t.getData(),o=this._polyline,a=r.getLayout("points");if(!a)return o.removeTextContent(),void(this._endLabel=null);var s=this._endLabel;s||((s=this._endLabel=new As({z2:200})).ignoreClip=!0,o.setTextContent(this._endLabel),o.disableLabelAnimation=!0);var l=function(t){for(var e,n,i=t.length/2;i>0&&(e=t[2*i-2],n=t[2*i-1],isNaN(e)||isNaN(n));i--);return i-1}(a);l>=0&&(Wh(o,Hh(t,"endLabel"),{inheritColor:n,labelFetcher:t,labelDataIndex:l,defaultText:function(t,e,n){return null!=n?Gw(r,n):Fw(r,t)},enableTextSetter:!0},function(t,e){var n=e.getBaseAxis(),i=n.isHorizontal(),r=n.inverse,o=i?r?"right":"left":"center",a=i?"middle":r?"top":"bottom";return{normal:{align:t.get("align")||o,verticalAlign:t.get("verticalAlign")||a}}}(i,e)),o.textConfig.position=null)}else this._endLabel&&(this._polyline.removeTextContent(),this._endLabel=null)},e.prototype._endLabelOnDuring=function(t,e,n,i,r,o,a){var s=this._endLabel,l=this._polyline;if(s){t<1&&null==i.originalX&&(i.originalX=s.x,i.originalY=s.y);var u=n.getLayout("points"),h=n.hostModel,c=h.get("connectNulls"),p=o.get("precision"),d=o.get("distance")||0,f=a.getBaseAxis(),g=f.isHorizontal(),y=f.inverse,v=e.shape,m=y?g?v.x:v.y+v.height:g?v.x+v.width:v.y,x=(g?d:0)*(y?-1:1),_=(g?0:-d)*(y?-1:1),b=g?"x":"y",w=function(t,e,n){for(var i,r,o=t.length/2,a="x"===n?0:1,s=0,l=-1,u=0;u=e||i>=e&&r<=e){l=u;break}s=u,i=r}else i=r;return{range:[s,l],t:(e-i)/(r-i)}}(u,m,b),S=w.range,M=S[1]-S[0],I=void 0;if(M>=1){if(M>1&&!c){var T=gS(u,S[0]);s.attr({x:T[0]+x,y:T[1]+_}),r&&(I=h.getRawValue(S[0]))}else{(T=l.getPointOn(m,b))&&s.attr({x:T[0]+x,y:T[1]+_});var C=h.getRawValue(S[0]),D=h.getRawValue(S[1]);r&&(I=Po(n,p,C,D,w.t))}i.lastFrameIndex=S[0]}else{var A=1===t||i.lastFrameIndex>0?S[0]:0;T=gS(u,A);r&&(I=h.getRawValue(A)),s.attr({x:T[0]+x,y:T[1]+_})}r&&$h(s).setLabelText(I)}},e.prototype._doUpdateAnimation=function(t,e,n,i,r,o,a){var s=this._polyline,l=this._polygon,u=t.hostModel,h=function(t,e,n,i,r,o,a,s){for(var l=function(t,e){var n=[];return e.diff(t).add((function(t){n.push({cmd:"+",idx:t})})).update((function(t,e){n.push({cmd:"=",idx:e,idx1:t})})).remove((function(t){n.push({cmd:"-",idx:t})})).execute(),n}(t,e),u=[],h=[],c=[],p=[],d=[],f=[],g=[],y=jw(r,e,a),v=t.getLayout("points")||[],m=e.getLayout("points")||[],x=0;x3e3||l&&hS(p,f)>3e3)return s.stopAnimation(),s.setShape({points:d}),void(l&&(l.stopAnimation(),l.setShape({points:d,stackedOnPoints:f})));s.shape.__points=h.current,s.shape.points=c;var g={shape:{points:d}};h.current!==c&&(g.shape.__points=h.next),s.stopAnimation(),ih(s,g,u),l&&(l.setShape({points:c,stackedOnPoints:p}),l.stopAnimation(),ih(l,{shape:{stackedOnPoints:f}},u),s.shape.points!==l.shape.points&&(l.shape.points=s.shape.points));for(var y=[],v=h.status,m=0;me&&(e=t[n]);return isFinite(e)?e:NaN},min:function(t){for(var e=1/0,n=0;n10&&"cartesian2d"===o.type&&r){var s=o.getBaseAxis(),l=o.getOtherAxis(s),u=s.getExtent(),h=n.getDevicePixelRatio(),c=Math.abs(u[1]-u[0])*(h||1),p=Math.round(a/c);if(isFinite(p)&&p>1){"lttb"===r&&t.setData(i.lttbDownSample(i.mapDimension(l.dim),1/p));var d=void 0;X(r)?d=_S[r]:U(r)&&(d=r),d&&t.setData(i.downSample(i.mapDimension(l.dim),1/p,d,bS))}}}}}var SS=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.getInitialData=function(t,e){return nx(null,this,{useEncodeDefaulter:!0})},e.prototype.getMarkerPosition=function(t){var e=this.coordinateSystem;if(e&&e.clampData){var n=e.dataToPoint(e.clampData(t)),i=this.getData(),r=i.getLayout("offset"),o=i.getLayout("size");return n[e.getBaseAxis().isHorizontal()?0:1]+=r+o/2,n}return[NaN,NaN]},e.type="series.__base_bar__",e.defaultOption={z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,barMinHeight:0,barMinAngle:0,large:!1,largeThreshold:400,progressive:3e3,progressiveChunkMode:"mod"},e}(ag);ag.registerClass(SS);var MS=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.getInitialData=function(){return nx(null,this,{useEncodeDefaulter:!0,createInvertedIndices:!!this.get("realtimeSort",!0)||null})},e.prototype.getProgressive=function(){return!!this.get("large")&&this.get("progressive")},e.prototype.getProgressiveThreshold=function(){var t=this.get("progressiveThreshold"),e=this.get("largeThreshold");return e>t&&(t=e),t},e.prototype.brushSelector=function(t,e,n){return n.rect(e.getItemLayout(t))},e.type="series.bar",e.dependencies=["grid","polar"],e.defaultOption=gc(SS.defaultOption,{clip:!0,roundCap:!1,showBackground:!1,backgroundStyle:{color:"rgba(180, 180, 180, 0.2)",borderColor:null,borderWidth:0,borderType:"solid",borderRadius:0,shadowBlur:0,shadowColor:null,shadowOffsetX:0,shadowOffsetY:0,opacity:1},select:{itemStyle:{borderColor:"#212121"}},realtimeSort:!1}),e}(SS),IS=function(){this.cx=0,this.cy=0,this.r0=0,this.r=0,this.startAngle=0,this.endAngle=2*Math.PI,this.clockwise=!0},TS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="sausage",n}return n(e,t),e.prototype.getDefaultShape=function(){return new IS},e.prototype.buildPath=function(t,e){var n=e.cx,i=e.cy,r=Math.max(e.r0||0,0),o=Math.max(e.r,0),a=.5*(o-r),s=r+a,l=e.startAngle,u=e.endAngle,h=e.clockwise,c=2*Math.PI,p=h?u-lo)return!0;o=u}return!1},e.prototype._isOrderDifferentInView=function(t,e){for(var n=e.scale,i=n.getExtent(),r=Math.max(0,i[0]),o=Math.min(i[1],n.getOrdinalMeta().categories.length-1);r<=o;++r)if(t.ordinalNumbers[r]!==n.getRawOrdinalNumber(r))return!0},e.prototype._updateSortWithinSameData=function(t,e,n,i){if(this._isOrderChangedWithinSameData(t,e,n)){var r=this._dataSort(t,n,e);this._isOrderDifferentInView(r,n)&&(this._removeOnRenderedListener(i),i.dispatchAction({type:"changeAxisOrder",componentType:n.dim+"Axis",axisId:n.index,sortInfo:r}))}},e.prototype._dispatchInitSort=function(t,e,n){var i=e.baseAxis,r=this._dataSort(t,i,(function(n){return t.get(t.mapDimension(e.otherAxis.dim),n)}));n.dispatchAction({type:"changeAxisOrder",componentType:i.dim+"Axis",isInitSort:!0,axisId:i.index,sortInfo:r})},e.prototype.remove=function(t,e){this._clear(this._model),this._removeOnRenderedListener(e)},e.prototype.dispose=function(t,e){this._removeOnRenderedListener(e)},e.prototype._removeOnRenderedListener=function(t){this._onRendered&&(t.getZr().off("rendered",this._onRendered),this._onRendered=null)},e.prototype._clear=function(t){var e=this.group,n=this._data;t&&t.isAnimationEnabled()&&n&&!this._isLargeDraw?(this._removeBackground(),this._backgroundEls=[],n.eachItemGraphicEl((function(e){lh(e,t,Ws(e).dataIndex)}))):e.removeAll(),this._data=null,this._isFirstFrame=!0},e.prototype._removeBackground=function(){this.group.remove(this._backgroundGroup),this._backgroundGroup=null},e.type="bar",e}(mg),PS={cartesian2d:function(t,e){var n=e.width<0?-1:1,i=e.height<0?-1:1;n<0&&(e.x+=e.width,e.width=-e.width),i<0&&(e.y+=e.height,e.height=-e.height);var r=t.x+t.width,o=t.y+t.height,a=AS(e.x,t.x),s=kS(e.x+e.width,r),l=AS(e.y,t.y),u=kS(e.y+e.height,o),h=sr?s:a,e.y=c&&l>o?u:l,e.width=h?0:s-a,e.height=c?0:u-l,n<0&&(e.x+=e.width,e.width=-e.width),i<0&&(e.y+=e.height,e.height=-e.height),h||c},polar:function(t,e){var n=e.r0<=e.r?1:-1;if(n<0){var i=e.r;e.r=e.r0,e.r0=i}var r=kS(e.r,t.r),o=AS(e.r0,t.r0);e.r=r,e.r0=o;var a=r-o<0;if(n<0){i=e.r;e.r=e.r0,e.r0=i}return a}},OS={cartesian2d:function(t,e,n,i,r,o,a,s,l){var u=new Ts({shape:A({},i),z2:1});(u.__dataIndex=n,u.name="item",o)&&(u.shape[r?"height":"width"]=0);return u},polar:function(t,e,n,i,r,o,a,s,l){var u=!r&&l?TS:Tu,h=new u({shape:i,z2:1});h.name="item";var c,p,d=FS(r);if(h.calculateTextPosition=(c=d,p=({isRoundCap:u===TS}||{}).isRoundCap,function(t,e,n){var i=e.position;if(!i||i instanceof Array)return yr(t,e,n);var r=c(i),o=null!=e.distance?e.distance:5,a=this.shape,s=a.cx,l=a.cy,u=a.r,h=a.r0,d=(u+h)/2,f=a.startAngle,g=a.endAngle,y=(f+g)/2,v=p?Math.abs(u-h)/2:0,m=Math.cos,x=Math.sin,_=s+u*m(f),b=l+u*x(f),w="left",S="top";switch(r){case"startArc":_=s+(h-o)*m(y),b=l+(h-o)*x(y),w="center",S="top";break;case"insideStartArc":_=s+(h+o)*m(y),b=l+(h+o)*x(y),w="center",S="bottom";break;case"startAngle":_=s+d*m(f)+CS(f,o+v,!1),b=l+d*x(f)+DS(f,o+v,!1),w="right",S="middle";break;case"insideStartAngle":_=s+d*m(f)+CS(f,-o+v,!1),b=l+d*x(f)+DS(f,-o+v,!1),w="left",S="middle";break;case"middle":_=s+d*m(y),b=l+d*x(y),w="center",S="middle";break;case"endArc":_=s+(u+o)*m(y),b=l+(u+o)*x(y),w="center",S="bottom";break;case"insideEndArc":_=s+(u-o)*m(y),b=l+(u-o)*x(y),w="center",S="top";break;case"endAngle":_=s+d*m(g)+CS(g,o+v,!0),b=l+d*x(g)+DS(g,o+v,!0),w="left",S="middle";break;case"insideEndAngle":_=s+d*m(g)+CS(g,-o+v,!0),b=l+d*x(g)+DS(g,-o+v,!0),w="right",S="middle";break;default:return yr(t,e,n)}return(t=t||{}).x=_,t.y=b,t.align=w,t.verticalAlign=S,t}),o){var f=r?"r":"endAngle",g={};h.shape[f]=r?0:i.startAngle,g[f]=i[f],(s?ih:rh)(h,{shape:g},o)}return h}};function RS(t,e,n,i,r,o,a,s){var l,u;o?(u={x:i.x,width:i.width},l={y:i.y,height:i.height}):(u={y:i.y,height:i.height},l={x:i.x,width:i.width}),s||(a?ih:rh)(n,{shape:l},e,r,null),(a?ih:rh)(n,{shape:u},e?t.baseAxis.model:null,r)}function NS(t,e){for(var n=0;n0?1:-1,a=i.height>0?1:-1;return{x:i.x+o*r/2,y:i.y+a*r/2,width:i.width-o*r,height:i.height-a*r}},polar:function(t,e,n){var i=t.getItemLayout(e);return{cx:i.cx,cy:i.cy,r0:i.r0,r:i.r,startAngle:i.startAngle,endAngle:i.endAngle,clockwise:i.clockwise}}};function FS(t){return function(t){var e=t?"Arc":"Angle";return function(t){switch(t){case"start":case"insideStart":case"end":case"insideEnd":return t+e;default:return t}}}(t)}function GS(t,e,n,i,r,o,a,s){var l=e.getItemVisual(n,"style");s||t.setShape("r",i.get(["itemStyle","borderRadius"])||0),t.useStyle(l);var u=i.getShallow("cursor");u&&t.attr("cursor",u);var h=s?a?r.r>=r.r0?"endArc":"startArc":r.endAngle>=r.startAngle?"endAngle":"startAngle":a?r.height>=0?"bottom":"top":r.width>=0?"right":"left",c=Hh(i);Wh(t,c,{labelFetcher:o,labelDataIndex:n,defaultText:Fw(o.getData(),n),inheritColor:l.fill,defaultOpacity:l.opacity,defaultOutsidePosition:h});var p=t.getTextContent();if(s&&p){var d=i.get(["label","position"]);t.textConfig.inside="middle"===d||null,function(t,e,n,i){if(j(i))t.setTextConfig({rotation:i});else if(Y(e))t.setTextConfig({rotation:0});else{var r,o=t.shape,a=o.clockwise?o.startAngle:o.endAngle,s=o.clockwise?o.endAngle:o.startAngle,l=(a+s)/2,u=n(e);switch(u){case"startArc":case"insideStartArc":case"middle":case"insideEndArc":case"endArc":r=l;break;case"startAngle":case"insideStartAngle":r=a;break;case"endAngle":case"insideEndAngle":r=s;break;default:return void t.setTextConfig({rotation:0})}var h=1.5*Math.PI-r;"middle"===u&&h>Math.PI/2&&h<1.5*Math.PI&&(h-=Math.PI),t.setTextConfig({rotation:h})}}(t,"outside"===d?h:d,FS(a),i.get(["label","rotate"]))}Jh(p,c,o.getRawValue(n),(function(t){return Gw(e,t)}));var f=i.getModel(["emphasis"]);Ol(t,f.get("focus"),f.get("blurScope"),f.get("disabled")),zl(t,i),function(t){return null!=t.startAngle&&null!=t.endAngle&&t.startAngle===t.endAngle}(r)&&(t.style.fill="none",t.style.stroke="none",E(t.states,(function(t){t.style&&(t.style.fill=t.style.stroke="none")})))}var WS=function(){},HS=function(t){function e(e){var n=t.call(this,e)||this;return n.type="largeBar",n}return n(e,t),e.prototype.getDefaultShape=function(){return new WS},e.prototype.buildPath=function(t,e){for(var n=e.points,i=this.baseDimIdx,r=1-this.baseDimIdx,o=[],a=[],s=this.barWidth,l=0;l=s[0]&&e<=s[0]+l[0]&&n>=s[1]&&n<=s[1]+l[1])return a[h]}return-1}(this,t.offsetX,t.offsetY);Ws(this).dataIndex=e>=0?e:null}),30,!1);function XS(t,e,n){if(sS(n,"cartesian2d")){var i=e,r=n.getArea();return{x:t?i.x:r.x,y:t?r.y:i.y,width:t?i.width:r.width,height:t?r.height:i.height}}var o=e;return{cx:(r=n.getArea()).cx,cy:r.cy,r0:t?r.r0:o.r0,r:t?r.r:o.r,startAngle:t?o.startAngle:0,endAngle:t?o.endAngle:2*Math.PI}}var ZS=2*Math.PI,jS=Math.PI/180;function qS(t,e){return mp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}function KS(t,e){var n=qS(t,e),i=t.get("center"),r=t.get("radius");Y(r)||(r=[0,r]),Y(i)||(i=[i,i]);var o=Er(n.width,e.getWidth()),a=Er(n.height,e.getHeight()),s=Math.min(o,a);return{cx:Er(i[0],o)+n.x,cy:Er(i[1],a)+n.y,r0:Er(r[0],s/2),r:Er(r[1],s/2)}}function $S(t,e,n){e.eachSeriesByType(t,(function(t){var e=t.getData(),i=e.mapDimension("value"),r=qS(t,n),o=KS(t,n),a=o.cx,s=o.cy,l=o.r,u=o.r0,h=-t.get("startAngle")*jS,c=t.get("minAngle")*jS,p=0;e.each(i,(function(t){!isNaN(t)&&p++}));var d=e.getSum(i),f=Math.PI/(d||p)*2,g=t.get("clockwise"),y=t.get("roseType"),v=t.get("stillShowZeroSum"),m=e.getDataExtent(i);m[0]=0;var x=ZS,_=0,b=h,w=g?1:-1;if(e.setLayout({viewRect:r,r:l}),e.each(i,(function(t,n){var i;if(isNaN(t))e.setItemLayout(n,{angle:NaN,startAngle:NaN,endAngle:NaN,clockwise:g,cx:a,cy:s,r0:u,r:y?NaN:l});else{(i="area"!==y?0===d&&v?f:t*f:ZS/p)n?a:o,h=Math.abs(l.label.y-n);if(h>=u.maxY){var c=l.label.x-e-l.len2*r,p=i+l.len,f=Math.abs(c)t.unconstrainedWidth?null:d:null;i.setStyle("width",f)}var g=i.getBoundingRect();o.width=g.width;var y=(i.style.margin||0)+2.1;o.height=g.height+y,o.y-=(o.height-c)/2}}}function nM(t){return"center"===t.position}function iM(t){var e,n,i=t.getData(),r=[],o=!1,a=(t.get("minShowLabelAngle")||0)*QS,s=i.getLayout("viewRect"),l=i.getLayout("r"),u=s.width,h=s.x,c=s.y,p=s.height;function d(t){t.ignore=!0}i.each((function(t){var s=i.getItemGraphicEl(t),c=s.shape,p=s.getTextContent(),f=s.getTextGuideLine(),g=i.getItemModel(t),y=g.getModel("label"),v=y.get("position")||g.get(["emphasis","label","position"]),m=y.get("distanceToLabelLine"),x=y.get("alignTo"),_=Er(y.get("edgeDistance"),u),b=y.get("bleedMargin"),w=g.getModel("labelLine"),S=w.get("length");S=Er(S,u);var M=w.get("length2");if(M=Er(M,u),Math.abs(c.endAngle-c.startAngle)0?"right":"left":k>0?"left":"right"}var B=Math.PI,F=0,G=y.get("rotate");if(j(G))F=G*(B/180);else if("center"===v)F=0;else if("radial"===G||!0===G){F=k<0?-A+B:-A}else if("tangential"===G&&"outside"!==v&&"outer"!==v){var W=Math.atan2(k,L);W<0&&(W=2*B+W),L>0&&(W=B+W),F=W-B}if(o=!!F,p.x=I,p.y=T,p.rotation=F,p.setStyle({verticalAlign:"middle"}),P){p.setStyle({align:D});var H=p.states.select;H&&(H.x+=p.x,H.y+=p.y)}else{var Y=p.getBoundingRect().clone();Y.applyTransform(p.getComputedTransform());var U=(p.style.margin||0)+2.1;Y.y-=U/2,Y.height+=U,r.push({label:p,labelLine:f,position:v,len:S,len2:M,minTurnAngle:w.get("minTurnAngle"),maxSurfaceAngle:w.get("maxSurfaceAngle"),surfaceNormal:new Ji(k,L),linePoints:C,textAlign:D,labelDistance:m,labelAlignTo:x,edgeDistance:_,bleedMargin:b,rect:Y,unconstrainedWidth:Y.width,labelStyleWidth:p.style.width})}s.setTextConfig({inside:P})}})),!o&&t.get("avoidLabelOverlap")&&function(t,e,n,i,r,o,a,s){for(var l=[],u=[],h=Number.MAX_VALUE,c=-Number.MAX_VALUE,p=0;p0){for(var l=o.getItemLayout(0),u=1;isNaN(l&&l.startAngle)&&u=n.r0}},e.type="pie",e}(mg);function sM(t,e,n){e=Y(e)&&{coordDimensions:e}||A({encodeDefine:t.getEncode()},e);var i=t.getSource(),r=jm(i,e).dimensions,o=new Zm(r,t);return o.initData(i,n),o}var lM=function(){function t(t,e){this._getDataWithEncodedVisual=t,this._getRawData=e}return t.prototype.getAllNames=function(){var t=this._getRawData();return t.mapArray(t.getName)},t.prototype.containName=function(t){return this._getRawData().indexOfName(t)>=0},t.prototype.indexOfName=function(t){return this._getDataWithEncodedVisual().indexOfName(t)},t.prototype.getItemVisual=function(t,e){return this._getDataWithEncodedVisual().getItemVisual(t,e)},t}(),uM=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments),this.legendVisualProvider=new lM(W(this.getData,this),W(this.getRawData,this)),this._defaultLabelLine(e)},e.prototype.mergeOption=function(){t.prototype.mergeOption.apply(this,arguments)},e.prototype.getInitialData=function(){return sM(this,{coordDimensions:["value"],encodeDefaulter:H(Hp,this)})},e.prototype.getDataParams=function(e){var n=this.getData(),i=t.prototype.getDataParams.call(this,e),r=[];return n.each(n.mapDimension("value"),(function(t){r.push(t)})),i.percent=Wr(r,e,n.hostModel.get("percentPrecision")),i.$vars.push("percent"),i},e.prototype._defaultLabelLine=function(t){co(t,"labelLine",["show"]);var e=t.labelLine,n=t.emphasis.labelLine;e.show=e.show&&t.label.show,n.show=n.show&&t.emphasis.label.show},e.type="series.pie",e.defaultOption={z:2,legendHoverLink:!0,colorBy:"data",center:["50%","50%"],radius:[0,"75%"],clockwise:!0,startAngle:90,minAngle:0,minShowLabelAngle:0,selectedOffset:10,percentPrecision:2,stillShowZeroSum:!0,left:0,top:0,right:0,bottom:0,width:null,height:null,label:{rotate:0,show:!0,overflow:"truncate",position:"outer",alignTo:"none",edgeDistance:"25%",bleedMargin:10,distanceToLabelLine:5},labelLine:{show:!0,length:15,length2:15,smooth:!1,minTurnAngle:90,maxSurfaceAngle:90,lineStyle:{width:1,type:"solid"}},itemStyle:{borderWidth:1,borderJoin:"round"},showEmptyCircle:!0,emptyCircleStyle:{color:"lightgray",opacity:1},labelLayout:{hideOverlap:!0},emphasis:{scale:!0,scaleSize:5},avoidLabelOverlap:!0,animationType:"expansion",animationDuration:1e3,animationTypeUpdate:"transition",animationEasingUpdate:"cubicInOut",animationDurationUpdate:500,animationEasing:"cubicInOut"},e}(ag);var hM=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){return nx(null,this,{useEncodeDefaulter:!0})},e.prototype.getProgressive=function(){var t=this.option.progressive;return null==t?this.option.large?5e3:this.get("progressive"):t},e.prototype.getProgressiveThreshold=function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?1e4:this.get("progressiveThreshold"):t},e.prototype.brushSelector=function(t,e,n){return n.point(e.getItemLayout(t))},e.prototype.getZLevelKey=function(){return this.getData().count()>this.getProgressiveThreshold()?this.id:""},e.type="series.scatter",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={coordinateSystem:"cartesian2d",z:2,legendHoverLink:!0,symbolSize:10,large:!1,largeThreshold:2e3,itemStyle:{opacity:.8},emphasis:{scale:!0},clip:!0,select:{itemStyle:{borderColor:"#212121"}},universalTransition:{divideShape:"clone"}},e}(ag),cM=function(){},pM=function(t){function e(e){var n=t.call(this,e)||this;return n._off=0,n.hoverDataIdx=-1,n}return n(e,t),e.prototype.getDefaultShape=function(){return new cM},e.prototype.reset=function(){this.notClear=!1,this._off=0},e.prototype.buildPath=function(t,e){var n,i=e.points,r=e.size,o=this.symbolProxy,a=o.shape,s=t.getContext?t.getContext():t,l=s&&r[0]<4,u=this.softClipShape;if(l)this._ctx=s;else{for(this._ctx=null,n=this._off;n=0;s--){var l=2*s,u=i[l]-o/2,h=i[l+1]-a/2;if(t>=u&&e>=h&&t<=u+o&&e<=h+a)return s}return-1},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect();return t=n[0],e=n[1],i.contain(t,e)?(this.hoverDataIdx=this.findDataIndex(t,e))>=0:(this.hoverDataIdx=-1,!1)},e.prototype.getBoundingRect=function(){var t=this._rect;if(!t){for(var e=this.shape,n=e.points,i=e.size,r=i[0],o=i[1],a=1/0,s=1/0,l=-1/0,u=-1/0,h=0;h=0&&(l.dataIndex=n+(t.startIndex||0))}))},t.prototype.remove=function(){this._clear()},t.prototype._clear=function(){this._newAdded=[],this.group.removeAll()},t}(),fM=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData();this._updateSymbolDraw(i,t).updateData(i,{clipShape:this._getClipShape(t)}),this._finished=!0},e.prototype.incrementalPrepareRender=function(t,e,n){var i=t.getData();this._updateSymbolDraw(i,t).incrementalPrepareUpdate(i),this._finished=!1},e.prototype.incrementalRender=function(t,e,n){this._symbolDraw.incrementalUpdate(t,e.getData(),{clipShape:this._getClipShape(e)}),this._finished=t.end===e.getData().count()},e.prototype.updateTransform=function(t,e,n){var i=t.getData();if(this.group.dirty(),!this._finished||i.count()>1e4)return{update:!0};var r=xS("").reset(t,e,n);r.progress&&r.progress({start:0,end:i.count(),count:i.count()},i),this._symbolDraw.updateLayout(i)},e.prototype.eachRendered=function(t){this._symbolDraw&&this._symbolDraw.eachRendered(t)},e.prototype._getClipShape=function(t){var e=t.coordinateSystem,n=e&&e.getArea&&e.getArea();return t.get("clip",!0)?n:null},e.prototype._updateSymbolDraw=function(t,e){var n=this._symbolDraw,i=e.pipelineContext.large;return n&&i===this._isLargeDraw||(n&&n.remove(),n=this._symbolDraw=i?new dM:new Zw,this._isLargeDraw=i,this.group.removeAll()),this.group.add(n.group),n},e.prototype.remove=function(t,e){this._symbolDraw&&this._symbolDraw.remove(!0),this._symbolDraw=null},e.prototype.dispose=function(){},e.type="scatter",e}(mg),gM=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.type="grid",e.dependencies=["xAxis","yAxis"],e.layoutMode="box",e.defaultOption={show:!1,z:0,left:"10%",top:60,right:"10%",bottom:70,containLabel:!1,backgroundColor:"rgba(0,0,0,0)",borderWidth:1,borderColor:"#ccc"},e}(Ip),yM=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getCoordSysModel=function(){return this.getReferringComponents("grid",Co).models[0]},e.type="cartesian2dAxis",e}(Ip);R(yM,h_);var vM={show:!0,z:0,inverse:!1,name:"",nameLocation:"end",nameRotate:null,nameTruncate:{maxWidth:null,ellipsis:"...",placeholder:"."},nameTextStyle:{},nameGap:15,silent:!1,triggerEvent:!1,tooltip:{show:!1},axisPointer:{},axisLine:{show:!0,onZero:!0,onZeroAxisIndex:null,lineStyle:{color:"#6E7079",width:1,type:"solid"},symbol:["none","none"],symbolSize:[10,15]},axisTick:{show:!0,inside:!1,length:5,lineStyle:{width:1}},axisLabel:{show:!0,inside:!1,rotate:0,showMinLabel:null,showMaxLabel:null,margin:8,fontSize:12},splitLine:{show:!0,lineStyle:{color:["#E0E6F1"],width:1,type:"solid"}},splitArea:{show:!1,areaStyle:{color:["rgba(250,250,250,0.2)","rgba(210,219,238,0.2)"]}}},mM=C({boundaryGap:!0,deduplication:null,splitLine:{show:!1},axisTick:{alignWithLabel:!1,interval:"auto"},axisLabel:{interval:"auto"}},vM),xM=C({boundaryGap:[0,0],axisLine:{show:"auto"},axisTick:{show:"auto"},splitNumber:5,minorTick:{show:!1,splitNumber:5,length:3,lineStyle:{}},minorSplitLine:{show:!1,lineStyle:{color:"#F4F7FD",width:1}}},vM),_M={category:mM,value:xM,time:C({splitNumber:6,axisLabel:{showMinLabel:!1,showMaxLabel:!1,rich:{primary:{fontWeight:"bold"}}},splitLine:{show:!1}},xM),log:k({logBase:10},xM)},bM={value:1,category:1,time:1,log:1};function wM(t,e,i,r){E(bM,(function(o,a){var s=C(C({},_M[a],!0),r,!0),l=function(t){function i(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e+"Axis."+a,n}return n(i,t),i.prototype.mergeDefaultAndTheme=function(t,e){var n=_p(this),i=n?wp(t):{};C(t,e.getTheme().get(a+"Axis")),C(t,this.getDefaultOption()),t.type=SM(t),n&&bp(t,i,n)},i.prototype.optionUpdated=function(){"category"===this.option.type&&(this.__ordinalMeta=ox.createByAxisModel(this))},i.prototype.getCategories=function(t){var e=this.option;if("category"===e.type)return t?e.data:this.__ordinalMeta.categories},i.prototype.getOrdinalMeta=function(){return this.__ordinalMeta},i.type=e+"Axis."+a,i.defaultOption=s,i}(i);t.registerComponentModel(l)})),t.registerSubTypeDefaulter(e+"Axis",SM)}function SM(t){return t.type||(t.data?"category":"value")}var MM=function(){function t(t){this.type="cartesian",this._dimList=[],this._axes={},this.name=t||""}return t.prototype.getAxis=function(t){return this._axes[t]},t.prototype.getAxes=function(){return z(this._dimList,(function(t){return this._axes[t]}),this)},t.prototype.getAxesByScale=function(t){return t=t.toLowerCase(),B(this.getAxes(),(function(e){return e.scale.type===t}))},t.prototype.addAxis=function(t){var e=t.dim;this._axes[e]=t,this._dimList.push(e)},t}(),IM=["x","y"];function TM(t){return"interval"===t.type||"time"===t.type}var CM=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="cartesian2d",e.dimensions=IM,e}return n(e,t),e.prototype.calcAffineTransform=function(){this._transform=this._invTransform=null;var t=this.getAxis("x").scale,e=this.getAxis("y").scale;if(TM(t)&&TM(e)){var n=t.getExtent(),i=e.getExtent(),r=this.dataToPoint([n[0],i[0]]),o=this.dataToPoint([n[1],i[1]]),a=n[1]-n[0],s=i[1]-i[0];if(a&&s){var l=(o[0]-r[0])/a,u=(o[1]-r[1])/s,h=r[0]-n[0]*l,c=r[1]-i[0]*u,p=this._transform=[l,0,0,u,h,c];this._invTransform=Bi([],p)}}},e.prototype.getBaseAxis=function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAxis("x")},e.prototype.containPoint=function(t){var e=this.getAxis("x"),n=this.getAxis("y");return e.contain(e.toLocalCoord(t[0]))&&n.contain(n.toLocalCoord(t[1]))},e.prototype.containData=function(t){return this.getAxis("x").containData(t[0])&&this.getAxis("y").containData(t[1])},e.prototype.dataToPoint=function(t,e,n){n=n||[];var i=t[0],r=t[1];if(this._transform&&null!=i&&isFinite(i)&&null!=r&&isFinite(r))return Ft(n,t,this._transform);var o=this.getAxis("x"),a=this.getAxis("y");return n[0]=o.toGlobalCoord(o.dataToCoord(i,e)),n[1]=a.toGlobalCoord(a.dataToCoord(r,e)),n},e.prototype.clampData=function(t,e){var n=this.getAxis("x").scale,i=this.getAxis("y").scale,r=n.getExtent(),o=i.getExtent(),a=n.parse(t[0]),s=i.parse(t[1]);return(e=e||[])[0]=Math.min(Math.max(Math.min(r[0],r[1]),a),Math.max(r[0],r[1])),e[1]=Math.min(Math.max(Math.min(o[0],o[1]),s),Math.max(o[0],o[1])),e},e.prototype.pointToData=function(t,e){var n=[];if(this._invTransform)return Ft(n,t,this._invTransform);var i=this.getAxis("x"),r=this.getAxis("y");return n[0]=i.coordToData(i.toLocalCoord(t[0]),e),n[1]=r.coordToData(r.toLocalCoord(t[1]),e),n},e.prototype.getOtherAxis=function(t){return this.getAxis("x"===t.dim?"y":"x")},e.prototype.getArea=function(){var t=this.getAxis("x").getGlobalExtent(),e=this.getAxis("y").getGlobalExtent(),n=Math.min(t[0],t[1]),i=Math.min(e[0],e[1]),r=Math.max(t[0],t[1])-n,o=Math.max(e[0],e[1])-i;return new sr(n,i,r,o)},e}(MM),DM=function(t){function e(e,n,i,r,o){var a=t.call(this,e,n,i)||this;return a.index=0,a.type=r||"value",a.position=o||"bottom",a}return n(e,t),e.prototype.isHorizontal=function(){var t=this.position;return"top"===t||"bottom"===t},e.prototype.getGlobalExtent=function(t){var e=this.getExtent();return e[0]=this.toGlobalCoord(e[0]),e[1]=this.toGlobalCoord(e[1]),t&&e[0]>e[1]&&e.reverse(),e},e.prototype.pointToData=function(t,e){return this.coordToData(this.toLocalCoord(t["x"===this.dim?0:1]),e)},e.prototype.setCategorySortInfo=function(t){if("category"!==this.type)return!1;this.model.option.categorySortInfo=t,this.scale.setSortInfo(t)},e}(G_);function AM(t,e,n){n=n||{};var i=t.coordinateSystem,r=e.axis,o={},a=r.getAxesOnZeroOf()[0],s=r.position,l=a?"onZero":s,u=r.dim,h=i.getRect(),c=[h.x,h.x+h.width,h.y,h.y+h.height],p={left:0,right:1,top:0,bottom:1,onZero:2},d=e.get("offset")||0,f="x"===u?[c[2]-d,c[3]+d]:[c[0]-d,c[1]+d];if(a){var g=a.toGlobalCoord(a.dataToCoord(0));f[p.onZero]=Math.max(Math.min(g,f[1]),f[0])}o.position=["y"===u?f[p[l]]:c[0],"x"===u?f[p[l]]:c[3]],o.rotation=Math.PI/2*("x"===u?0:1);o.labelDirection=o.tickDirection=o.nameDirection={top:-1,bottom:1,left:-1,right:1}[s],o.labelOffset=a?f[p[s]]-f[p.onZero]:0,e.get(["axisTick","inside"])&&(o.tickDirection=-o.tickDirection),it(n.labelInside,e.get(["axisLabel","inside"]))&&(o.labelDirection=-o.labelDirection);var y=e.get(["axisLabel","rotate"]);return o.labelRotate="top"===l?-y:y,o.z2=1,o}function kM(t){return"cartesian2d"===t.get("coordinateSystem")}function LM(t){var e={xAxisModel:null,yAxisModel:null};return E(e,(function(n,i){var r=i.replace(/Model$/,""),o=t.getReferringComponents(r,Co).models[0];e[i]=o})),e}var PM=Math.log;function OM(t,e,n){var i=vx.prototype,r=i.getTicks.call(n),o=i.getTicks.call(n,!0),a=r.length-1,s=i.getInterval.call(n),l=e_(t,e),u=l.extent,h=l.fixMin,c=l.fixMax;if("log"===t.type){var p=PM(t.base);u=[PM(u[0])/p,PM(u[1])/p]}t.setExtent(u[0],u[1]),t.calcNiceExtent({splitNumber:a,fixMin:h,fixMax:c});var d=i.getExtent.call(t);h&&(u[0]=d[0]),c&&(u[1]=d[1]);var f=i.getInterval.call(t),g=u[0],y=u[1];if(h&&c)f=(y-g)/a;else if(h)for(y=u[0]+f*a;yu[0]&&isFinite(g)&&isFinite(u[0]);)f=ux(f),g=u[1]-f*a;else{t.getTicks().length-1>a&&(f=ux(f));var v=f*a;(g=zr((y=Math.ceil(u[1]/f)*f)-v))<0&&u[0]>=0?(g=0,y=zr(v)):y>0&&u[1]<=0&&(y=0,g=-zr(v))}var m=(r[0].value-o[0].value)/s,x=(r[a].value-o[a].value)/s;i.setExtent.call(t,g+f*m,y+f*x),i.setInterval.call(t,f),(m||x)&&i.setNiceExtent.call(t,g+f,y-f)}var RM=function(){function t(t,e,n){this.type="grid",this._coordsMap={},this._coordsList=[],this._axesMap={},this._axesList=[],this.axisPointerEnabled=!0,this.dimensions=IM,this._initCartesian(t,e,n),this.model=t}return t.prototype.getRect=function(){return this._rect},t.prototype.update=function(t,e){var n=this._axesMap;function i(t){var e,n=G(t),i=n.length;if(i){for(var r=[],o=i-1;o>=0;o--){var a=t[+n[o]],s=a.model,l=a.scale;sx(l)&&s.get("alignTicks")&&null==s.get("interval")?r.push(a):(n_(l,s),sx(l)&&(e=a))}r.length&&(e||n_((e=r.pop()).scale,e.model),E(r,(function(t){OM(t.scale,t.model,e.scale)})))}}this._updateScale(t,this.model),i(n.x),i(n.y);var r={};E(n.x,(function(t){EM(n,"y",t,r)})),E(n.y,(function(t){EM(n,"x",t,r)})),this.resize(this.model,e)},t.prototype.resize=function(t,e,n){var i=t.getBoxLayoutParams(),r=!n&&t.get("containLabel"),o=mp(i,{width:e.getWidth(),height:e.getHeight()});this._rect=o;var a=this._axesList;function s(){E(a,(function(t){var e=t.isHorizontal(),n=e?[0,o.width]:[0,o.height],i=t.inverse?1:0;t.setExtent(n[i],n[1-i]),function(t,e){var n=t.getExtent(),i=n[0]+n[1];t.toGlobalCoord="x"===t.dim?function(t){return t+e}:function(t){return i-t+e},t.toLocalCoord="x"===t.dim?function(t){return t-e}:function(t){return i-t+e}}(t,e?o.x:o.y)}))}s(),r&&(E(a,(function(t){if(!t.model.get(["axisLabel","inside"])){var e=function(t){var e=t.model,n=t.scale;if(e.get(["axisLabel","show"])&&!n.isBlank()){var i,r,o=n.getExtent();r=n instanceof gx?n.count():(i=n.getTicks()).length;var a,s=t.getLabelModel(),l=r_(t),u=1;r>40&&(u=Math.ceil(r/40));for(var h=0;h0&&i>0||n<0&&i<0)}(t)}var VM=Math.PI,BM=function(){function t(t,e){this.group=new Cr,this.opt=e,this.axisModel=t,k(e,{labelOffset:0,nameDirection:1,tickDirection:1,labelDirection:1,silent:!0,handleAutoShown:function(){return!0}});var n=new Cr({x:e.position[0],y:e.position[1],rotation:e.rotation});n.updateTransform(),this._transformGroup=n}return t.prototype.hasBuilder=function(t){return!!FM[t]},t.prototype.add=function(t){FM[t](this.opt,this.axisModel,this.group,this._transformGroup)},t.prototype.getGroup=function(){return this.group},t.innerTextLayout=function(t,e,n){var i,r,o=Ur(e-t);return Xr(o)?(r=n>0?"top":"bottom",i="center"):Xr(o-VM)?(r=n>0?"bottom":"top",i="center"):(r="middle",i=o>0&&o0?"right":"left":n>0?"left":"right"),{rotation:o,textAlign:i,textVerticalAlign:r}},t.makeAxisEventDataBase=function(t){var e={componentType:t.mainType,componentIndex:t.componentIndex};return e[t.mainType+"Index"]=t.componentIndex,e},t.isLabelSilent=function(t){var e=t.get("tooltip");return t.get("silent")||!(t.get("triggerEvent")||e&&e.show)},t}(),FM={axisLine:function(t,e,n,i){var r=e.get(["axisLine","show"]);if("auto"===r&&t.handleAutoShown&&(r=t.handleAutoShown("axisLine")),r){var o=e.axis.getExtent(),a=i.transform,s=[o[0],0],l=[o[1],0];a&&(Ft(s,s,a),Ft(l,l,a));var u=A({lineCap:"round"},e.getModel(["axisLine","lineStyle"]).getLineStyle()),h=new Eu({subPixelOptimize:!0,shape:{x1:s[0],y1:s[1],x2:l[0],y2:l[1]},style:u,strokeContainThreshold:t.strokeContainThreshold||5,silent:!0,z2:1});h.anid="line",n.add(h);var c=e.get(["axisLine","symbol"]);if(null!=c){var p=e.get(["axisLine","symbolSize"]);X(c)&&(c=[c,c]),(X(p)||j(p))&&(p=[p,p]);var d=Py(e.get(["axisLine","symbolOffset"])||0,p),f=p[0],g=p[1];E([{rotate:t.rotation+Math.PI/2,offset:d[0],r:0},{rotate:t.rotation-Math.PI/2,offset:d[1],r:Math.sqrt((s[0]-l[0])*(s[0]-l[0])+(s[1]-l[1])*(s[1]-l[1]))}],(function(e,i){if("none"!==c[i]&&null!=c[i]){var r=ky(c[i],-f/2,-g/2,f,g,u.stroke,!0),o=e.r+e.offset;r.attr({rotation:e.rotate,x:s[0]+o*Math.cos(t.rotation),y:s[1]-o*Math.sin(t.rotation),silent:!0,z2:11}),n.add(r)}}))}}},axisTickLabel:function(t,e,n,i){var r=function(t,e,n,i){var r=n.axis,o=n.getModel("axisTick"),a=o.get("show");"auto"===a&&i.handleAutoShown&&(a=i.handleAutoShown("axisTick"));if(!a||r.scale.isBlank())return;for(var s=o.getModel("lineStyle"),l=i.tickDirection*o.get("length"),u=YM(r.getTicksCoords(),e.transform,l,k(s.getLineStyle(),{stroke:n.get(["axisLine","lineStyle","color"])}),"ticks"),h=0;hc[1]?-1:1,d=["start"===s?c[0]-p*h:"end"===s?c[1]+p*h:(c[0]+c[1])/2,HM(s)?t.labelOffset+l*h:0],f=e.get("nameRotate");null!=f&&(f=f*VM/180),HM(s)?o=BM.innerTextLayout(t.rotation,null!=f?f:t.rotation,l):(o=function(t,e,n,i){var r,o,a=Ur(n-t),s=i[0]>i[1],l="start"===e&&!s||"start"!==e&&s;Xr(a-VM/2)?(o=l?"bottom":"top",r="center"):Xr(a-1.5*VM)?(o=l?"top":"bottom",r="center"):(o="middle",r=a<1.5*VM&&a>VM/2?l?"left":"right":l?"right":"left");return{rotation:a,textAlign:r,textVerticalAlign:o}}(t.rotation,s,f||0,c),null!=(a=t.axisNameAvailableWidth)&&(a=Math.abs(a/Math.sin(o.rotation)),!isFinite(a)&&(a=null)));var g=u.getFont(),y=e.get("nameTruncate",!0)||{},v=y.ellipsis,m=it(t.nameTruncateMaxWidth,y.maxWidth,a),x=new As({x:d[0],y:d[1],rotation:o.rotation,silent:BM.isLabelSilent(e),style:Yh(u,{text:r,font:g,overflow:"truncate",width:m,ellipsis:v,fill:u.getTextColor()||e.get(["axisLine","lineStyle","color"]),align:u.get("align")||o.textAlign,verticalAlign:u.get("verticalAlign")||o.textVerticalAlign}),z2:1});if(Nh({el:x,componentModel:e,itemName:r}),x.__fullText=r,x.anid="name",e.get("triggerEvent")){var _=BM.makeAxisEventDataBase(e);_.targetType="axisName",_.name=r,Ws(x).eventData=_}i.add(x),x.updateTransform(),n.add(x),x.decomposeTransform()}}};function GM(t){t&&(t.ignore=!0)}function WM(t,e){var n=t&&t.getBoundingRect().clone(),i=e&&e.getBoundingRect().clone();if(n&&i){var r=Oi([]);return zi(r,r,-t.rotation),n.applyTransform(Ni([],r,t.getLocalTransform())),i.applyTransform(Ni([],r,e.getLocalTransform())),n.intersect(i)}}function HM(t){return"middle"===t||"center"===t}function YM(t,e,n,i,r){for(var o=[],a=[],s=[],l=0;l=0||t===e}function ZM(t){var e=jM(t);if(e){var n=e.axisPointerModel,i=e.axis.scale,r=n.option,o=n.get("status"),a=n.get("value");null!=a&&(a=i.parse(a));var s=qM(n);null==o&&(r.status=s?"show":"hide");var l=i.getExtent().slice();l[0]>l[1]&&l.reverse(),(null==a||a>l[1])&&(a=l[1]),a0&&!c.min?c.min=0:null!=c.min&&c.min<0&&!c.max&&(c.max=0);var p=a;null!=c.color&&(p=k({color:c.color},a));var d=C(T(c),{boundaryGap:t,splitNumber:e,scale:n,axisLine:i,axisTick:r,axisLabel:o,name:c.text,showName:s,nameLocation:"end",nameGap:u,nameTextStyle:p,triggerEvent:h},!1);if(s||(d.name=""),X(l)){var f=d.name;d.name=l.replace("{value}",null!=f?f:"")}else U(l)&&(d.name=l(d.name,d));var g=new pc(d,null,this.ecModel);return R(g,h_.prototype),g.mainType="radar",g.componentIndex=this.componentIndex,g}),this);this._indicatorModels=c},e.prototype.getIndicatorModels=function(){return this._indicatorModels},e.type="radar",e.defaultOption={z:0,center:["50%","50%"],radius:"75%",startAngle:90,axisName:{show:!0},boundaryGap:[0,0],splitNumber:5,axisNameGap:15,scale:!1,shape:"polygon",axisLine:C({lineStyle:{color:"#bbb"}},vI.axisLine),axisLabel:mI(vI.axisLabel,!1),axisTick:mI(vI.axisTick,!1),splitLine:mI(vI.splitLine,!0),splitArea:mI(vI.splitArea,!0),indicator:[]},e}(Ip),_I=["axisLine","axisTickLabel","axisName"],bI=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeAll(),this._buildAxes(t),this._buildSplitLineAndArea(t)},e.prototype._buildAxes=function(t){var e=t.coordinateSystem;E(z(e.getIndicatorAxes(),(function(t){var n=t.model.get("showName")?t.name:"";return new BM(t.model,{axisName:n,position:[e.cx,e.cy],rotation:t.angle,labelDirection:-1,tickDirection:-1,nameDirection:1})})),(function(t){E(_I,t.add,t),this.group.add(t.getGroup())}),this)},e.prototype._buildSplitLineAndArea=function(t){var e=t.coordinateSystem,n=e.getIndicatorAxes();if(n.length){var i=t.get("shape"),r=t.getModel("splitLine"),o=t.getModel("splitArea"),a=r.getModel("lineStyle"),s=o.getModel("areaStyle"),l=r.get("show"),u=o.get("show"),h=a.get("color"),c=s.get("color"),p=Y(h)?h:[h],d=Y(c)?c:[c],f=[],g=[];if("circle"===i)for(var y=n[0].getTicksCoords(),v=e.cx,m=e.cy,x=0;x3?1.4:r>1?1.2:1.1;AI(this,"zoom","zoomOnMouseWheel",t,{scale:i>0?s:1/s,originX:o,originY:a,isAvailableBehavior:null})}if(n){var l=Math.abs(i);AI(this,"scrollMove","moveOnMouseWheel",t,{scrollDelta:(i>0?1:-1)*(l>3?.4:l>1?.15:.05),originX:o,originY:a,isAvailableBehavior:null})}}},e.prototype._pinchHandler=function(t){TI(this._zr,"globalPan")||AI(this,"zoom",null,t,{scale:t.pinchScale>1?1.1:1/1.1,originX:t.pinchX,originY:t.pinchY,isAvailableBehavior:null})},e}(Xt);function AI(t,e,n,i,r){t.pointerChecker&&t.pointerChecker(i,r.originX,r.originY)&&(se(i.event),kI(t,e,n,i,r))}function kI(t,e,n,i,r){r.isAvailableBehavior=W(LI,null,n,i),t.trigger(e,r)}function LI(t,e,n){var i=n[t];return!t||i&&(!X(i)||e.event[i+"Key"])}function PI(t,e,n){var i=t.target;i.x+=e,i.y+=n,i.dirty()}function OI(t,e,n,i){var r=t.target,o=t.zoomLimit,a=t.zoom=t.zoom||1;if(a*=e,o){var s=o.min||0,l=o.max||1/0;a=Math.max(Math.min(l,a),s)}var u=a/t.zoom;t.zoom=a,r.x-=(n-r.x)*(u-1),r.y-=(i-r.y)*(u-1),r.scaleX*=u,r.scaleY*=u,r.dirty()}var RI,NI={axisPointer:1,tooltip:1,brush:1};function EI(t,e,n){var i=e.getComponentByElement(t.topTarget),r=i&&i.coordinateSystem;return i&&i!==n&&!NI.hasOwnProperty(i.mainType)&&r&&r.model!==n}function zI(t){X(t)&&(t=(new DOMParser).parseFromString(t,"text/xml"));var e=t;for(9===e.nodeType&&(e=e.firstChild);"svg"!==e.nodeName.toLowerCase()||1!==e.nodeType;)e=e.nextSibling;return e}var VI={fill:"fill",stroke:"stroke","stroke-width":"lineWidth",opacity:"opacity","fill-opacity":"fillOpacity","stroke-opacity":"strokeOpacity","stroke-dasharray":"lineDash","stroke-dashoffset":"lineDashOffset","stroke-linecap":"lineCap","stroke-linejoin":"lineJoin","stroke-miterlimit":"miterLimit","font-family":"fontFamily","font-size":"fontSize","font-style":"fontStyle","font-weight":"fontWeight","text-anchor":"textAlign",visibility:"visibility",display:"display"},BI=G(VI),FI={"alignment-baseline":"textBaseline","stop-color":"stopColor"},GI=G(FI),WI=function(){function t(){this._defs={},this._root=null}return t.prototype.parse=function(t,e){e=e||{};var n=zI(t);this._defsUsePending=[];var i=new Cr;this._root=i;var r=[],o=n.getAttribute("viewBox")||"",a=parseFloat(n.getAttribute("width")||e.width),s=parseFloat(n.getAttribute("height")||e.height);isNaN(a)&&(a=null),isNaN(s)&&(s=null),jI(n,i,null,!0,!1);for(var l,u,h=n.firstChild;h;)this._parseNode(h,i,r,null,!1,!1),h=h.nextSibling;if(function(t,e){for(var n=0;n=4&&(l={x:parseFloat(c[0]||0),y:parseFloat(c[1]||0),width:parseFloat(c[2]),height:parseFloat(c[3])})}if(l&&null!=a&&null!=s&&(u=iT(l,{x:0,y:0,width:a,height:s}),!e.ignoreViewBox)){var p=i;(i=new Cr).add(p),p.scaleX=p.scaleY=u.scale,p.x=u.x,p.y=u.y}return e.ignoreRootClip||null==a||null==s||i.setClipPath(new Ts({shape:{x:0,y:0,width:a,height:s}})),{root:i,width:a,height:s,viewBoxRect:l,viewBoxTransform:u,named:r}},t.prototype._parseNode=function(t,e,n,i,r,o){var a,s=t.nodeName.toLowerCase(),l=i;if("defs"===s&&(r=!0),"text"===s&&(o=!0),"defs"===s||"switch"===s)a=e;else{if(!r){var u=RI[s];if(u&&mt(RI,s)){a=u.call(this,t,e);var h=t.getAttribute("name");if(h){var c={name:h,namedFrom:null,svgNodeTagLower:s,el:a};n.push(c),"g"===s&&(l=c)}else i&&n.push({name:i.name,namedFrom:i,svgNodeTagLower:s,el:a});e.add(a)}}var p=HI[s];if(p&&mt(HI,s)){var d=p.call(this,t),f=t.getAttribute("id");f&&(this._defs[f]=d)}}if(a&&a.isGroup)for(var g=t.firstChild;g;)1===g.nodeType?this._parseNode(g,a,n,l,r,o):3===g.nodeType&&o&&this._parseText(g,a),g=g.nextSibling},t.prototype._parseText=function(t,e){var n=new ys({style:{text:t.textContent},silent:!0,x:this._textX||0,y:this._textY||0});XI(e,n),jI(t,n,this._defsUsePending,!1,!1),function(t,e){var n=e.__selfStyle;if(n){var i=n.textBaseline,r=i;i&&"auto"!==i?"baseline"===i?r="alphabetic":"before-edge"===i||"text-before-edge"===i?r="top":"after-edge"===i||"text-after-edge"===i?r="bottom":"central"!==i&&"mathematical"!==i||(r="middle"):r="alphabetic",t.style.textBaseline=r}var o=e.__inheritedStyle;if(o){var a=o.textAlign,s=a;a&&("middle"===a&&(s="center"),t.style.textAlign=s)}}(n,e);var i=n.style,r=i.fontSize;r&&r<9&&(i.fontSize=9,n.scaleX*=r/9,n.scaleY*=r/9);var o=(i.fontSize||i.fontFamily)&&[i.fontStyle,i.fontWeight,(i.fontSize||12)+"px",i.fontFamily||"sans-serif"].join(" ");i.font=o;var a=n.getBoundingRect();return this._textX+=a.width,e.add(n),n},t.internalField=void(RI={g:function(t,e){var n=new Cr;return XI(e,n),jI(t,n,this._defsUsePending,!1,!1),n},rect:function(t,e){var n=new Ts;return XI(e,n),jI(t,n,this._defsUsePending,!1,!1),n.setShape({x:parseFloat(t.getAttribute("x")||"0"),y:parseFloat(t.getAttribute("y")||"0"),width:parseFloat(t.getAttribute("width")||"0"),height:parseFloat(t.getAttribute("height")||"0")}),n.silent=!0,n},circle:function(t,e){var n=new uu;return XI(e,n),jI(t,n,this._defsUsePending,!1,!1),n.setShape({cx:parseFloat(t.getAttribute("cx")||"0"),cy:parseFloat(t.getAttribute("cy")||"0"),r:parseFloat(t.getAttribute("r")||"0")}),n.silent=!0,n},line:function(t,e){var n=new Eu;return XI(e,n),jI(t,n,this._defsUsePending,!1,!1),n.setShape({x1:parseFloat(t.getAttribute("x1")||"0"),y1:parseFloat(t.getAttribute("y1")||"0"),x2:parseFloat(t.getAttribute("x2")||"0"),y2:parseFloat(t.getAttribute("y2")||"0")}),n.silent=!0,n},ellipse:function(t,e){var n=new cu;return XI(e,n),jI(t,n,this._defsUsePending,!1,!1),n.setShape({cx:parseFloat(t.getAttribute("cx")||"0"),cy:parseFloat(t.getAttribute("cy")||"0"),rx:parseFloat(t.getAttribute("rx")||"0"),ry:parseFloat(t.getAttribute("ry")||"0")}),n.silent=!0,n},polygon:function(t,e){var n,i=t.getAttribute("points");i&&(n=ZI(i));var r=new Lu({shape:{points:n||[]},silent:!0});return XI(e,r),jI(t,r,this._defsUsePending,!1,!1),r},polyline:function(t,e){var n,i=t.getAttribute("points");i&&(n=ZI(i));var r=new Ou({shape:{points:n||[]},silent:!0});return XI(e,r),jI(t,r,this._defsUsePending,!1,!1),r},image:function(t,e){var n=new xs;return XI(e,n),jI(t,n,this._defsUsePending,!1,!1),n.setStyle({image:t.getAttribute("xlink:href")||t.getAttribute("href"),x:+t.getAttribute("x"),y:+t.getAttribute("y"),width:+t.getAttribute("width"),height:+t.getAttribute("height")}),n.silent=!0,n},text:function(t,e){var n=t.getAttribute("x")||"0",i=t.getAttribute("y")||"0",r=t.getAttribute("dx")||"0",o=t.getAttribute("dy")||"0";this._textX=parseFloat(n)+parseFloat(r),this._textY=parseFloat(i)+parseFloat(o);var a=new Cr;return XI(e,a),jI(t,a,this._defsUsePending,!1,!0),a},tspan:function(t,e){var n=t.getAttribute("x"),i=t.getAttribute("y");null!=n&&(this._textX=parseFloat(n)),null!=i&&(this._textY=parseFloat(i));var r=t.getAttribute("dx")||"0",o=t.getAttribute("dy")||"0",a=new Cr;return XI(e,a),jI(t,a,this._defsUsePending,!1,!0),this._textX+=parseFloat(r),this._textY+=parseFloat(o),a},path:function(t,e){var n=au(t.getAttribute("d")||"");return XI(e,n),jI(t,n,this._defsUsePending,!1,!1),n.silent=!0,n}}),t}(),HI={lineargradient:function(t){var e=parseInt(t.getAttribute("x1")||"0",10),n=parseInt(t.getAttribute("y1")||"0",10),i=parseInt(t.getAttribute("x2")||"10",10),r=parseInt(t.getAttribute("y2")||"0",10),o=new Uu(e,n,i,r);return YI(t,o),UI(t,o),o},radialgradient:function(t){var e=parseInt(t.getAttribute("cx")||"0",10),n=parseInt(t.getAttribute("cy")||"0",10),i=parseInt(t.getAttribute("r")||"0",10),r=new Xu(e,n,i);return YI(t,r),UI(t,r),r}};function YI(t,e){"userSpaceOnUse"===t.getAttribute("gradientUnits")&&(e.global=!0)}function UI(t,e){for(var n=t.firstChild;n;){if(1===n.nodeType&&"stop"===n.nodeName.toLocaleLowerCase()){var i=n.getAttribute("offset"),r=void 0;r=i&&i.indexOf("%")>0?parseInt(i,10)/100:i?parseFloat(i):0;var o={};nT(n,o,o);var a=o.stopColor||n.getAttribute("stop-color")||"#000000";e.colorStops.push({offset:r,color:a})}n=n.nextSibling}}function XI(t,e){t&&t.__inheritedStyle&&(e.__inheritedStyle||(e.__inheritedStyle={}),k(e.__inheritedStyle,t.__inheritedStyle))}function ZI(t){for(var e=JI(t),n=[],i=0;i0;o-=2){var a=i[o],s=i[o-1],l=JI(a);switch(r=r||[1,0,0,1,0,0],s){case"translate":Ei(r,r,[parseFloat(l[0]),parseFloat(l[1]||"0")]);break;case"scale":Vi(r,r,[parseFloat(l[0]),parseFloat(l[1]||l[0])]);break;case"rotate":zi(r,r,-parseFloat(l[0])*tT);break;case"skewX":Ni(r,[1,0,Math.tan(parseFloat(l[0])*tT),1,0,0],r);break;case"skewY":Ni(r,[1,Math.tan(parseFloat(l[0])*tT),0,1,0,0],r);break;case"matrix":r[0]=parseFloat(l[0]),r[1]=parseFloat(l[1]),r[2]=parseFloat(l[2]),r[3]=parseFloat(l[3]),r[4]=parseFloat(l[4]),r[5]=parseFloat(l[5])}}e.setLocalTransform(r)}}(t,e),nT(t,a,s),i||function(t,e,n){for(var i=0;i0,f={api:n,geo:s,mapOrGeoModel:t,data:a,isVisualEncodedByVisualMap:d,isGeo:o,transformInfoRaw:c};"geoJSON"===s.resourceType?this._buildGeoJSON(f):"geoSVG"===s.resourceType&&this._buildSVG(f),this._updateController(t,e,n),this._updateMapSelectHandler(t,l,n,i)},t.prototype._buildGeoJSON=function(t){var e=this._regionsGroupByName=ft(),n=ft(),i=this._regionsGroup,r=t.transformInfoRaw,o=t.mapOrGeoModel,a=t.data,s=t.geo.projection,l=s&&s.stream;function u(t,e){return e&&(t=e(t)),t&&[t[0]*r.scaleX+r.x,t[1]*r.scaleY+r.y]}function h(t){for(var e=[],n=!l&&s&&s.project,i=0;i=0)&&(p=r);var d=a?{normal:{align:"center",verticalAlign:"middle"}}:null;Wh(e,Hh(i),{labelFetcher:p,labelDataIndex:c,defaultText:n},d);var f=e.getTextContent();if(f&&(MT(f).ignore=f.ignore,e.textConfig&&a)){var g=e.getBoundingRect().clone();e.textConfig.layoutRect=g,e.textConfig.position=[(a[0]-g.x)/g.width*100+"%",(a[1]-g.y)/g.height*100+"%"]}e.disableLabelAnimation=!0}else e.removeTextContent(),e.removeTextConfig(),e.disableLabelAnimation=null}function kT(t,e,n,i,r,o){t.data?t.data.setItemGraphicEl(o,e):Ws(e).eventData={componentType:"geo",componentIndex:r.componentIndex,geoIndex:r.componentIndex,name:n,region:i&&i.option||{}}}function LT(t,e,n,i,r){t.data||Nh({el:e,componentModel:r,itemName:n,itemTooltipOption:i.get("tooltip")})}function PT(t,e,n,i,r){e.highDownSilentOnTouch=!!r.get("selectedMode");var o=i.getModel("emphasis"),a=o.get("focus");return Ol(e,a,o.get("blurScope"),o.get("disabled")),t.isGeo&&function(t,e,n){var i=Ws(t);i.componentMainType=e.mainType,i.componentIndex=e.componentIndex,i.componentHighDownName=n}(e,r,n),a}function OT(t,e,n){var i,r=[];function o(){i=[]}function a(){i.length&&(r.push(i),i=[])}var s=e({polygonStart:o,polygonEnd:a,lineStart:o,lineEnd:a,point:function(t,e){isFinite(t)&&isFinite(e)&&i.push([t,e])},sphere:function(){}});return!n&&s.polygonStart(),E(t,(function(t){s.lineStart();for(var e=0;e-1&&(n.style.stroke=n.style.fill,n.style.fill="#fff",n.style.lineWidth=2),n},e.type="series.map",e.dependencies=["geo"],e.layoutMode="box",e.defaultOption={z:2,coordinateSystem:"geo",map:"",left:"center",top:"center",aspectScale:null,showLegendSymbol:!0,boundingCoords:null,center:null,zoom:1,scaleLimit:null,selectedMode:!0,label:{show:!1,color:"#000"},itemStyle:{borderWidth:.5,borderColor:"#444",areaColor:"#eee"},emphasis:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{areaColor:"rgba(255,215,0,0.8)"}},select:{label:{show:!0,color:"rgb(100,0,0)"},itemStyle:{color:"rgba(255,215,0,0.8)"}},nameProperty:"name"},e}(ag);function ET(t){var e={};t.eachSeriesByType("map",(function(t){var n=t.getHostGeoModel(),i=n?"o"+n.id:"i"+t.getMapType();(e[i]=e[i]||[]).push(t)})),E(e,(function(t,e){for(var n,i,r,o=(n=z(t,(function(t){return t.getData()})),i=t[0].get("mapValueCalculation"),r={},E(n,(function(t){t.each(t.mapDimension("value"),(function(e,n){var i="ec-"+t.getName(n);r[i]=r[i]||[],isNaN(e)||r[i].push(e)}))})),n[0].map(n[0].mapDimension("value"),(function(t,e){for(var o="ec-"+n[0].getName(e),a=0,s=1/0,l=-1/0,u=r[o].length,h=0;h1?(d.width=p,d.height=p/x):(d.height=p,d.width=p*x),d.y=c[1]-d.height/2,d.x=c[0]-d.width/2;else{var b=t.getBoxLayoutParams();b.aspect=x,d=mp(b,{width:v,height:m})}this.setViewRect(d.x,d.y,d.width,d.height),this.setCenter(t.get("center")),this.setZoom(t.get("zoom"))}R(HT,BT);var XT=new(function(){function t(){this.dimensions=WT}return t.prototype.create=function(t,e){var n=[];function i(t){return{nameProperty:t.get("nameProperty"),aspectScale:t.get("aspectScale"),projection:t.get("projection")}}t.eachComponent("geo",(function(t,r){var o=t.get("map"),a=new HT(o+r,o,A({nameMap:t.get("nameMap")},i(t)));a.zoomLimit=t.get("scaleLimit"),n.push(a),t.coordinateSystem=a,a.model=t,a.resize=UT,a.resize(t,e)})),t.eachSeries((function(t){if("geo"===t.get("coordinateSystem")){var e=t.get("geoIndex")||0;t.coordinateSystem=n[e]}}));var r={};return t.eachSeriesByType("map",(function(t){if(!t.getHostGeoModel()){var e=t.getMapType();r[e]=r[e]||[],r[e].push(t)}})),E(r,(function(t,r){var o=z(t,(function(t){return t.get("nameMap")})),a=new HT(r,r,A({nameMap:D(o)},i(t[0])));a.zoomLimit=it.apply(null,z(t,(function(t){return t.get("scaleLimit")}))),n.push(a),a.resize=UT,a.resize(t[0],e),E(t,(function(t){t.coordinateSystem=a,function(t,e){E(e.get("geoCoord"),(function(e,n){t.addGeoCoord(n,e)}))}(a,t)}))})),n},t.prototype.getFilledRegions=function(t,e,n,i){for(var r=(t||[]).slice(),o=ft(),a=0;a=0;){var o=e[n];o.hierNode.prelim+=i,o.hierNode.modifier+=i,r+=o.hierNode.change,i+=o.hierNode.shift+r}}(t);var o=(n[0].hierNode.prelim+n[n.length-1].hierNode.prelim)/2;r?(t.hierNode.prelim=r.hierNode.prelim+e(t,r),t.hierNode.modifier=t.hierNode.prelim-o):t.hierNode.prelim=o}else r&&(t.hierNode.prelim=r.hierNode.prelim+e(t,r));t.parentNode.hierNode.defaultAncestor=function(t,e,n,i){if(e){for(var r=t,o=t,a=o.parentNode.children[0],s=e,l=r.hierNode.modifier,u=o.hierNode.modifier,h=a.hierNode.modifier,c=s.hierNode.modifier;s=iC(s),o=rC(o),s&&o;){r=iC(r),a=rC(a),r.hierNode.ancestor=t;var p=s.hierNode.prelim+c-o.hierNode.prelim-u+i(s,o);p>0&&(aC(oC(s,t,n),t,p),u+=p,l+=p),c+=s.hierNode.modifier,u+=o.hierNode.modifier,l+=r.hierNode.modifier,h+=a.hierNode.modifier}s&&!iC(r)&&(r.hierNode.thread=s,r.hierNode.modifier+=c-l),o&&!rC(a)&&(a.hierNode.thread=o,a.hierNode.modifier+=u-h,n=t)}return n}(t,r,t.parentNode.hierNode.defaultAncestor||i[0],e)}function tC(t){var e=t.hierNode.prelim+t.parentNode.hierNode.modifier;t.setLayout({x:e},!0),t.hierNode.modifier+=t.parentNode.hierNode.modifier}function eC(t){return arguments.length?t:sC}function nC(t,e){return t-=Math.PI/2,{x:e*Math.cos(t),y:e*Math.sin(t)}}function iC(t){var e=t.children;return e.length&&t.isExpand?e[e.length-1]:t.hierNode.thread}function rC(t){var e=t.children;return e.length&&t.isExpand?e[0]:t.hierNode.thread}function oC(t,e,n){return t.hierNode.ancestor.parentNode===e.parentNode?t.hierNode.ancestor:n}function aC(t,e,n){var i=n/(e.hierNode.i-t.hierNode.i);e.hierNode.change-=i,e.hierNode.shift+=n,e.hierNode.modifier+=n,e.hierNode.prelim+=n,t.hierNode.change+=i}function sC(t,e){return t.parentNode===e.parentNode?1:2}var lC=function(){this.parentPoint=[],this.childPoints=[]},uC=function(t){function e(e){return t.call(this,e)||this}return n(e,t),e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new lC},e.prototype.buildPath=function(t,e){var n=e.childPoints,i=n.length,r=e.parentPoint,o=n[0],a=n[i-1];if(1===i)return t.moveTo(r[0],r[1]),void t.lineTo(o[0],o[1]);var s=e.orient,l="TB"===s||"BT"===s?0:1,u=1-l,h=Er(e.forkPosition,1),c=[];c[l]=r[l],c[u]=r[u]+(a[u]-r[u])*h,t.moveTo(r[0],r[1]),t.lineTo(c[0],c[1]),t.moveTo(o[0],o[1]),c[l]=o[l],t.lineTo(c[0],c[1]),c[l]=a[l],t.lineTo(c[0],c[1]),t.lineTo(a[0],a[1]);for(var p=1;pm.x)||(_-=Math.PI);var S=b?"left":"right",M=s.getModel("label"),I=M.get("rotate"),T=I*(Math.PI/180),C=y.getTextContent();C&&(y.setTextConfig({position:M.get("position")||S,rotation:null==I?-_:T,origin:"center"}),C.setStyle("verticalAlign","middle"))}var D=s.get(["emphasis","focus"]),A="ancestor"===D?a.getAncestorsIndices():"descendant"===D?a.getDescendantIndices():null;A&&(Ws(n).focus=A),function(t,e,n,i,r,o,a,s){var l=e.getModel(),u=t.get("edgeShape"),h=t.get("layout"),c=t.getOrient(),p=t.get(["lineStyle","curveness"]),d=t.get("edgeForkPosition"),f=l.getModel("lineStyle").getLineStyle(),g=i.__edge;if("curve"===u)e.parentNode&&e.parentNode!==n&&(g||(g=i.__edge=new Fu({shape:yC(h,c,p,r,r)})),ih(g,{shape:yC(h,c,p,o,a)},t));else if("polyline"===u)if("orthogonal"===h){if(e!==n&&e.children&&0!==e.children.length&&!0===e.isExpand){for(var y=e.children,v=[],m=0;me&&(e=i.height)}this.height=e+1},t.prototype.getNodeById=function(t){if(this.getId()===t)return this;for(var e=0,n=this.children,i=n.length;e=0&&this.hostTree.data.setItemLayout(this.dataIndex,t,e)},t.prototype.getLayout=function(){return this.hostTree.data.getItemLayout(this.dataIndex)},t.prototype.getModel=function(t){if(!(this.dataIndex<0))return this.hostTree.data.getItemModel(this.dataIndex).getModel(t)},t.prototype.getLevelModel=function(){return(this.hostTree.levelModels||[])[this.depth]},t.prototype.setVisual=function(t,e){this.dataIndex>=0&&this.hostTree.data.setItemVisual(this.dataIndex,t,e)},t.prototype.getVisual=function(t){return this.hostTree.data.getItemVisual(this.dataIndex,t)},t.prototype.getRawIndex=function(){return this.hostTree.data.getRawIndex(this.dataIndex)},t.prototype.getId=function(){return this.hostTree.data.getId(this.dataIndex)},t.prototype.getChildIndex=function(){if(this.parentNode){for(var t=this.parentNode.children,e=0;e=0){var i=n.getData().tree.root,r=t.targetNode;if(X(r)&&(r=i.getNodeById(r)),r&&i.contains(r))return{node:r};var o=t.targetNodeId;if(null!=o&&(r=i.getNodeById(o)))return{node:r}}}function AC(t){for(var e=[];t;)(t=t.parentNode)&&e.push(t);return e.reverse()}function kC(t,e){return P(AC(t),e)>=0}function LC(t,e){for(var n=[];t;){var i=t.dataIndex;n.push({name:t.name,dataIndex:i,value:e.getRawValue(i)}),t=t.parentNode}return n.reverse(),n}var PC=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.hasSymbolVisual=!0,e.ignoreStyleOnData=!0,e}return n(e,t),e.prototype.getInitialData=function(t){var e={name:t.name,children:t.data},n=t.leaves||{},i=new pc(n,this,this.ecModel),r=CC.createTree(e,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=r.getNodeByDataIndex(e);return n&&n.children.length&&n.isExpand||(t.parentModel=i),t}))}));var o=0;r.eachNode("preorder",(function(t){t.depth>o&&(o=t.depth)}));var a=t.expandAndCollapse&&t.initialTreeDepth>=0?t.initialTreeDepth:o;return r.root.eachNode("preorder",(function(t){var e=t.hostTree.data.getRawDataItem(t.dataIndex);t.isExpand=e&&null!=e.collapsed?!e.collapsed:t.depth<=a})),r.data},e.prototype.getOrient=function(){var t=this.get("orient");return"horizontal"===t?t="LR":"vertical"===t&&(t="TB"),t},e.prototype.setZoom=function(t){this.option.zoom=t},e.prototype.setCenter=function(t){this.option.center=t},e.prototype.formatTooltip=function(t,e,n){for(var i=this.getData().tree,r=i.root.children[0],o=i.getNodeByDataIndex(t),a=o.getValue(),s=o.name;o&&o!==r;)s=o.parentNode.name+"."+s,o=o.parentNode;return Uf("nameValue",{name:s,value:a,noValue:isNaN(a)||null==a})},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treeAncestors=LC(i,this),n},e.type="series.tree",e.layoutMode="box",e.defaultOption={z:2,coordinateSystem:"view",left:"12%",top:"12%",right:"12%",bottom:"12%",layout:"orthogonal",edgeShape:"curve",edgeForkPosition:"50%",roam:!1,nodeScaleRatio:.4,center:null,zoom:1,orient:"LR",symbol:"emptyCircle",symbolSize:7,expandAndCollapse:!0,initialTreeDepth:2,lineStyle:{color:"#ccc",width:1.5,curveness:.5},itemStyle:{color:"lightsteelblue",borderWidth:1.5},label:{show:!0},animationEasing:"linear",animationDuration:700,animationDurationUpdate:500},e}(ag);function OC(t,e){for(var n,i=[t];n=i.pop();)if(e(n),n.isExpand){var r=n.children;if(r.length)for(var o=r.length-1;o>=0;o--)i.push(r[o])}}function RC(t,e){t.eachSeriesByType("tree",(function(t){!function(t,e){var n=function(t,e){return mp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e);t.layoutInfo=n;var i=t.get("layout"),r=0,o=0,a=null;"radial"===i?(r=2*Math.PI,o=Math.min(n.height,n.width)/2,a=eC((function(t,e){return(t.parentNode===e.parentNode?1:2)/t.depth}))):(r=n.width,o=n.height,a=eC());var s=t.getData().tree.root,l=s.children[0];if(l){!function(t){var e=t;e.hierNode={defaultAncestor:null,ancestor:e,prelim:0,modifier:0,change:0,shift:0,i:0,thread:null};for(var n,i,r=[e];n=r.pop();)if(i=n.children,n.isExpand&&i.length)for(var o=i.length-1;o>=0;o--){var a=i[o];a.hierNode={defaultAncestor:null,ancestor:a,prelim:0,modifier:0,change:0,shift:0,i:o,thread:null},r.push(a)}}(s),function(t,e,n){for(var i,r=[t],o=[];i=r.pop();)if(o.push(i),i.isExpand){var a=i.children;if(a.length)for(var s=0;sh.getLayout().x&&(h=t),t.depth>c.depth&&(c=t)}));var p=u===h?1:a(u,h)/2,d=p-u.getLayout().x,f=0,g=0,y=0,v=0;if("radial"===i)f=r/(h.getLayout().x+p+d),g=o/(c.depth-1||1),OC(l,(function(t){y=(t.getLayout().x+d)*f,v=(t.depth-1)*g;var e=nC(y,v);t.setLayout({x:e.x,y:e.y,rawX:y,rawY:v},!0)}));else{var m=t.getOrient();"RL"===m||"LR"===m?(g=o/(h.getLayout().x+p+d),f=r/(c.depth-1||1),OC(l,(function(t){v=(t.getLayout().x+d)*g,y="LR"===m?(t.depth-1)*f:r-(t.depth-1)*f,t.setLayout({x:y,y:v},!0)}))):"TB"!==m&&"BT"!==m||(f=r/(h.getLayout().x+p+d),g=o/(c.depth-1||1),OC(l,(function(t){y=(t.getLayout().x+d)*f,v="TB"===m?(t.depth-1)*g:o-(t.depth-1)*g,t.setLayout({x:y,y:v},!0)})))}}}(t,e)}))}function NC(t){t.eachSeriesByType("tree",(function(t){var e=t.getData();e.tree.eachNode((function(t){var n=t.getModel().getModel("itemStyle").getItemStyle();A(e.ensureUniqueItemVisual(t.dataIndex,"style"),n)}))}))}var EC=["treemapZoomToNode","treemapRender","treemapMove"];function zC(t){var e=t.getData().tree,n={};e.eachNode((function(e){for(var i=e;i&&i.depth>1;)i=i.parentNode;var r=td(t.ecModel,i.name||i.dataIndex+"",n);e.setVisual("decal",r)}))}var VC=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.preventUsingHoverLayer=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){var n={name:t.name,children:t.data};BC(n);var i=t.levels||[],r=this.designatedVisualItemStyle={},o=new pc({itemStyle:r},this,e),a=z((i=t.levels=function(t,e){var n,i,r=ho(e.get("color")),o=ho(e.get(["aria","decal","decals"]));if(!r)return;E(t=t||[],(function(t){var e=new pc(t),r=e.get("color"),o=e.get("decal");(e.get(["itemStyle","color"])||r&&"none"!==r)&&(n=!0),(e.get(["itemStyle","decal"])||o&&"none"!==o)&&(i=!0)}));var a=t[0]||(t[0]={});n||(a.color=r.slice());!i&&o&&(a.decal=o.slice());return t}(i,e))||[],(function(t){return new pc(t,o,e)}),this),s=CC.createTree(n,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=s.getNodeByDataIndex(e),i=n?a[n.depth]:null;return t.parentModel=i||o,t}))}));return s.data},e.prototype.optionUpdated=function(){this.resetViewRoot()},e.prototype.formatTooltip=function(t,e,n){var i=this.getData(),r=this.getRawValue(t);return Uf("nameValue",{name:i.getName(t),value:r})},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treeAncestors=LC(i,this),n.treePathInfo=n.treeAncestors,n},e.prototype.setLayoutInfo=function(t){this.layoutInfo=this.layoutInfo||{},A(this.layoutInfo,t)},e.prototype.mapIdToIndex=function(t){var e=this._idIndexMap;e||(e=this._idIndexMap=ft(),this._idIndexMapCount=0);var n=e.get(t);return null==n&&e.set(t,n=this._idIndexMapCount++),n},e.prototype.getViewRoot=function(){return this._viewRoot},e.prototype.resetViewRoot=function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)},e.prototype.enableAriaDecal=function(){zC(this)},e.type="series.treemap",e.layoutMode="box",e.defaultOption={progressive:0,left:"center",top:"middle",width:"80%",height:"80%",sort:!0,clipWindow:"origin",squareRatio:.5*(1+Math.sqrt(5)),leafDepth:null,drillDownIcon:"▶",zoomToNodeRatio:.1024,roam:!0,nodeClick:"zoomToNode",animation:!0,animationDurationUpdate:900,animationEasing:"quinticInOut",breadcrumb:{show:!0,height:22,left:"center",top:"bottom",emptyItemWidth:25,itemStyle:{color:"rgba(0,0,0,0.7)",textStyle:{color:"#fff"}}},label:{show:!0,distance:0,padding:5,position:"inside",color:"#fff",overflow:"truncate"},upperLabel:{show:!1,position:[0,"50%"],height:20,overflow:"truncate",verticalAlign:"middle"},itemStyle:{color:null,colorAlpha:null,colorSaturation:null,borderWidth:0,gapWidth:0,borderColor:"#fff",borderColorSaturation:null},emphasis:{upperLabel:{show:!0,position:[0,"50%"],overflow:"truncate",verticalAlign:"middle"}},visualDimension:0,visualMin:null,visualMax:null,color:[],colorAlpha:null,colorSaturation:null,colorMappingBy:"index",visibleMin:10,childrenVisibleMin:null,levels:[]},e}(ag);function BC(t){var e=0;E(t.children,(function(t){BC(t);var n=t.value;Y(n)&&(n=n[0]),e+=n}));var n=t.value;Y(n)&&(n=n[0]),(null==n||isNaN(n))&&(n=e),n<0&&(n=0),Y(t.value)?t.value[0]=n:t.value=n}var FC=function(){function t(t){this.group=new Cr,t.add(this.group)}return t.prototype.render=function(t,e,n,i){var r=t.getModel("breadcrumb"),o=this.group;if(o.removeAll(),r.get("show")&&n){var a=r.getModel("itemStyle"),s=a.getModel("textStyle"),l={pos:{left:r.get("left"),right:r.get("right"),top:r.get("top"),bottom:r.get("bottom")},box:{width:e.getWidth(),height:e.getHeight()},emptyItemWidth:r.get("emptyItemWidth"),totalWidth:0,renderList:[]};this._prepare(n,l,s),this._renderContent(t,l,a,s,i),xp(o,l.pos,l.box)}},t.prototype._prepare=function(t,e,n){for(var i=t;i;i=i.parentNode){var r=xo(i.getModel().get("name"),""),o=n.getTextRect(r),a=Math.max(o.width+16,e.emptyItemWidth);e.totalWidth+=a+8,e.renderList.push({node:i,text:r,width:a})}},t.prototype._renderContent=function(t,e,n,i,r){for(var o,a,s,l,u,h,c,p,d,f=0,g=e.emptyItemWidth,y=t.get(["breadcrumb","height"]),v=(o=e.pos,a=e.box,l=a.width,u=a.height,h=Er(o.left,l),c=Er(o.top,u),p=Er(o.right,l),d=Er(o.bottom,u),(isNaN(h)||isNaN(parseFloat(o.left)))&&(h=0),(isNaN(p)||isNaN(parseFloat(o.right)))&&(p=l),(isNaN(c)||isNaN(parseFloat(o.top)))&&(c=0),(isNaN(d)||isNaN(parseFloat(o.bottom)))&&(d=u),s=np(s||0),{width:Math.max(p-h-s[1]-s[3],0),height:Math.max(d-c-s[0]-s[2],0)}),m=e.totalWidth,x=e.renderList,_=x.length-1;_>=0;_--){var b=x[_],w=b.node,S=b.width,M=b.text;m>v.width&&(m-=S-g,S=g,M=null);var I=new Lu({shape:{points:GC(f,0,S,y,_===x.length-1,0===_)},style:k(n.getItemStyle(),{lineJoin:"bevel"}),textContent:new As({style:{text:M,fill:i.getTextColor(),font:i.getFont()}}),textConfig:{position:"inside"},z2:1e5,onclick:H(r,w)});I.disableLabelAnimation=!0,this.group.add(I),WC(I,t,w),f+=S+8}},t.prototype.remove=function(){this.group.removeAll()},t}();function GC(t,e,n,i,r,o){var a=[[r?t:t-5,e],[t+n,e],[t+n,e+i],[r?t:t-5,e+i]];return!o&&a.splice(2,0,[t+n+5,e+i/2]),!r&&a.push([t,e+i/2]),a}function WC(t,e,n){Ws(t).eventData={componentType:"series",componentSubType:"treemap",componentIndex:e.componentIndex,seriesIndex:e.seriesIndex,seriesName:e.name,seriesType:"treemap",selfType:"breadcrumb",nodeData:{dataIndex:n&&n.dataIndex,name:n&&n.name},treePathInfo:n&&LC(n,e)}}var HC=function(){function t(){this._storage=[],this._elExistsMap={}}return t.prototype.add=function(t,e,n,i,r){return!this._elExistsMap[t.id]&&(this._elExistsMap[t.id]=!0,this._storage.push({el:t,target:e,duration:n,delay:i,easing:r}),!0)},t.prototype.finished=function(t){return this._finishedCallback=t,this},t.prototype.start=function(){for(var t=this,e=this._storage.length,n=function(){--e<=0&&(t._storage.length=0,t._elExistsMap={},t._finishedCallback&&t._finishedCallback())},i=0,r=this._storage.length;i3||Math.abs(t.dy)>3)){var e=this.seriesModel.getData().tree.root;if(!e)return;var n=e.getLayout();if(!n)return;this.api.dispatchAction({type:"treemapMove",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:n.x+t.dx,y:n.y+t.dy,width:n.width,height:n.height}})}},e.prototype._onZoom=function(t){var e=t.originX,n=t.originY;if("animating"!==this._state){var i=this.seriesModel.getData().tree.root;if(!i)return;var r=i.getLayout();if(!r)return;var o=new sr(r.x,r.y,r.width,r.height),a=this.seriesModel.layoutInfo,s=[1,0,0,1,0,0];Ei(s,s,[-(e-=a.x),-(n-=a.y)]),Vi(s,s,[t.scale,t.scale]),Ei(s,s,[e,n]),o.applyTransform(s),this.api.dispatchAction({type:"treemapRender",from:this.uid,seriesId:this.seriesModel.id,rootRect:{x:o.x,y:o.y,width:o.width,height:o.height}})}},e.prototype._initEvents=function(t){var e=this;t.on("click",(function(t){if("ready"===e._state){var n=e.seriesModel.get("nodeClick",!0);if(n){var i=e.findTarget(t.offsetX,t.offsetY);if(i){var r=i.node;if(r.getLayout().isLeafRoot)e._rootToNode(i);else if("zoomToNode"===n)e._zoomToNode(i);else if("link"===n){var o=r.hostTree.data.getItemModel(r.dataIndex),a=o.get("link",!0),s=o.get("target",!0)||"blank";a&&pp(a,s)}}}}}),this)},e.prototype._renderBreadcrumb=function(t,e,n){var i=this;n||(n=null!=t.get("leafDepth",!0)?{node:t.getViewRoot()}:this.findTarget(e.getWidth()/2,e.getHeight()/2))||(n={node:t.getData().tree.root}),(this._breadcrumb||(this._breadcrumb=new FC(this.group))).render(t,e,n.node,(function(e){"animating"!==i._state&&(kC(t.getViewRoot(),e)?i._rootToNode({node:e}):i._zoomToNode({node:e}))}))},e.prototype.remove=function(){this._clearController(),this._containerGroup&&this._containerGroup.removeAll(),this._storage={nodeGroup:[],background:[],content:[]},this._state="ready",this._breadcrumb&&this._breadcrumb.remove()},e.prototype.dispose=function(){this._clearController()},e.prototype._zoomToNode=function(t){this.api.dispatchAction({type:"treemapZoomToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},e.prototype._rootToNode=function(t){this.api.dispatchAction({type:"treemapRootToNode",from:this.uid,seriesId:this.seriesModel.id,targetNode:t.node})},e.prototype.findTarget=function(t,e){var n;return this.seriesModel.getViewRoot().eachNode({attr:"viewChildren",order:"preorder"},(function(i){var r=this._storage.background[i.getRawIndex()];if(r){var o=r.transformCoordToLocal(t,e),a=r.shape;if(!(a.x<=o[0]&&o[0]<=a.x+a.width&&a.y<=o[1]&&o[1]<=a.y+a.height))return!1;n={node:i,offsetX:o[0],offsetY:o[1]}}}),this),n},e.type="treemap",e}(mg);var JC=E,QC=q,tD=-1,eD=function(){function t(e){var n=e.mappingMethod,i=e.type,r=this.option=T(e);this.type=i,this.mappingMethod=n,this._normalizeData=cD[n];var o=t.visualHandlers[i];this.applyVisual=o.applyVisual,this.getColorMapper=o.getColorMapper,this._normalizedToVisual=o._normalizedToVisual[n],"piecewise"===n?(nD(r),function(t){var e=t.pieceList;t.hasSpecialVisual=!1,E(e,(function(e,n){e.originIndex=n,null!=e.visual&&(t.hasSpecialVisual=!0)}))}(r)):"category"===n?r.categories?function(t){var e=t.categories,n=t.categoryMap={},i=t.visual;if(JC(e,(function(t,e){n[t]=e})),!Y(i)){var r=[];q(i)?JC(i,(function(t,e){var i=n[e];r[null!=i?i:tD]=t})):r[-1]=i,i=hD(t,r)}for(var o=e.length-1;o>=0;o--)null==i[o]&&(delete n[e[o]],e.pop())}(r):nD(r,!0):(lt("linear"!==n||r.dataExtent),nD(r))}return t.prototype.mapValueToVisual=function(t){var e=this._normalizeData(t);return this._normalizedToVisual(e,t)},t.prototype.getNormalizer=function(){return W(this._normalizeData,this)},t.listVisualTypes=function(){return G(t.visualHandlers)},t.isValidType=function(e){return t.visualHandlers.hasOwnProperty(e)},t.eachVisual=function(t,e,n){q(t)?E(t,e,n):e.call(n,t)},t.mapVisual=function(e,n,i){var r,o=Y(e)?[]:q(e)?{}:(r=!0,null);return t.eachVisual(e,(function(t,e){var a=n.call(i,t,e);r?o=a:o[e]=a})),o},t.retrieveVisuals=function(e){var n,i={};return e&&JC(t.visualHandlers,(function(t,r){e.hasOwnProperty(r)&&(i[r]=e[r],n=!0)})),n?i:null},t.prepareVisualTypes=function(t){if(Y(t))t=t.slice();else{if(!QC(t))return[];var e=[];JC(t,(function(t,n){e.push(n)})),t=e}return t.sort((function(t,e){return"color"===e&&"color"!==t&&0===t.indexOf("color")?1:-1})),t},t.dependsOn=function(t,e){return"color"===e?!(!t||0!==t.indexOf(e)):t===e},t.findPieceIndex=function(t,e,n){for(var i,r=1/0,o=0,a=e.length;ou[1]&&(u[1]=l);var h=e.get("colorMappingBy"),c={type:a.name,dataExtent:u,visual:a.range};"color"!==c.type||"index"!==h&&"id"!==h?c.mappingMethod="linear":(c.mappingMethod="category",c.loop=!0);var p=new eD(c);return dD(p).drColorMappingBy=h,p}(0,r,o,0,u,d);E(d,(function(t,e){if(t.depth>=n.length||t===n[t.depth]){var o=function(t,e,n,i,r,o){var a=A({},e);if(r){var s=r.type,l="color"===s&&dD(r).drColorMappingBy,u="index"===l?i:"id"===l?o.mapIdToIndex(n.getId()):n.getValue(t.get("visualDimension"));a[s]=r.mapValueToVisual(u)}return a}(r,u,t,e,f,i);gD(t,o,n,i)}}))}else s=yD(u),h.fill=s}}function yD(t){var e=vD(t,"color");if(e){var n=vD(t,"colorAlpha"),i=vD(t,"colorSaturation");return i&&(e=Dn(e,null,null,i)),n&&(e=An(e,n)),e}}function vD(t,e){var n=t[e];if(null!=n&&"none"!==n)return n}function mD(t,e){var n=t.get(e);return Y(n)&&n.length?{name:e,range:n}:null}var xD=Math.max,_D=Math.min,bD=it,wD=E,SD=["itemStyle","borderWidth"],MD=["itemStyle","gapWidth"],ID=["upperLabel","show"],TD=["upperLabel","height"],CD={seriesType:"treemap",reset:function(t,e,n,i){var r=n.getWidth(),o=n.getHeight(),a=t.option,s=mp(t.getBoxLayoutParams(),{width:n.getWidth(),height:n.getHeight()}),l=a.size||[],u=Er(bD(s.width,l[0]),r),h=Er(bD(s.height,l[1]),o),c=i&&i.type,p=DC(i,["treemapZoomToNode","treemapRootToNode"],t),d="treemapRender"===c||"treemapMove"===c?i.rootRect:null,f=t.getViewRoot(),g=AC(f);if("treemapMove"!==c){var y="treemapZoomToNode"===c?function(t,e,n,i,r){var o,a=(e||{}).node,s=[i,r];if(!a||a===n)return s;var l=i*r,u=l*t.option.zoomToNodeRatio;for(;o=a.parentNode;){for(var h=0,c=o.children,p=0,d=c.length;pYr&&(u=Yr),a=o}ua[1]&&(a[1]=e)}))):a=[NaN,NaN];return{sum:i,dataExtent:a}}(e,a,s);if(0===u.sum)return t.viewChildren=[];if(u.sum=function(t,e,n,i,r){if(!i)return n;for(var o=t.get("visibleMin"),a=r.length,s=a,l=a-1;l>=0;l--){var u=r["asc"===i?a-l-1:l].getValue();u/n*ei&&(i=a));var l=t.area*t.area,u=e*e*n;return l?xD(u*i/l,l/(u*r)):1/0}function kD(t,e,n,i,r){var o=e===n.width?0:1,a=1-o,s=["x","y"],l=["width","height"],u=n[s[o]],h=e?t.area/e:0;(r||h>n[l[a]])&&(h=n[l[a]]);for(var c=0,p=t.length;ci&&(i=e);var o=i%2?i+2:i+3;r=[];for(var a=0;a0&&(m[0]=-m[0],m[1]=-m[1]);var _=v[0]<0?-1:1;if("start"!==i.__position&&"end"!==i.__position){var b=-Math.atan2(v[1],v[0]);u[0].8?"left":h[0]<-.8?"right":"center",p=h[1]>.8?"top":h[1]<-.8?"bottom":"middle";break;case"start":i.x=-h[0]*f+l[0],i.y=-h[1]*g+l[1],c=h[0]>.8?"right":h[0]<-.8?"left":"center",p=h[1]>.8?"bottom":h[1]<-.8?"top":"middle";break;case"insideStartTop":case"insideStart":case"insideStartBottom":i.x=f*_+l[0],i.y=l[1]+w,c=v[0]<0?"right":"left",i.originX=-f*_,i.originY=-w;break;case"insideMiddleTop":case"insideMiddle":case"insideMiddleBottom":case"middle":i.x=x[0],i.y=x[1]+w,c="center",i.originY=-w;break;case"insideEndTop":case"insideEnd":case"insideEndBottom":i.x=-f*_+u[0],i.y=u[1]+w,c=v[0]>=0?"right":"left",i.originX=f*_,i.originY=-w}i.scaleX=i.scaleY=r,i.setStyle({verticalAlign:i.__verticalAlign||p,align:i.__align||c})}}}function S(t,e){var n=t.__specifiedRotation;if(null==n){var i=a.tangentAt(e);t.attr("rotation",(1===e?-1:1)*Math.PI/2-Math.atan2(i[1],i[0]))}else t.attr("rotation",n)}},e}(Cr),dA=function(){function t(t){this.group=new Cr,this._LineCtor=t||pA}return t.prototype.updateData=function(t){var e=this;this._progressiveEls=null;var n=this,i=n.group,r=n._lineData;n._lineData=t,r||i.removeAll();var o=fA(t);t.diff(r).add((function(n){e._doAdd(t,n,o)})).update((function(n,i){e._doUpdate(r,t,i,n,o)})).remove((function(t){i.remove(r.getItemGraphicEl(t))})).execute()},t.prototype.updateLayout=function(){var t=this._lineData;t&&t.eachItemGraphicEl((function(e,n){e.updateLayout(t,n)}),this)},t.prototype.incrementalPrepareUpdate=function(t){this._seriesScope=fA(t),this._lineData=null,this.group.removeAll()},t.prototype.incrementalUpdate=function(t,e){function n(t){t.isGroup||function(t){return t.animators&&t.animators.length>0}(t)||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}this._progressiveEls=[];for(var i=t.start;i=0?i+=u:i-=u:f>=0?i-=u:i+=u}return i}function MA(t,e){var n=[],i=Qe,r=[[],[],[]],o=[[],[]],a=[];e/=2,t.eachEdge((function(t,s){var l=t.getLayout(),u=t.getVisual("fromSymbol"),h=t.getVisual("toSymbol");l.__original||(l.__original=[Mt(l[0]),Mt(l[1])],l[2]&&l.__original.push(Mt(l[2])));var c=l.__original;if(null!=l[2]){if(St(r[0],c[0]),St(r[1],c[2]),St(r[2],c[1]),u&&"none"!==u){var p=jD(t.node1),d=SA(r,c[0],p*e);i(r[0][0],r[1][0],r[2][0],d,n),r[0][0]=n[3],r[1][0]=n[4],i(r[0][1],r[1][1],r[2][1],d,n),r[0][1]=n[3],r[1][1]=n[4]}if(h&&"none"!==h){p=jD(t.node2),d=SA(r,c[1],p*e);i(r[0][0],r[1][0],r[2][0],d,n),r[1][0]=n[1],r[2][0]=n[2],i(r[0][1],r[1][1],r[2][1],d,n),r[1][1]=n[1],r[2][1]=n[2]}St(l[0],r[0]),St(l[1],r[2]),St(l[2],r[1])}else{if(St(o[0],c[0]),St(o[1],c[1]),Dt(a,o[1],o[0]),Rt(a,a),u&&"none"!==u){p=jD(t.node1);Ct(o[0],o[0],a,p*e)}if(h&&"none"!==h){p=jD(t.node2);Ct(o[1],o[1],a,-p*e)}St(l[0],o[0]),St(l[1],o[1])}}))}function IA(t){return"view"===t.type}var TA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){var n=new Zw,i=new dA,r=this.group;this._controller=new DI(e.getZr()),this._controllerHost={target:r},r.add(n.group),r.add(i.group),this._symbolDraw=n,this._lineDraw=i,this._firstRender=!0},e.prototype.render=function(t,e,n){var i=this,r=t.coordinateSystem;this._model=t;var o=this._symbolDraw,a=this._lineDraw,s=this.group;if(IA(r)){var l={x:r.x,y:r.y,scaleX:r.scaleX,scaleY:r.scaleY};this._firstRender?s.attr(l):ih(s,l,t)}MA(t.getGraph(),ZD(t));var u=t.getData();o.updateData(u);var h=t.getEdgeData();a.updateData(h),this._updateNodeAndLinkScale(),this._updateController(t,e,n),clearTimeout(this._layoutTimeout);var c=t.forceLayout,p=t.get(["force","layoutAnimation"]);c&&this._startForceLayoutIteration(c,p),u.graph.eachNode((function(t){var e=t.dataIndex,n=t.getGraphicEl(),r=t.getModel();if(n){n.off("drag").off("dragend");var o=r.get("draggable");o&&n.on("drag",(function(){c&&(c.warmUp(),!i._layouting&&i._startForceLayoutIteration(c,p),c.setFixed(e),u.setItemLayout(e,[n.x,n.y]))})).on("dragend",(function(){c&&c.setUnfixed(e)})),n.setDraggable(o&&!!c),"adjacency"===r.get(["emphasis","focus"])&&(Ws(n).focus=t.getAdjacentDataIndices())}})),u.graph.eachEdge((function(t){var e=t.getGraphicEl(),n=t.getModel().get(["emphasis","focus"]);e&&"adjacency"===n&&(Ws(e).focus={edge:[t.dataIndex],node:[t.node1.dataIndex,t.node2.dataIndex]})}));var d="circular"===t.get("layout")&&t.get(["circular","rotateLabel"]),f=u.getLayout("cx"),g=u.getLayout("cy");u.eachItemGraphicEl((function(t,e){var n=u.getItemModel(e).get(["label","rotate"])||0,i=t.getSymbolPath();if(d){var r=u.getItemLayout(e),o=Math.atan2(r[1]-g,r[0]-f);o<0&&(o=2*Math.PI+o);var a=r[0]=0&&t.call(e,n[r],r)},t.prototype.eachEdge=function(t,e){for(var n=this.edges,i=n.length,r=0;r=0&&n[r].node1.dataIndex>=0&&n[r].node2.dataIndex>=0&&t.call(e,n[r],r)},t.prototype.breadthFirstTraverse=function(t,e,n,i){if(e instanceof AA||(e=this._nodesMap[CA(e)]),e){for(var r="out"===n?"outEdges":"in"===n?"inEdges":"edges",o=0;o=0&&n.node2.dataIndex>=0}));for(r=0,o=i.length;r=0&&this[t][e].setItemVisual(this.dataIndex,n,i)},getVisual:function(n){return this[t][e].getItemVisual(this.dataIndex,n)},setLayout:function(n,i){this.dataIndex>=0&&this[t][e].setItemLayout(this.dataIndex,n,i)},getLayout:function(){return this[t][e].getItemLayout(this.dataIndex)},getGraphicEl:function(){return this[t][e].getItemGraphicEl(this.dataIndex)},getRawIndex:function(){return this[t][e].getRawIndex(this.dataIndex)}}}function PA(t,e,n,i,r){for(var o=new DA(i),a=0;a "+p)),u++)}var d,f=n.get("coordinateSystem");if("cartesian2d"===f||"polar"===f)d=nx(t,n);else{var g=ud.get(f),y=g&&g.dimensions||[];P(y,"value")<0&&y.concat(["value"]);var v=jm(t,{coordDimensions:y,encodeDefine:n.getEncode()}).dimensions;(d=new Zm(v,n)).initData(t)}var m=new Zm(["value"],n);return m.initData(l,s),r&&r(d,m),mC({mainData:d,struct:o,structAttr:"graph",datas:{node:d,edge:m},datasAttr:{node:"data",edge:"edgeData"}}),o.update(),o}R(AA,LA("hostGraph","data")),R(kA,LA("hostGraph","edgeData"));var OA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments);var n=this;function i(){return n._categoriesData}this.legendVisualProvider=new lM(i,i),this.fillDataTextStyle(e.edges||e.links),this._updateCategoriesData()},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),this.fillDataTextStyle(e.edges||e.links),this._updateCategoriesData()},e.prototype.mergeDefaultAndTheme=function(e){t.prototype.mergeDefaultAndTheme.apply(this,arguments),co(e,"edgeLabel",["show"])},e.prototype.getInitialData=function(t,e){var n,i=t.edges||t.links||[],r=t.data||t.nodes||[],o=this;if(r&&i){VD(n=this)&&(n.__curvenessList=[],n.__edgeMap={},BD(n));var a=PA(r,i,this,!0,(function(t,e){t.wrapMethod("getItemModel",(function(t){var e=o._categoriesModels[t.getShallow("category")];return e&&(e.parentModel=t.parentModel,t.parentModel=e),t}));var n=pc.prototype.getModel;function i(t,e){var i=n.call(this,t,e);return i.resolveParentPath=r,i}function r(t){if(t&&("label"===t[0]||"label"===t[1])){var e=t.slice();return"label"===t[0]?e[0]="edgeLabel":"label"===t[1]&&(e[1]="edgeLabel"),e}return t}e.wrapMethod("getItemModel",(function(t){return t.resolveParentPath=r,t.getModel=i,t}))}));return E(a.edges,(function(t){!function(t,e,n,i){if(VD(n)){var r=FD(t,e,n),o=n.__edgeMap,a=o[GD(r)];o[r]&&!a?o[r].isForward=!0:a&&o[r]&&(a.isForward=!0,o[r].isForward=!1),o[r]=o[r]||[],o[r].push(i)}}(t.node1,t.node2,this,t.dataIndex)}),this),a.data}},e.prototype.getGraph=function(){return this.getData().graph},e.prototype.getEdgeData=function(){return this.getGraph().edgeData},e.prototype.getCategoriesData=function(){return this._categoriesData},e.prototype.formatTooltip=function(t,e,n){if("edge"===n){var i=this.getData(),r=this.getDataParams(t,n),o=i.graph.getEdgeByIndex(t),a=i.getName(o.node1.dataIndex),s=i.getName(o.node2.dataIndex),l=[];return null!=a&&l.push(a),null!=s&&l.push(s),Uf("nameValue",{name:l.join(" > "),value:r.value,noValue:null==r.value})}return ig({series:this,dataIndex:t,multipleSeries:e})},e.prototype._updateCategoriesData=function(){var t=z(this.option.categories||[],(function(t){return null!=t.value?t:A({value:0},t)})),e=new Zm(["value"],this);e.initData(t),this._categoriesData=e,this._categoriesModels=e.mapArray((function(t){return e.getItemModel(t)}))},e.prototype.setZoom=function(t){this.option.zoom=t},e.prototype.setCenter=function(t){this.option.center=t},e.prototype.isAnimationEnabled=function(){return t.prototype.isAnimationEnabled.call(this)&&!("force"===this.get("layout")&&this.get(["force","layoutAnimation"]))},e.type="series.graph",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={z:2,coordinateSystem:"view",legendHoverLink:!0,layout:null,circular:{rotateLabel:!1},force:{initLayout:null,repulsion:[0,50],gravity:.1,friction:.6,edgeLength:30,layoutAnimation:!0},left:"center",top:"center",symbol:"circle",symbolSize:10,edgeSymbol:["none","none"],edgeSymbolSize:10,edgeLabel:{position:"middle",distance:5},draggable:!1,roam:!1,center:null,zoom:1,nodeScaleRatio:.6,label:{show:!1,formatter:"{b}"},itemStyle:{},lineStyle:{color:"#aaa",width:1,opacity:.5},emphasis:{scale:!0,label:{show:!0}},select:{itemStyle:{borderColor:"#212121"}}},e}(ag),RA={type:"graphRoam",event:"graphRoam",update:"none"};var NA=function(){this.angle=0,this.width=10,this.r=10,this.x=0,this.y=0},EA=function(t){function e(e){var n=t.call(this,e)||this;return n.type="pointer",n}return n(e,t),e.prototype.getDefaultShape=function(){return new NA},e.prototype.buildPath=function(t,e){var n=Math.cos,i=Math.sin,r=e.r,o=e.width,a=e.angle,s=e.x-n(a)*o*(o>=r/3?1:2),l=e.y-i(a)*o*(o>=r/3?1:2);a=e.angle-Math.PI/2,t.moveTo(s,l),t.lineTo(e.x+n(a)*o,e.y+i(a)*o),t.lineTo(e.x+n(e.angle)*r,e.y+i(e.angle)*r),t.lineTo(e.x-n(a)*o,e.y-i(a)*o),t.lineTo(s,l)},e}(fs);function zA(t,e){var n=null==t?"":t+"";return e&&(X(e)?n=e.replace("{value}",n):U(e)&&(n=e(t))),n}var VA=2*Math.PI,BA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeAll();var i=t.get(["axisLine","lineStyle","color"]),r=function(t,e){var n=t.get("center"),i=e.getWidth(),r=e.getHeight(),o=Math.min(i,r);return{cx:Er(n[0],e.getWidth()),cy:Er(n[1],e.getHeight()),r:Er(t.get("radius"),o/2)}}(t,n);this._renderMain(t,e,n,i,r),this._data=t.getData()},e.prototype.dispose=function(){},e.prototype._renderMain=function(t,e,n,i,r){for(var o=this.group,a=t.get("clockwise"),s=-t.get("startAngle")/180*Math.PI,l=-t.get("endAngle")/180*Math.PI,u=t.getModel("axisLine"),h=u.get("roundCap")?TS:Tu,c=u.get("show"),p=u.getModel("lineStyle"),d=p.get("width"),f=(l-s)%VA||l===s?(l-s)%VA:VA,g=s,y=0;c&&y=t&&(0===e?0:i[e-1][0]).8?"bottom":"middle",align:u<-.4?"left":u>.4?"right":"center"},{inheritColor:R}),silent:!0}))}if(m.get("show")&&k!==_){P=(P=m.get("distance"))?P+l:l;for(var N=0;N<=b;N++){u=Math.cos(M),h=Math.sin(M);var E=new Eu({shape:{x1:u*(f-P)+p,y1:h*(f-P)+d,x2:u*(f-S-P)+p,y2:h*(f-S-P)+d},silent:!0,style:D});"auto"===D.stroke&&E.setStyle({stroke:i((k+N/b)/_)}),c.add(E),M+=T}M-=T}else M+=I}},e.prototype._renderPointer=function(t,e,n,i,r,o,a,s,l){var u=this.group,h=this._data,c=this._progressEls,p=[],d=t.get(["pointer","show"]),f=t.getModel("progress"),g=f.get("show"),y=t.getData(),v=y.mapDimension("value"),m=+t.get("min"),x=+t.get("max"),_=[m,x],b=[o,a];function w(e,n){var i,o=y.getItemModel(e).getModel("pointer"),a=Er(o.get("width"),r.r),s=Er(o.get("length"),r.r),l=t.get(["pointer","icon"]),u=o.get("offsetCenter"),h=Er(u[0],r.r),c=Er(u[1],r.r),p=o.get("keepAspect");return(i=l?ky(l,h-a/2,c-s,a,s,null,p):new EA({shape:{angle:-Math.PI/2,width:a,r:s,x:h,y:c}})).rotation=-(n+Math.PI/2),i.x=r.cx,i.y=r.cy,i}function S(t,e){var n=f.get("roundCap")?TS:Tu,i=f.get("overlap"),a=i?f.get("width"):l/y.count(),u=i?r.r-a:r.r-(t+1)*a,h=i?r.r:r.r-t*a,c=new n({shape:{startAngle:o,endAngle:e,cx:r.cx,cy:r.cy,clockwise:s,r0:u,r:h}});return i&&(c.z2=x-y.get(v,t)%x),c}(g||d)&&(y.diff(h).add((function(e){var n=y.get(v,e);if(d){var i=w(e,o);rh(i,{rotation:-((isNaN(+n)?b[0]:Nr(n,_,b,!0))+Math.PI/2)},t),u.add(i),y.setItemGraphicEl(e,i)}if(g){var r=S(e,o),a=f.get("clip");rh(r,{shape:{endAngle:Nr(n,_,b,a)}},t),u.add(r),Hs(t.seriesIndex,y.dataType,e,r),p[e]=r}})).update((function(e,n){var i=y.get(v,e);if(d){var r=h.getItemGraphicEl(n),a=r?r.rotation:o,s=w(e,a);s.rotation=a,ih(s,{rotation:-((isNaN(+i)?b[0]:Nr(i,_,b,!0))+Math.PI/2)},t),u.add(s),y.setItemGraphicEl(e,s)}if(g){var l=c[n],m=S(e,l?l.shape.endAngle:o),x=f.get("clip");ih(m,{shape:{endAngle:Nr(i,_,b,x)}},t),u.add(m),Hs(t.seriesIndex,y.dataType,e,m),p[e]=m}})).execute(),y.each((function(t){var e=y.getItemModel(t),n=e.getModel("emphasis"),r=n.get("focus"),o=n.get("blurScope"),a=n.get("disabled");if(d){var s=y.getItemGraphicEl(t),l=y.getItemVisual(t,"style"),u=l.fill;if(s instanceof xs){var h=s.style;s.useStyle(A({image:h.image,x:h.x,y:h.y,width:h.width,height:h.height},l))}else s.useStyle(l),"pointer"!==s.type&&s.setColor(u);s.setStyle(e.getModel(["pointer","itemStyle"]).getItemStyle()),"auto"===s.style.fill&&s.setStyle("fill",i(Nr(y.get(v,t),_,[0,1],!0))),s.z2EmphasisLift=0,zl(s,e),Ol(s,r,o,a)}if(g){var c=p[t];c.useStyle(y.getItemVisual(t,"style")),c.setStyle(e.getModel(["progress","itemStyle"]).getItemStyle()),c.z2EmphasisLift=0,zl(c,e),Ol(c,r,o,a)}})),this._progressEls=p)},e.prototype._renderAnchor=function(t,e){var n=t.getModel("anchor");if(n.get("show")){var i=n.get("size"),r=n.get("icon"),o=n.get("offsetCenter"),a=n.get("keepAspect"),s=ky(r,e.cx-i/2+Er(o[0],e.r),e.cy-i/2+Er(o[1],e.r),i,i,null,a);s.z2=n.get("showAbove")?1:0,s.setStyle(n.getModel("itemStyle").getItemStyle()),this.group.add(s)}},e.prototype._renderTitleAndDetail=function(t,e,n,i,r){var o=this,a=t.getData(),s=a.mapDimension("value"),l=+t.get("min"),u=+t.get("max"),h=new Cr,c=[],p=[],d=t.isAnimationEnabled(),f=t.get(["pointer","showAbove"]);a.diff(this._data).add((function(t){c[t]=new As({silent:!0}),p[t]=new As({silent:!0})})).update((function(t,e){c[t]=o._titleEls[e],p[t]=o._detailEls[e]})).execute(),a.each((function(e){var n=a.getItemModel(e),o=a.get(s,e),g=new Cr,y=i(Nr(o,[l,u],[0,1],!0)),v=n.getModel("title");if(v.get("show")){var m=v.get("offsetCenter"),x=r.cx+Er(m[0],r.r),_=r.cy+Er(m[1],r.r);(D=c[e]).attr({z2:f?0:2,style:Yh(v,{x:x,y:_,text:a.getName(e),align:"center",verticalAlign:"middle"},{inheritColor:y})}),g.add(D)}var b=n.getModel("detail");if(b.get("show")){var w=b.get("offsetCenter"),S=r.cx+Er(w[0],r.r),M=r.cy+Er(w[1],r.r),I=Er(b.get("width"),r.r),T=Er(b.get("height"),r.r),C=t.get(["progress","show"])?a.getItemVisual(e,"style").fill:y,D=p[e],A=b.get("formatter");D.attr({z2:f?0:2,style:Yh(b,{x:S,y:M,text:zA(o,A),width:isNaN(I)?null:I,height:isNaN(T)?null:T,align:"center",verticalAlign:"middle"},{inheritColor:C})}),Jh(D,{normal:b},o,(function(t){return zA(t,A)})),d&&Qh(D,e,a,t,{getFormattedLabel:function(t,e,n,i,r,a){return zA(a?a.interpolatedValue:o,A)}}),g.add(D)}h.add(g)})),this.group.add(h),this._titleEls=c,this._detailEls=p},e.type="gauge",e}(mg),FA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.visualStyleAccessPath="itemStyle",n}return n(e,t),e.prototype.getInitialData=function(t,e){return sM(this,["value"])},e.type="series.gauge",e.defaultOption={z:2,colorBy:"data",center:["50%","50%"],legendHoverLink:!0,radius:"75%",startAngle:225,endAngle:-45,clockwise:!0,min:0,max:100,splitNumber:10,axisLine:{show:!0,roundCap:!1,lineStyle:{color:[[1,"#E6EBF8"]],width:10}},progress:{show:!1,overlap:!0,width:10,roundCap:!1,clip:!0},splitLine:{show:!0,length:10,distance:10,lineStyle:{color:"#63677A",width:3,type:"solid"}},axisTick:{show:!0,splitNumber:5,length:6,distance:10,lineStyle:{color:"#63677A",width:1,type:"solid"}},axisLabel:{show:!0,distance:15,color:"#464646",fontSize:12},pointer:{icon:null,offsetCenter:[0,0],show:!0,showAbove:!0,length:"60%",width:6,keepAspect:!1},anchor:{show:!1,showAbove:!1,size:6,icon:"circle",offsetCenter:[0,0],keepAspect:!1,itemStyle:{color:"#fff",borderWidth:0,borderColor:"#5470c6"}},title:{show:!0,offsetCenter:[0,"20%"],color:"#464646",fontSize:16,valueAnimation:!1},detail:{show:!0,backgroundColor:"rgba(0,0,0,0)",borderWidth:0,borderColor:"#ccc",width:100,height:null,padding:[5,10],offsetCenter:[0,"40%"],color:"#464646",fontSize:30,fontWeight:"bold",lineHeight:30,valueAnimation:!1}},e}(ag);var GA=["itemStyle","opacity"],WA=function(t){function e(e,n){var i=t.call(this)||this,r=i,o=new Ou,a=new As;return r.setTextContent(a),i.setTextGuideLine(o),i.updateData(e,n,!0),i}return n(e,t),e.prototype.updateData=function(t,e,n){var i=this,r=t.hostModel,o=t.getItemModel(e),a=t.getItemLayout(e),s=o.getModel("emphasis"),l=o.get(GA);l=null==l?1:l,n||uh(i),i.useStyle(t.getItemVisual(e,"style")),i.style.lineJoin="round",n?(i.setShape({points:a.points}),i.style.opacity=0,rh(i,{style:{opacity:l}},r,e)):ih(i,{style:{opacity:l},shape:{points:a.points}},r,e),zl(i,o),this._updateLabel(t,e),Ol(this,s.get("focus"),s.get("blurScope"),s.get("disabled"))},e.prototype._updateLabel=function(t,e){var n=this,i=this.getTextGuideLine(),r=n.getTextContent(),o=t.hostModel,a=t.getItemModel(e),s=t.getItemLayout(e).label,l=t.getItemVisual(e,"style"),u=l.fill;Wh(r,Hh(a),{labelFetcher:t.hostModel,labelDataIndex:e,defaultOpacity:l.opacity,defaultText:t.getName(e)},{normal:{align:s.textAlign,verticalAlign:s.verticalAlign}}),n.setTextConfig({local:!0,inside:!!s.inside,insideStroke:u,outsideFill:u});var h=s.linePoints;i.setShape({points:h}),n.textGuideLineConfig={anchor:h?new Ji(h[0][0],h[0][1]):null},ih(r,{style:{x:s.x,y:s.y}},o,e),r.attr({rotation:s.rotation,originX:s.x,originY:s.y,z2:10}),cb(n,pb(a),{stroke:u})},e}(Lu),HA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.ignoreLabelLineUpdate=!0,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this._data,o=this.group;i.diff(r).add((function(t){var e=new WA(i,t);i.setItemGraphicEl(t,e),o.add(e)})).update((function(t,e){var n=r.getItemGraphicEl(e);n.updateData(i,t),o.add(n),i.setItemGraphicEl(t,n)})).remove((function(e){lh(r.getItemGraphicEl(e),t,e)})).execute(),this._data=i},e.prototype.remove=function(){this.group.removeAll(),this._data=null},e.prototype.dispose=function(){},e.type="funnel",e}(mg),YA=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(e){t.prototype.init.apply(this,arguments),this.legendVisualProvider=new lM(W(this.getData,this),W(this.getRawData,this)),this._defaultLabelLine(e)},e.prototype.getInitialData=function(t,e){return sM(this,{coordDimensions:["value"],encodeDefaulter:H(Hp,this)})},e.prototype._defaultLabelLine=function(t){co(t,"labelLine",["show"]);var e=t.labelLine,n=t.emphasis.labelLine;e.show=e.show&&t.label.show,n.show=n.show&&t.emphasis.label.show},e.prototype.getDataParams=function(e){var n=this.getData(),i=t.prototype.getDataParams.call(this,e),r=n.mapDimension("value"),o=n.getSum(r);return i.percent=o?+(n.get(r,e)/o*100).toFixed(2):0,i.$vars.push("percent"),i},e.type="series.funnel",e.defaultOption={z:2,legendHoverLink:!0,colorBy:"data",left:80,top:60,right:80,bottom:60,minSize:"0%",maxSize:"100%",sort:"descending",orient:"vertical",gap:0,funnelAlign:"center",label:{show:!0,position:"outer"},labelLine:{show:!0,length:20,lineStyle:{width:1}},itemStyle:{borderColor:"#fff",borderWidth:1},emphasis:{label:{show:!0}},select:{itemStyle:{borderColor:"#212121"}}},e}(ag);function UA(t,e){t.eachSeriesByType("funnel",(function(t){var n=t.getData(),i=n.mapDimension("value"),r=t.get("sort"),o=function(t,e){return mp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e),a=t.get("orient"),s=o.width,l=o.height,u=function(t,e){for(var n=t.mapDimension("value"),i=t.mapArray(n,(function(t){return t})),r=[],o="ascending"===e,a=0,s=t.count();a5)return;var i=this._model.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]);"none"!==i.behavior&&this._dispatchExpand({axisExpandWindow:i.axisExpandWindow})}this._mouseDownPoint=null},mousemove:function(t){if(!this._mouseDownPoint&&rk(this,"mousemove")){var e=this._model,n=e.coordinateSystem.getSlidedAxisExpandWindow([t.offsetX,t.offsetY]),i=n.behavior;"jump"===i&&this._throttledDispatchExpand.debounceNextCall(e.get("axisExpandDebounce")),this._throttledDispatchExpand("none"===i?null:{axisExpandWindow:n.axisExpandWindow,animation:"jump"===i?null:{duration:0}})}}};function rk(t,e){var n=t._model;return n.get("axisExpandable")&&n.get("axisExpandTriggerOn")===e}var ok=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(){t.prototype.init.apply(this,arguments),this.mergeOption({})},e.prototype.mergeOption=function(t){var e=this.option;t&&C(e,t,!0),this._initDimensions()},e.prototype.contains=function(t,e){var n=t.get("parallelIndex");return null!=n&&e.getComponent("parallel",n)===this},e.prototype.setAxisExpand=function(t){E(["axisExpandable","axisExpandCenter","axisExpandCount","axisExpandWidth","axisExpandWindow"],(function(e){t.hasOwnProperty(e)&&(this.option[e]=t[e])}),this)},e.prototype._initDimensions=function(){var t=this.dimensions=[],e=this.parallelAxisIndex=[];E(B(this.ecModel.queryComponents({mainType:"parallelAxis"}),(function(t){return(t.get("parallelIndex")||0)===this.componentIndex}),this),(function(n){t.push("dim"+n.get("dim")),e.push(n.componentIndex)}))},e.type="parallel",e.dependencies=["parallelAxis"],e.layoutMode="box",e.defaultOption={z:0,left:80,top:60,right:80,bottom:60,layout:"horizontal",axisExpandable:!1,axisExpandCenter:null,axisExpandCount:0,axisExpandWidth:50,axisExpandRate:17,axisExpandDebounce:50,axisExpandSlideTriggerArea:[-.15,.05,.4],axisExpandTriggerOn:"click",parallelAxisDefault:null},e}(Ip),ak=function(t){function e(e,n,i,r,o){var a=t.call(this,e,n,i)||this;return a.type=r||"value",a.axisIndex=o,a}return n(e,t),e.prototype.isHorizontal=function(){return"horizontal"!==this.coordinateSystem.getModel().get("layout")},e}(G_);function sk(t,e,n,i,r,o){t=t||0;var a=n[1]-n[0];if(null!=r&&(r=uk(r,[0,a])),null!=o&&(o=Math.max(o,null!=r?r:0)),"all"===i){var s=Math.abs(e[1]-e[0]);s=uk(s,[0,a]),r=o=uk(s,[r,o]),i=0}e[0]=uk(e[0],n),e[1]=uk(e[1],n);var l=lk(e,i);e[i]+=t;var u,h=r||0,c=n.slice();return l.sign<0?c[0]+=h:c[1]-=h,e[i]=uk(e[i],c),u=lk(e,i),null!=r&&(u.sign!==l.sign||u.spano&&(e[1-i]=e[i]+u.sign*o),e}function lk(t,e){var n=t[e]-t[1-e];return{span:Math.abs(n),sign:n>0?-1:n<0?1:e?-1:1}}function uk(t,e){return Math.min(null!=e[1]?e[1]:1/0,Math.max(null!=e[0]?e[0]:-1/0,t))}var hk=E,ck=Math.min,pk=Math.max,dk=Math.floor,fk=Math.ceil,gk=zr,yk=Math.PI,vk=function(){function t(t,e,n){this.type="parallel",this._axesMap=ft(),this._axesLayout={},this.dimensions=t.dimensions,this._model=t,this._init(t,e,n)}return t.prototype._init=function(t,e,n){var i=t.dimensions,r=t.parallelAxisIndex;hk(i,(function(t,n){var i=r[n],o=e.getComponent("parallelAxis",i),a=this._axesMap.set(t,new ak(t,i_(o),[0,0],o.get("type"),i)),s="category"===a.type;a.onBand=s&&o.get("boundaryGap"),a.inverse=o.get("inverse"),o.axis=a,a.model=o,a.coordinateSystem=o.coordinateSystem=this}),this)},t.prototype.update=function(t,e){this._updateAxesFromSeries(this._model,t)},t.prototype.containPoint=function(t){var e=this._makeLayoutInfo(),n=e.axisBase,i=e.layoutBase,r=e.pixelDimIndex,o=t[1-r],a=t[r];return o>=n&&o<=n+e.axisLength&&a>=i&&a<=i+e.layoutLength},t.prototype.getModel=function(){return this._model},t.prototype._updateAxesFromSeries=function(t,e){e.eachSeries((function(n){if(t.contains(n,e)){var i=n.getData();hk(this.dimensions,(function(t){var e=this._axesMap.get(t);e.scale.unionExtentFromData(i,i.mapDimension(t)),n_(e.scale,e.model)}),this)}}),this)},t.prototype.resize=function(t,e){this._rect=mp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()}),this._layoutAxes()},t.prototype.getRect=function(){return this._rect},t.prototype._makeLayoutInfo=function(){var t,e=this._model,n=this._rect,i=["x","y"],r=["width","height"],o=e.get("layout"),a="horizontal"===o?0:1,s=n[r[a]],l=[0,s],u=this.dimensions.length,h=mk(e.get("axisExpandWidth"),l),c=mk(e.get("axisExpandCount")||0,[0,u]),p=e.get("axisExpandable")&&u>3&&u>c&&c>1&&h>0&&s>0,d=e.get("axisExpandWindow");d?(t=mk(d[1]-d[0],l),d[1]=d[0]+t):(t=mk(h*(c-1),l),(d=[h*(e.get("axisExpandCenter")||dk(u/2))-t/2])[1]=d[0]+t);var f=(s-t)/(u-c);f<3&&(f=0);var g=[dk(gk(d[0]/h,1))+1,fk(gk(d[1]/h,1))-1],y=f/h*d[0];return{layout:o,pixelDimIndex:a,layoutBase:n[i[a]],layoutLength:s,axisBase:n[i[1-a]],axisLength:n[r[1-a]],axisExpandable:p,axisExpandWidth:h,axisCollapseWidth:f,axisExpandWindow:d,axisCount:u,winInnerIndices:g,axisExpandWindow0Pos:y}},t.prototype._layoutAxes=function(){var t=this._rect,e=this._axesMap,n=this.dimensions,i=this._makeLayoutInfo(),r=i.layout;e.each((function(t){var e=[0,i.axisLength],n=t.inverse?1:0;t.setExtent(e[n],e[1-n])})),hk(n,(function(e,n){var o=(i.axisExpandable?_k:xk)(n,i),a={horizontal:{x:o.position,y:i.axisLength},vertical:{x:0,y:o.position}},s={horizontal:yk/2,vertical:0},l=[a[r].x+t.x,a[r].y+t.y],u=s[r],h=[1,0,0,1,0,0];zi(h,h,u),Ei(h,h,l),this._axesLayout[e]={position:l,rotation:u,transform:h,axisNameAvailableWidth:o.axisNameAvailableWidth,axisLabelShow:o.axisLabelShow,nameTruncateMaxWidth:o.nameTruncateMaxWidth,tickDirection:1,labelDirection:1}}),this)},t.prototype.getAxis=function(t){return this._axesMap.get(t)},t.prototype.dataToPoint=function(t,e){return this.axisCoordToPoint(this._axesMap.get(e).dataToCoord(t),e)},t.prototype.eachActiveState=function(t,e,n,i){null==n&&(n=0),null==i&&(i=t.count());var r=this._axesMap,o=this.dimensions,a=[],s=[];E(o,(function(e){a.push(t.mapDimension(e)),s.push(r.get(e).model)}));for(var l=this.hasAxisBrushed(),u=n;ur*(1-h[0])?(l="jump",a=s-r*(1-h[2])):(a=s-r*h[1])>=0&&(a=s-r*(1-h[1]))<=0&&(a=0),(a*=e.axisExpandWidth/u)?sk(a,i,o,"all"):l="none";else{var p=i[1]-i[0];(i=[pk(0,o[1]*s/p-p/2)])[1]=ck(o[1],i[0]+p),i[0]=i[1]-p}return{axisExpandWindow:i,behavior:l}},t}();function mk(t,e){return ck(pk(t,e[0]),e[1])}function xk(t,e){var n=e.layoutLength/(e.axisCount-1);return{position:n*t,axisNameAvailableWidth:n,axisLabelShow:!0}}function _k(t,e){var n,i,r=e.layoutLength,o=e.axisExpandWidth,a=e.axisCount,s=e.axisCollapseWidth,l=e.winInnerIndices,u=s,h=!1;return t=0;n--)Vr(e[n])},e.prototype.getActiveState=function(t){var e=this.activeIntervals;if(!e.length)return"normal";if(null==t||isNaN(+t))return"inactive";if(1===e.length){var n=e[0];if(n[0]<=t&&t<=n[1])return"active"}else for(var i=0,r=e.length;i6}(t)||o){if(a&&!o){"single"===s.brushMode&&Gk(t);var l=T(s);l.brushType=rL(l.brushType,a),l.panelId=a===Sk?null:a.panelId,o=t._creatingCover=Ok(t,l),t._covers.push(o)}if(o){var u=sL[rL(t._brushType,a)];o.__brushOption.range=u.getCreatingRange(tL(t,o,t._track)),i&&(Rk(t,o),u.updateCommon(t,o)),Nk(t,o),r={isEnd:i}}}else i&&"single"===s.brushMode&&s.removeOnClick&&Bk(t,e,n)&&Gk(t)&&(r={isEnd:i,removeOnClick:!0});return r}function rL(t,e){return"auto"===t?e.defaultBrushType:t}var oL={mousedown:function(t){if(this._dragging)aL(this,t);else if(!t.target||!t.target.draggable){eL(t);var e=this.group.transformCoordToLocal(t.offsetX,t.offsetY);this._creatingCover=null,(this._creatingPanel=Bk(this,t,e))&&(this._dragging=!0,this._track=[e.slice()])}},mousemove:function(t){var e=t.offsetX,n=t.offsetY,i=this.group.transformCoordToLocal(e,n);if(function(t,e,n){if(t._brushType&&!function(t,e,n){var i=t._zr;return e<0||e>i.getWidth()||n<0||n>i.getHeight()}(t,e.offsetX,e.offsetY)){var i=t._zr,r=t._covers,o=Bk(t,e,n);if(!t._dragging)for(var a=0;a=0&&(o[r[a].depth]=new pc(r[a],this,e));if(i&&n)return PA(i,n,this,!0,(function(t,e){t.wrapMethod("getItemModel",(function(t,e){var n=t.parentModel,i=n.getData().getItemLayout(e);if(i){var r=i.depth,o=n.levelModels[r];o&&(t.parentModel=o)}return t})),e.wrapMethod("getItemModel",(function(t,e){var n=t.parentModel,i=n.getGraph().getEdgeByIndex(e).node1.getLayout();if(i){var r=i.depth,o=n.levelModels[r];o&&(t.parentModel=o)}return t}))})).data},e.prototype.setNodePosition=function(t,e){var n=(this.option.data||this.option.nodes)[t];n.localX=e[0],n.localY=e[1]},e.prototype.getGraph=function(){return this.getData().graph},e.prototype.getEdgeData=function(){return this.getGraph().edgeData},e.prototype.formatTooltip=function(t,e,n){function i(t){return isNaN(t)||null==t}if("edge"===n){var r=this.getDataParams(t,n),o=r.data,a=r.value;return Uf("nameValue",{name:o.source+" -- "+o.target,value:a,noValue:i(a)})}var s=this.getGraph().getNodeByIndex(t).getLayout().value,l=this.getDataParams(t,n).data.name;return Uf("nameValue",{name:null!=l?l+"":null,value:s,noValue:i(s)})},e.prototype.optionUpdated=function(){},e.prototype.getDataParams=function(e,n){var i=t.prototype.getDataParams.call(this,e,n);if(null==i.value&&"node"===n){var r=this.getGraph().getNodeByIndex(e).getLayout().value;i.value=r}return i},e.type="series.sankey",e.defaultOption={z:2,coordinateSystem:"view",left:"5%",top:"5%",right:"20%",bottom:"5%",orient:"horizontal",nodeWidth:20,nodeGap:8,draggable:!0,layoutIterations:32,label:{show:!0,position:"right",fontSize:12},levels:[],nodeAlign:"justify",lineStyle:{color:"#314656",opacity:.2,curveness:.5},emphasis:{label:{show:!0},lineStyle:{opacity:.5}},select:{itemStyle:{borderColor:"#212121"}},animationEasing:"linear",animationDuration:1e3},e}(ag);function wL(t,e){t.eachSeriesByType("sankey",(function(t){var n=t.get("nodeWidth"),i=t.get("nodeGap"),r=function(t,e){return mp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()})}(t,e);t.layoutInfo=r;var o=r.width,a=r.height,s=t.getGraph(),l=s.nodes,u=s.edges;!function(t){E(t,(function(t){var e=PL(t.outEdges,LL),n=PL(t.inEdges,LL),i=t.getValue()||0,r=Math.max(e,n,i);t.setLayout({value:r},!0)}))}(l),function(t,e,n,i,r,o,a,s,l){(function(t,e,n,i,r,o,a){for(var s=[],l=[],u=[],h=[],c=0,p=0;p=0;v&&y.depth>d&&(d=y.depth),g.setLayout({depth:v?y.depth:c},!0),"vertical"===o?g.setLayout({dy:n},!0):g.setLayout({dx:n},!0);for(var m=0;mc-1?d:c-1;a&&"left"!==a&&function(t,e,n,i){if("right"===e){for(var r=[],o=t,a=0;o.length;){for(var s=0;s0;o--)IL(s,l*=.99,a),ML(s,r,n,i,a),OL(s,l,a),ML(s,r,n,i,a)}(t,e,o,r,i,a,s),function(t,e){var n="vertical"===e?"x":"y";E(t,(function(t){t.outEdges.sort((function(t,e){return t.node2.getLayout()[n]-e.node2.getLayout()[n]})),t.inEdges.sort((function(t,e){return t.node1.getLayout()[n]-e.node1.getLayout()[n]}))})),E(t,(function(t){var e=0,n=0;E(t.outEdges,(function(t){t.setLayout({sy:e},!0),e+=t.getLayout().dy})),E(t.inEdges,(function(t){t.setLayout({ty:n},!0),n+=t.getLayout().dy}))}))}(t,s)}(l,u,n,i,o,a,0!==B(l,(function(t){return 0===t.getLayout().value})).length?0:t.get("layoutIterations"),t.get("orient"),t.get("nodeAlign"))}))}function SL(t){var e=t.hostGraph.data.getRawDataItem(t.dataIndex);return null!=e.depth&&e.depth>=0}function ML(t,e,n,i,r){var o="vertical"===r?"x":"y";E(t,(function(t){var a,s,l;t.sort((function(t,e){return t.getLayout()[o]-e.getLayout()[o]}));for(var u=0,h=t.length,c="vertical"===r?"dx":"dy",p=0;p0&&(a=s.getLayout()[o]+l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0)),u=s.getLayout()[o]+s.getLayout()[c]+e;if((l=u-e-("vertical"===r?i:n))>0){a=s.getLayout()[o]-l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0),u=a;for(p=h-2;p>=0;--p)(l=(s=t[p]).getLayout()[o]+s.getLayout()[c]+e-u)>0&&(a=s.getLayout()[o]-l,"vertical"===r?s.setLayout({x:a},!0):s.setLayout({y:a},!0)),u=s.getLayout()[o]}}))}function IL(t,e,n){E(t.slice().reverse(),(function(t){E(t,(function(t){if(t.outEdges.length){var i=PL(t.outEdges,TL,n)/PL(t.outEdges,LL);if(isNaN(i)){var r=t.outEdges.length;i=r?PL(t.outEdges,CL,n)/r:0}if("vertical"===n){var o=t.getLayout().x+(i-kL(t,n))*e;t.setLayout({x:o},!0)}else{var a=t.getLayout().y+(i-kL(t,n))*e;t.setLayout({y:a},!0)}}}))}))}function TL(t,e){return kL(t.node2,e)*t.getValue()}function CL(t,e){return kL(t.node2,e)}function DL(t,e){return kL(t.node1,e)*t.getValue()}function AL(t,e){return kL(t.node1,e)}function kL(t,e){return"vertical"===e?t.getLayout().x+t.getLayout().dx/2:t.getLayout().y+t.getLayout().dy/2}function LL(t){return t.getValue()}function PL(t,e,n){for(var i=0,r=t.length,o=-1;++oi&&(i=e)})),E(e,(function(e){var r=new eD({type:"color",mappingMethod:"linear",dataExtent:[n,i],visual:t.get("color")}).mapValueToVisual(e.getLayout().value),o=e.getModel().get(["itemStyle","color"]);null!=o?(e.setVisual("color",o),e.setVisual("style",{fill:o})):(e.setVisual("color",r),e.setVisual("style",{fill:r}))}))}}))}var NL=function(){function t(){}return t.prototype.getInitialData=function(t,e){var n,i,r=e.getComponent("xAxis",this.get("xAxisIndex")),o=e.getComponent("yAxis",this.get("yAxisIndex")),a=r.get("type"),s=o.get("type");"category"===a?(t.layout="horizontal",n=r.getOrdinalMeta(),i=!0):"category"===s?(t.layout="vertical",n=o.getOrdinalMeta(),i=!0):t.layout=t.layout||"horizontal";var l=["x","y"],u="horizontal"===t.layout?0:1,h=this._baseAxisDim=l[u],c=l[1-u],p=[r,o],d=p[u].get("type"),f=p[1-u].get("type"),g=t.data;if(g&&i){var y=[];E(g,(function(t,e){var n;Y(t)?(n=t.slice(),t.unshift(e)):Y(t.value)?((n=A({},t)).value=n.value.slice(),t.value.unshift(e)):n=t,y.push(n)})),t.data=y}var v=this.defaultValueDimensions,m=[{name:h,type:Tm(d),ordinalMeta:n,otherDims:{tooltip:!1,itemName:0},dimsDef:["base"]},{name:c,type:Tm(f),dimsDef:v.slice()}];return sM(this,{coordDimensions:m,dimensionsCount:v.length+1,encodeDefaulter:H(Wp,m,this)})},t.prototype.getBaseAxis=function(){var t=this._baseAxisDim;return this.ecModel.getComponent(t+"Axis",this.get(t+"AxisIndex")).axis},t}(),EL=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.defaultValueDimensions=[{name:"min",defaultTooltip:!0},{name:"Q1",defaultTooltip:!0},{name:"median",defaultTooltip:!0},{name:"Q3",defaultTooltip:!0},{name:"max",defaultTooltip:!0}],n.visualDrawType="stroke",n}return n(e,t),e.type="series.boxplot",e.dependencies=["xAxis","yAxis","grid"],e.defaultOption={z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,layout:null,boxWidth:[7,50],itemStyle:{color:"#fff",borderWidth:1},emphasis:{scale:!0,itemStyle:{borderWidth:2,shadowBlur:5,shadowOffsetX:1,shadowOffsetY:1,shadowColor:"rgba(0,0,0,0.2)"}},animationDuration:800},e}(ag);R(EL,NL,!0);var zL=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this.group,o=this._data;this._data||r.removeAll();var a="horizontal"===t.get("layout")?1:0;i.diff(o).add((function(t){if(i.hasValue(t)){var e=FL(i.getItemLayout(t),i,t,a,!0);i.setItemGraphicEl(t,e),r.add(e)}})).update((function(t,e){var n=o.getItemGraphicEl(e);if(i.hasValue(t)){var s=i.getItemLayout(t);n?(uh(n),GL(s,n,i,t)):n=FL(s,i,t,a),r.add(n),i.setItemGraphicEl(t,n)}else r.remove(n)})).remove((function(t){var e=o.getItemGraphicEl(t);e&&r.remove(e)})).execute(),this._data=i},e.prototype.remove=function(t){var e=this.group,n=this._data;this._data=null,n&&n.eachItemGraphicEl((function(t){t&&e.remove(t)}))},e.type="boxplot",e}(mg),VL=function(){},BL=function(t){function e(e){var n=t.call(this,e)||this;return n.type="boxplotBoxPath",n}return n(e,t),e.prototype.getDefaultShape=function(){return new VL},e.prototype.buildPath=function(t,e){var n=e.points,i=0;for(t.moveTo(n[i][0],n[i][1]),i++;i<4;i++)t.lineTo(n[i][0],n[i][1]);for(t.closePath();ig){var _=[v,x];i.push(_)}}}return{boxData:n,outliers:i}}(e.getRawData(),t.config);return[{dimensions:["ItemName","Low","Q1","Q2","Q3","High"],data:i.boxData},{data:i.outliers}]}};var ZL=["color","borderColor"],jL=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){this.group.removeClipPath(),this._progressiveEls=null,this._updateDrawMode(t),this._isLargeDraw?this._renderLarge(t):this._renderNormal(t)},e.prototype.incrementalPrepareRender=function(t,e,n){this._clear(),this._updateDrawMode(t)},e.prototype.incrementalRender=function(t,e,n,i){this._progressiveEls=[],this._isLargeDraw?this._incrementalRenderLarge(t,e):this._incrementalRenderNormal(t,e)},e.prototype.eachRendered=function(t){zh(this._progressiveEls||this.group,t)},e.prototype._updateDrawMode=function(t){var e=t.pipelineContext.large;null!=this._isLargeDraw&&e===this._isLargeDraw||(this._isLargeDraw=e,this._clear())},e.prototype._renderNormal=function(t){var e=t.getData(),n=this._data,i=this.group,r=e.getLayout("isSimpleBox"),o=t.get("clip",!0),a=t.coordinateSystem,s=a.getArea&&a.getArea();this._data||i.removeAll(),e.diff(n).add((function(n){if(e.hasValue(n)){var a=e.getItemLayout(n);if(o&&JL(s,a))return;var l=$L(a,n,!0);rh(l,{shape:{points:a.ends}},t,n),QL(l,e,n,r),i.add(l),e.setItemGraphicEl(n,l)}})).update((function(a,l){var u=n.getItemGraphicEl(l);if(e.hasValue(a)){var h=e.getItemLayout(a);o&&JL(s,h)?i.remove(u):(u?(ih(u,{shape:{points:h.ends}},t,a),uh(u)):u=$L(h),QL(u,e,a,r),i.add(u),e.setItemGraphicEl(a,u))}else i.remove(u)})).remove((function(t){var e=n.getItemGraphicEl(t);e&&i.remove(e)})).execute(),this._data=e},e.prototype._renderLarge=function(t){this._clear(),iP(t,this.group);var e=t.get("clip",!0)?aS(t.coordinateSystem,!1,t):null;e?this.group.setClipPath(e):this.group.removeClipPath()},e.prototype._incrementalRenderNormal=function(t,e){for(var n,i=e.getData(),r=i.getLayout("isSimpleBox");null!=(n=t.next());){var o=$L(i.getItemLayout(n));QL(o,i,n,r),o.incremental=!0,this.group.add(o),this._progressiveEls.push(o)}},e.prototype._incrementalRenderLarge=function(t,e){iP(e,this.group,this._progressiveEls,!0)},e.prototype.remove=function(t){this._clear()},e.prototype._clear=function(){this.group.removeAll(),this._data=null},e.type="candlestick",e}(mg),qL=function(){},KL=function(t){function e(e){var n=t.call(this,e)||this;return n.type="normalCandlestickBox",n}return n(e,t),e.prototype.getDefaultShape=function(){return new qL},e.prototype.buildPath=function(t,e){var n=e.points;this.__simpleBox?(t.moveTo(n[4][0],n[4][1]),t.lineTo(n[6][0],n[6][1])):(t.moveTo(n[0][0],n[0][1]),t.lineTo(n[1][0],n[1][1]),t.lineTo(n[2][0],n[2][1]),t.lineTo(n[3][0],n[3][1]),t.closePath(),t.moveTo(n[4][0],n[4][1]),t.lineTo(n[5][0],n[5][1]),t.moveTo(n[6][0],n[6][1]),t.lineTo(n[7][0],n[7][1]))},e}(fs);function $L(t,e,n){var i=t.ends;return new KL({shape:{points:n?tP(i,t):i},z2:100})}function JL(t,e){for(var n=!0,i=0;i0?"borderColor":"borderColor0"])||n.get(["itemStyle",t>0?"color":"color0"]),o=n.getModel("itemStyle").getItemStyle(ZL);e.useStyle(o),e.style.fill=null,e.style.stroke=r}var oP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.defaultValueDimensions=[{name:"open",defaultTooltip:!0},{name:"close",defaultTooltip:!0},{name:"lowest",defaultTooltip:!0},{name:"highest",defaultTooltip:!0}],n}return n(e,t),e.prototype.getShadowDim=function(){return"open"},e.prototype.brushSelector=function(t,e,n){var i=e.getItemLayout(t);return i&&n.rect(i.brushRect)},e.type="series.candlestick",e.dependencies=["xAxis","yAxis","grid"],e.defaultOption={z:2,coordinateSystem:"cartesian2d",legendHoverLink:!0,layout:null,clip:!0,itemStyle:{color:"#eb5454",color0:"#47b262",borderColor:"#eb5454",borderColor0:"#47b262",borderWidth:1},emphasis:{scale:!0,itemStyle:{borderWidth:2}},barMaxWidth:null,barMinWidth:null,barWidth:null,large:!0,largeThreshold:600,progressive:3e3,progressiveThreshold:1e4,progressiveChunkMode:"mod",animationEasing:"linear",animationDuration:300},e}(ag);function aP(t){t&&Y(t.series)&&E(t.series,(function(t){q(t)&&"k"===t.type&&(t.type="candlestick")}))}R(oP,NL,!0);var sP=["itemStyle","borderColor"],lP=["itemStyle","borderColor0"],uP=["itemStyle","color"],hP=["itemStyle","color0"],cP={seriesType:"candlestick",plan:gg(),performRawSeries:!0,reset:function(t,e){function n(t,e){return e.get(t>0?uP:hP)}function i(t,e){return e.get(t>0?sP:lP)}if(!e.isSeriesFiltered(t))return!t.pipelineContext.large&&{progress:function(t,e){for(var r;null!=(r=t.next());){var o=e.getItemModel(r),a=e.getItemLayout(r).sign,s=o.getItemStyle();s.fill=n(a,o),s.stroke=i(a,o)||s.fill,A(e.ensureUniqueItemVisual(r,"style"),s)}}}}},pP={seriesType:"candlestick",plan:gg(),reset:function(t){var e=t.coordinateSystem,n=t.getData(),i=function(t,e){var n,i=t.getBaseAxis(),r="category"===i.type?i.getBandWidth():(n=i.getExtent(),Math.abs(n[1]-n[0])/e.count()),o=Er(rt(t.get("barMaxWidth"),r),r),a=Er(rt(t.get("barMinWidth"),1),r),s=t.get("barWidth");return null!=s?Er(s,r):Math.max(Math.min(r/2,o),a)}(t,n),r=["x","y"],o=n.getDimensionIndex(n.mapDimension(r[0])),a=z(n.mapDimensionsAll(r[1]),n.getDimensionIndex,n),s=a[0],l=a[1],u=a[2],h=a[3];if(n.setLayout({candleWidth:i,isSimpleBox:i<=1.3}),!(o<0||a.length<4))return{progress:t.pipelineContext.large?function(t,n){var i,r,a=_x(4*t.count),c=0,p=[],d=[],f=n.getStore();for(;null!=(r=t.next());){var g=f.get(o,r),y=f.get(s,r),v=f.get(l,r),m=f.get(u,r),x=f.get(h,r);isNaN(g)||isNaN(m)||isNaN(x)?(a[c++]=NaN,c+=3):(a[c++]=dP(f,r,y,v,l),p[0]=g,p[1]=m,i=e.dataToPoint(p,null,d),a[c++]=i?i[0]:NaN,a[c++]=i?i[1]:NaN,p[1]=x,i=e.dataToPoint(p,null,d),a[c++]=i?i[1]:NaN)}n.setLayout("largePoints",a)}:function(t,n){var r,a=n.getStore();for(;null!=(r=t.next());){var c=a.get(o,r),p=a.get(s,r),d=a.get(l,r),f=a.get(u,r),g=a.get(h,r),y=Math.min(p,d),v=Math.max(p,d),m=S(y,c),x=S(v,c),_=S(f,c),b=S(g,c),w=[];M(w,x,0),M(w,m,1),w.push(T(b),T(x),T(_),T(m)),n.setItemLayout(r,{sign:dP(a,r,p,d,l),initBaseline:p>d?x[1]:m[1],ends:w,brushRect:I(f,g,c)})}function S(t,n){var i=[];return i[0]=n,i[1]=t,isNaN(n)||isNaN(t)?[NaN,NaN]:e.dataToPoint(i)}function M(t,e,n){var r=e.slice(),o=e.slice();r[0]=Sh(r[0]+i/2,1,!1),o[0]=Sh(o[0]-i/2,1,!0),n?t.push(r,o):t.push(o,r)}function I(t,e,n){var r=S(t,n),o=S(e,n);return r[0]-=i/2,o[0]-=i/2,{x:r[0],y:r[1],width:i,height:o[1]-r[1]}}function T(t){return t[0]=Sh(t[0],1),t}}}}};function dP(t,e,n,i,r){return n>i?-1:n0?t.get(r,e-1)<=i?1:-1:1}function fP(t,e){var n=e.rippleEffectColor||e.color;t.eachChild((function(t){t.attr({z:e.z,zlevel:e.zlevel,style:{stroke:"stroke"===e.brushType?n:null,fill:"fill"===e.brushType?n:null}})}))}var gP=function(t){function e(e,n){var i=t.call(this)||this,r=new Ww(e,n),o=new Cr;return i.add(r),i.add(o),i.updateData(e,n),i}return n(e,t),e.prototype.stopEffectAnimation=function(){this.childAt(1).removeAll()},e.prototype.startEffectAnimation=function(t){for(var e=t.symbolType,n=t.color,i=t.rippleNumber,r=this.childAt(1),o=0;o0&&(o=this._getLineLength(i)/s*1e3),o!==this._period||a!==this._loop){i.stopAnimation();var u=void 0;u=U(l)?l(n):l,i.__t>0&&(u=-o*i.__t),this._animateSymbol(i,o,u,a)}this._period=o,this._loop=a}},e.prototype._animateSymbol=function(t,e,n,i){if(e>0){t.__t=0;var r=this,o=t.animate("",i).when(e,{__t:1}).delay(n).during((function(){r._updateSymbolPosition(t)}));i||o.done((function(){r.remove(t)})),o.start()}},e.prototype._getLineLength=function(t){return Et(t.__p1,t.__cp1)+Et(t.__cp1,t.__p2)},e.prototype._updateAnimationPoints=function(t,e){t.__p1=e[0],t.__p2=e[1],t.__cp1=e[2]||[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]},e.prototype.updateData=function(t,e,n){this.childAt(0).updateData(t,e,n),this._updateEffectSymbol(t,e)},e.prototype._updateSymbolPosition=function(t){var e=t.__p1,n=t.__p2,i=t.__cp1,r=t.__t,o=[t.x,t.y],a=o.slice(),s=Ke,l=$e;o[0]=s(e[0],i[0],n[0],r),o[1]=s(e[1],i[1],n[1],r);var u=l(e[0],i[0],n[0],r),h=l(e[1],i[1],n[1],r);t.rotation=-Math.atan2(h,u)-Math.PI/2,"line"!==this._symbolType&&"rect"!==this._symbolType&&"roundRect"!==this._symbolType||(void 0!==t.__lastT&&t.__lastT=0&&!(i[o]<=e);o--);o=Math.min(o,r-2)}else{for(o=a;oe);o++);o=Math.min(o-1,r-2)}var s=(e-i[o])/(i[o+1]-i[o]),l=n[o],u=n[o+1];t.x=l[0]*(1-s)+s*u[0],t.y=l[1]*(1-s)+s*u[1];var h=u[0]-l[0],c=u[1]-l[1];t.rotation=-Math.atan2(c,h)-Math.PI/2,this._lastFrame=o,this._lastFramePercent=e,t.ignore=!1}},e}(mP),bP=function(){this.polyline=!1,this.curveness=0,this.segs=[]},wP=function(t){function e(e){var n=t.call(this,e)||this;return n._off=0,n.hoverDataIdx=-1,n}return n(e,t),e.prototype.reset=function(){this.notClear=!1,this._off=0},e.prototype.getDefaultStyle=function(){return{stroke:"#000",fill:null}},e.prototype.getDefaultShape=function(){return new bP},e.prototype.buildPath=function(t,e){var n,i=e.segs,r=e.curveness;if(e.polyline)for(n=this._off;n0){t.moveTo(i[n++],i[n++]);for(var a=1;a0){var c=(s+u)/2-(l-h)*r,p=(l+h)/2-(u-s)*r;t.quadraticCurveTo(c,p,u,h)}else t.lineTo(u,h)}this.incremental&&(this._off=n,this.notClear=!0)},e.prototype.findDataIndex=function(t,e){var n=this.shape,i=n.segs,r=n.curveness,o=this.style.lineWidth;if(n.polyline)for(var a=0,s=0;s0)for(var u=i[s++],h=i[s++],c=1;c0){if($a(u,h,(u+p)/2-(h-d)*r,(h+d)/2-(p-u)*r,p,d,o,t,e))return a}else if(qa(u,h,p,d,o,t,e))return a;a++}return-1},e.prototype.contain=function(t,e){var n=this.transformCoordToLocal(t,e),i=this.getBoundingRect();return t=n[0],e=n[1],i.contain(t,e)?(this.hoverDataIdx=this.findDataIndex(t,e))>=0:(this.hoverDataIdx=-1,!1)},e.prototype.getBoundingRect=function(){var t=this._rect;if(!t){for(var e=this.shape.segs,n=1/0,i=1/0,r=-1/0,o=-1/0,a=0;a0&&(o.dataIndex=n+t.__startIndex)}))},t.prototype._clear=function(){this._newAdded=[],this.group.removeAll()},t}(),MP={seriesType:"lines",plan:gg(),reset:function(t){var e=t.coordinateSystem;if(e){var n=t.get("polyline"),i=t.pipelineContext.large;return{progress:function(r,o){var a=[];if(i){var s=void 0,l=r.end-r.start;if(n){for(var u=0,h=r.start;h0&&(l||s.configLayer(o,{motionBlur:!0,lastFrameAlpha:Math.max(Math.min(a/10+.9,1),0)})),r.updateData(i);var u=t.get("clip",!0)&&aS(t.coordinateSystem,!1,t);u?this.group.setClipPath(u):this.group.removeClipPath(),this._lastZlevel=o,this._finished=!0},e.prototype.incrementalPrepareRender=function(t,e,n){var i=t.getData();this._updateLineDraw(i,t).incrementalPrepareUpdate(i),this._clearLayer(n),this._finished=!1},e.prototype.incrementalRender=function(t,e,n){this._lineDraw.incrementalUpdate(t,e.getData()),this._finished=t.end===e.getData().count()},e.prototype.eachRendered=function(t){this._lineDraw&&this._lineDraw.eachRendered(t)},e.prototype.updateTransform=function(t,e,n){var i=t.getData(),r=t.pipelineContext;if(!this._finished||r.large||r.progressiveRender)return{update:!0};var o=MP.reset(t,e,n);o.progress&&o.progress({start:0,end:i.count(),count:i.count()},i),this._lineDraw.updateLayout(),this._clearLayer(n)},e.prototype._updateLineDraw=function(t,e){var n=this._lineDraw,i=this._showEffect(e),r=!!e.get("polyline"),o=e.pipelineContext.large;return n&&i===this._hasEffet&&r===this._isPolyline&&o===this._isLargeDraw||(n&&n.remove(),n=this._lineDraw=o?new SP:new dA(r?i?_P:xP:i?mP:pA),this._hasEffet=i,this._isPolyline=r,this._isLargeDraw=o),this.group.add(n.group),n},e.prototype._showEffect=function(t){return!!t.get(["effect","show"])},e.prototype._clearLayer=function(t){var e=t.getZr();"svg"===e.painter.getType()||null==this._lastZlevel||e.painter.getLayer(this._lastZlevel).clear(!0)},e.prototype.remove=function(t,e){this._lineDraw&&this._lineDraw.remove(),this._lineDraw=null,this._clearLayer(e)},e.prototype.dispose=function(t,e){this.remove(t,e)},e.type="lines",e}(mg),TP="undefined"==typeof Uint32Array?Array:Uint32Array,CP="undefined"==typeof Float64Array?Array:Float64Array;function DP(t){var e=t.data;e&&e[0]&&e[0][0]&&e[0][0].coord&&(t.data=z(e,(function(t){var e={coords:[t[0].coord,t[1].coord]};return t[0].name&&(e.fromName=t[0].name),t[1].name&&(e.toName=t[1].name),D([e,t[0],t[1]])})))}var AP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.visualStyleAccessPath="lineStyle",n.visualDrawType="stroke",n}return n(e,t),e.prototype.init=function(e){e.data=e.data||[],DP(e);var n=this._processFlatCoordsArray(e.data);this._flatCoords=n.flatCoords,this._flatCoordsOffset=n.flatCoordsOffset,n.flatCoords&&(e.data=new Float32Array(n.count)),t.prototype.init.apply(this,arguments)},e.prototype.mergeOption=function(e){if(DP(e),e.data){var n=this._processFlatCoordsArray(e.data);this._flatCoords=n.flatCoords,this._flatCoordsOffset=n.flatCoordsOffset,n.flatCoords&&(e.data=new Float32Array(n.count))}t.prototype.mergeOption.apply(this,arguments)},e.prototype.appendData=function(t){var e=this._processFlatCoordsArray(t.data);e.flatCoords&&(this._flatCoords?(this._flatCoords=gt(this._flatCoords,e.flatCoords),this._flatCoordsOffset=gt(this._flatCoordsOffset,e.flatCoordsOffset)):(this._flatCoords=e.flatCoords,this._flatCoordsOffset=e.flatCoordsOffset),t.data=new Float32Array(e.count)),this.getRawData().appendData(t.data)},e.prototype._getCoordsFromItemModel=function(t){var e=this.getData().getItemModel(t),n=e.option instanceof Array?e.option:e.getShallow("coords");return n},e.prototype.getLineCoordsCount=function(t){return this._flatCoordsOffset?this._flatCoordsOffset[2*t+1]:this._getCoordsFromItemModel(t).length},e.prototype.getLineCoords=function(t,e){if(this._flatCoordsOffset){for(var n=this._flatCoordsOffset[2*t],i=this._flatCoordsOffset[2*t+1],r=0;r ")})},e.prototype.preventIncremental=function(){return!!this.get(["effect","show"])},e.prototype.getProgressive=function(){var t=this.option.progressive;return null==t?this.option.large?1e4:this.get("progressive"):t},e.prototype.getProgressiveThreshold=function(){var t=this.option.progressiveThreshold;return null==t?this.option.large?2e4:this.get("progressiveThreshold"):t},e.prototype.getZLevelKey=function(){var t=this.getModel("effect"),e=t.get("trailLength");return this.getData().count()>this.getProgressiveThreshold()?this.id:t.get("show")&&e>0?e+"":""},e.type="series.lines",e.dependencies=["grid","polar","geo","calendar"],e.defaultOption={coordinateSystem:"geo",z:2,legendHoverLink:!0,xAxisIndex:0,yAxisIndex:0,symbol:["none","none"],symbolSize:[10,10],geoIndex:0,effect:{show:!1,period:4,constantSpeed:0,symbol:"circle",symbolSize:3,loop:!0,trailLength:.2},large:!1,largeThreshold:2e3,polyline:!1,clip:!0,label:{show:!1,position:"end"},lineStyle:{opacity:.5}},e}(ag);function kP(t){return t instanceof Array||(t=[t,t]),t}var LP={seriesType:"lines",reset:function(t){var e=kP(t.get("symbol")),n=kP(t.get("symbolSize")),i=t.getData();return i.setVisual("fromSymbol",e&&e[0]),i.setVisual("toSymbol",e&&e[1]),i.setVisual("fromSymbolSize",n&&n[0]),i.setVisual("toSymbolSize",n&&n[1]),{dataEach:i.hasItemOption?function(t,e){var n=t.getItemModel(e),i=kP(n.getShallow("symbol",!0)),r=kP(n.getShallow("symbolSize",!0));i[0]&&t.setItemVisual(e,"fromSymbol",i[0]),i[1]&&t.setItemVisual(e,"toSymbol",i[1]),r[0]&&t.setItemVisual(e,"fromSymbolSize",r[0]),r[1]&&t.setItemVisual(e,"toSymbolSize",r[1])}:null}}};var PP=function(){function t(){this.blurSize=30,this.pointSize=20,this.maxOpacity=1,this.minOpacity=0,this._gradientPixels={inRange:null,outOfRange:null};var t=h.createCanvas();this.canvas=t}return t.prototype.update=function(t,e,n,i,r,o){var a=this._getBrush(),s=this._getGradient(r,"inRange"),l=this._getGradient(r,"outOfRange"),u=this.pointSize+this.blurSize,h=this.canvas,c=h.getContext("2d"),p=t.length;h.width=e,h.height=n;for(var d=0;d0){var I=o(v)?s:l;v>0&&(v=v*S+w),x[_++]=I[M],x[_++]=I[M+1],x[_++]=I[M+2],x[_++]=I[M+3]*v*256}else _+=4}return c.putImageData(m,0,0),h},t.prototype._getBrush=function(){var t=this._brushCanvas||(this._brushCanvas=h.createCanvas()),e=this.pointSize+this.blurSize,n=2*e;t.width=n,t.height=n;var i=t.getContext("2d");return i.clearRect(0,0,n,n),i.shadowOffsetX=n,i.shadowBlur=this.blurSize,i.shadowColor="#000",i.beginPath(),i.arc(-e,e,this.pointSize,0,2*Math.PI,!0),i.closePath(),i.fill(),t},t.prototype._getGradient=function(t,e){for(var n=this._gradientPixels,i=n[e]||(n[e]=new Uint8ClampedArray(1024)),r=[0,0,0,0],o=0,a=0;a<256;a++)t[e](a/255,!0,r),i[o++]=r[0],i[o++]=r[1],i[o++]=r[2],i[o++]=r[3];return i},t}();function OP(t){var e=t.dimensions;return"lng"===e[0]&&"lat"===e[1]}var RP=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i;e.eachComponent("visualMap",(function(e){e.eachTargetSeries((function(n){n===t&&(i=e)}))})),this._progressiveEls=null,this.group.removeAll();var r=t.coordinateSystem;"cartesian2d"===r.type||"calendar"===r.type?this._renderOnCartesianAndCalendar(t,n,0,t.getData().count()):OP(r)&&this._renderOnGeo(r,t,i,n)},e.prototype.incrementalPrepareRender=function(t,e,n){this.group.removeAll()},e.prototype.incrementalRender=function(t,e,n,i){var r=e.coordinateSystem;r&&(OP(r)?this.render(e,n,i):(this._progressiveEls=[],this._renderOnCartesianAndCalendar(e,i,t.start,t.end,!0)))},e.prototype.eachRendered=function(t){zh(this._progressiveEls||this.group,t)},e.prototype._renderOnCartesianAndCalendar=function(t,e,n,i,r){var o,a,s,l,u=t.coordinateSystem;if(sS(u,"cartesian2d")){var h=u.getAxis("x"),c=u.getAxis("y");0,o=h.getBandWidth(),a=c.getBandWidth(),s=h.scale.getExtent(),l=c.scale.getExtent()}for(var p=this.group,d=t.getData(),f=t.getModel(["emphasis","itemStyle"]).getItemStyle(),g=t.getModel(["blur","itemStyle"]).getItemStyle(),y=t.getModel(["select","itemStyle"]).getItemStyle(),v=t.get(["itemStyle","borderRadius"]),m=Hh(t),x=t.getModel("emphasis"),_=x.get("focus"),b=x.get("blurScope"),w=x.get("disabled"),S=sS(u,"cartesian2d")?[d.mapDimension("x"),d.mapDimension("y"),d.mapDimension("value")]:[d.mapDimension("time"),d.mapDimension("value")],M=n;Ms[1]||Dl[1])continue;var A=u.dataToPoint([C,D]);I=new Ts({shape:{x:Math.floor(Math.round(A[0])-o/2),y:Math.floor(Math.round(A[1])-a/2),width:Math.ceil(o),height:Math.ceil(a)},style:T})}else{if(isNaN(d.get(S[1],M)))continue;I=new Ts({z2:1,shape:u.dataToRect([d.get(S[0],M)]).contentShape,style:T})}if(d.hasItemOption){var k=d.getItemModel(M),L=k.getModel("emphasis");f=L.getModel("itemStyle").getItemStyle(),g=k.getModel(["blur","itemStyle"]).getItemStyle(),y=k.getModel(["select","itemStyle"]).getItemStyle(),v=k.get(["itemStyle","borderRadius"]),_=L.get("focus"),b=L.get("blurScope"),w=L.get("disabled"),m=Hh(k)}I.shape.r=v;var P=t.getRawValue(M),O="-";P&&null!=P[2]&&(O=P[2]+""),Wh(I,m,{labelFetcher:t,labelDataIndex:M,defaultOpacity:T.opacity,defaultText:O}),I.ensureState("emphasis").style=f,I.ensureState("blur").style=g,I.ensureState("select").style=y,Ol(I,_,b,w),I.incremental=r,r&&(I.states.emphasis.hoverLayer=!0),p.add(I),d.setItemGraphicEl(M,I),this._progressiveEls&&this._progressiveEls.push(I)}},e.prototype._renderOnGeo=function(t,e,n,i){var r=n.targetVisuals.inRange,o=n.targetVisuals.outOfRange,a=e.getData(),s=this._hmLayer||this._hmLayer||new PP;s.blurSize=e.get("blurSize"),s.pointSize=e.get("pointSize"),s.minOpacity=e.get("minOpacity"),s.maxOpacity=e.get("maxOpacity");var l=t.getViewRect().clone(),u=t.getRoamTransform();l.applyTransform(u);var h=Math.max(l.x,0),c=Math.max(l.y,0),p=Math.min(l.width+l.x,i.getWidth()),d=Math.min(l.height+l.y,i.getHeight()),f=p-h,g=d-c,y=[a.mapDimension("lng"),a.mapDimension("lat"),a.mapDimension("value")],v=a.mapArray(y,(function(e,n,i){var r=t.dataToPoint([e,n]);return r[0]-=h,r[1]-=c,r.push(i),r})),m=n.getExtent(),x="visualMap.continuous"===n.type?function(t,e){var n=t[1]-t[0];return e=[(e[0]-t[0])/n,(e[1]-t[0])/n],function(t){return t>=e[0]&&t<=e[1]}}(m,n.option.range):function(t,e,n){var i=t[1]-t[0],r=(e=z(e,(function(e){return{interval:[(e.interval[0]-t[0])/i,(e.interval[1]-t[0])/i]}}))).length,o=0;return function(t){var i;for(i=o;i=0;i--){var a;if((a=e[i].interval)[0]<=t&&t<=a[1]){o=i;break}}return i>=0&&i0?1:-1}(n,o,r,i,c),function(t,e,n,i,r,o,a,s,l,u){var h,c=l.valueDim,p=l.categoryDim,d=Math.abs(n[p.wh]),f=t.getItemVisual(e,"symbolSize");h=Y(f)?f.slice():null==f?["100%","100%"]:[f,f];h[p.index]=Er(h[p.index],d),h[c.index]=Er(h[c.index],i?d:Math.abs(o)),u.symbolSize=h,(u.symbolScale=[h[0]/s,h[1]/s])[c.index]*=(l.isHorizontal?-1:1)*a}(t,e,r,o,0,c.boundingLength,c.pxSign,u,i,c),function(t,e,n,i,r){var o=t.get(EP)||0;o&&(VP.attr({scaleX:e[0],scaleY:e[1],rotation:n}),VP.updateTransform(),o/=VP.getLineScale(),o*=e[i.valueDim.index]);r.valueLineWidth=o||0}(n,c.symbolScale,l,i,c);var p=c.symbolSize,d=Py(n.get("symbolOffset"),p);return function(t,e,n,i,r,o,a,s,l,u,h,c){var p=h.categoryDim,d=h.valueDim,f=c.pxSign,g=Math.max(e[d.index]+s,0),y=g;if(i){var v=Math.abs(l),m=it(t.get("symbolMargin"),"15%")+"",x=!1;m.lastIndexOf("!")===m.length-1&&(x=!0,m=m.slice(0,m.length-1));var _=Er(m,e[d.index]),b=Math.max(g+2*_,0),w=x?0:2*_,S=eo(i),M=S?i:nO((v+w)/b);b=g+2*(_=(v-M*g)/2/(x?M:Math.max(M-1,1))),w=x?0:2*_,S||"fixed"===i||(M=u?nO((Math.abs(u)+w)/b):0),y=M*b-w,c.repeatTimes=M,c.symbolMargin=_}var I=f*(y/2),T=c.pathPosition=[];T[p.index]=n[p.wh]/2,T[d.index]="start"===a?I:"end"===a?l-I:l/2,o&&(T[0]+=o[0],T[1]+=o[1]);var C=c.bundlePosition=[];C[p.index]=n[p.xy],C[d.index]=n[d.xy];var D=c.barRectShape=A({},n);D[d.wh]=f*Math.max(Math.abs(n[d.wh]),Math.abs(T[d.index]+I)),D[p.wh]=n[p.wh];var k=c.clipShape={};k[p.xy]=-n[p.xy],k[p.wh]=h.ecSize[p.wh],k[d.xy]=0,k[d.wh]=n[d.wh]}(n,p,r,o,0,d,s,c.valueLineWidth,c.boundingLength,c.repeatCutLength,i,c),c}function GP(t,e){return t.toGlobalCoord(t.dataToCoord(t.scale.parse(e)))}function WP(t){var e=t.symbolPatternSize,n=ky(t.symbolType,-e/2,-e/2,e,e);return n.attr({culling:!0}),"image"!==n.type&&n.setStyle({strokeNoScale:!0}),n}function HP(t,e,n,i){var r=t.__pictorialBundle,o=n.symbolSize,a=n.valueLineWidth,s=n.pathPosition,l=e.valueDim,u=n.repeatTimes||0,h=0,c=o[e.valueDim.index]+a+2*n.symbolMargin;for(QP(t,(function(t){t.__pictorialAnimationIndex=h,t.__pictorialRepeatTimes=u,h0:i<0)&&(r=u-1-t),e[l.index]=c*(r-u/2+.5)+s[l.index],{x:e[0],y:e[1],scaleX:n.symbolScale[0],scaleY:n.symbolScale[1],rotation:n.rotation}}}function YP(t,e,n,i){var r=t.__pictorialBundle,o=t.__pictorialMainPath;o?tO(o,null,{x:n.pathPosition[0],y:n.pathPosition[1],scaleX:n.symbolScale[0],scaleY:n.symbolScale[1],rotation:n.rotation},n,i):(o=t.__pictorialMainPath=WP(n),r.add(o),tO(o,{x:n.pathPosition[0],y:n.pathPosition[1],scaleX:0,scaleY:0,rotation:n.rotation},{scaleX:n.symbolScale[0],scaleY:n.symbolScale[1]},n,i))}function UP(t,e,n){var i=A({},e.barRectShape),r=t.__pictorialBarRect;r?tO(r,null,{shape:i},e,n):((r=t.__pictorialBarRect=new Ts({z2:2,shape:i,silent:!0,style:{stroke:"transparent",fill:"transparent",lineWidth:0}})).disableMorphing=!0,t.add(r))}function XP(t,e,n,i){if(n.symbolClip){var r=t.__pictorialClipPath,o=A({},n.clipShape),a=e.valueDim,s=n.animationModel,l=n.dataIndex;if(r)ih(r,{shape:o},s,l);else{o[a.wh]=0,r=new Ts({shape:o}),t.__pictorialBundle.setClipPath(r),t.__pictorialClipPath=r;var u={};u[a.wh]=n.clipShape[a.wh],Vh[i?"updateProps":"initProps"](r,{shape:u},s,l)}}}function ZP(t,e){var n=t.getItemModel(e);return n.getAnimationDelayParams=jP,n.isAnimationEnabled=qP,n}function jP(t){return{index:t.__pictorialAnimationIndex,count:t.__pictorialRepeatTimes}}function qP(){return this.parentModel.isAnimationEnabled()&&!!this.getShallow("animation")}function KP(t,e,n,i){var r=new Cr,o=new Cr;return r.add(o),r.__pictorialBundle=o,o.x=n.bundlePosition[0],o.y=n.bundlePosition[1],n.symbolRepeat?HP(r,e,n):YP(r,0,n),UP(r,n,i),XP(r,e,n,i),r.__pictorialShapeStr=JP(t,n),r.__pictorialSymbolMeta=n,r}function $P(t,e,n,i){var r=i.__pictorialBarRect;r&&r.removeTextContent();var o=[];QP(i,(function(t){o.push(t)})),i.__pictorialMainPath&&o.push(i.__pictorialMainPath),i.__pictorialClipPath&&(n=null),E(o,(function(t){ah(t,{scaleX:0,scaleY:0},n,e,(function(){i.parent&&i.parent.remove(i)}))})),t.setItemGraphicEl(e,null)}function JP(t,e){return[t.getItemVisual(e.dataIndex,"symbol")||"none",!!e.symbolRepeat,!!e.symbolClip].join(":")}function QP(t,e,n){E(t.__pictorialBundle.children(),(function(i){i!==t.__pictorialBarRect&&e.call(n,i)}))}function tO(t,e,n,i,r,o){e&&t.attr(e),i.symbolClip&&!r?n&&t.attr(n):n&&Vh[r?"updateProps":"initProps"](t,n,i.animationModel,i.dataIndex,o)}function eO(t,e,n){var i=n.dataIndex,r=n.itemModel,o=r.getModel("emphasis"),a=o.getModel("itemStyle").getItemStyle(),s=r.getModel(["blur","itemStyle"]).getItemStyle(),l=r.getModel(["select","itemStyle"]).getItemStyle(),u=r.getShallow("cursor"),h=o.get("focus"),c=o.get("blurScope"),p=o.get("scale");QP(t,(function(t){if(t instanceof xs){var e=t.style;t.useStyle(A({image:e.image,x:e.x,y:e.y,width:e.width,height:e.height},n.style))}else t.useStyle(n.style);var i=t.ensureState("emphasis");i.style=a,p&&(i.scaleX=1.1*t.scaleX,i.scaleY=1.1*t.scaleY),t.ensureState("blur").style=s,t.ensureState("select").style=l,u&&(t.cursor=u),t.z2=n.z2}));var d=e.valueDim.posDesc[+(n.boundingLength>0)];Wh(t.__pictorialBarRect,Hh(r),{labelFetcher:e.seriesModel,labelDataIndex:i,defaultText:Fw(e.seriesModel.getData(),i),inheritColor:n.style.fill,defaultOpacity:n.style.opacity,defaultOutsidePosition:d}),Ol(t,h,c,o.get("disabled"))}function nO(t){var e=Math.round(t);return Math.abs(t-e)<1e-4?e:Math.ceil(t)}var iO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.hasSymbolVisual=!0,n.defaultSymbol="roundRect",n}return n(e,t),e.prototype.getInitialData=function(e){return e.stack=null,t.prototype.getInitialData.apply(this,arguments)},e.type="series.pictorialBar",e.dependencies=["grid"],e.defaultOption=gc(SS.defaultOption,{symbol:"circle",symbolSize:null,symbolRotate:null,symbolPosition:null,symbolOffset:null,symbolMargin:null,symbolRepeat:!1,symbolRepeatDirection:"end",symbolClip:!1,symbolBoundingData:null,symbolPatternSize:400,barGap:"-100%",progressive:0,emphasis:{scale:!1},select:{itemStyle:{borderColor:"#212121"}}}),e}(SS);var rO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._layers=[],n}return n(e,t),e.prototype.render=function(t,e,n){var i=t.getData(),r=this,o=this.group,a=t.getLayerSeries(),s=i.getLayout("layoutInfo"),l=s.rect,u=s.boundaryGap;function h(t){return t.name}o.x=0,o.y=l.y+u[0];var c=new Sm(this._layersSeries||[],a,h,h),p=[];function d(e,n,s){var l=r._layers;if("remove"!==e){for(var u,h,c=[],d=[],f=a[n].indices,g=0;go&&(o=s),i.push(s)}for(var u=0;uo&&(o=c)}return{y0:r,max:o}}(l),h=u.y0,c=n/u.max,p=o.length,d=o[0].indices.length,f=0;fMath.PI/2?"right":"left"):S&&"center"!==S?"left"===S?(m=r.r0+w,a>Math.PI/2&&(S="right")):"right"===S&&(m=r.r-w,a>Math.PI/2&&(S="left")):(m=o===2*Math.PI&&0===r.r0?0:(r.r+r.r0)/2,S="center"),g.style.align=S,g.style.verticalAlign=f(p,"verticalAlign")||"middle",g.x=m*s+r.cx,g.y=m*l+r.cy;var M=f(p,"rotate"),I=0;"radial"===M?(I=-a)<-Math.PI/2&&(I+=Math.PI):"tangential"===M?(I=Math.PI/2-a)>Math.PI/2?I-=Math.PI:I<-Math.PI/2&&(I+=Math.PI):j(M)&&(I=M*Math.PI/180),g.rotation=I})),h.dirtyStyle()},e}(Tu),uO="sunburstRootToNode",hO="sunburstHighlight";var cO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n,i){var r=this;this.seriesModel=t,this.api=n,this.ecModel=e;var o=t.getData(),a=o.tree.root,s=t.getViewRoot(),l=this.group,u=t.get("renderLabelForZeroData"),h=[];s.eachNode((function(t){h.push(t)}));var c=this._oldChildren||[];!function(i,r){if(0===i.length&&0===r.length)return;function s(t){return t.getId()}function h(s,h){!function(i,r){u||!i||i.getValue()||(i=null);if(i!==a&&r!==a)if(r&&r.piece)i?(r.piece.updateData(!1,i,t,e,n),o.setItemGraphicEl(i.dataIndex,r.piece)):function(t){if(!t)return;t.piece&&(l.remove(t.piece),t.piece=null)}(r);else if(i){var s=new lO(i,t,e,n);l.add(s),o.setItemGraphicEl(i.dataIndex,s)}}(null==s?null:i[s],null==h?null:r[h])}new Sm(r,i,s,s).add(h).update(h).remove(H(h,null)).execute()}(h,c),function(i,o){o.depth>0?(r.virtualPiece?r.virtualPiece.updateData(!1,i,t,e,n):(r.virtualPiece=new lO(i,t,e,n),l.add(r.virtualPiece)),o.piece.off("click"),r.virtualPiece.on("click",(function(t){r._rootToNode(o.parentNode)}))):r.virtualPiece&&(l.remove(r.virtualPiece),r.virtualPiece=null)}(a,s),this._initEvents(),this._oldChildren=h},e.prototype._initEvents=function(){var t=this;this.group.off("click"),this.group.on("click",(function(e){var n=!1;t.seriesModel.getViewRoot().eachNode((function(i){if(!n&&i.piece&&i.piece===e.target){var r=i.getModel().get("nodeClick");if("rootToNode"===r)t._rootToNode(i);else if("link"===r){var o=i.getModel(),a=o.get("link");if(a)pp(a,o.get("target",!0)||"_blank")}n=!0}}))}))},e.prototype._rootToNode=function(t){t!==this.seriesModel.getViewRoot()&&this.api.dispatchAction({type:uO,from:this.uid,seriesId:this.seriesModel.id,targetNode:t})},e.prototype.containPoint=function(t,e){var n=e.getData().getItemLayout(0);if(n){var i=t[0]-n.cx,r=t[1]-n.cy,o=Math.sqrt(i*i+r*r);return o<=n.r&&o>=n.r0}},e.type="sunburst",e}(mg),pO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.ignoreStyleOnData=!0,n}return n(e,t),e.prototype.getInitialData=function(t,e){var n={name:t.name,children:t.data};dO(n);var i=this._levelModels=z(t.levels||[],(function(t){return new pc(t,this,e)}),this),r=CC.createTree(n,this,(function(t){t.wrapMethod("getItemModel",(function(t,e){var n=r.getNodeByDataIndex(e),o=i[n.depth];return o&&(t.parentModel=o),t}))}));return r.data},e.prototype.optionUpdated=function(){this.resetViewRoot()},e.prototype.getDataParams=function(e){var n=t.prototype.getDataParams.apply(this,arguments),i=this.getData().tree.getNodeByDataIndex(e);return n.treePathInfo=LC(i,this),n},e.prototype.getLevelModel=function(t){return this._levelModels&&this._levelModels[t.depth]},e.prototype.getViewRoot=function(){return this._viewRoot},e.prototype.resetViewRoot=function(t){t?this._viewRoot=t:t=this._viewRoot;var e=this.getRawData().tree.root;t&&(t===e||e.contains(t))||(this._viewRoot=e)},e.prototype.enableAriaDecal=function(){zC(this)},e.type="series.sunburst",e.defaultOption={z:2,center:["50%","50%"],radius:[0,"75%"],clockwise:!0,startAngle:90,minAngle:0,stillShowZeroSum:!0,nodeClick:"rootToNode",renderLabelForZeroData:!1,label:{rotate:"radial",show:!0,opacity:1,align:"center",position:"inside",distance:5,silent:!0},itemStyle:{borderWidth:1,borderColor:"white",borderType:"solid",shadowBlur:0,shadowColor:"rgba(0, 0, 0, 0.2)",shadowOffsetX:0,shadowOffsetY:0,opacity:1},emphasis:{focus:"descendant"},blur:{itemStyle:{opacity:.2},label:{opacity:.1}},animationType:"expansion",animationDuration:1e3,animationDurationUpdate:500,data:[],sort:"desc"},e}(ag);function dO(t){var e=0;E(t.children,(function(t){dO(t);var n=t.value;Y(n)&&(n=n[0]),e+=n}));var n=t.value;Y(n)&&(n=n[0]),(null==n||isNaN(n))&&(n=e),n<0&&(n=0),Y(t.value)?t.value[0]=n:t.value=n}var fO=Math.PI/180;function gO(t,e,n){e.eachSeriesByType(t,(function(t){var e=t.get("center"),i=t.get("radius");Y(i)||(i=[0,i]),Y(e)||(e=[e,e]);var r=n.getWidth(),o=n.getHeight(),a=Math.min(r,o),s=Er(e[0],r),l=Er(e[1],o),u=Er(i[0],a/2),h=Er(i[1],a/2),c=-t.get("startAngle")*fO,p=t.get("minAngle")*fO,d=t.getData().tree.root,f=t.getViewRoot(),g=f.depth,y=t.get("sort");null!=y&&yO(f,y);var v=0;E(f.children,(function(t){!isNaN(t.getValue())&&v++}));var m=f.getValue(),x=Math.PI/(m||v)*2,_=f.depth>0,b=f.height-(_?-1:1),w=(h-u)/(b||1),S=t.get("clockwise"),M=t.get("stillShowZeroSum"),I=S?1:-1,T=function(e,n){if(e){var i=n;if(e!==d){var r=e.getValue(),o=0===m&&M?x:r*x;o1;)r=r.parentNode;var o=n.getColorFromPalette(r.name||r.dataIndex+"",e);return t.depth>1&&X(o)&&(o=Sn(o,(t.depth-1)/(i-1)*.5)),o}(r,t,i.root.height)),A(n.ensureUniqueItemVisual(r.dataIndex,"style"),o)}))}))}var mO={color:"fill",borderColor:"stroke"},xO={symbol:1,symbolSize:1,symbolKeepAspect:1,legendIcon:1,visualMeta:1,liftZ:1,decal:1},_O=So(),bO=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(){this.currentZLevel=this.get("zlevel",!0),this.currentZ=this.get("z",!0)},e.prototype.getInitialData=function(t,e){return nx(null,this)},e.prototype.getDataParams=function(e,n,i){var r=t.prototype.getDataParams.call(this,e,n);return i&&(r.info=_O(i).info),r},e.type="series.custom",e.dependencies=["grid","polar","geo","singleAxis","calendar"],e.defaultOption={coordinateSystem:"cartesian2d",z:2,legendHoverLink:!0,clip:!1},e}(ag);function wO(t,e){return e=e||[0,0],z(["x","y"],(function(n,i){var r=this.getAxis(n),o=e[i],a=t[i]/2;return"category"===r.type?r.getBandWidth():Math.abs(r.dataToCoord(o-a)-r.dataToCoord(o+a))}),this)}function SO(t,e){return e=e||[0,0],z([0,1],(function(n){var i=e[n],r=t[n]/2,o=[],a=[];return o[n]=i-r,a[n]=i+r,o[1-n]=a[1-n]=e[1-n],Math.abs(this.dataToPoint(o)[n]-this.dataToPoint(a)[n])}),this)}function MO(t,e){var n=this.getAxis(),i=e instanceof Array?e[0]:e,r=(t instanceof Array?t[0]:t)/2;return"category"===n.type?n.getBandWidth():Math.abs(n.dataToCoord(i-r)-n.dataToCoord(i+r))}function IO(t,e){return e=e||[0,0],z(["Radius","Angle"],(function(n,i){var r=this["get"+n+"Axis"](),o=e[i],a=t[i]/2,s="category"===r.type?r.getBandWidth():Math.abs(r.dataToCoord(o-a)-r.dataToCoord(o+a));return"Angle"===n&&(s=s*Math.PI/180),s}),this)}function TO(t,e,n,i){return t&&(t.legacy||!1!==t.legacy&&!n&&!i&&"tspan"!==e&&("text"===e||mt(t,"text")))}function CO(t,e,n){var i,r,o,a=t;if("text"===e)o=a;else{o={},mt(a,"text")&&(o.text=a.text),mt(a,"rich")&&(o.rich=a.rich),mt(a,"textFill")&&(o.fill=a.textFill),mt(a,"textStroke")&&(o.stroke=a.textStroke),mt(a,"fontFamily")&&(o.fontFamily=a.fontFamily),mt(a,"fontSize")&&(o.fontSize=a.fontSize),mt(a,"fontStyle")&&(o.fontStyle=a.fontStyle),mt(a,"fontWeight")&&(o.fontWeight=a.fontWeight),r={type:"text",style:o,silent:!0},i={};var s=mt(a,"textPosition");n?i.position=s?a.textPosition:"inside":s&&(i.position=a.textPosition),mt(a,"textPosition")&&(i.position=a.textPosition),mt(a,"textOffset")&&(i.offset=a.textOffset),mt(a,"textRotation")&&(i.rotation=a.textRotation),mt(a,"textDistance")&&(i.distance=a.textDistance)}return DO(o,t),E(o.rich,(function(t){DO(t,t)})),{textConfig:i,textContent:r}}function DO(t,e){e&&(e.font=e.textFont||e.font,mt(e,"textStrokeWidth")&&(t.lineWidth=e.textStrokeWidth),mt(e,"textAlign")&&(t.align=e.textAlign),mt(e,"textVerticalAlign")&&(t.verticalAlign=e.textVerticalAlign),mt(e,"textLineHeight")&&(t.lineHeight=e.textLineHeight),mt(e,"textWidth")&&(t.width=e.textWidth),mt(e,"textHeight")&&(t.height=e.textHeight),mt(e,"textBackgroundColor")&&(t.backgroundColor=e.textBackgroundColor),mt(e,"textPadding")&&(t.padding=e.textPadding),mt(e,"textBorderColor")&&(t.borderColor=e.textBorderColor),mt(e,"textBorderWidth")&&(t.borderWidth=e.textBorderWidth),mt(e,"textBorderRadius")&&(t.borderRadius=e.textBorderRadius),mt(e,"textBoxShadowColor")&&(t.shadowColor=e.textBoxShadowColor),mt(e,"textBoxShadowBlur")&&(t.shadowBlur=e.textBoxShadowBlur),mt(e,"textBoxShadowOffsetX")&&(t.shadowOffsetX=e.textBoxShadowOffsetX),mt(e,"textBoxShadowOffsetY")&&(t.shadowOffsetY=e.textBoxShadowOffsetY))}function AO(t,e,n){var i=t;i.textPosition=i.textPosition||n.position||"inside",null!=n.offset&&(i.textOffset=n.offset),null!=n.rotation&&(i.textRotation=n.rotation),null!=n.distance&&(i.textDistance=n.distance);var r=i.textPosition.indexOf("inside")>=0,o=t.fill||"#000";kO(i,e);var a=null==i.textFill;return r?a&&(i.textFill=n.insideFill||"#fff",!i.textStroke&&n.insideStroke&&(i.textStroke=n.insideStroke),!i.textStroke&&(i.textStroke=o),null==i.textStrokeWidth&&(i.textStrokeWidth=2)):(a&&(i.textFill=t.fill||n.outsideFill||"#000"),!i.textStroke&&n.outsideStroke&&(i.textStroke=n.outsideStroke)),i.text=e.text,i.rich=e.rich,E(e.rich,(function(t){kO(t,t)})),i}function kO(t,e){e&&(mt(e,"fill")&&(t.textFill=e.fill),mt(e,"stroke")&&(t.textStroke=e.fill),mt(e,"lineWidth")&&(t.textStrokeWidth=e.lineWidth),mt(e,"font")&&(t.font=e.font),mt(e,"fontStyle")&&(t.fontStyle=e.fontStyle),mt(e,"fontWeight")&&(t.fontWeight=e.fontWeight),mt(e,"fontSize")&&(t.fontSize=e.fontSize),mt(e,"fontFamily")&&(t.fontFamily=e.fontFamily),mt(e,"align")&&(t.textAlign=e.align),mt(e,"verticalAlign")&&(t.textVerticalAlign=e.verticalAlign),mt(e,"lineHeight")&&(t.textLineHeight=e.lineHeight),mt(e,"width")&&(t.textWidth=e.width),mt(e,"height")&&(t.textHeight=e.height),mt(e,"backgroundColor")&&(t.textBackgroundColor=e.backgroundColor),mt(e,"padding")&&(t.textPadding=e.padding),mt(e,"borderColor")&&(t.textBorderColor=e.borderColor),mt(e,"borderWidth")&&(t.textBorderWidth=e.borderWidth),mt(e,"borderRadius")&&(t.textBorderRadius=e.borderRadius),mt(e,"shadowColor")&&(t.textBoxShadowColor=e.shadowColor),mt(e,"shadowBlur")&&(t.textBoxShadowBlur=e.shadowBlur),mt(e,"shadowOffsetX")&&(t.textBoxShadowOffsetX=e.shadowOffsetX),mt(e,"shadowOffsetY")&&(t.textBoxShadowOffsetY=e.shadowOffsetY),mt(e,"textShadowColor")&&(t.textShadowColor=e.textShadowColor),mt(e,"textShadowBlur")&&(t.textShadowBlur=e.textShadowBlur),mt(e,"textShadowOffsetX")&&(t.textShadowOffsetX=e.textShadowOffsetX),mt(e,"textShadowOffsetY")&&(t.textShadowOffsetY=e.textShadowOffsetY))}var LO={position:["x","y"],scale:["scaleX","scaleY"],origin:["originX","originY"]},PO=G(LO),OO=(V(Ki,(function(t,e){return t[e]=1,t}),{}),Ki.join(", "),["","style","shape","extra"]),RO=So();function NO(t,e,n,i,r){var o=t+"Animation",a=eh(t,i,r)||{},s=RO(e).userDuring;return a.duration>0&&(a.during=s?W(WO,{el:e,userDuring:s}):null,a.setToFinal=!0,a.scope=t),A(a,n[o]),a}function EO(t,e,n,i){var r=(i=i||{}).dataIndex,o=i.isInit,a=i.clearStyle,s=n.isAnimationEnabled(),l=RO(t),u=e.style;l.userDuring=e.during;var h={},c={};if(function(t,e,n){for(var i=0;i=0)){var c=t.getAnimationStyleProps(),p=c?c.style:null;if(p){!r&&(r=i.style={});var d=G(n);for(u=0;u0&&t.animateFrom(p,d)}else!function(t,e,n,i,r){if(r){var o=NO("update",t,e,i,n);o.duration>0&&t.animateFrom(r,o)}}(t,e,r||0,n,h);zO(t,e),u?t.dirty():t.markRedraw()}function zO(t,e){for(var n=RO(t).leaveToProps,i=0;i=0){!o&&(o=i[t]={});var p=G(a);for(h=0;hi[1]&&i.reverse(),{coordSys:{type:"polar",cx:t.cx,cy:t.cy,r:i[1],r0:i[0]},api:{coord:function(i){var r=e.dataToRadius(i[0]),o=n.dataToAngle(i[1]),a=t.coordToPoint([r,o]);return a.push(r,o*Math.PI/180),a},size:W(IO,t)}}},calendar:function(t){var e=t.getRect(),n=t.getRangeInfo();return{coordSys:{type:"calendar",x:e.x,y:e.y,width:e.width,height:e.height,cellWidth:t.getCellWidth(),cellHeight:t.getCellHeight(),rangeInfo:{start:n.start,end:n.end,weeks:n.weeks,dayCount:n.allDay}},api:{coord:function(e,n){return t.dataToPoint(e,n)}}}}};function aR(t){return t instanceof fs}function sR(t){return t instanceof da}var lR=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n,i){this._progressiveEls=null;var r=this._data,o=t.getData(),a=this.group,s=dR(t,o,e,n);r||a.removeAll(),o.diff(r).add((function(e){gR(n,null,e,s(e,i),t,a,o)})).remove((function(e){var n=r.getItemGraphicEl(e);VO(n,_O(n).option,t)})).update((function(e,l){var u=r.getItemGraphicEl(l);gR(n,u,e,s(e,i),t,a,o)})).execute();var l=t.get("clip",!0)?aS(t.coordinateSystem,!1,t):null;l?a.setClipPath(l):a.removeClipPath(),this._data=o},e.prototype.incrementalPrepareRender=function(t,e,n){this.group.removeAll(),this._data=null},e.prototype.incrementalRender=function(t,e,n,i,r){var o=e.getData(),a=dR(e,o,n,i),s=this._progressiveEls=[];function l(t){t.isGroup||(t.incremental=!0,t.ensureState("emphasis").hoverLayer=!0)}for(var u=t.start;u=0?e.getStore().get(r,n):void 0}var o=e.get(i.name,n),a=i&&i.ordinalMeta;return a?a.categories[o]:o},styleEmphasis:function(n,i){0;null==i&&(i=s);var r=m(i,KO).getItemStyle(),o=x(i,KO),a=Yh(o,null,null,!0,!0);a.text=o.getShallow("show")?ot(t.getFormattedLabel(i,KO),t.getFormattedLabel(i,$O),Fw(e,i)):null;var l=Uh(o,null,!0);return b(n,r),r=AO(r,a,l),n&&_(r,n),r.legacy=!0,r},visual:function(t,n){if(null==n&&(n=s),mt(mO,t)){var i=e.getItemVisual(n,"style");return i?i[mO[t]]:null}if(mt(xO,t))return e.getItemVisual(n,t)},barLayout:function(t){if("cartesian2d"===o.type){return function(t){var e=[],n=t.axis,i="axis0";if("category"===n.type){for(var r=n.getBandWidth(),o=0;o=c;p--){VO(e.childAt(p),_O(e).option,r)}}(t,c,n,i,r),a>=0?o.replaceAt(c,a):o.add(c),c}function vR(t,e,n){var i,r=_O(t),o=e.type,a=e.shape,s=e.style;return n.isUniversalTransitionEnabled()||null!=o&&o!==r.customGraphicType||"path"===o&&((i=a)&&(mt(i,"pathData")||mt(i,"d")))&&MR(a)!==r.customPathData||"image"===o&&mt(s,"image")&&s.image!==r.customImagePath}function mR(t,e,n){var i=e?xR(t,e):t,r=e?_R(t,i,KO):t.style,o=t.type,a=i?i.textConfig:null,s=t.textContent,l=s?e?xR(s,e):s:null;if(r&&(n.isLegacy||TO(r,o,!!a,!!l))){n.isLegacy=!0;var u=CO(r,o,!e);!a&&u.textConfig&&(a=u.textConfig),!l&&u.textContent&&(l=u.textContent)}if(!e&&l){var h=l;!h.type&&(h.type="text")}var c=e?n[e]:n.normal;c.cfg=a,c.conOpt=l}function xR(t,e){return e?t?t[e]:null:t}function _R(t,e,n){var i=e&&e.style;return null==i&&n===KO&&t&&(i=t.styleEmphasis),i}function bR(t,e){var n=t&&t.name;return null!=n?n:"e\0\0"+e}function wR(t,e){var n=this.context,i=null!=t?n.newChildren[t]:null,r=null!=e?n.oldChildren[e]:null;yR(n.api,r,n.dataIndex,i,n.seriesModel,n.group)}function SR(t){var e=this.context,n=e.oldChildren[t];VO(n,_O(n).option,e.seriesModel)}function MR(t){return t&&(t.pathData||t.d)}var IR=So(),TR=T,CR=W,DR=function(){function t(){this._dragging=!1,this.animationThreshold=15}return t.prototype.render=function(t,e,n,i){var r=e.get("value"),o=e.get("status");if(this._axisModel=t,this._axisPointerModel=e,this._api=n,i||this._lastValue!==r||this._lastStatus!==o){this._lastValue=r,this._lastStatus=o;var a=this._group,s=this._handle;if(!o||"hide"===o)return a&&a.hide(),void(s&&s.hide());a&&a.show(),s&&s.show();var l={};this.makeElOption(l,r,t,e,n);var u=l.graphicKey;u!==this._lastGraphicKey&&this.clear(n),this._lastGraphicKey=u;var h=this._moveAnimation=this.determineAnimation(t,e);if(a){var c=H(AR,e,h);this.updatePointerEl(a,l,c),this.updateLabelEl(a,l,c,e)}else a=this._group=new Cr,this.createPointerEl(a,l,t,e),this.createLabelEl(a,l,t,e),n.getZr().add(a);OR(a,e,!0),this._renderHandle(r)}},t.prototype.remove=function(t){this.clear(t)},t.prototype.dispose=function(t){this.clear(t)},t.prototype.determineAnimation=function(t,e){var n=e.get("animation"),i=t.axis,r="category"===i.type,o=e.get("snap");if(!o&&!r)return!1;if("auto"===n||null==n){var a=this.animationThreshold;if(r&&i.getBandWidth()>a)return!0;if(o){var s=jM(t).seriesDataCount,l=i.getExtent();return Math.abs(l[0]-l[1])/s>a}return!1}return!0===n},t.prototype.makeElOption=function(t,e,n,i,r){},t.prototype.createPointerEl=function(t,e,n,i){var r=e.pointer;if(r){var o=IR(t).pointerEl=new Vh[r.type](TR(e.pointer));t.add(o)}},t.prototype.createLabelEl=function(t,e,n,i){if(e.label){var r=IR(t).labelEl=new As(TR(e.label));t.add(r),LR(r,i)}},t.prototype.updatePointerEl=function(t,e,n){var i=IR(t).pointerEl;i&&e.pointer&&(i.setStyle(e.pointer.style),n(i,{shape:e.pointer.shape}))},t.prototype.updateLabelEl=function(t,e,n,i){var r=IR(t).labelEl;r&&(r.setStyle(e.label.style),n(r,{x:e.label.x,y:e.label.y}),LR(r,i))},t.prototype._renderHandle=function(t){if(!this._dragging&&this.updateHandleTransform){var e,n=this._axisPointerModel,i=this._api.getZr(),r=this._handle,o=n.getModel("handle"),a=n.get("status");if(!o.get("show")||!a||"hide"===a)return r&&i.remove(r),void(this._handle=null);this._handle||(e=!0,r=this._handle=Lh(o.get("icon"),{cursor:"move",draggable:!0,onmousemove:function(t){se(t.event)},onmousedown:CR(this._onHandleDragMove,this,0,0),drift:CR(this._onHandleDragMove,this),ondragend:CR(this._onHandleDragEnd,this)}),i.add(r)),OR(r,n,!1),r.setStyle(o.getItemStyle(null,["color","borderColor","borderWidth","opacity","shadowColor","shadowBlur","shadowOffsetX","shadowOffsetY"]));var s=o.get("size");Y(s)||(s=[s,s]),r.scaleX=s[0]/2,r.scaleY=s[1]/2,Dg(this,"_doDispatchAxisPointer",o.get("throttle")||0,"fixRate"),this._moveHandleToValue(t,e)}},t.prototype._moveHandleToValue=function(t,e){AR(this._axisPointerModel,!e&&this._moveAnimation,this._handle,PR(this.getHandleTransform(t,this._axisModel,this._axisPointerModel)))},t.prototype._onHandleDragMove=function(t,e){var n=this._handle;if(n){this._dragging=!0;var i=this.updateHandleTransform(PR(n),[t,e],this._axisModel,this._axisPointerModel);this._payloadInfo=i,n.stopAnimation(),n.attr(PR(i)),IR(n).lastProp=null,this._doDispatchAxisPointer()}},t.prototype._doDispatchAxisPointer=function(){if(this._handle){var t=this._payloadInfo,e=this._axisModel;this._api.dispatchAction({type:"updateAxisPointer",x:t.cursorPoint[0],y:t.cursorPoint[1],tooltipOption:t.tooltipOption,axesInfo:[{axisDim:e.axis.dim,axisIndex:e.componentIndex}]})}},t.prototype._onHandleDragEnd=function(){if(this._dragging=!1,this._handle){var t=this._axisPointerModel.get("value");this._moveHandleToValue(t),this._api.dispatchAction({type:"hideTip"})}},t.prototype.clear=function(t){this._lastValue=null,this._lastStatus=null;var e=t.getZr(),n=this._group,i=this._handle;e&&n&&(this._lastGraphicKey=null,n&&e.remove(n),i&&e.remove(i),this._group=null,this._handle=null,this._payloadInfo=null),Ag(this,"_doDispatchAxisPointer")},t.prototype.doClear=function(){},t.prototype.buildLabel=function(t,e,n){return{x:t[n=n||0],y:t[1-n],width:e[n],height:e[1-n]}},t}();function AR(t,e,n,i){kR(IR(n).lastProp,i)||(IR(n).lastProp=i,e?ih(n,i,t):(n.stopAnimation(),n.attr(i)))}function kR(t,e){if(q(t)&&q(e)){var n=!0;return E(e,(function(e,i){n=n&&kR(t[i],e)})),!!n}return t===e}function LR(t,e){t[e.get(["label","show"])?"show":"hide"]()}function PR(t){return{x:t.x||0,y:t.y||0,rotation:t.rotation||0}}function OR(t,e,n){var i=e.get("z"),r=e.get("zlevel");t&&t.traverse((function(t){"group"!==t.type&&(null!=i&&(t.z=i),null!=r&&(t.zlevel=r),t.silent=n)}))}function RR(t){var e,n=t.get("type"),i=t.getModel(n+"Style");return"line"===n?(e=i.getLineStyle()).fill=null:"shadow"===n&&((e=i.getAreaStyle()).stroke=null),e}function NR(t,e,n,i,r){var o=ER(n.get("value"),e.axis,e.ecModel,n.get("seriesDataIndices"),{precision:n.get(["label","precision"]),formatter:n.get(["label","formatter"])}),a=n.getModel("label"),s=np(a.get("padding")||0),l=a.getFont(),u=cr(o,l),h=r.position,c=u.width+s[1]+s[3],p=u.height+s[0]+s[2],d=r.align;"right"===d&&(h[0]-=c),"center"===d&&(h[0]-=c/2);var f=r.verticalAlign;"bottom"===f&&(h[1]-=p),"middle"===f&&(h[1]-=p/2),function(t,e,n,i){var r=i.getWidth(),o=i.getHeight();t[0]=Math.min(t[0]+e,r)-e,t[1]=Math.min(t[1]+n,o)-n,t[0]=Math.max(t[0],0),t[1]=Math.max(t[1],0)}(h,c,p,i);var g=a.get("backgroundColor");g&&"auto"!==g||(g=e.get(["axisLine","lineStyle","color"])),t.label={x:h[0],y:h[1],style:Yh(a,{text:o,font:l,fill:a.getTextColor(),padding:s,backgroundColor:g}),z2:10}}function ER(t,e,n,i,r){t=e.scale.parse(t);var o=e.scale.getLabel({value:t},{precision:r.precision}),a=r.formatter;if(a){var s={value:o_(e,{value:t}),axisDimension:e.dim,axisIndex:e.index,seriesData:[]};E(i,(function(t){var e=n.getSeriesByIndex(t.seriesIndex),i=t.dataIndexInside,r=e&&e.getDataParams(i);r&&s.seriesData.push(r)})),X(a)?o=a.replace("{value}",o):U(a)&&(o=a(s))}return o}function zR(t,e,n){var i=[1,0,0,1,0,0];return zi(i,i,n.rotation),Ei(i,i,n.position),Ih([t.dataToCoord(e),(n.labelOffset||0)+(n.labelDirection||1)*(n.labelMargin||0)],i)}function VR(t,e,n,i,r,o){var a=BM.innerTextLayout(n.rotation,0,n.labelDirection);n.labelMargin=r.get(["label","margin"]),NR(e,i,r,o,{position:zR(i.axis,t,n),align:a.textAlign,verticalAlign:a.textVerticalAlign})}function BR(t,e,n){return{x1:t[n=n||0],y1:t[1-n],x2:e[n],y2:e[1-n]}}function FR(t,e,n){return{x:t[n=n||0],y:t[1-n],width:e[n],height:e[1-n]}}function GR(t,e,n,i,r,o){return{cx:t,cy:e,r0:n,r:i,startAngle:r,endAngle:o,clockwise:!0}}var WR=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis,a=o.grid,s=i.get("type"),l=HR(a,o).getOtherAxis(o).getGlobalExtent(),u=o.toGlobalCoord(o.dataToCoord(e,!0));if(s&&"none"!==s){var h=RR(i),c=YR[s](o,u,l);c.style=h,t.graphicKey=c.type,t.pointer=c}VR(e,t,AM(a.model,n),n,i,r)},e.prototype.getHandleTransform=function(t,e,n){var i=AM(e.axis.grid.model,e,{labelInside:!1});i.labelMargin=n.get(["handle","margin"]);var r=zR(e.axis,t,i);return{x:r[0],y:r[1],rotation:i.rotation+(i.labelDirection<0?Math.PI:0)}},e.prototype.updateHandleTransform=function(t,e,n,i){var r=n.axis,o=r.grid,a=r.getGlobalExtent(!0),s=HR(o,r).getOtherAxis(r).getGlobalExtent(),l="x"===r.dim?0:1,u=[t.x,t.y];u[l]+=e[l],u[l]=Math.min(a[1],u[l]),u[l]=Math.max(a[0],u[l]);var h=(s[1]+s[0])/2,c=[h,h];c[l]=u[l];return{x:u[0],y:u[1],rotation:t.rotation,cursorPoint:c,tooltipOption:[{verticalAlign:"middle"},{align:"center"}][l]}},e}(DR);function HR(t,e){var n={};return n[e.dim+"AxisIndex"]=e.index,t.getCartesian(n)}var YR={line:function(t,e,n){return{type:"Line",subPixelOptimize:!0,shape:BR([e,n[0]],[e,n[1]],UR(t))}},shadow:function(t,e,n){var i=Math.max(1,t.getBandWidth()),r=n[1]-n[0];return{type:"Rect",shape:FR([e-i/2,n[0]],[i,r],UR(t))}}};function UR(t){return"x"===t.dim?0:1}var XR=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="axisPointer",e.defaultOption={show:"auto",z:50,type:"line",snap:!1,triggerTooltip:!0,value:null,status:null,link:[],animation:null,animationDurationUpdate:200,lineStyle:{color:"#B9BEC9",width:1,type:"dashed"},shadowStyle:{color:"rgba(210,219,238,0.2)"},label:{show:!0,formatter:null,precision:"auto",margin:3,color:"#fff",padding:[5,7,5,7],backgroundColor:"auto",borderColor:null,borderWidth:0,borderRadius:3},handle:{show:!1,icon:"M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z",size:45,margin:50,color:"#333",shadowBlur:3,shadowColor:"#aaa",shadowOffsetX:0,shadowOffsetY:2,throttle:40}},e}(Ip),ZR=So(),jR=E;function qR(t,e,n){if(!r.node){var i=e.getZr();ZR(i).records||(ZR(i).records={}),function(t,e){if(ZR(t).initialized)return;function n(n,i){t.on(n,(function(n){var r=function(t){var e={showTip:[],hideTip:[]},n=function(i){var r=e[i.type];r?r.push(i):(i.dispatchAction=n,t.dispatchAction(i))};return{dispatchAction:n,pendings:e}}(e);jR(ZR(t).records,(function(t){t&&i(t,n,r.dispatchAction)})),function(t,e){var n,i=t.showTip.length,r=t.hideTip.length;i?n=t.showTip[i-1]:r&&(n=t.hideTip[r-1]);n&&(n.dispatchAction=null,e.dispatchAction(n))}(r.pendings,e)}))}ZR(t).initialized=!0,n("click",H($R,"click")),n("mousemove",H($R,"mousemove")),n("globalout",KR)}(i,e),(ZR(i).records[t]||(ZR(i).records[t]={})).handler=n}}function KR(t,e,n){t.handler("leave",null,n)}function $R(t,e,n,i){e.handler(t,n,i)}function JR(t,e){if(!r.node){var n=e.getZr();(ZR(n).records||{})[t]&&(ZR(n).records[t]=null)}}var QR=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=e.getComponent("tooltip"),r=t.get("triggerOn")||i&&i.get("triggerOn")||"mousemove|click";qR("axisPointer",n,(function(t,e,n){"none"!==r&&("leave"===t||r.indexOf(t)>=0)&&n({type:"updateAxisPointer",currTrigger:t,x:e&&e.offsetX,y:e&&e.offsetY})}))},e.prototype.remove=function(t,e){JR("axisPointer",e)},e.prototype.dispose=function(t,e){JR("axisPointer",e)},e.type="axisPointer",e}(fg);function tN(t,e){var n,i=[],r=t.seriesIndex;if(null==r||!(n=e.getSeriesByIndex(r)))return{point:[]};var o=n.getData(),a=wo(o,t);if(null==a||a<0||Y(a))return{point:[]};var s=o.getItemGraphicEl(a),l=n.coordinateSystem;if(n.getTooltipPosition)i=n.getTooltipPosition(a)||[];else if(l&&l.dataToPoint)if(t.isStacked){var u=l.getBaseAxis(),h=l.getOtherAxis(u).dim,c=u.dim,p="x"===h||"radius"===h?1:0,d=o.mapDimension(c),f=[];f[p]=o.get(d,a),f[1-p]=o.get(o.getCalculationInfo("stackResultDimension"),a),i=l.dataToPoint(f)||[]}else i=l.dataToPoint(o.getValues(z(l.dimensions,(function(t){return o.mapDimension(t)})),a))||[];else if(s){var g=s.getBoundingRect().clone();g.applyTransform(s.transform),i=[g.x+g.width/2,g.y+g.height/2]}return{point:i,el:s}}var eN=So();function nN(t,e,n){var i=t.currTrigger,r=[t.x,t.y],o=t,a=t.dispatchAction||W(n.dispatchAction,n),s=e.getComponent("axisPointer").coordSysAxesInfo;if(s){sN(r)&&(r=tN({seriesIndex:o.seriesIndex,dataIndex:o.dataIndex},e).point);var l=sN(r),u=o.axesInfo,h=s.axesInfo,c="leave"===i||sN(r),p={},d={},f={list:[],map:{}},g={showPointer:H(rN,d),showTooltip:H(oN,f)};E(s.coordSysMap,(function(t,e){var n=l||t.containPoint(r);E(s.coordSysAxesInfo[e],(function(t,e){var i=t.axis,o=function(t,e){for(var n=0;n<(t||[]).length;n++){var i=t[n];if(e.axis.dim===i.axisDim&&e.axis.model.componentIndex===i.axisIndex)return i}}(u,t);if(!c&&n&&(!u||o)){var a=o&&o.value;null!=a||l||(a=i.pointToData(r)),null!=a&&iN(t,a,g,!1,p)}}))}));var y={};return E(h,(function(t,e){var n=t.linkGroup;n&&!d[e]&&E(n.axesInfo,(function(e,i){var r=d[i];if(e!==t&&r){var o=r.value;n.mapper&&(o=t.axis.scale.parse(n.mapper(o,aN(e),aN(t)))),y[t.key]=o}}))})),E(y,(function(t,e){iN(h[e],t,g,!0,p)})),function(t,e,n){var i=n.axesInfo=[];E(e,(function(e,n){var r=e.axisPointerModel.option,o=t[n];o?(!e.useHandle&&(r.status="show"),r.value=o.value,r.seriesDataIndices=(o.payloadBatch||[]).slice()):!e.useHandle&&(r.status="hide"),"show"===r.status&&i.push({axisDim:e.axis.dim,axisIndex:e.axis.model.componentIndex,value:r.value})}))}(d,h,p),function(t,e,n,i){if(sN(e)||!t.list.length)return void i({type:"hideTip"});var r=((t.list[0].dataByAxis[0]||{}).seriesDataIndices||[])[0]||{};i({type:"showTip",escapeConnect:!0,x:e[0],y:e[1],tooltipOption:n.tooltipOption,position:n.position,dataIndexInside:r.dataIndexInside,dataIndex:r.dataIndex,seriesIndex:r.seriesIndex,dataByCoordSys:t.list})}(f,r,t,a),function(t,e,n){var i=n.getZr(),r="axisPointerLastHighlights",o=eN(i)[r]||{},a=eN(i)[r]={};E(t,(function(t,e){var n=t.axisPointerModel.option;"show"===n.status&&E(n.seriesDataIndices,(function(t){var e=t.seriesIndex+" | "+t.dataIndex;a[e]=t}))}));var s=[],l=[];E(o,(function(t,e){!a[e]&&l.push(t)})),E(a,(function(t,e){!o[e]&&s.push(t)})),l.length&&n.dispatchAction({type:"downplay",escapeConnect:!0,notBlur:!0,batch:l}),s.length&&n.dispatchAction({type:"highlight",escapeConnect:!0,notBlur:!0,batch:s})}(h,0,n),p}}function iN(t,e,n,i,r){var o=t.axis;if(!o.scale.isBlank()&&o.containData(e))if(t.involveSeries){var a=function(t,e){var n=e.axis,i=n.dim,r=t,o=[],a=Number.MAX_VALUE,s=-1;return E(e.seriesModels,(function(e,l){var u,h,c=e.getData().mapDimensionsAll(i);if(e.getAxisTooltipData){var p=e.getAxisTooltipData(c,t,n);h=p.dataIndices,u=p.nestestValue}else{if(!(h=e.getData().indicesOfNearest(c[0],t,"category"===n.type?.5:null)).length)return;u=e.getData().get(c[0],h[0])}if(null!=u&&isFinite(u)){var d=t-u,f=Math.abs(d);f<=a&&((f=0&&s<0)&&(a=f,s=d,r=u,o.length=0),E(h,(function(t){o.push({seriesIndex:e.seriesIndex,dataIndexInside:t,dataIndex:e.getData().getRawIndex(t)})})))}})),{payloadBatch:o,snapToValue:r}}(e,t),s=a.payloadBatch,l=a.snapToValue;s[0]&&null==r.seriesIndex&&A(r,s[0]),!i&&t.snap&&o.containData(l)&&null!=l&&(e=l),n.showPointer(t,e,s),n.showTooltip(t,a,l)}else n.showPointer(t,e)}function rN(t,e,n,i){t[e.key]={value:n,payloadBatch:i}}function oN(t,e,n,i){var r=n.payloadBatch,o=e.axis,a=o.model,s=e.axisPointerModel;if(e.triggerTooltip&&r.length){var l=e.coordSys.model,u=KM(l),h=t.map[u];h||(h=t.map[u]={coordSysId:l.id,coordSysIndex:l.componentIndex,coordSysType:l.type,coordSysMainType:l.mainType,dataByAxis:[]},t.list.push(h)),h.dataByAxis.push({axisDim:o.dim,axisIndex:a.componentIndex,axisType:a.type,axisId:a.id,value:i,valueLabelOpt:{precision:s.get(["label","precision"]),formatter:s.get(["label","formatter"])},seriesDataIndices:r.slice()})}}function aN(t){var e=t.axis.model,n={},i=n.axisDim=t.axis.dim;return n.axisIndex=n[i+"AxisIndex"]=e.componentIndex,n.axisName=n[i+"AxisName"]=e.name,n.axisId=n[i+"AxisId"]=e.id,n}function sN(t){return!t||null==t[0]||isNaN(t[0])||null==t[1]||isNaN(t[1])}function lN(t){JM.registerAxisPointerClass("CartesianAxisPointer",WR),t.registerComponentModel(XR),t.registerComponentView(QR),t.registerPreprocessor((function(t){if(t){(!t.axisPointer||0===t.axisPointer.length)&&(t.axisPointer={});var e=t.axisPointer.link;e&&!Y(e)&&(t.axisPointer.link=[e])}})),t.registerProcessor(t.PRIORITY.PROCESSOR.STATISTIC,(function(t,e){t.getComponent("axisPointer").coordSysAxesInfo=UM(t,e)})),t.registerAction({type:"updateAxisPointer",event:"updateAxisPointer",update:":updateAxisPointer"},nN)}var uN=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis;"angle"===o.dim&&(this.animationThreshold=Math.PI/18);var a=o.polar,s=a.getOtherAxis(o).getExtent(),l=o.dataToCoord(e),u=i.get("type");if(u&&"none"!==u){var h=RR(i),c=hN[u](o,a,l,s);c.style=h,t.graphicKey=c.type,t.pointer=c}var p=function(t,e,n,i,r){var o=e.axis,a=o.dataToCoord(t),s=i.getAngleAxis().getExtent()[0];s=s/180*Math.PI;var l,u,h,c=i.getRadiusAxis().getExtent();if("radius"===o.dim){var p=[1,0,0,1,0,0];zi(p,p,s),Ei(p,p,[i.cx,i.cy]),l=Ih([a,-r],p);var d=e.getModel("axisLabel").get("rotate")||0,f=BM.innerTextLayout(s,d*Math.PI/180,-1);u=f.textAlign,h=f.textVerticalAlign}else{var g=c[1];l=i.coordToPoint([g+r,a]);var y=i.cx,v=i.cy;u=Math.abs(l[0]-y)/g<.3?"center":l[0]>y?"left":"right",h=Math.abs(l[1]-v)/g<.3?"middle":l[1]>v?"top":"bottom"}return{position:l,align:u,verticalAlign:h}}(e,n,0,a,i.get(["label","margin"]));NR(t,n,i,r,p)},e}(DR);var hN={line:function(t,e,n,i){return"angle"===t.dim?{type:"Line",shape:BR(e.coordToPoint([i[0],n]),e.coordToPoint([i[1],n]))}:{type:"Circle",shape:{cx:e.cx,cy:e.cy,r:n}}},shadow:function(t,e,n,i){var r=Math.max(1,t.getBandWidth()),o=Math.PI/180;return"angle"===t.dim?{type:"Sector",shape:GR(e.cx,e.cy,i[0],i[1],(-n-r/2)*o,(r/2-n)*o)}:{type:"Sector",shape:GR(e.cx,e.cy,n-r/2,n+r/2,0,2*Math.PI)}}},cN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.findAxisModel=function(t){var e;return this.ecModel.eachComponent(t,(function(t){t.getCoordSysModel()===this&&(e=t)}),this),e},e.type="polar",e.dependencies=["radiusAxis","angleAxis"],e.defaultOption={z:0,center:["50%","50%"],radius:"80%"},e}(Ip),pN=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getCoordSysModel=function(){return this.getReferringComponents("polar",Co).models[0]},e.type="polarAxis",e}(Ip);R(pN,h_);var dN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="angleAxis",e}(pN),fN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="radiusAxis",e}(pN),gN=function(t){function e(e,n){return t.call(this,"radius",e,n)||this}return n(e,t),e.prototype.pointToData=function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},e}(G_);gN.prototype.dataToRadius=G_.prototype.dataToCoord,gN.prototype.radiusToData=G_.prototype.coordToData;var yN=So(),vN=function(t){function e(e,n){return t.call(this,"angle",e,n||[0,360])||this}return n(e,t),e.prototype.pointToData=function(t,e){return this.polar.pointToData(t,e)["radius"===this.dim?0:1]},e.prototype.calculateCategoryInterval=function(){var t=this,e=t.getLabelModel(),n=t.scale,i=n.getExtent(),r=n.count();if(i[1]-i[0]<1)return 0;var o=i[0],a=t.dataToCoord(o+1)-t.dataToCoord(o),s=Math.abs(a),l=cr(null==o?"":o+"",e.getFont(),"center","top"),u=Math.max(l.height,7)/s;isNaN(u)&&(u=1/0);var h=Math.max(0,Math.floor(u)),c=yN(t.model),p=c.lastAutoInterval,d=c.lastTickCount;return null!=p&&null!=d&&Math.abs(p-h)<=1&&Math.abs(d-r)<=1&&p>h?h=p:(c.lastTickCount=r,c.lastAutoInterval=h),h},e}(G_);vN.prototype.dataToAngle=G_.prototype.dataToCoord,vN.prototype.angleToData=G_.prototype.coordToData;var mN=["radius","angle"],xN=function(){function t(t){this.dimensions=mN,this.type="polar",this.cx=0,this.cy=0,this._radiusAxis=new gN,this._angleAxis=new vN,this.axisPointerEnabled=!0,this.name=t||"",this._radiusAxis.polar=this._angleAxis.polar=this}return t.prototype.containPoint=function(t){var e=this.pointToCoord(t);return this._radiusAxis.contain(e[0])&&this._angleAxis.contain(e[1])},t.prototype.containData=function(t){return this._radiusAxis.containData(t[0])&&this._angleAxis.containData(t[1])},t.prototype.getAxis=function(t){return this["_"+t+"Axis"]},t.prototype.getAxes=function(){return[this._radiusAxis,this._angleAxis]},t.prototype.getAxesByScale=function(t){var e=[],n=this._angleAxis,i=this._radiusAxis;return n.scale.type===t&&e.push(n),i.scale.type===t&&e.push(i),e},t.prototype.getAngleAxis=function(){return this._angleAxis},t.prototype.getRadiusAxis=function(){return this._radiusAxis},t.prototype.getOtherAxis=function(t){var e=this._angleAxis;return t===e?this._radiusAxis:e},t.prototype.getBaseAxis=function(){return this.getAxesByScale("ordinal")[0]||this.getAxesByScale("time")[0]||this.getAngleAxis()},t.prototype.getTooltipAxes=function(t){var e=null!=t&&"auto"!==t?this.getAxis(t):this.getBaseAxis();return{baseAxes:[e],otherAxes:[this.getOtherAxis(e)]}},t.prototype.dataToPoint=function(t,e){return this.coordToPoint([this._radiusAxis.dataToRadius(t[0],e),this._angleAxis.dataToAngle(t[1],e)])},t.prototype.pointToData=function(t,e){var n=this.pointToCoord(t);return[this._radiusAxis.radiusToData(n[0],e),this._angleAxis.angleToData(n[1],e)]},t.prototype.pointToCoord=function(t){var e=t[0]-this.cx,n=t[1]-this.cy,i=this.getAngleAxis(),r=i.getExtent(),o=Math.min(r[0],r[1]),a=Math.max(r[0],r[1]);i.inverse?o=a-360:a=o+360;var s=Math.sqrt(e*e+n*n);e/=s,n/=s;for(var l=Math.atan2(-n,e)/Math.PI*180,u=la;)l+=360*u;return[s,l]},t.prototype.coordToPoint=function(t){var e=t[0],n=t[1]/180*Math.PI;return[Math.cos(n)*e+this.cx,-Math.sin(n)*e+this.cy]},t.prototype.getArea=function(){var t=this.getAngleAxis(),e=this.getRadiusAxis().getExtent().slice();e[0]>e[1]&&e.reverse();var n=t.getExtent(),i=Math.PI/180;return{cx:this.cx,cy:this.cy,r0:e[0],r:e[1],startAngle:-n[0]*i,endAngle:-n[1]*i,clockwise:t.inverse,contain:function(t,e){var n=t-this.cx,i=e-this.cy,r=n*n+i*i-1e-4,o=this.r,a=this.r0;return r<=o*o&&r>=a*a}}},t.prototype.convertToPixel=function(t,e,n){return _N(e)===this?this.dataToPoint(n):null},t.prototype.convertFromPixel=function(t,e,n){return _N(e)===this?this.pointToData(n):null},t}();function _N(t){var e=t.seriesModel,n=t.polarModel;return n&&n.coordinateSystem||e&&e.coordinateSystem}function bN(t,e){var n=this,i=n.getAngleAxis(),r=n.getRadiusAxis();if(i.scale.setExtent(1/0,-1/0),r.scale.setExtent(1/0,-1/0),t.eachSeries((function(t){if(t.coordinateSystem===n){var e=t.getData();E(u_(e,"radius"),(function(t){r.scale.unionExtentFromData(e,t)})),E(u_(e,"angle"),(function(t){i.scale.unionExtentFromData(e,t)}))}})),n_(i.scale,i.model),n_(r.scale,r.model),"category"===i.type&&!i.onBand){var o=i.getExtent(),a=360/i.scale.count();i.inverse?o[1]+=a:o[1]-=a,i.setExtent(o[0],o[1])}}function wN(t,e){if(t.type=e.get("type"),t.scale=i_(e),t.onBand=e.get("boundaryGap")&&"category"===t.type,t.inverse=e.get("inverse"),function(t){return"angleAxis"===t.mainType}(e)){t.inverse=t.inverse!==e.get("clockwise");var n=e.get("startAngle");t.setExtent(n,n+(t.inverse?-360:360))}e.axis=t,t.model=e}var SN={dimensions:mN,create:function(t,e){var n=[];return t.eachComponent("polar",(function(t,i){var r=new xN(i+"");r.update=bN;var o=r.getRadiusAxis(),a=r.getAngleAxis(),s=t.findAxisModel("radiusAxis"),l=t.findAxisModel("angleAxis");wN(o,s),wN(a,l),function(t,e,n){var i=e.get("center"),r=n.getWidth(),o=n.getHeight();t.cx=Er(i[0],r),t.cy=Er(i[1],o);var a=t.getRadiusAxis(),s=Math.min(r,o)/2,l=e.get("radius");null==l?l=[0,"100%"]:Y(l)||(l=[0,l]);var u=[Er(l[0],s),Er(l[1],s)];a.inverse?a.setExtent(u[1],u[0]):a.setExtent(u[0],u[1])}(r,t,e),n.push(r),t.coordinateSystem=r,r.model=t})),t.eachSeries((function(t){if("polar"===t.get("coordinateSystem")){var e=t.getReferringComponents("polar",Co).models[0];0,t.coordinateSystem=e.coordinateSystem}})),n}},MN=["axisLine","axisLabel","axisTick","minorTick","splitLine","minorSplitLine","splitArea"];function IN(t,e,n){e[1]>e[0]&&(e=e.slice().reverse());var i=t.coordToPoint([e[0],n]),r=t.coordToPoint([e[1],n]);return{x1:i[0],y1:i[1],x2:r[0],y2:r[1]}}function TN(t){return t.getRadiusAxis().inverse?0:1}function CN(t){var e=t[0],n=t[t.length-1];e&&n&&Math.abs(Math.abs(e.coord-n.coord)-360)<1e-4&&t.pop()}var DN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.axisPointerClass="PolarAxisPointer",n}return n(e,t),e.prototype.render=function(t,e){if(this.group.removeAll(),t.get("show")){var n=t.axis,i=n.polar,r=i.getRadiusAxis().getExtent(),o=n.getTicksCoords(),a=n.getMinorTicksCoords(),s=z(n.getViewLabels(),(function(t){t=T(t);var e=n.scale,i="ordinal"===e.type?e.getRawOrdinalNumber(t.tickValue):t.tickValue;return t.coord=n.dataToCoord(i),t}));CN(s),CN(o),E(MN,(function(e){!t.get([e,"show"])||n.scale.isBlank()&&"axisLine"!==e||AN[e](this.group,t,i,o,a,r,s)}),this)}},e.type="angleAxis",e}(JM),AN={axisLine:function(t,e,n,i,r,o){var a,s=e.getModel(["axisLine","lineStyle"]),l=TN(n),u=l?0:1;(a=0===o[u]?new uu({shape:{cx:n.cx,cy:n.cy,r:o[l]},style:s.getLineStyle(),z2:1,silent:!0}):new Du({shape:{cx:n.cx,cy:n.cy,r:o[l],r0:o[u]},style:s.getLineStyle(),z2:1,silent:!0})).style.fill=null,t.add(a)},axisTick:function(t,e,n,i,r,o){var a=e.getModel("axisTick"),s=(a.get("inside")?-1:1)*a.get("length"),l=o[TN(n)],u=z(i,(function(t){return new Eu({shape:IN(n,[l,l+s],t.coord)})}));t.add(bh(u,{style:k(a.getModel("lineStyle").getLineStyle(),{stroke:e.get(["axisLine","lineStyle","color"])})}))},minorTick:function(t,e,n,i,r,o){if(r.length){for(var a=e.getModel("axisTick"),s=e.getModel("minorTick"),l=(a.get("inside")?-1:1)*s.get("length"),u=o[TN(n)],h=[],c=0;cf?"left":"right",v=Math.abs(d[1]-g)/p<.3?"middle":d[1]>g?"top":"bottom";if(s&&s[c]){var m=s[c];q(m)&&m.textStyle&&(a=new pc(m.textStyle,l,l.ecModel))}var x=new As({silent:BM.isLabelSilent(e),style:Yh(a,{x:d[0],y:d[1],fill:a.getTextColor()||e.get(["axisLine","lineStyle","color"]),text:i.formattedLabel,align:y,verticalAlign:v})});if(t.add(x),h){var _=BM.makeAxisEventDataBase(e);_.targetType="axisLabel",_.value=i.rawLabel,Ws(x).eventData=_}}),this)},splitLine:function(t,e,n,i,r,o){var a=e.getModel("splitLine").getModel("lineStyle"),s=a.get("color"),l=0;s=s instanceof Array?s:[s];for(var u=[],h=0;h=0?"p":"n",T=_;m&&(i[s][M]||(i[s][M]={p:_,n:_}),T=i[s][M][I]);var C=void 0,D=void 0,A=void 0,k=void 0;if("radius"===c.dim){var L=c.dataToCoord(S)-_,P=o.dataToCoord(M);Math.abs(L)=k})}}}))}var zN={startAngle:90,clockwise:!0,splitNumber:12,axisLabel:{rotate:0}},VN={splitNumber:5},BN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="polar",e}(fg);function FN(t,e){e=e||{};var n=t.coordinateSystem,i=t.axis,r={},o=i.position,a=i.orient,s=n.getRect(),l=[s.x,s.x+s.width,s.y,s.y+s.height],u={horizontal:{top:l[2],bottom:l[3]},vertical:{left:l[0],right:l[1]}};r.position=["vertical"===a?u.vertical[o]:l[0],"horizontal"===a?u.horizontal[o]:l[3]];r.rotation=Math.PI/2*{horizontal:0,vertical:1}[a];r.labelDirection=r.tickDirection=r.nameDirection={top:-1,bottom:1,right:1,left:-1}[o],t.get(["axisTick","inside"])&&(r.tickDirection=-r.tickDirection),it(e.labelInside,t.get(["axisLabel","inside"]))&&(r.labelDirection=-r.labelDirection);var h=e.rotate;return null==h&&(h=t.get(["axisLabel","rotate"])),r.labelRotation="top"===o?-h:h,r.z2=1,r}var GN=["axisLine","axisTickLabel","axisName"],WN=["splitArea","splitLine"],HN=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.axisPointerClass="SingleAxisPointer",n}return n(e,t),e.prototype.render=function(e,n,i,r){var o=this.group;o.removeAll();var a=this._axisGroup;this._axisGroup=new Cr;var s=FN(e),l=new BM(e,s);E(GN,l.add,l),o.add(this._axisGroup),o.add(l.getGroup()),E(WN,(function(t){e.get([t,"show"])&&YN[t](this,this.group,this._axisGroup,e)}),this),Dh(a,this._axisGroup,e),t.prototype.render.call(this,e,n,i,r)},e.prototype.remove=function(){eI(this)},e.type="singleAxis",e}(JM),YN={splitLine:function(t,e,n,i){var r=i.axis;if(!r.scale.isBlank()){var o=i.getModel("splitLine"),a=o.getModel("lineStyle"),s=a.get("color");s=s instanceof Array?s:[s];for(var l=i.coordinateSystem.getRect(),u=r.isHorizontal(),h=[],c=0,p=r.getTicksCoords({tickModel:o}),d=[],f=[],g=0;g=e.y&&t[1]<=e.y+e.height:n.contain(n.toLocalCoord(t[1]))&&t[0]>=e.y&&t[0]<=e.y+e.height},t.prototype.pointToData=function(t){var e=this.getAxis();return[e.coordToData(e.toLocalCoord(t["horizontal"===e.orient?0:1]))]},t.prototype.dataToPoint=function(t){var e=this.getAxis(),n=this.getRect(),i=[],r="horizontal"===e.orient?0:1;return t instanceof Array&&(t=t[0]),i[r]=e.toGlobalCoord(e.dataToCoord(+t)),i[1-r]=0===r?n.y+n.height/2:n.x+n.width/2,i},t.prototype.convertToPixel=function(t,e,n){return qN(e)===this?this.dataToPoint(n):null},t.prototype.convertFromPixel=function(t,e,n){return qN(e)===this?this.pointToData(n):null},t}();function qN(t){var e=t.seriesModel,n=t.singleAxisModel;return n&&n.coordinateSystem||e&&e.coordinateSystem}var KN={create:function(t,e){var n=[];return t.eachComponent("singleAxis",(function(i,r){var o=new jN(i,t,e);o.name="single_"+r,o.resize(i,e),i.coordinateSystem=o,n.push(o)})),t.eachSeries((function(t){if("singleAxis"===t.get("coordinateSystem")){var e=t.getReferringComponents("singleAxis",Co).models[0];t.coordinateSystem=e&&e.coordinateSystem}})),n},dimensions:ZN},$N=["x","y"],JN=["width","height"],QN=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.makeElOption=function(t,e,n,i,r){var o=n.axis,a=o.coordinateSystem,s=nE(a,1-eE(o)),l=a.dataToPoint(e)[0],u=i.get("type");if(u&&"none"!==u){var h=RR(i),c=tE[u](o,l,s);c.style=h,t.graphicKey=c.type,t.pointer=c}VR(e,t,FN(n),n,i,r)},e.prototype.getHandleTransform=function(t,e,n){var i=FN(e,{labelInside:!1});i.labelMargin=n.get(["handle","margin"]);var r=zR(e.axis,t,i);return{x:r[0],y:r[1],rotation:i.rotation+(i.labelDirection<0?Math.PI:0)}},e.prototype.updateHandleTransform=function(t,e,n,i){var r=n.axis,o=r.coordinateSystem,a=eE(r),s=nE(o,a),l=[t.x,t.y];l[a]+=e[a],l[a]=Math.min(s[1],l[a]),l[a]=Math.max(s[0],l[a]);var u=nE(o,1-a),h=(u[1]+u[0])/2,c=[h,h];return c[a]=l[a],{x:l[0],y:l[1],rotation:t.rotation,cursorPoint:c,tooltipOption:{verticalAlign:"middle"}}},e}(DR),tE={line:function(t,e,n){return{type:"Line",subPixelOptimize:!0,shape:BR([e,n[0]],[e,n[1]],eE(t))}},shadow:function(t,e,n){var i=t.getBandWidth(),r=n[1]-n[0];return{type:"Rect",shape:FR([e-i/2,n[0]],[i,r],eE(t))}}};function eE(t){return t.isHorizontal()?0:1}function nE(t,e){var n=t.getRect();return[n[$N[e]],n[$N[e]]+n[JN[e]]]}var iE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="single",e}(fg);var rE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(e,n,i){var r=wp(e);t.prototype.init.apply(this,arguments),oE(e,r)},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),oE(this.option,e)},e.prototype.getCellSize=function(){return this.option.cellSize},e.type="calendar",e.defaultOption={z:2,left:80,top:60,cellSize:20,orient:"horizontal",splitLine:{show:!0,lineStyle:{color:"#000",width:1,type:"solid"}},itemStyle:{color:"#fff",borderWidth:1,borderColor:"#ccc"},dayLabel:{show:!0,firstDay:0,position:"start",margin:"50%",color:"#000"},monthLabel:{show:!0,position:"start",margin:5,align:"center",formatter:null,color:"#000"},yearLabel:{show:!0,position:null,margin:30,formatter:null,color:"#ccc",fontFamily:"sans-serif",fontWeight:"bolder",fontSize:20}},e}(Ip);function oE(t,e){var n,i=t.cellSize;1===(n=Y(i)?i:t.cellSize=[i,i]).length&&(n[1]=n[0]);var r=z([0,1],(function(t){return function(t,e){return null!=t[gp[e][0]]||null!=t[gp[e][1]]&&null!=t[gp[e][2]]}(e,t)&&(n[t]="auto"),null!=n[t]&&"auto"!==n[t]}));bp(t,e,{type:"box",ignoreSize:r})}var aE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){var i=this.group;i.removeAll();var r=t.coordinateSystem,o=r.getRangeInfo(),a=r.getOrient(),s=e.getLocaleModel();this._renderDayRect(t,o,i),this._renderLines(t,o,a,i),this._renderYearText(t,o,a,i),this._renderMonthText(t,s,a,i),this._renderWeekText(t,s,o,a,i)},e.prototype._renderDayRect=function(t,e,n){for(var i=t.coordinateSystem,r=t.getModel("itemStyle").getItemStyle(),o=i.getCellWidth(),a=i.getCellHeight(),s=e.start.time;s<=e.end.time;s=i.getNextNDay(s,1).time){var l=i.dataToRect([s],!1).tl,u=new Ts({shape:{x:l[0],y:l[1],width:o,height:a},cursor:"default",style:r});n.add(u)}},e.prototype._renderLines=function(t,e,n,i){var r=this,o=t.coordinateSystem,a=t.getModel(["splitLine","lineStyle"]).getLineStyle(),s=t.get(["splitLine","show"]),l=a.lineWidth;this._tlpoints=[],this._blpoints=[],this._firstDayOfMonth=[],this._firstDayPoints=[];for(var u=e.start,h=0;u.time<=e.end.time;h++){p(u.formatedDate),0===h&&(u=o.getDateInfo(e.start.y+"-"+e.start.m));var c=u.date;c.setMonth(c.getMonth()+1),u=o.getDateInfo(c)}function p(e){r._firstDayOfMonth.push(o.getDateInfo(e)),r._firstDayPoints.push(o.dataToRect([e],!1).tl);var l=r._getLinePointsOfOneWeek(t,e,n);r._tlpoints.push(l[0]),r._blpoints.push(l[l.length-1]),s&&r._drawSplitline(l,a,i)}p(o.getNextNDay(e.end.time,1).formatedDate),s&&this._drawSplitline(r._getEdgesPoints(r._tlpoints,l,n),a,i),s&&this._drawSplitline(r._getEdgesPoints(r._blpoints,l,n),a,i)},e.prototype._getEdgesPoints=function(t,e,n){var i=[t[0].slice(),t[t.length-1].slice()],r="horizontal"===n?0:1;return i[0][r]=i[0][r]-e/2,i[1][r]=i[1][r]+e/2,i},e.prototype._drawSplitline=function(t,e,n){var i=new Ou({z2:20,shape:{points:t},style:e});n.add(i)},e.prototype._getLinePointsOfOneWeek=function(t,e,n){for(var i=t.coordinateSystem,r=i.getDateInfo(e),o=[],a=0;a<7;a++){var s=i.getNextNDay(r.time,a),l=i.dataToRect([s.time],!1);o[2*s.day]=l.tl,o[2*s.day+1]=l["horizontal"===n?"bl":"tr"]}return o},e.prototype._formatterLabel=function(t,e){return X(t)&&t?(n=t,E(e,(function(t,e){n=n.replace("{"+e+"}",i?op(t):t)})),n):U(t)?t(e):e.nameMap;var n,i},e.prototype._yearTextPositionControl=function(t,e,n,i,r){var o=e[0],a=e[1],s=["center","bottom"];"bottom"===i?(a+=r,s=["center","top"]):"left"===i?o-=r:"right"===i?(o+=r,s=["center","top"]):a-=r;var l=0;return"left"!==i&&"right"!==i||(l=Math.PI/2),{rotation:l,x:o,y:a,style:{align:s[0],verticalAlign:s[1]}}},e.prototype._renderYearText=function(t,e,n,i){var r=t.getModel("yearLabel");if(r.get("show")){var o=r.get("margin"),a=r.get("position");a||(a="horizontal"!==n?"top":"left");var s=[this._tlpoints[this._tlpoints.length-1],this._blpoints[0]],l=(s[0][0]+s[1][0])/2,u=(s[0][1]+s[1][1])/2,h="horizontal"===n?0:1,c={top:[l,s[h][1]],bottom:[l,s[1-h][1]],left:[s[1-h][0],u],right:[s[h][0],u]},p=e.start.y;+e.end.y>+e.start.y&&(p=p+"-"+e.end.y);var d=r.get("formatter"),f={start:e.start.y,end:e.end.y,nameMap:p},g=this._formatterLabel(d,f),y=new As({z2:30,style:Yh(r,{text:g})});y.attr(this._yearTextPositionControl(y,c[a],n,a,o)),i.add(y)}},e.prototype._monthTextPositionControl=function(t,e,n,i,r){var o="left",a="top",s=t[0],l=t[1];return"horizontal"===n?(l+=r,e&&(o="center"),"start"===i&&(a="bottom")):(s+=r,e&&(a="middle"),"start"===i&&(o="right")),{x:s,y:l,align:o,verticalAlign:a}},e.prototype._renderMonthText=function(t,e,n,i){var r=t.getModel("monthLabel");if(r.get("show")){var o=r.get("nameMap"),a=r.get("margin"),s=r.get("position"),l=r.get("align"),u=[this._tlpoints,this._blpoints];o&&!X(o)||(o&&(e=Sc(o)||e),o=e.get(["time","monthAbbr"])||[]);var h="start"===s?0:1,c="horizontal"===n?0:1;a="start"===s?-a:a;for(var p="center"===l,d=0;d=i.start.time&&n.timea.end.time&&t.reverse(),t},t.prototype._getRangeInfo=function(t){var e,n=[this.getDateInfo(t[0]),this.getDateInfo(t[1])];n[0].time>n[1].time&&(e=!0,n.reverse());var i=Math.floor(n[1].time/sE)-Math.floor(n[0].time/sE)+1,r=new Date(n[0].time),o=r.getDate(),a=n[1].date.getDate();r.setDate(o+i-1);var s=r.getDate();if(s!==a)for(var l=r.getTime()-n[1].time>0?1:-1;(s=r.getDate())!==a&&(r.getTime()-n[1].time)*l>0;)i-=l,r.setDate(s-l);var u=Math.floor((i+n[0].day+6)/7),h=e?1-u:u-1;return e&&n.reverse(),{range:[n[0].formatedDate,n[1].formatedDate],start:n[0],end:n[1],allDay:i,weeks:u,nthWeek:h,fweek:n[0].day,lweek:n[1].day}},t.prototype._getDateByWeeksAndDay=function(t,e,n){var i=this._getRangeInfo(n);if(t>i.weeks||0===t&&ei.lweek)return null;var r=7*(t-1)-i.fweek+e,o=new Date(i.start.time);return o.setDate(+i.start.d+r),this.getDateInfo(o)},t.create=function(e,n){var i=[];return e.eachComponent("calendar",(function(r){var o=new t(r,e,n);i.push(o),r.coordinateSystem=o})),e.eachSeries((function(t){"calendar"===t.get("coordinateSystem")&&(t.coordinateSystem=i[t.get("calendarIndex")||0])})),i},t.dimensions=["time","value"],t}();function uE(t){var e=t.calendarModel,n=t.seriesModel;return e?e.coordinateSystem:n?n.coordinateSystem:null}function hE(t,e){var n;return E(e,(function(e){null!=t[e]&&"auto"!==t[e]&&(n=!0)})),n}var cE=["transition","enterFrom","leaveTo"],pE=cE.concat(["enterAnimation","updateAnimation","leaveAnimation"]);function dE(t,e,n){if(n&&(!t[n]&&e[n]&&(t[n]={}),t=t[n],e=e[n]),t&&e)for(var i=n?cE:pE,r=0;r=0;l--){var p,d,f;if(f=null!=(d=xo((p=n[l]).id,null))?r.get(d):null){var g=f.parent,y=(c=yE(g),{}),v=xp(f,p,g===i?{width:o,height:a}:{width:c.width,height:c.height},null,{hv:p.hv,boundingMode:p.bounding},y);if(!yE(f).isNew&&v){for(var m=p.transition,x={},_=0;_=0)?x[b]=w:f[b]=w}ih(f,x,t,0)}else f.attr(y)}}},e.prototype._clear=function(){var t=this,e=this._elMap;e.each((function(n){_E(n,yE(n).option,e,t._lastGraphicModel)})),this._elMap=ft()},e.prototype.dispose=function(){this._clear()},e.type="graphic",e}(fg);function mE(t){var e=mt(gE,t)?gE[t]:vh(t);var n=new e({});return yE(n).type=t,n}function xE(t,e,n,i){var r=mE(n);return e.add(r),i.set(t,r),yE(r).id=t,yE(r).isNew=!0,r}function _E(t,e,n,i){t&&t.parent&&("group"===t.type&&t.traverse((function(t){_E(t,e,n,i)})),VO(t,e,i),n.removeKey(yE(t).id))}function bE(t,e,n,i){if(!t.isGroup){var r=t;r.cursor=rt(e.cursor,da.prototype.cursor),r.z=rt(e.z,n||0),r.zlevel=rt(e.zlevel,i||0);var o=e.z2;null!=o&&(r.z2=o||0)}E(G(e),(function(n){var i=e[n];0===n.indexOf("on")&&U(i)&&(t[n]=i)})),t.draggable=e.draggable,null!=e.name&&(t.name=e.name),null!=e.id&&(t.id=e.id)}var wE=["x","y","radius","angle","single"],SE=["cartesian2d","polar","singleAxis"];function ME(t){return t+"Axis"}function IE(t,e){var n,i=ft(),r=[],o=ft();t.eachComponent({mainType:"dataZoom",query:e},(function(t){o.get(t.uid)||s(t)}));do{n=!1,t.eachComponent("dataZoom",a)}while(n);function a(t){!o.get(t.uid)&&function(t){var e=!1;return t.eachTargetAxis((function(t,n){var r=i.get(t);r&&r[n]&&(e=!0)})),e}(t)&&(s(t),n=!0)}function s(t){o.set(t.uid,!0),r.push(t),t.eachTargetAxis((function(t,e){(i.get(t)||i.set(t,[]))[e]=!0}))}return r}function TE(t){var e=t.ecModel,n={infoList:[],infoMap:ft()};return t.eachTargetAxis((function(t,i){var r=e.getComponent(ME(t),i);if(r){var o=r.getCoordSysModel();if(o){var a=o.uid,s=n.infoMap.get(a);s||(s={model:o,axisModels:[]},n.infoList.push(s),n.infoMap.set(a,s)),s.axisModels.push(r)}}})),n}var CE=function(){function t(){this.indexList=[],this.indexMap=[]}return t.prototype.add=function(t){this.indexMap[t]||(this.indexList.push(t),this.indexMap[t]=!0)},t}(),DE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._autoThrottle=!0,n._noTarget=!0,n._rangePropMode=["percent","percent"],n}return n(e,t),e.prototype.init=function(t,e,n){var i=AE(t);this.settledOption=i,this.mergeDefaultAndTheme(t,n),this._doInit(i)},e.prototype.mergeOption=function(t){var e=AE(t);C(this.option,t,!0),C(this.settledOption,e,!0),this._doInit(e)},e.prototype._doInit=function(t){var e=this.option;this._setDefaultThrottle(t),this._updateRangeUse(t);var n=this.settledOption;E([["start","startValue"],["end","endValue"]],(function(t,i){"value"===this._rangePropMode[i]&&(e[t[0]]=n[t[0]]=null)}),this),this._resetTarget()},e.prototype._resetTarget=function(){var t=this.get("orient",!0),e=this._targetAxisInfoMap=ft();this._fillSpecifiedTargetAxis(e)?this._orient=t||this._makeAutoOrientByTargetAxis():(this._orient=t||"horizontal",this._fillAutoTargetAxisByOrient(e,this._orient)),this._noTarget=!0,e.each((function(t){t.indexList.length&&(this._noTarget=!1)}),this)},e.prototype._fillSpecifiedTargetAxis=function(t){var e=!1;return E(wE,(function(n){var i=this.getReferringComponents(ME(n),Do);if(i.specified){e=!0;var r=new CE;E(i.models,(function(t){r.add(t.componentIndex)})),t.set(n,r)}}),this),e},e.prototype._fillAutoTargetAxisByOrient=function(t,e){var n=this.ecModel,i=!0;if(i){var r="vertical"===e?"y":"x";o(n.findComponents({mainType:r+"Axis"}),r)}i&&o(n.findComponents({mainType:"singleAxis",filter:function(t){return t.get("orient",!0)===e}}),"single");function o(e,n){var r=e[0];if(r){var o=new CE;if(o.add(r.componentIndex),t.set(n,o),i=!1,"x"===n||"y"===n){var a=r.getReferringComponents("grid",Co).models[0];a&&E(e,(function(t){r.componentIndex!==t.componentIndex&&a===t.getReferringComponents("grid",Co).models[0]&&o.add(t.componentIndex)}))}}}i&&E(wE,(function(e){if(i){var r=n.findComponents({mainType:ME(e),filter:function(t){return"category"===t.get("type",!0)}});if(r[0]){var o=new CE;o.add(r[0].componentIndex),t.set(e,o),i=!1}}}),this)},e.prototype._makeAutoOrientByTargetAxis=function(){var t;return this.eachTargetAxis((function(e){!t&&(t=e)}),this),"y"===t?"vertical":"horizontal"},e.prototype._setDefaultThrottle=function(t){if(t.hasOwnProperty("throttle")&&(this._autoThrottle=!1),this._autoThrottle){var e=this.ecModel.option;this.option.throttle=e.animation&&e.animationDurationUpdate>0?100:20}},e.prototype._updateRangeUse=function(t){var e=this._rangePropMode,n=this.get("rangeMode");E([["start","startValue"],["end","endValue"]],(function(i,r){var o=null!=t[i[0]],a=null!=t[i[1]];o&&!a?e[r]="percent":!o&&a?e[r]="value":n?e[r]=n[r]:o&&(e[r]="percent")}))},e.prototype.noTarget=function(){return this._noTarget},e.prototype.getFirstTargetAxisModel=function(){var t;return this.eachTargetAxis((function(e,n){null==t&&(t=this.ecModel.getComponent(ME(e),n))}),this),t},e.prototype.eachTargetAxis=function(t,e){this._targetAxisInfoMap.each((function(n,i){E(n.indexList,(function(n){t.call(e,i,n)}))}))},e.prototype.getAxisProxy=function(t,e){var n=this.getAxisModel(t,e);if(n)return n.__dzAxisProxy},e.prototype.getAxisModel=function(t,e){var n=this._targetAxisInfoMap.get(t);if(n&&n.indexMap[e])return this.ecModel.getComponent(ME(t),e)},e.prototype.setRawRange=function(t){var e=this.option,n=this.settledOption;E([["start","startValue"],["end","endValue"]],(function(i){null==t[i[0]]&&null==t[i[1]]||(e[i[0]]=n[i[0]]=t[i[0]],e[i[1]]=n[i[1]]=t[i[1]])}),this),this._updateRangeUse(t)},e.prototype.setCalculatedRange=function(t){var e=this.option;E(["start","startValue","end","endValue"],(function(n){e[n]=t[n]}))},e.prototype.getPercentRange=function(){var t=this.findRepresentativeAxisProxy();if(t)return t.getDataPercentWindow()},e.prototype.getValueRange=function(t,e){if(null!=t||null!=e)return this.getAxisProxy(t,e).getDataValueWindow();var n=this.findRepresentativeAxisProxy();return n?n.getDataValueWindow():void 0},e.prototype.findRepresentativeAxisProxy=function(t){if(t)return t.__dzAxisProxy;for(var e,n=this._targetAxisInfoMap.keys(),i=0;i=0}(e)){var n=ME(this._dimName),i=e.getReferringComponents(n,Co).models[0];i&&this._axisIndex===i.componentIndex&&t.push(e)}}),this),t},t.prototype.getAxisModel=function(){return this.ecModel.getComponent(this._dimName+"Axis",this._axisIndex)},t.prototype.getMinMaxSpan=function(){return T(this._minMaxSpan)},t.prototype.calculateDataWindow=function(t){var e,n=this._dataExtent,i=this.getAxisModel().axis.scale,r=this._dataZoomModel.getRangePropMode(),o=[0,100],a=[],s=[];OE(["start","end"],(function(l,u){var h=t[l],c=t[l+"Value"];"percent"===r[u]?(null==h&&(h=o[u]),c=i.parse(Nr(h,o,n))):(e=!0,h=Nr(c=null==c?n[u]:i.parse(c),n,o)),s[u]=c,a[u]=h})),RE(s),RE(a);var l=this._minMaxSpan;function u(t,e,n,r,o){var a=o?"Span":"ValueSpan";sk(0,t,n,"all",l["min"+a],l["max"+a]);for(var s=0;s<2;s++)e[s]=Nr(t[s],n,r,!0),o&&(e[s]=i.parse(e[s]))}return e?u(s,a,n,o,!1):u(a,s,o,n,!0),{valueWindow:s,percentWindow:a}},t.prototype.reset=function(t){if(t===this._dataZoomModel){var e=this.getTargetSeriesModels();this._dataExtent=function(t,e,n){var i=[1/0,-1/0];OE(n,(function(t){!function(t,e,n){e&&E(u_(e,n),(function(n){var i=e.getApproximateExtent(n);i[0]t[1]&&(t[1]=i[1])}))}(i,t.getData(),e)}));var r=t.getAxisModel(),o=Qx(r.axis.scale,r,i).calculate();return[o.min,o.max]}(this,this._dimName,e),this._updateMinMaxSpan();var n=this.calculateDataWindow(t.settledOption);this._valueWindow=n.valueWindow,this._percentWindow=n.percentWindow,this._setAxisModel()}},t.prototype.filterData=function(t,e){if(t===this._dataZoomModel){var n=this._dimName,i=this.getTargetSeriesModels(),r=t.get("filterMode"),o=this._valueWindow;"none"!==r&&OE(i,(function(t){var e=t.getData(),i=e.mapDimensionsAll(n);if(i.length){if("weakFilter"===r){var a=e.getStore(),s=z(i,(function(t){return e.getDimensionIndex(t)}),e);e.filterSelf((function(t){for(var e,n,r,l=0;lo[1];if(h&&!c&&!p)return!0;h&&(r=!0),c&&(e=!0),p&&(n=!0)}return r&&e&&n}))}else OE(i,(function(n){if("empty"===r)t.setData(e=e.map(n,(function(t){return function(t){return t>=o[0]&&t<=o[1]}(t)?t:NaN})));else{var i={};i[n]=o,e.selectRange(i)}}));OE(i,(function(t){e.setApproximateExtent(o,t)}))}}))}},t.prototype._updateMinMaxSpan=function(){var t=this._minMaxSpan={},e=this._dataZoomModel,n=this._dataExtent;OE(["min","max"],(function(i){var r=e.get(i+"Span"),o=e.get(i+"ValueSpan");null!=o&&(o=this.getAxisModel().axis.scale.parse(o)),null!=o?r=Nr(n[0]+o,n,[0,100],!0):null!=r&&(o=Nr(r,[0,100],n,!0)-n[0]),t[i+"Span"]=r,t[i+"ValueSpan"]=o}),this)},t.prototype._setAxisModel=function(){var t=this.getAxisModel(),e=this._percentWindow,n=this._valueWindow;if(e){var i=Gr(n,[0,500]);i=Math.min(i,20);var r=t.axis.scale.rawExtentInfo;0!==e[0]&&r.setDeterminedMinMax("min",+n[0].toFixed(i)),100!==e[1]&&r.setDeterminedMinMax("max",+n[1].toFixed(i)),r.freeze()}},t}();var EE={getTargetSeries:function(t){function e(e){t.eachComponent("dataZoom",(function(n){n.eachTargetAxis((function(i,r){var o=t.getComponent(ME(i),r);e(i,r,o,n)}))}))}e((function(t,e,n,i){n.__dzAxisProxy=null}));var n=[];e((function(e,i,r,o){r.__dzAxisProxy||(r.__dzAxisProxy=new NE(e,i,o,t),n.push(r.__dzAxisProxy))}));var i=ft();return E(n,(function(t){E(t.getTargetSeriesModels(),(function(t){i.set(t.uid,t)}))})),i},overallReset:function(t,e){t.eachComponent("dataZoom",(function(t){t.eachTargetAxis((function(e,n){t.getAxisProxy(e,n).reset(t)})),t.eachTargetAxis((function(n,i){t.getAxisProxy(n,i).filterData(t,e)}))})),t.eachComponent("dataZoom",(function(t){var e=t.findRepresentativeAxisProxy();if(e){var n=e.getDataPercentWindow(),i=e.getDataValueWindow();t.setCalculatedRange({start:n[0],end:n[1],startValue:i[0],endValue:i[1]})}}))}};var zE=!1;function VE(t){zE||(zE=!0,t.registerProcessor(t.PRIORITY.PROCESSOR.FILTER,EE),function(t){t.registerAction("dataZoom",(function(t,e){E(IE(e,t),(function(e){e.setRawRange({start:t.start,end:t.end,startValue:t.startValue,endValue:t.endValue})}))}))}(t),t.registerSubTypeDefaulter("dataZoom",(function(){return"slider"})))}function BE(t){t.registerComponentModel(kE),t.registerComponentView(PE),VE(t)}var FE=function(){},GE={};function WE(t,e){GE[t]=e}function HE(t){return GE[t]}var YE=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(){t.prototype.optionUpdated.apply(this,arguments);var e=this.ecModel;E(this.option.feature,(function(t,n){var i=HE(n);i&&(i.getDefaultOption&&(i.defaultOption=i.getDefaultOption(e)),C(t,i.defaultOption))}))},e.type="toolbox",e.layoutMode={type:"box",ignoreSize:!0},e.defaultOption={show:!0,z:6,orient:"horizontal",left:"right",top:"top",backgroundColor:"transparent",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemSize:15,itemGap:8,showTitle:!0,iconStyle:{borderColor:"#666",color:"none"},emphasis:{iconStyle:{borderColor:"#3E98C5"}},tooltip:{show:!1,position:"bottom"}},e}(Ip);function UE(t,e){var n=np(e.get("padding")),i=e.getItemStyle(["color","opacity"]);return i.fill=e.get("backgroundColor"),t=new Ts({shape:{x:t.x-n[3],y:t.y-n[0],width:t.width+n[1]+n[3],height:t.height+n[0]+n[2],r:e.get("borderRadius")},style:i,silent:!0,z2:-1})}var XE=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n,i){var r=this.group;if(r.removeAll(),t.get("show")){var o=+t.get("itemSize"),a=t.get("feature")||{},s=this._features||(this._features={}),l=[];E(a,(function(t,e){l.push(e)})),new Sm(this._featureNames||[],l).add(u).update(u).remove(H(u,null)).execute(),this._featureNames=l,function(t,e,n){var i=e.getBoxLayoutParams(),r=e.get("padding"),o={width:n.getWidth(),height:n.getHeight()},a=mp(i,o,r);vp(e.get("orient"),t,e.get("itemGap"),a.width,a.height),xp(t,i,o,r)}(r,t,n),r.add(UE(r.getBoundingRect(),t)),r.eachChild((function(t){var e=t.__title,i=t.ensureState("emphasis"),a=i.textConfig||(i.textConfig={}),s=t.getTextContent(),l=s&&s.states.emphasis;if(l&&!U(l)&&e){var u=l.style||(l.style={}),h=cr(e,As.makeFont(u)),c=t.x+r.x,p=!1;t.y+r.y+o+h.height>n.getHeight()&&(a.position="top",p=!0);var d=p?-5-h.height:o+8;c+h.width/2>n.getWidth()?(a.position=["100%",d],u.align="right"):c-h.width/2<0&&(a.position=[0,d],u.align="left")}}))}function u(u,h){var c,p=l[u],d=l[h],f=a[p],g=new pc(f,t,t.ecModel);if(i&&null!=i.newTitle&&i.featureName===p&&(f.title=i.newTitle),p&&!d){if(function(t){return 0===t.indexOf("my")}(p))c={onclick:g.option.onclick,featureName:p};else{var y=HE(p);if(!y)return;c=new y}s[p]=c}else if(!(c=s[d]))return;c.uid=fc("toolbox-feature"),c.model=g,c.ecModel=e,c.api=n;var v=c instanceof FE;p||!d?!g.get("show")||v&&c.unusable?v&&c.remove&&c.remove(e,n):(!function(i,a,s){var l,u,h=i.getModel("iconStyle"),c=i.getModel(["emphasis","iconStyle"]),p=a instanceof FE&&a.getIcons?a.getIcons():i.get("icon"),d=i.get("title")||{};X(p)?(l={})[s]=p:l=p;X(d)?(u={})[s]=d:u=d;var f=i.iconPaths={};E(l,(function(s,l){var p=Lh(s,{},{x:-o/2,y:-o/2,width:o,height:o});p.setStyle(h.getItemStyle()),p.ensureState("emphasis").style=c.getItemStyle();var d=new As({style:{text:u[l],align:c.get("textAlign"),borderRadius:c.get("textBorderRadius"),padding:c.get("textPadding"),fill:null},ignore:!0});p.setTextContent(d),Nh({el:p,componentModel:t,itemName:l,formatterParamsExtra:{title:u[l]}}),p.__title=u[l],p.on("mouseover",(function(){var e=c.getItemStyle(),n="vertical"===t.get("orient")?null==t.get("right")?"right":"left":null==t.get("bottom")?"bottom":"top";d.setStyle({fill:c.get("textFill")||e.fill||e.stroke||"#000",backgroundColor:c.get("textBackgroundColor")}),p.setTextConfig({position:c.get("textPosition")||n}),d.ignore=!t.get("showTitle"),xl(this)})).on("mouseout",(function(){"emphasis"!==i.get(["iconStatus",l])&&_l(this),d.hide()})),("emphasis"===i.get(["iconStatus",l])?xl:_l)(p),r.add(p),p.on("click",W(a.onclick,a,e,n,l)),f[l]=p}))}(g,c,p),g.setIconStatus=function(t,e){var n=this.option,i=this.iconPaths;n.iconStatus=n.iconStatus||{},n.iconStatus[t]=e,i[t]&&("emphasis"===e?xl:_l)(i[t])},c instanceof FE&&c.render&&c.render(g,e,n,i)):v&&c.dispose&&c.dispose(e,n)}},e.prototype.updateView=function(t,e,n,i){E(this._features,(function(t){t instanceof FE&&t.updateView&&t.updateView(t.model,e,n,i)}))},e.prototype.remove=function(t,e){E(this._features,(function(n){n instanceof FE&&n.remove&&n.remove(t,e)})),this.group.removeAll()},e.prototype.dispose=function(t,e){E(this._features,(function(n){n instanceof FE&&n.dispose&&n.dispose(t,e)}))},e.type="toolbox",e}(fg);var ZE=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.onclick=function(t,e){var n=this.model,i=n.get("name")||t.get("title.0.text")||"echarts",o="svg"===e.getZr().painter.getType(),a=o?"svg":n.get("type",!0)||"png",s=e.getConnectedDataURL({type:a,backgroundColor:n.get("backgroundColor",!0)||t.get("backgroundColor")||"#fff",connectedBackgroundColor:n.get("connectedBackgroundColor"),excludeComponents:n.get("excludeComponents"),pixelRatio:n.get("pixelRatio")}),l=r.browser;if(U(MouseEvent)&&(l.newEdge||!l.ie&&!l.edge)){var u=document.createElement("a");u.download=i+"."+a,u.target="_blank",u.href=s;var h=new MouseEvent("click",{view:document.defaultView,bubbles:!0,cancelable:!1});u.dispatchEvent(h)}else if(window.navigator.msSaveOrOpenBlob||o){var c=s.split(","),p=c[0].indexOf("base64")>-1,d=o?decodeURIComponent(c[1]):c[1];p&&(d=window.atob(d));var f=i+"."+a;if(window.navigator.msSaveOrOpenBlob){for(var g=d.length,y=new Uint8Array(g);g--;)y[g]=d.charCodeAt(g);var v=new Blob([y]);window.navigator.msSaveOrOpenBlob(v,f)}else{var m=document.createElement("iframe");document.body.appendChild(m);var x=m.contentWindow,_=x.document;_.open("image/svg+xml","replace"),_.write(d),_.close(),x.focus(),_.execCommand("SaveAs",!0,f),document.body.removeChild(m)}}else{var b=n.get("lang"),w='',S=window.open();S.document.write(w),S.document.title=i}},e.getDefaultOption=function(t){return{show:!0,icon:"M4.7,22.9L29.3,45.5L54.7,23.4M4.6,43.6L4.6,58L53.8,58L53.8,43.6M29.2,45.1L29.2,0",title:t.getLocaleModel().get(["toolbox","saveAsImage","title"]),type:"png",connectedBackgroundColor:"#fff",name:"",excludeComponents:["toolbox"],lang:t.getLocaleModel().get(["toolbox","saveAsImage","lang"])}},e}(FE),jE="__ec_magicType_stack__",qE=[["line","bar"],["stack"]],KE=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.getIcons=function(){var t=this.model,e=t.get("icon"),n={};return E(t.get("type"),(function(t){e[t]&&(n[t]=e[t])})),n},e.getDefaultOption=function(t){return{show:!0,type:[],icon:{line:"M4.1,28.9h7.1l9.3-22l7.4,38l9.7-19.7l3,12.8h14.9M4.1,58h51.4",bar:"M6.7,22.9h10V48h-10V22.9zM24.9,13h10v35h-10V13zM43.2,2h10v46h-10V2zM3.1,58h53.7",stack:"M8.2,38.4l-8.4,4.1l30.6,15.3L60,42.5l-8.1-4.1l-21.5,11L8.2,38.4z M51.9,30l-8.1,4.2l-13.4,6.9l-13.9-6.9L8.2,30l-8.4,4.2l8.4,4.2l22.2,11l21.5-11l8.1-4.2L51.9,30z M51.9,21.7l-8.1,4.2L35.7,30l-5.3,2.8L24.9,30l-8.4-4.1l-8.3-4.2l-8.4,4.2L8.2,30l8.3,4.2l13.9,6.9l13.4-6.9l8.1-4.2l8.1-4.1L51.9,21.7zM30.4,2.2L-0.2,17.5l8.4,4.1l8.3,4.2l8.4,4.2l5.5,2.7l5.3-2.7l8.1-4.2l8.1-4.2l8.1-4.1L30.4,2.2z"},title:t.getLocaleModel().get(["toolbox","magicType","title"]),option:{},seriesIndex:{}}},e.prototype.onclick=function(t,e,n){var i=this.model,r=i.get(["seriesIndex",n]);if($E[n]){var o,a={series:[]};E(qE,(function(t){P(t,n)>=0&&E(t,(function(t){i.setIconStatus(t,"normal")}))})),i.setIconStatus(n,"emphasis"),t.eachComponent({mainType:"series",query:null==r?null:{seriesIndex:r}},(function(t){var e=t.subType,r=t.id,o=$E[n](e,r,t,i);o&&(k(o,t.option),a.series.push(o));var s=t.coordinateSystem;if(s&&"cartesian2d"===s.type&&("line"===n||"bar"===n)){var l=s.getAxesByScale("ordinal")[0];if(l){var u=l.dim+"Axis",h=t.getReferringComponents(u,Co).models[0].componentIndex;a[u]=a[u]||[];for(var c=0;c<=h;c++)a[u][h]=a[u][h]||{};a[u][h].boundaryGap="bar"===n}}}));var s=n;"stack"===n&&(o=C({stack:i.option.title.tiled,tiled:i.option.title.stack},i.option.title),"emphasis"!==i.get(["iconStatus",n])&&(s="tiled")),e.dispatchAction({type:"changeMagicType",currentType:s,newOption:a,newTitle:o,featureName:"magicType"})}},e}(FE),$E={line:function(t,e,n,i){if("bar"===t)return C({id:e,type:"line",data:n.get("data"),stack:n.get("stack"),markPoint:n.get("markPoint"),markLine:n.get("markLine")},i.get(["option","line"])||{},!0)},bar:function(t,e,n,i){if("line"===t)return C({id:e,type:"bar",data:n.get("data"),stack:n.get("stack"),markPoint:n.get("markPoint"),markLine:n.get("markLine")},i.get(["option","bar"])||{},!0)},stack:function(t,e,n,i){var r=n.get("stack")===jE;if("line"===t||"bar"===t)return i.setIconStatus("stack",r?"normal":"emphasis"),C({id:e,stack:r?"":jE},i.get(["option","stack"])||{},!0)}};um({type:"changeMagicType",event:"magicTypeChanged",update:"prepareAndUpdate"},(function(t,e){e.mergeOption(t.newOption)}));var JE=new Array(60).join("-"),QE="\t";function tz(t){return t.replace(/^\s\s*/,"").replace(/\s\s*$/,"")}var ez=new RegExp("[\t]+","g");function nz(t,e){var n=t.split(new RegExp("\n*"+JE+"\n*","g")),i={series:[]};return E(n,(function(t,n){if(function(t){if(t.slice(0,t.indexOf("\n")).indexOf(QE)>=0)return!0}(t)){var r=function(t){for(var e=t.split(/\n+/g),n=[],i=z(tz(e.shift()).split(ez),(function(t){return{name:t,data:[]}})),r=0;r=0)&&t(r,i._targetInfoList)}))}return t.prototype.setOutputRanges=function(t,e){return this.matchOutputRanges(t,e,(function(t,e,n){if((t.coordRanges||(t.coordRanges=[])).push(e),!t.coordRange){t.coordRange=e;var i=yz[t.brushType](0,n,e);t.__rangeOffset={offset:mz[t.brushType](i.values,t.range,[1,1]),xyMinMax:i.xyMinMax}}})),t},t.prototype.matchOutputRanges=function(t,e,n){E(t,(function(t){var i=this.findTargetInfo(t,e);i&&!0!==i&&E(i.coordSyses,(function(i){var r=yz[t.brushType](1,i,t.range,!0);n(t,r.values,i,e)}))}),this)},t.prototype.setInputRanges=function(t,e){E(t,(function(t){var n,i,r,o,a,s=this.findTargetInfo(t,e);if(t.range=t.range||[],s&&!0!==s){t.panelId=s.panelId;var l=yz[t.brushType](0,s.coordSys,t.coordRange),u=t.__rangeOffset;t.range=u?mz[t.brushType](l.values,u.offset,(n=l.xyMinMax,i=u.xyMinMax,r=_z(n),o=_z(i),a=[r[0]/o[0],r[1]/o[1]],isNaN(a[0])&&(a[0]=1),isNaN(a[1])&&(a[1]=1),a)):l.values}}),this)},t.prototype.makePanelOpts=function(t,e){return z(this._targetInfoList,(function(n){var i=n.getPanelRect();return{panelId:n.panelId,defaultBrushType:e?e(n):null,clipPath:uL(i),isTargetByCursor:cL(i,t,n.coordSysModel),getLinearBrushOtherExtent:hL(i)}}))},t.prototype.controlSeries=function(t,e,n){var i=this.findTargetInfo(t,n);return!0===i||i&&P(i.coordSyses,e.coordinateSystem)>=0},t.prototype.findTargetInfo=function(t,e){for(var n=this._targetInfoList,i=pz(e,t),r=0;rt[1]&&t.reverse(),t}function pz(t,e){return Io(t,e,{includeMainTypes:uz})}var dz={grid:function(t,e){var n=t.xAxisModels,i=t.yAxisModels,r=t.gridModels,o=ft(),a={},s={};(n||i||r)&&(E(n,(function(t){var e=t.axis.grid.model;o.set(e.id,e),a[e.id]=!0})),E(i,(function(t){var e=t.axis.grid.model;o.set(e.id,e),s[e.id]=!0})),E(r,(function(t){o.set(t.id,t),a[t.id]=!0,s[t.id]=!0})),o.each((function(t){var r=t.coordinateSystem,o=[];E(r.getCartesians(),(function(t,e){(P(n,t.getAxis("x").model)>=0||P(i,t.getAxis("y").model)>=0)&&o.push(t)})),e.push({panelId:"grid--"+t.id,gridModel:t,coordSysModel:t,coordSys:o[0],coordSyses:o,getPanelRect:gz.grid,xAxisDeclared:a[t.id],yAxisDeclared:s[t.id]})})))},geo:function(t,e){E(t.geoModels,(function(t){var n=t.coordinateSystem;e.push({panelId:"geo--"+t.id,geoModel:t,coordSysModel:t,coordSys:n,coordSyses:[n],getPanelRect:gz.geo})}))}},fz=[function(t,e){var n=t.xAxisModel,i=t.yAxisModel,r=t.gridModel;return!r&&n&&(r=n.axis.grid.model),!r&&i&&(r=i.axis.grid.model),r&&r===e.gridModel},function(t,e){var n=t.geoModel;return n&&n===e.geoModel}],gz={grid:function(){return this.coordSys.master.getRect().clone()},geo:function(){var t=this.coordSys,e=t.getBoundingRect().clone();return e.applyTransform(Mh(t)),e}},yz={lineX:H(vz,0),lineY:H(vz,1),rect:function(t,e,n,i){var r=t?e.pointToData([n[0][0],n[1][0]],i):e.dataToPoint([n[0][0],n[1][0]],i),o=t?e.pointToData([n[0][1],n[1][1]],i):e.dataToPoint([n[0][1],n[1][1]],i),a=[cz([r[0],o[0]]),cz([r[1],o[1]])];return{values:a,xyMinMax:a}},polygon:function(t,e,n,i){var r=[[1/0,-1/0],[1/0,-1/0]];return{values:z(n,(function(n){var o=t?e.pointToData(n,i):e.dataToPoint(n,i);return r[0][0]=Math.min(r[0][0],o[0]),r[1][0]=Math.min(r[1][0],o[1]),r[0][1]=Math.max(r[0][1],o[0]),r[1][1]=Math.max(r[1][1],o[1]),o})),xyMinMax:r}}};function vz(t,e,n,i){var r=n.getAxis(["x","y"][t]),o=cz(z([0,1],(function(t){return e?r.coordToData(r.toLocalCoord(i[t]),!0):r.toGlobalCoord(r.dataToCoord(i[t]))}))),a=[];return a[t]=o,a[1-t]=[NaN,NaN],{values:o,xyMinMax:a}}var mz={lineX:H(xz,0),lineY:H(xz,1),rect:function(t,e,n){return[[t[0][0]-n[0]*e[0][0],t[0][1]-n[0]*e[0][1]],[t[1][0]-n[1]*e[1][0],t[1][1]-n[1]*e[1][1]]]},polygon:function(t,e,n){return z(t,(function(t,i){return[t[0]-n[0]*e[i][0],t[1]-n[1]*e[i][1]]}))}};function xz(t,e,n,i){return[e[0]-i[t]*n[0],e[1]-i[t]*n[1]]}function _z(t){return t?[t[0][1]-t[0][0],t[1][1]-t[1][0]]:[NaN,NaN]}var bz,wz,Sz=E,Mz=uo+"toolbox-dataZoom_",Iz=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n,i){this._brushController||(this._brushController=new Pk(n.getZr()),this._brushController.on("brush",W(this._onBrush,this)).mount()),function(t,e,n,i,r){var o=n._isZoomActive;i&&"takeGlobalCursor"===i.type&&(o="dataZoomSelect"===i.key&&i.dataZoomSelectActive);n._isZoomActive=o,t.setIconStatus("zoom",o?"emphasis":"normal");var a=new hz(Cz(t),e,{include:["grid"]}).makePanelOpts(r,(function(t){return t.xAxisDeclared&&!t.yAxisDeclared?"lineX":!t.xAxisDeclared&&t.yAxisDeclared?"lineY":"rect"}));n._brushController.setPanels(a).enableBrush(!(!o||!a.length)&&{brushType:"auto",brushStyle:t.getModel("brushStyle").getItemStyle()})}(t,e,this,i,n),function(t,e){t.setIconStatus("back",function(t){return sz(t).length}(e)>1?"emphasis":"normal")}(t,e)},e.prototype.onclick=function(t,e,n){Tz[n].call(this)},e.prototype.remove=function(t,e){this._brushController&&this._brushController.unmount()},e.prototype.dispose=function(t,e){this._brushController&&this._brushController.dispose()},e.prototype._onBrush=function(t){var e=t.areas;if(t.isEnd&&e.length){var n={},i=this.ecModel;this._brushController.updateCovers([]),new hz(Cz(this.model),i,{include:["grid"]}).matchOutputRanges(e,i,(function(t,e,n){if("cartesian2d"===n.type){var i=t.brushType;"rect"===i?(r("x",n,e[0]),r("y",n,e[1])):r({lineX:"x",lineY:"y"}[i],n,e)}})),function(t,e){var n=sz(t);oz(e,(function(e,i){for(var r=n.length-1;r>=0&&!n[r][i];r--);if(r<0){var o=t.queryComponents({mainType:"dataZoom",subType:"select",id:i})[0];if(o){var a=o.getPercentRange();n[0][i]={dataZoomId:i,start:a[0],end:a[1]}}}})),n.push(e)}(i,n),this._dispatchZoomAction(n)}function r(t,e,r){var o=e.getAxis(t),a=o.model,s=function(t,e,n){var i;return n.eachComponent({mainType:"dataZoom",subType:"select"},(function(n){n.getAxisModel(t,e.componentIndex)&&(i=n)})),i}(t,a,i),l=s.findRepresentativeAxisProxy(a).getMinMaxSpan();null==l.minValueSpan&&null==l.maxValueSpan||(r=sk(0,r.slice(),o.scale.getExtent(),0,l.minValueSpan,l.maxValueSpan)),s&&(n[s.id]={dataZoomId:s.id,startValue:r[0],endValue:r[1]})}},e.prototype._dispatchZoomAction=function(t){var e=[];Sz(t,(function(t,n){e.push(T(t))})),e.length&&this.api.dispatchAction({type:"dataZoom",from:this.uid,batch:e})},e.getDefaultOption=function(t){return{show:!0,filterMode:"filter",icon:{zoom:"M0,13.5h26.9 M13.5,26.9V0 M32.1,13.5H58V58H13.5 V32.1",back:"M22,1.4L9.9,13.5l12.3,12.3 M10.3,13.5H54.9v44.6 H10.3v-26"},title:t.getLocaleModel().get(["toolbox","dataZoom","title"]),brushStyle:{borderWidth:0,color:"rgba(210,219,238,0.2)"}}},e}(FE),Tz={zoom:function(){var t=!this._isZoomActive;this.api.dispatchAction({type:"takeGlobalCursor",key:"dataZoomSelect",dataZoomSelectActive:t})},back:function(){this._dispatchZoomAction(function(t){var e=sz(t),n=e[e.length-1];e.length>1&&e.pop();var i={};return oz(n,(function(t,n){for(var r=e.length-1;r>=0;r--)if(t=e[r][n]){i[n]=t;break}})),i}(this.ecModel))}};function Cz(t){var e={xAxisIndex:t.get("xAxisIndex",!0),yAxisIndex:t.get("yAxisIndex",!0),xAxisId:t.get("xAxisId",!0),yAxisId:t.get("yAxisId",!0)};return null==e.xAxisIndex&&null==e.xAxisId&&(e.xAxisIndex="all"),null==e.yAxisIndex&&null==e.yAxisId&&(e.yAxisIndex="all"),e}bz="dataZoom",wz=function(t){var e=t.getComponent("toolbox",0),n=["feature","dataZoom"];if(e&&null!=e.get(n)){var i=e.getModel(n),r=[],o=Io(t,Cz(i));return Sz(o.xAxisModels,(function(t){return a(t,"xAxis","xAxisIndex")})),Sz(o.yAxisModels,(function(t){return a(t,"yAxis","yAxisIndex")})),r}function a(t,e,n){var o=t.componentIndex,a={type:"select",$fromToolbox:!0,filterMode:i.get("filterMode",!0)||"filter",id:Mz+e+o};a[n]=o,r.push(a)}},lt(null==Zp.get(bz)&&wz),Zp.set(bz,wz);var Dz=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="tooltip",e.dependencies=["axisPointer"],e.defaultOption={z:60,show:!0,showContent:!0,trigger:"item",triggerOn:"mousemove|click",alwaysShowContent:!1,displayMode:"single",renderMode:"auto",confine:null,showDelay:0,hideDelay:100,transitionDuration:.4,enterable:!1,backgroundColor:"#fff",shadowBlur:10,shadowColor:"rgba(0, 0, 0, .2)",shadowOffsetX:1,shadowOffsetY:2,borderRadius:4,borderWidth:1,padding:null,extraCssText:"",axisPointer:{type:"line",axis:"auto",animation:"auto",animationDurationUpdate:200,animationEasingUpdate:"exponentialOut",crossStyle:{color:"#999",width:1,type:"dashed",textStyle:{}}},textStyle:{color:"#666",fontSize:14}},e}(Ip);function Az(t){var e=t.get("confine");return null!=e?!!e:"richText"===t.get("renderMode")}function kz(t){if(r.domSupported)for(var e=document.documentElement.style,n=0,i=t.length;n-1?(u+="top:50%",h+="translateY(-50%) rotate("+(a="left"===s?-225:-45)+"deg)"):(u+="left:50%",h+="translateX(-50%) rotate("+(a="top"===s?225:45)+"deg)");var c=a*Math.PI/180,p=l+r,d=p*Math.abs(Math.cos(c))+p*Math.abs(Math.sin(c)),f=e+" solid "+r+"px;";return'
    '}(n,i,r)),X(t))o.innerHTML=t+a;else if(t){o.innerHTML="",Y(t)||(t=[t]);for(var s=0;s=0?this._tryShow(n,i):"leave"===e&&this._hide(i))}),this))},e.prototype._keepShow=function(){var t=this._tooltipModel,e=this._ecModel,n=this._api;if(null!=this._lastX&&null!=this._lastY&&"none"!==t.get("triggerOn")){var i=this;clearTimeout(this._refreshUpdateTimeout),this._refreshUpdateTimeout=setTimeout((function(){!n.isDisposed()&&i.manuallyShowTip(t,e,n,{x:i._lastX,y:i._lastY,dataByCoordSys:i._lastDataByCoordSys})}))}},e.prototype.manuallyShowTip=function(t,e,n,i){if(i.from!==this.uid&&!r.node&&n.getDom()){var o=Zz(i,n);this._ticket="";var a=i.dataByCoordSys,s=function(t,e,n){var i=To(t).queryOptionMap,r=i.keys()[0];if(!r||"series"===r)return;var o,a=Ao(e,r,i.get(r),{useDefault:!1,enableAll:!1,enableNone:!1}).models[0];if(!a)return;if(n.getViewOfComponentModel(a).group.traverse((function(e){var n=Ws(e).tooltipConfig;if(n&&n.name===t.name)return o=e,!0})),o)return{componentMainType:r,componentIndex:a.componentIndex,el:o}}(i,e,n);if(s){var l=s.el.getBoundingRect().clone();l.applyTransform(s.el.transform),this._tryShow({offsetX:l.x+l.width/2,offsetY:l.y+l.height/2,target:s.el,position:i.position,positionDefault:"bottom"},o)}else if(i.tooltip&&null!=i.x&&null!=i.y){var u=Yz;u.x=i.x,u.y=i.y,u.update(),Ws(u).tooltipConfig={name:null,option:i.tooltip},this._tryShow({offsetX:i.x,offsetY:i.y,target:u},o)}else if(a)this._tryShow({offsetX:i.x,offsetY:i.y,position:i.position,dataByCoordSys:a,tooltipOption:i.tooltipOption},o);else if(null!=i.seriesIndex){if(this._manuallyAxisShowTip(t,e,n,i))return;var h=tN(i,e),c=h.point[0],p=h.point[1];null!=c&&null!=p&&this._tryShow({offsetX:c,offsetY:p,target:h.el,position:i.position,positionDefault:"bottom"},o)}else null!=i.x&&null!=i.y&&(n.dispatchAction({type:"updateAxisPointer",x:i.x,y:i.y}),this._tryShow({offsetX:i.x,offsetY:i.y,position:i.position,target:n.getZr().findHover(i.x,i.y).target},o))}},e.prototype.manuallyHideTip=function(t,e,n,i){var r=this._tooltipContent;!this._alwaysShowContent&&this._tooltipModel&&r.hideLater(this._tooltipModel.get("hideDelay")),this._lastX=this._lastY=this._lastDataByCoordSys=null,i.from!==this.uid&&this._hide(Zz(i,n))},e.prototype._manuallyAxisShowTip=function(t,e,n,i){var r=i.seriesIndex,o=i.dataIndex,a=e.getComponent("axisPointer").coordSysAxesInfo;if(null!=r&&null!=o&&null!=a){var s=e.getSeriesByIndex(r);if(s)if("axis"===Xz([s.getData().getItemModel(o),s,(s.coordinateSystem||{}).model],this._tooltipModel).get("trigger"))return n.dispatchAction({type:"updateAxisPointer",seriesIndex:r,dataIndex:o,position:i.position}),!0}},e.prototype._tryShow=function(t,e){var n=t.target;if(this._tooltipModel){this._lastX=t.offsetX,this._lastY=t.offsetY;var i=t.dataByCoordSys;if(i&&i.length)this._showAxisTooltip(i,t);else if(n){var r,o;this._lastDataByCoordSys=null,my(n,(function(t){return null!=Ws(t).dataIndex?(r=t,!0):null!=Ws(t).tooltipConfig?(o=t,!0):void 0}),!0),r?this._showSeriesItemTooltip(t,r,e):o?this._showComponentItemTooltip(t,o,e):this._hide(e)}else this._lastDataByCoordSys=null,this._hide(e)}},e.prototype._showOrMove=function(t,e){var n=t.get("showDelay");e=W(e,this),clearTimeout(this._showTimout),n>0?this._showTimout=setTimeout(e,n):e()},e.prototype._showAxisTooltip=function(t,e){var n=this._ecModel,i=this._tooltipModel,r=[e.offsetX,e.offsetY],o=Xz([e.tooltipOption],i),a=this._renderMode,s=[],l=Uf("section",{blocks:[],noHeader:!0}),u=[],h=new ng;E(t,(function(t){E(t.dataByAxis,(function(t){var e=n.getComponent(t.axisDim+"Axis",t.axisIndex),r=t.value;if(e&&null!=r){var o=ER(r,e.axis,n,t.seriesDataIndices,t.valueLabelOpt),c=Uf("section",{header:o,noHeader:!ut(o),sortBlocks:!0,blocks:[]});l.blocks.push(c),E(t.seriesDataIndices,(function(l){var p=n.getSeriesByIndex(l.seriesIndex),d=l.dataIndexInside,f=p.getDataParams(d);if(!(f.dataIndex<0)){f.axisDim=t.axisDim,f.axisIndex=t.axisIndex,f.axisType=t.axisType,f.axisId=t.axisId,f.axisValue=o_(e.axis,{value:r}),f.axisValueLabel=o,f.marker=h.makeTooltipMarker("item",cp(f.color),a);var g=lf(p.formatTooltip(d,!0,null)),y=g.frag;if(y){var v=Xz([p],i).get("valueFormatter");c.blocks.push(v?A({valueFormatter:v},y):y)}g.text&&u.push(g.text),s.push(f)}}))}}))})),l.blocks.reverse(),u.reverse();var c=e.position,p=o.get("order"),d=$f(l,h,a,p,n.get("useUTC"),o.get("textStyle"));d&&u.unshift(d);var f="richText"===a?"\n\n":"
    ",g=u.join(f);this._showOrMove(o,(function(){this._updateContentNotChangedOnAxis(t,s)?this._updatePosition(o,c,r[0],r[1],this._tooltipContent,s):this._showTooltipContent(o,g,s,Math.random()+"",r[0],r[1],c,null,h)}))},e.prototype._showSeriesItemTooltip=function(t,e,n){var i=this._ecModel,r=Ws(e),o=r.seriesIndex,a=i.getSeriesByIndex(o),s=r.dataModel||a,l=r.dataIndex,u=r.dataType,h=s.getData(u),c=this._renderMode,p=t.positionDefault,d=Xz([h.getItemModel(l),s,a&&(a.coordinateSystem||{}).model],this._tooltipModel,p?{position:p}:null),f=d.get("trigger");if(null==f||"item"===f){var g=s.getDataParams(l,u),y=new ng;g.marker=y.makeTooltipMarker("item",cp(g.color),c);var v=lf(s.formatTooltip(l,!1,u)),m=d.get("order"),x=d.get("valueFormatter"),_=v.frag,b=_?$f(x?A({valueFormatter:x},_):_,y,c,m,i.get("useUTC"),d.get("textStyle")):v.text,w="item_"+s.name+"_"+l;this._showOrMove(d,(function(){this._showTooltipContent(d,b,g,w,t.offsetX,t.offsetY,t.position,t.target,y)})),n({type:"showTip",dataIndexInside:l,dataIndex:h.getRawIndex(l),seriesIndex:o,from:this.uid})}},e.prototype._showComponentItemTooltip=function(t,e,n){var i=Ws(e),r=i.tooltipConfig.option||{};if(X(r)){r={content:r,formatter:r}}var o=[r],a=this._ecModel.getComponent(i.componentMainType,i.componentIndex);a&&o.push(a),o.push({formatter:r.content});var s=t.positionDefault,l=Xz(o,this._tooltipModel,s?{position:s}:null),u=l.get("content"),h=Math.random()+"",c=new ng;this._showOrMove(l,(function(){var n=T(l.get("formatterParams")||{});this._showTooltipContent(l,u,n,h,t.offsetX,t.offsetY,t.position,e,c)})),n({type:"showTip",from:this.uid})},e.prototype._showTooltipContent=function(t,e,n,i,r,o,a,s,l){if(this._ticket="",t.get("showContent")&&t.get("show")){var u=this._tooltipContent;u.setEnterable(t.get("enterable"));var h=t.get("formatter");a=a||t.get("position");var c=e,p=this._getNearestPoint([r,o],n,t.get("trigger"),t.get("borderColor")).color;if(h)if(X(h)){var d=t.ecModel.get("useUTC"),f=Y(n)?n[0]:n;c=h,f&&f.axisType&&f.axisType.indexOf("time")>=0&&(c=zc(f.axisValue,c,d)),c=up(c,n,!0)}else if(U(h)){var g=W((function(e,i){e===this._ticket&&(u.setContent(i,l,t,p,a),this._updatePosition(t,a,r,o,u,n,s))}),this);this._ticket=i,c=h(n,i,g)}else c=h;u.setContent(c,l,t,p,a),u.show(t,p),this._updatePosition(t,a,r,o,u,n,s)}},e.prototype._getNearestPoint=function(t,e,n,i){return"axis"===n||Y(e)?{color:i||("html"===this._renderMode?"#fff":"none")}:Y(e)?void 0:{color:i||e.color||e.borderColor}},e.prototype._updatePosition=function(t,e,n,i,r,o,a){var s=this._api.getWidth(),l=this._api.getHeight();e=e||t.get("position");var u=r.getSize(),h=t.get("align"),c=t.get("verticalAlign"),p=a&&a.getBoundingRect().clone();if(a&&p.applyTransform(a.transform),U(e)&&(e=e([n,i],o,r.el,p,{viewSize:[s,l],contentSize:u.slice()})),Y(e))n=Er(e[0],s),i=Er(e[1],l);else if(q(e)){var d=e;d.width=u[0],d.height=u[1];var f=mp(d,{width:s,height:l});n=f.x,i=f.y,h=null,c=null}else if(X(e)&&a){var g=function(t,e,n,i){var r=n[0],o=n[1],a=Math.ceil(Math.SQRT2*i)+8,s=0,l=0,u=e.width,h=e.height;switch(t){case"inside":s=e.x+u/2-r/2,l=e.y+h/2-o/2;break;case"top":s=e.x+u/2-r/2,l=e.y-o-a;break;case"bottom":s=e.x+u/2-r/2,l=e.y+h+a;break;case"left":s=e.x-r-a,l=e.y+h/2-o/2;break;case"right":s=e.x+u+a,l=e.y+h/2-o/2}return[s,l]}(e,p,u,t.get("borderWidth"));n=g[0],i=g[1]}else{g=function(t,e,n,i,r,o,a){var s=n.getSize(),l=s[0],u=s[1];null!=o&&(t+l+o+2>i?t-=l+o:t+=o);null!=a&&(e+u+a>r?e-=u+a:e+=a);return[t,e]}(n,i,r,s,l,h?null:20,c?null:20);n=g[0],i=g[1]}if(h&&(n-=jz(h)?u[0]/2:"right"===h?u[0]:0),c&&(i-=jz(c)?u[1]/2:"bottom"===c?u[1]:0),Az(t)){g=function(t,e,n,i,r){var o=n.getSize(),a=o[0],s=o[1];return t=Math.min(t+a,i)-a,e=Math.min(e+s,r)-s,t=Math.max(t,0),e=Math.max(e,0),[t,e]}(n,i,r,s,l);n=g[0],i=g[1]}r.moveTo(n,i)},e.prototype._updateContentNotChangedOnAxis=function(t,e){var n=this._lastDataByCoordSys,i=this._cbParamsList,r=!!n&&n.length===t.length;return r&&E(n,(function(n,o){var a=n.dataByAxis||[],s=(t[o]||{}).dataByAxis||[];(r=r&&a.length===s.length)&&E(a,(function(t,n){var o=s[n]||{},a=t.seriesDataIndices||[],l=o.seriesDataIndices||[];(r=r&&t.value===o.value&&t.axisType===o.axisType&&t.axisId===o.axisId&&a.length===l.length)&&E(a,(function(t,e){var n=l[e];r=r&&t.seriesIndex===n.seriesIndex&&t.dataIndex===n.dataIndex})),i&&E(t.seriesDataIndices,(function(t){var n=t.seriesIndex,o=e[n],a=i[n];o&&a&&a.data!==o.data&&(r=!1)}))}))})),this._lastDataByCoordSys=t,this._cbParamsList=e,!!r},e.prototype._hide=function(t){this._lastDataByCoordSys=null,t({type:"hideTip",from:this.uid})},e.prototype.dispose=function(t,e){!r.node&&e.getDom()&&(Ag(this,"_updatePosition"),this._tooltipContent.dispose(),JR("itemTooltip",e))},e.type="tooltip",e}(fg);function Xz(t,e,n){var i,r=e.ecModel;n?(i=new pc(n,r,r),i=new pc(e.option,i,r)):i=e;for(var o=t.length-1;o>=0;o--){var a=t[o];a&&(a instanceof pc&&(a=a.get("tooltip",!0)),X(a)&&(a={formatter:a}),a&&(i=new pc(a,i,r)))}return i}function Zz(t,e){return t.dispatchAction||W(e.dispatchAction,e)}function jz(t){return"center"===t||"middle"===t}var qz=["rect","polygon","keep","clear"];function Kz(t,e){var n=ho(t?t.brush:[]);if(n.length){var i=[];E(n,(function(t){var e=t.hasOwnProperty("toolbox")?t.toolbox:[];e instanceof Array&&(i=i.concat(e))}));var r=t&&t.toolbox;Y(r)&&(r=r[0]),r||(r={feature:{}},t.toolbox=[r]);var o=r.feature||(r.feature={}),a=o.brush||(o.brush={}),s=a.type||(a.type=[]);s.push.apply(s,i),function(t){var e={};E(t,(function(t){e[t]=1})),t.length=0,E(e,(function(e,n){t.push(n)}))}(s),e&&!s.length&&s.push.apply(s,qz)}}var $z=E;function Jz(t){if(t)for(var e in t)if(t.hasOwnProperty(e))return!0}function Qz(t,e,n){var i={};return $z(e,(function(e){var r,o=i[e]=((r=function(){}).prototype.__hidden=r.prototype,new r);$z(t[e],(function(t,i){if(eD.isValidType(i)){var r={type:i,visual:t};n&&n(r,e),o[i]=new eD(r),"opacity"===i&&((r=T(r)).type="colorAlpha",o.__hidden.__alphaForOpacity=new eD(r))}}))})),i}function tV(t,e,n){var i;E(n,(function(t){e.hasOwnProperty(t)&&Jz(e[t])&&(i=!0)})),i&&E(n,(function(n){e.hasOwnProperty(n)&&Jz(e[n])?t[n]=T(e[n]):delete t[n]}))}var eV={lineX:nV(0),lineY:nV(1),rect:{point:function(t,e,n){return t&&n.boundingRect.contain(t[0],t[1])},rect:function(t,e,n){return t&&n.boundingRect.intersect(t)}},polygon:{point:function(t,e,n){return t&&n.boundingRect.contain(t[0],t[1])&&f_(n.range,t[0],t[1])},rect:function(t,e,n){var i=n.range;if(!t||i.length<=1)return!1;var r=t.x,o=t.y,a=t.width,s=t.height,l=i[0];return!!(f_(i,r,o)||f_(i,r+a,o)||f_(i,r,o+s)||f_(i,r+a,o+s)||sr.create(t).contain(l[0],l[1])||Ph(r,o,r+a,o,i)||Ph(r,o,r,o+s,i)||Ph(r+a,o,r+a,o+s,i)||Ph(r,o+s,r+a,o+s,i))||void 0}}};function nV(t){var e=["x","y"],n=["width","height"];return{point:function(e,n,i){if(e){var r=i.range;return iV(e[t],r)}},rect:function(i,r,o){if(i){var a=o.range,s=[i[e[t]],i[e[t]]+i[n[t]]];return s[1]e[0][1]&&(e[0][1]=o[0]),o[1]e[1][1]&&(e[1][1]=o[1])}return e&&pV(e)}};function pV(t){return new sr(t[0][0],t[1][0],t[0][1]-t[0][0],t[1][1]-t[1][0])}var dV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){this.ecModel=t,this.api=e,this.model,(this._brushController=new Pk(e.getZr())).on("brush",W(this._onBrush,this)).mount()},e.prototype.render=function(t,e,n,i){this.model=t,this._updateController(t,e,n,i)},e.prototype.updateTransform=function(t,e,n,i){sV(e),this._updateController(t,e,n,i)},e.prototype.updateVisual=function(t,e,n,i){this.updateTransform(t,e,n,i)},e.prototype.updateView=function(t,e,n,i){this._updateController(t,e,n,i)},e.prototype._updateController=function(t,e,n,i){(!i||i.$from!==t.id)&&this._brushController.setPanels(t.brushTargetManager.makePanelOpts(n)).enableBrush(t.brushOption).updateCovers(t.areas.slice())},e.prototype.dispose=function(){this._brushController.dispose()},e.prototype._onBrush=function(t){var e=this.model.id,n=this.model.brushTargetManager.setOutputRanges(t.areas,this.ecModel);(!t.isEnd||t.removeOnClick)&&this.api.dispatchAction({type:"brush",brushId:e,areas:T(n),$from:e}),t.isEnd&&this.api.dispatchAction({type:"brushEnd",brushId:e,areas:T(n),$from:e})},e.type="brush",e}(fg),fV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.areas=[],n.brushOption={},n}return n(e,t),e.prototype.optionUpdated=function(t,e){var n=this.option;!e&&tV(n,t,["inBrush","outOfBrush"]);var i=n.inBrush=n.inBrush||{};n.outOfBrush=n.outOfBrush||{color:"#ddd"},i.hasOwnProperty("liftZ")||(i.liftZ=5)},e.prototype.setAreas=function(t){t&&(this.areas=z(t,(function(t){return gV(this.option,t)}),this))},e.prototype.setBrushOption=function(t){this.brushOption=gV(this.option,t),this.brushType=this.brushOption.brushType},e.type="brush",e.dependencies=["geo","grid","xAxis","yAxis","parallel","series"],e.defaultOption={seriesIndex:"all",brushType:"rect",brushMode:"single",transformable:!0,brushStyle:{borderWidth:1,color:"rgba(210,219,238,0.3)",borderColor:"#D2DBEE"},throttleType:"fixRate",throttleDelay:0,removeOnClick:!0,z:1e4},e}(Ip);function gV(t,e){return C({brushType:t.brushType,brushMode:t.brushMode,transformable:t.transformable,brushStyle:new pc(t.brushStyle).getItemStyle(),removeOnClick:t.removeOnClick,z:t.z},e,!0)}var yV=["rect","polygon","lineX","lineY","keep","clear"],vV=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return n(e,t),e.prototype.render=function(t,e,n){var i,r,o;e.eachComponent({mainType:"brush"},(function(t){i=t.brushType,r=t.brushOption.brushMode||"single",o=o||!!t.areas.length})),this._brushType=i,this._brushMode=r,E(t.get("type",!0),(function(e){t.setIconStatus(e,("keep"===e?"multiple"===r:"clear"===e?o:e===i)?"emphasis":"normal")}))},e.prototype.updateView=function(t,e,n){this.render(t,e,n)},e.prototype.getIcons=function(){var t=this.model,e=t.get("icon",!0),n={};return E(t.get("type",!0),(function(t){e[t]&&(n[t]=e[t])})),n},e.prototype.onclick=function(t,e,n){var i=this._brushType,r=this._brushMode;"clear"===n?(e.dispatchAction({type:"axisAreaSelect",intervals:[]}),e.dispatchAction({type:"brush",command:"clear",areas:[]})):e.dispatchAction({type:"takeGlobalCursor",key:"brush",brushOption:{brushType:"keep"===n?i:i!==n&&n,brushMode:"keep"===n?"multiple"===r?"single":"multiple":r}})},e.getDefaultOption=function(t){return{show:!0,type:yV.slice(),icon:{rect:"M7.3,34.7 M0.4,10V-0.2h9.8 M89.6,10V-0.2h-9.8 M0.4,60v10.2h9.8 M89.6,60v10.2h-9.8 M12.3,22.4V10.5h13.1 M33.6,10.5h7.8 M49.1,10.5h7.8 M77.5,22.4V10.5h-13 M12.3,31.1v8.2 M77.7,31.1v8.2 M12.3,47.6v11.9h13.1 M33.6,59.5h7.6 M49.1,59.5 h7.7 M77.5,47.6v11.9h-13",polygon:"M55.2,34.9c1.7,0,3.1,1.4,3.1,3.1s-1.4,3.1-3.1,3.1 s-3.1-1.4-3.1-3.1S53.5,34.9,55.2,34.9z M50.4,51c1.7,0,3.1,1.4,3.1,3.1c0,1.7-1.4,3.1-3.1,3.1c-1.7,0-3.1-1.4-3.1-3.1 C47.3,52.4,48.7,51,50.4,51z M55.6,37.1l1.5-7.8 M60.1,13.5l1.6-8.7l-7.8,4 M59,19l-1,5.3 M24,16.1l6.4,4.9l6.4-3.3 M48.5,11.6 l-5.9,3.1 M19.1,12.8L9.7,5.1l1.1,7.7 M13.4,29.8l1,7.3l6.6,1.6 M11.6,18.4l1,6.1 M32.8,41.9 M26.6,40.4 M27.3,40.2l6.1,1.6 M49.9,52.1l-5.6-7.6l-4.9-1.2",lineX:"M15.2,30 M19.7,15.6V1.9H29 M34.8,1.9H40.4 M55.3,15.6V1.9H45.9 M19.7,44.4V58.1H29 M34.8,58.1H40.4 M55.3,44.4 V58.1H45.9 M12.5,20.3l-9.4,9.6l9.6,9.8 M3.1,29.9h16.5 M62.5,20.3l9.4,9.6L62.3,39.7 M71.9,29.9H55.4",lineY:"M38.8,7.7 M52.7,12h13.2v9 M65.9,26.6V32 M52.7,46.3h13.2v-9 M24.9,12H11.8v9 M11.8,26.6V32 M24.9,46.3H11.8v-9 M48.2,5.1l-9.3-9l-9.4,9.2 M38.9-3.9V12 M48.2,53.3l-9.3,9l-9.4-9.2 M38.9,62.3V46.4",keep:"M4,10.5V1h10.3 M20.7,1h6.1 M33,1h6.1 M55.4,10.5V1H45.2 M4,17.3v6.6 M55.6,17.3v6.6 M4,30.5V40h10.3 M20.7,40 h6.1 M33,40h6.1 M55.4,30.5V40H45.2 M21,18.9h62.9v48.6H21V18.9z",clear:"M22,14.7l30.9,31 M52.9,14.7L22,45.7 M4.7,16.8V4.2h13.1 M26,4.2h7.8 M41.6,4.2h7.8 M70.3,16.8V4.2H57.2 M4.7,25.9v8.6 M70.3,25.9v8.6 M4.7,43.2v12.6h13.1 M26,55.8h7.8 M41.6,55.8h7.8 M70.3,43.2v12.6H57.2"},title:t.getLocaleModel().get(["toolbox","brush","title"])}},e}(FE);var mV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.layoutMode={type:"box",ignoreSize:!0},n}return n(e,t),e.type="title",e.defaultOption={z:6,show:!0,text:"",target:"blank",subtext:"",subtarget:"blank",left:0,top:0,backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,padding:5,itemGap:10,textStyle:{fontSize:18,fontWeight:"bold",color:"#464646"},subtextStyle:{fontSize:12,color:"#6E7079"}},e}(Ip),xV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.render=function(t,e,n){if(this.group.removeAll(),t.get("show")){var i=this.group,r=t.getModel("textStyle"),o=t.getModel("subtextStyle"),a=t.get("textAlign"),s=rt(t.get("textBaseline"),t.get("textVerticalAlign")),l=new As({style:Yh(r,{text:t.get("text"),fill:r.getTextColor()},{disableBox:!0}),z2:10}),u=l.getBoundingRect(),h=t.get("subtext"),c=new As({style:Yh(o,{text:h,fill:o.getTextColor(),y:u.height+t.get("itemGap"),verticalAlign:"top"},{disableBox:!0}),z2:10}),p=t.get("link"),d=t.get("sublink"),f=t.get("triggerEvent",!0);l.silent=!p&&!f,c.silent=!d&&!f,p&&l.on("click",(function(){pp(p,"_"+t.get("target"))})),d&&c.on("click",(function(){pp(d,"_"+t.get("subtarget"))})),Ws(l).eventData=Ws(c).eventData=f?{componentType:"title",componentIndex:t.componentIndex}:null,i.add(l),h&&i.add(c);var g=i.getBoundingRect(),y=t.getBoxLayoutParams();y.width=g.width,y.height=g.height;var v=mp(y,{width:n.getWidth(),height:n.getHeight()},t.get("padding"));a||("middle"===(a=t.get("left")||t.get("right"))&&(a="center"),"right"===a?v.x+=v.width:"center"===a&&(v.x+=v.width/2)),s||("center"===(s=t.get("top")||t.get("bottom"))&&(s="middle"),"bottom"===s?v.y+=v.height:"middle"===s&&(v.y+=v.height/2),s=s||"top"),i.x=v.x,i.y=v.y,i.markRedraw();var m={align:a,verticalAlign:s};l.setStyle(m),c.setStyle(m),g=i.getBoundingRect();var x=v.margin,_=t.getItemStyle(["color","opacity"]);_.fill=t.get("backgroundColor");var b=new Ts({shape:{x:g.x-x[3],y:g.y-x[0],width:g.width+x[1]+x[3],height:g.height+x[0]+x[2],r:t.get("borderRadius")},style:_,subPixelOptimize:!0,silent:!0});i.add(b)}},e.type="title",e}(fg);var _V=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.layoutMode="box",n}return n(e,t),e.prototype.init=function(t,e,n){this.mergeDefaultAndTheme(t,n),this._initData()},e.prototype.mergeOption=function(e){t.prototype.mergeOption.apply(this,arguments),this._initData()},e.prototype.setCurrentIndex=function(t){null==t&&(t=this.option.currentIndex);var e=this._data.count();this.option.loop?t=(t%e+e)%e:(t>=e&&(t=e-1),t<0&&(t=0)),this.option.currentIndex=t},e.prototype.getCurrentIndex=function(){return this.option.currentIndex},e.prototype.isIndexMax=function(){return this.getCurrentIndex()>=this._data.count()-1},e.prototype.setPlayState=function(t){this.option.autoPlay=!!t},e.prototype.getPlayState=function(){return!!this.option.autoPlay},e.prototype._initData=function(){var t,e=this.option,n=e.data||[],i=e.axisType,r=this._names=[];"category"===i?(t=[],E(n,(function(e,n){var i,o=xo(fo(e),"");q(e)?(i=T(e)).value=n:i=n,t.push(i),r.push(o)}))):t=n;var o={category:"ordinal",time:"time",value:"number"}[i]||"number";(this._data=new Zm([{name:"value",type:o}],this)).initData(t,r)},e.prototype.getData=function(){return this._data},e.prototype.getCategories=function(){if("category"===this.get("axisType"))return this._names.slice()},e.type="timeline",e.defaultOption={z:4,show:!0,axisType:"time",realtime:!0,left:"20%",top:null,right:"20%",bottom:0,width:null,height:40,padding:5,controlPosition:"left",autoPlay:!1,rewind:!1,loop:!0,playInterval:2e3,currentIndex:0,itemStyle:{},label:{color:"#000"},data:[]},e}(Ip),bV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="timeline.slider",e.defaultOption=gc(_V.defaultOption,{backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderWidth:0,orient:"horizontal",inverse:!1,tooltip:{trigger:"item"},symbol:"circle",symbolSize:12,lineStyle:{show:!0,width:2,color:"#DAE1F5"},label:{position:"auto",show:!0,interval:"auto",rotate:0,color:"#A4B1D7"},itemStyle:{color:"#A4B1D7",borderWidth:1},checkpointStyle:{symbol:"circle",symbolSize:15,color:"#316bf3",borderColor:"#fff",borderWidth:2,shadowBlur:2,shadowOffsetX:1,shadowOffsetY:1,shadowColor:"rgba(0, 0, 0, 0.3)",animation:!0,animationDuration:300,animationEasing:"quinticInOut"},controlStyle:{show:!0,showPlayBtn:!0,showPrevBtn:!0,showNextBtn:!0,itemSize:24,itemGap:12,position:"left",playIcon:"path://M31.6,53C17.5,53,6,41.5,6,27.4S17.5,1.8,31.6,1.8C45.7,1.8,57.2,13.3,57.2,27.4S45.7,53,31.6,53z M31.6,3.3 C18.4,3.3,7.5,14.1,7.5,27.4c0,13.3,10.8,24.1,24.1,24.1C44.9,51.5,55.7,40.7,55.7,27.4C55.7,14.1,44.9,3.3,31.6,3.3z M24.9,21.3 c0-2.2,1.6-3.1,3.5-2l10.5,6.1c1.899,1.1,1.899,2.9,0,4l-10.5,6.1c-1.9,1.1-3.5,0.2-3.5-2V21.3z",stopIcon:"path://M30.9,53.2C16.8,53.2,5.3,41.7,5.3,27.6S16.8,2,30.9,2C45,2,56.4,13.5,56.4,27.6S45,53.2,30.9,53.2z M30.9,3.5C17.6,3.5,6.8,14.4,6.8,27.6c0,13.3,10.8,24.1,24.101,24.1C44.2,51.7,55,40.9,55,27.6C54.9,14.4,44.1,3.5,30.9,3.5z M36.9,35.8c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H36c0.5,0,0.9,0.4,0.9,1V35.8z M27.8,35.8 c0,0.601-0.4,1-0.9,1h-1.3c-0.5,0-0.9-0.399-0.9-1V19.5c0-0.6,0.4-1,0.9-1H27c0.5,0,0.9,0.4,0.9,1L27.8,35.8L27.8,35.8z",nextIcon:"M2,18.5A1.52,1.52,0,0,1,.92,18a1.49,1.49,0,0,1,0-2.12L7.81,9.36,1,3.11A1.5,1.5,0,1,1,3,.89l8,7.34a1.48,1.48,0,0,1,.49,1.09,1.51,1.51,0,0,1-.46,1.1L3,18.08A1.5,1.5,0,0,1,2,18.5Z",prevIcon:"M10,.5A1.52,1.52,0,0,1,11.08,1a1.49,1.49,0,0,1,0,2.12L4.19,9.64,11,15.89a1.5,1.5,0,1,1-2,2.22L1,10.77A1.48,1.48,0,0,1,.5,9.68,1.51,1.51,0,0,1,1,8.58L9,.92A1.5,1.5,0,0,1,10,.5Z",prevBtnSize:18,nextBtnSize:18,color:"#A4B1D7",borderColor:"#A4B1D7",borderWidth:1},emphasis:{label:{show:!0,color:"#6f778d"},itemStyle:{color:"#316BF3"},controlStyle:{color:"#316BF3",borderColor:"#316BF3",borderWidth:2}},progress:{lineStyle:{color:"#316BF3"},itemStyle:{color:"#316BF3"},label:{color:"#6f778d"}},data:[]}),e}(_V);R(bV,sf.prototype);var wV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="timeline",e}(fg),SV=function(t){function e(e,n,i,r){var o=t.call(this,e,n,i)||this;return o.type=r||"value",o}return n(e,t),e.prototype.getLabelModel=function(){return this.model.getModel("label")},e.prototype.isHorizontal=function(){return"horizontal"===this.model.get("orient")},e}(G_),MV=Math.PI,IV=So(),TV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(t,e){this.api=e},e.prototype.render=function(t,e,n){if(this.model=t,this.api=n,this.ecModel=e,this.group.removeAll(),t.get("show",!0)){var i=this._layout(t,n),r=this._createGroup("_mainGroup"),o=this._createGroup("_labelGroup"),a=this._axis=this._createAxis(i,t);t.formatTooltip=function(t){return Uf("nameValue",{noName:!0,value:a.scale.getLabel({value:t})})},E(["AxisLine","AxisTick","Control","CurrentPointer"],(function(e){this["_render"+e](i,r,a,t)}),this),this._renderAxisLabel(i,o,a,t),this._position(i,t)}this._doPlayStop(),this._updateTicksStatus()},e.prototype.remove=function(){this._clearTimer(),this.group.removeAll()},e.prototype.dispose=function(){this._clearTimer()},e.prototype._layout=function(t,e){var n,i,r,o,a=t.get(["label","position"]),s=t.get("orient"),l=function(t,e){return mp(t.getBoxLayoutParams(),{width:e.getWidth(),height:e.getHeight()},t.get("padding"))}(t,e),u={horizontal:"center",vertical:(n=null==a||"auto"===a?"horizontal"===s?l.y+l.height/2=0||"+"===n?"left":"right"},h={horizontal:n>=0||"+"===n?"top":"bottom",vertical:"middle"},c={horizontal:0,vertical:MV/2},p="vertical"===s?l.height:l.width,d=t.getModel("controlStyle"),f=d.get("show",!0),g=f?d.get("itemSize"):0,y=f?d.get("itemGap"):0,v=g+y,m=t.get(["label","rotate"])||0;m=m*MV/180;var x=d.get("position",!0),_=f&&d.get("showPlayBtn",!0),b=f&&d.get("showPrevBtn",!0),w=f&&d.get("showNextBtn",!0),S=0,M=p;"left"===x||"bottom"===x?(_&&(i=[0,0],S+=v),b&&(r=[S,0],S+=v),w&&(o=[M-g,0],M-=v)):(_&&(i=[M-g,0],M-=v),b&&(r=[0,0],S+=v),w&&(o=[M-g,0],M-=v));var I=[S,M];return t.get("inverse")&&I.reverse(),{viewRect:l,mainLength:p,orient:s,rotation:c[s],labelRotation:m,labelPosOpt:n,labelAlign:t.get(["label","align"])||u[s],labelBaseline:t.get(["label","verticalAlign"])||t.get(["label","baseline"])||h[s],playPosition:i,prevBtnPosition:r,nextBtnPosition:o,axisExtent:I,controlSize:g,controlGap:y}},e.prototype._position=function(t,e){var n=this._mainGroup,i=this._labelGroup,r=t.viewRect;if("vertical"===t.orient){var o=[1,0,0,1,0,0],a=r.x,s=r.y+r.height;Ei(o,o,[-a,-s]),zi(o,o,-MV/2),Ei(o,o,[a,s]),(r=r.clone()).applyTransform(o)}var l=y(r),u=y(n.getBoundingRect()),h=y(i.getBoundingRect()),c=[n.x,n.y],p=[i.x,i.y];p[0]=c[0]=l[0][0];var d,f=t.labelPosOpt;null==f||X(f)?(v(c,u,l,1,d="+"===f?0:1),v(p,h,l,1,1-d)):(v(c,u,l,1,d=f>=0?0:1),p[1]=c[1]+f);function g(t){t.originX=l[0][0]-t.x,t.originY=l[1][0]-t.y}function y(t){return[[t.x,t.x+t.width],[t.y,t.y+t.height]]}function v(t,e,n,i,r){t[i]+=n[i][r]-e[i][r]}n.setPosition(c),i.setPosition(p),n.rotation=i.rotation=t.rotation,g(n),g(i)},e.prototype._createAxis=function(t,e){var n=e.getData(),i=e.get("axisType"),r=function(t,e){if(e=e||t.get("type"))switch(e){case"category":return new gx({ordinalMeta:t.getCategories(),extent:[1/0,-1/0]});case"time":return new Px({locale:t.ecModel.getLocaleModel(),useUTC:t.ecModel.get("useUTC")});default:return new vx}}(e,i);r.getTicks=function(){return n.mapArray(["value"],(function(t){return{value:t}}))};var o=n.getDataExtent("value");r.setExtent(o[0],o[1]),r.calcNiceTicks();var a=new SV("value",r,t.axisExtent,i);return a.model=e,a},e.prototype._createGroup=function(t){var e=this[t]=new Cr;return this.group.add(e),e},e.prototype._renderAxisLine=function(t,e,n,i){var r=n.getExtent();if(i.get(["lineStyle","show"])){var o=new Eu({shape:{x1:r[0],y1:0,x2:r[1],y2:0},style:A({lineCap:"round"},i.getModel("lineStyle").getLineStyle()),silent:!0,z2:1});e.add(o);var a=this._progressLine=new Eu({shape:{x1:r[0],x2:this._currentPointer?this._currentPointer.x:r[0],y1:0,y2:0},style:k({lineCap:"round",lineWidth:o.style.lineWidth},i.getModel(["progress","lineStyle"]).getLineStyle()),silent:!0,z2:1});e.add(a)}},e.prototype._renderAxisTick=function(t,e,n,i){var r=this,o=i.getData(),a=n.scale.getTicks();this._tickSymbols=[],E(a,(function(t){var a=n.dataToCoord(t.value),s=o.getItemModel(t.value),l=s.getModel("itemStyle"),u=s.getModel(["emphasis","itemStyle"]),h=s.getModel(["progress","itemStyle"]),c={x:a,y:0,onclick:W(r._changeTimeline,r,t.value)},p=CV(s,l,e,c);p.ensureState("emphasis").style=u.getItemStyle(),p.ensureState("progress").style=h.getItemStyle(),Pl(p);var d=Ws(p);s.get("tooltip")?(d.dataIndex=t.value,d.dataModel=i):d.dataIndex=d.dataModel=null,r._tickSymbols.push(p)}))},e.prototype._renderAxisLabel=function(t,e,n,i){var r=this;if(n.getLabelModel().get("show")){var o=i.getData(),a=n.getViewLabels();this._tickLabels=[],E(a,(function(i){var a=i.tickValue,s=o.getItemModel(a),l=s.getModel("label"),u=s.getModel(["emphasis","label"]),h=s.getModel(["progress","label"]),c=n.dataToCoord(i.tickValue),p=new As({x:c,y:0,rotation:t.labelRotation-t.rotation,onclick:W(r._changeTimeline,r,a),silent:!1,style:Yh(l,{text:i.formattedLabel,align:t.labelAlign,verticalAlign:t.labelBaseline})});p.ensureState("emphasis").style=Yh(u),p.ensureState("progress").style=Yh(h),e.add(p),Pl(p),IV(p).dataIndex=a,r._tickLabels.push(p)}))}},e.prototype._renderControl=function(t,e,n,i){var r=t.controlSize,o=t.rotation,a=i.getModel("controlStyle").getItemStyle(),s=i.getModel(["emphasis","controlStyle"]).getItemStyle(),l=i.getPlayState(),u=i.get("inverse",!0);function h(t,n,l,u){if(t){var h=gr(rt(i.get(["controlStyle",n+"BtnSize"]),r),r),c=function(t,e,n,i){var r=i.style,o=Lh(t.get(["controlStyle",e]),i||{},new sr(n[0],n[1],n[2],n[3]));r&&o.setStyle(r);return o}(i,n+"Icon",[0,-h/2,h,h],{x:t[0],y:t[1],originX:r/2,originY:0,rotation:u?-o:0,rectHover:!0,style:a,onclick:l});c.ensureState("emphasis").style=s,e.add(c),Pl(c)}}h(t.nextBtnPosition,"next",W(this._changeTimeline,this,u?"-":"+")),h(t.prevBtnPosition,"prev",W(this._changeTimeline,this,u?"+":"-")),h(t.playPosition,l?"stop":"play",W(this._handlePlayClick,this,!l),!0)},e.prototype._renderCurrentPointer=function(t,e,n,i){var r=i.getData(),o=i.getCurrentIndex(),a=r.getItemModel(o).getModel("checkpointStyle"),s=this,l={onCreate:function(t){t.draggable=!0,t.drift=W(s._handlePointerDrag,s),t.ondragend=W(s._handlePointerDragend,s),DV(t,s._progressLine,o,n,i,!0)},onUpdate:function(t){DV(t,s._progressLine,o,n,i)}};this._currentPointer=CV(a,a,this._mainGroup,{},this._currentPointer,l)},e.prototype._handlePlayClick=function(t){this._clearTimer(),this.api.dispatchAction({type:"timelinePlayChange",playState:t,from:this.uid})},e.prototype._handlePointerDrag=function(t,e,n){this._clearTimer(),this._pointerChangeTimeline([n.offsetX,n.offsetY])},e.prototype._handlePointerDragend=function(t){this._pointerChangeTimeline([t.offsetX,t.offsetY],!0)},e.prototype._pointerChangeTimeline=function(t,e){var n=this._toAxisCoord(t)[0],i=Vr(this._axis.getExtent().slice());n>i[1]&&(n=i[1]),n=0&&(a[o]=+a[o].toFixed(c)),[a,h]}var VV={min:H(zV,"min"),max:H(zV,"max"),average:H(zV,"average"),median:H(zV,"median")};function BV(t,e){var n=t.getData(),i=t.coordinateSystem;if(e&&!function(t){return!isNaN(parseFloat(t.x))&&!isNaN(parseFloat(t.y))}(e)&&!Y(e.coord)&&i){var r=i.dimensions,o=FV(e,n,i,t);if((e=T(e)).type&&VV[e.type]&&o.baseAxis&&o.valueAxis){var a=P(r,o.baseAxis.dim),s=P(r,o.valueAxis.dim),l=VV[e.type](n,o.baseDataDim,o.valueDataDim,a,s);e.coord=l[0],e.value=l[1]}else{for(var u=[null!=e.xAxis?e.xAxis:e.radiusAxis,null!=e.yAxis?e.yAxis:e.angleAxis],h=0;h<2;h++)VV[u[h]]&&(u[h]=HV(n,n.mapDimension(r[h]),u[h]));e.coord=u}}return e}function FV(t,e,n,i){var r={};return null!=t.valueIndex||null!=t.valueDim?(r.valueDataDim=null!=t.valueIndex?e.getDimension(t.valueIndex):t.valueDim,r.valueAxis=n.getAxis(function(t,e){var n=t.getData().getDimensionInfo(e);return n&&n.coordDim}(i,r.valueDataDim)),r.baseAxis=n.getOtherAxis(r.valueAxis),r.baseDataDim=e.mapDimension(r.baseAxis.dim)):(r.baseAxis=i.getBaseAxis(),r.valueAxis=n.getOtherAxis(r.baseAxis),r.baseDataDim=e.mapDimension(r.baseAxis.dim),r.valueDataDim=e.mapDimension(r.valueAxis.dim)),r}function GV(t,e){return!(t&&t.containData&&e.coord&&!function(t){return!(isNaN(parseFloat(t.x))&&isNaN(parseFloat(t.y)))}(e))||t.containData(e.coord)}function WV(t,e){return t?function(t,n,i,r){return pf(r<2?t.coord&&t.coord[r]:t.value,e[r])}:function(t,n,i,r){return pf(t.value,e[r])}}function HV(t,e,n){if("average"===n){var i=0,r=0;return t.each(e,(function(t,e){isNaN(t)||(i+=t,r++)})),i/r}return"median"===n?t.getMedian(e):t.getDataExtent(e)["max"===n?1:0]}var YV=So(),UV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.init=function(){this.markerGroupMap=ft()},e.prototype.render=function(t,e,n){var i=this,r=this.markerGroupMap;r.each((function(t){YV(t).keep=!1})),e.eachSeries((function(t){var r=NV.getMarkerModelFromSeries(t,i.type);r&&i.renderSeries(t,r,e,n)})),r.each((function(t){!YV(t).keep&&i.group.remove(t.group)}))},e.prototype.markKeep=function(t){YV(t).keep=!0},e.prototype.blurSeries=function(t){var e=this;E(t,(function(t){var n=NV.getMarkerModelFromSeries(t,e.type);n&&n.getData().eachItemGraphicEl((function(t){t&&bl(t)}))}))},e.type="marker",e}(fg);function XV(t,e,n){var i=e.coordinateSystem;t.each((function(r){var o,a=t.getItemModel(r),s=Er(a.get("x"),n.getWidth()),l=Er(a.get("y"),n.getHeight());if(isNaN(s)||isNaN(l)){if(e.getMarkerPosition)o=e.getMarkerPosition(t.getValues(t.dimensions,r));else if(i){var u=t.get(i.dimensions[0],r),h=t.get(i.dimensions[1],r);o=i.dataToPoint([u,h])}}else o=[s,l];isNaN(s)||(o[0]=s),isNaN(l)||(o[1]=l),t.setItemLayout(r,o)}))}var ZV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=NV.getMarkerModelFromSeries(t,"markPoint");e&&(XV(e.getData(),t,n),this.markerGroupMap.get(t.id).updateLayout())}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,new Zw),u=function(t,e,n){var i;i=t?z(t&&t.dimensions,(function(t){return A(A({},e.getData().getDimensionInfo(e.getData().mapDimension(t))||{}),{name:t,ordinalMeta:null})})):[{name:"value",type:"float"}];var r=new Zm(i,n),o=z(n.get("data"),H(BV,e));t&&(o=B(o,H(GV,t)));var a=WV(!!t,i);return r.initData(o,null,a),r}(r,t,e);e.setData(u),XV(e.getData(),t,i),u.each((function(t){var n=u.getItemModel(t),i=n.getShallow("symbol"),r=n.getShallow("symbolSize"),o=n.getShallow("symbolRotate"),s=n.getShallow("symbolOffset"),l=n.getShallow("symbolKeepAspect");if(U(i)||U(r)||U(o)||U(s)){var h=e.getRawValue(t),c=e.getDataParams(t);U(i)&&(i=i(h,c)),U(r)&&(r=r(h,c)),U(o)&&(o=o(h,c)),U(s)&&(s=s(h,c))}var p=n.getModel("itemStyle").getItemStyle(),d=fy(a,"color");p.fill||(p.fill=d),u.setItemVisual(t,{symbol:i,symbolSize:r,symbolRotate:o,symbolOffset:s,symbolKeepAspect:l,style:p})})),l.updateData(u),this.group.add(l.group),u.eachItemGraphicEl((function(t){t.traverse((function(t){Ws(t).dataModel=e}))})),this.markKeep(l),l.group.silent=e.get("silent")||t.get("silent")},e.type="markPoint",e}(UV);var jV=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.createMarkerModelFromSeries=function(t,n,i){return new e(t,n,i)},e.type="markLine",e.defaultOption={z:5,symbol:["circle","arrow"],symbolSize:[8,16],symbolOffset:0,precision:2,tooltip:{trigger:"item"},label:{show:!0,position:"end",distance:5},lineStyle:{type:"dashed"},emphasis:{label:{show:!0},lineStyle:{width:3}},animationEasing:"linear"},e}(NV),qV=So(),KV=function(t,e,n,i){var r,o=t.getData();if(Y(i))r=i;else{var a=i.type;if("min"===a||"max"===a||"average"===a||"median"===a||null!=i.xAxis||null!=i.yAxis){var s=void 0,l=void 0;if(null!=i.yAxis||null!=i.xAxis)s=e.getAxis(null!=i.yAxis?"y":"x"),l=it(i.yAxis,i.xAxis);else{var u=FV(i,o,e,t);s=u.valueAxis,l=HV(o,ex(o,u.valueDataDim),a)}var h="x"===s.dim?0:1,c=1-h,p=T(i),d={coord:[]};p.type=null,p.coord=[],p.coord[c]=-1/0,d.coord[c]=1/0;var f=n.get("precision");f>=0&&j(l)&&(l=+l.toFixed(Math.min(f,20))),p.coord[h]=d.coord[h]=l,r=[p,d,{type:a,valueIndex:i.valueIndex,value:l}]}else r=[]}var g=[BV(t,r[0]),BV(t,r[1]),A({},r[2])];return g[2].type=g[2].type||null,C(g[2],g[0]),C(g[2],g[1]),g};function $V(t){return!isNaN(t)&&!isFinite(t)}function JV(t,e,n,i){var r=1-t,o=i.dimensions[t];return $V(e[r])&&$V(n[r])&&e[t]===n[t]&&i.getAxis(o).containData(e[t])}function QV(t,e){if("cartesian2d"===t.type){var n=e[0].coord,i=e[1].coord;if(n&&i&&(JV(1,n,i,t)||JV(0,n,i,t)))return!0}return GV(t,e[0])&&GV(t,e[1])}function tB(t,e,n,i,r){var o,a=i.coordinateSystem,s=t.getItemModel(e),l=Er(s.get("x"),r.getWidth()),u=Er(s.get("y"),r.getHeight());if(isNaN(l)||isNaN(u)){if(i.getMarkerPosition)o=i.getMarkerPosition(t.getValues(t.dimensions,e));else{var h=a.dimensions,c=t.get(h[0],e),p=t.get(h[1],e);o=a.dataToPoint([c,p])}if(sS(a,"cartesian2d")){var d=a.getAxis("x"),f=a.getAxis("y");h=a.dimensions;$V(t.get(h[0],e))?o[0]=d.toGlobalCoord(d.getExtent()[n?0:1]):$V(t.get(h[1],e))&&(o[1]=f.toGlobalCoord(f.getExtent()[n?0:1]))}isNaN(l)||(o[0]=l),isNaN(u)||(o[1]=u)}else o=[l,u];t.setItemLayout(e,o)}var eB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=NV.getMarkerModelFromSeries(t,"markLine");if(e){var i=e.getData(),r=qV(e).from,o=qV(e).to;r.each((function(e){tB(r,e,!0,t,n),tB(o,e,!1,t,n)})),i.each((function(t){i.setItemLayout(t,[r.getItemLayout(t),o.getItemLayout(t)])})),this.markerGroupMap.get(t.id).updateLayout()}}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,new dA);this.group.add(l.group);var u=function(t,e,n){var i;i=t?z(t&&t.dimensions,(function(t){return A(A({},e.getData().getDimensionInfo(e.getData().mapDimension(t))||{}),{name:t,ordinalMeta:null})})):[{name:"value",type:"float"}];var r=new Zm(i,n),o=new Zm(i,n),a=new Zm([],n),s=z(n.get("data"),H(KV,e,t,n));t&&(s=B(s,H(QV,t)));var l=WV(!!t,i);return r.initData(z(s,(function(t){return t[0]})),null,l),o.initData(z(s,(function(t){return t[1]})),null,l),a.initData(z(s,(function(t){return t[2]}))),a.hasItemOption=!0,{from:r,to:o,line:a}}(r,t,e),h=u.from,c=u.to,p=u.line;qV(e).from=h,qV(e).to=c,e.setData(p);var d=e.get("symbol"),f=e.get("symbolSize"),g=e.get("symbolRotate"),y=e.get("symbolOffset");function v(e,n,r){var o=e.getItemModel(n);tB(e,n,r,t,i);var s=o.getModel("itemStyle").getItemStyle();null==s.fill&&(s.fill=fy(a,"color")),e.setItemVisual(n,{symbolKeepAspect:o.get("symbolKeepAspect"),symbolOffset:rt(o.get("symbolOffset",!0),y[r?0:1]),symbolRotate:rt(o.get("symbolRotate",!0),g[r?0:1]),symbolSize:rt(o.get("symbolSize"),f[r?0:1]),symbol:rt(o.get("symbol",!0),d[r?0:1]),style:s})}Y(d)||(d=[d,d]),Y(f)||(f=[f,f]),Y(g)||(g=[g,g]),Y(y)||(y=[y,y]),u.from.each((function(t){v(h,t,!0),v(c,t,!1)})),p.each((function(t){var e=p.getItemModel(t).getModel("lineStyle").getLineStyle();p.setItemLayout(t,[h.getItemLayout(t),c.getItemLayout(t)]),null==e.stroke&&(e.stroke=h.getItemVisual(t,"style").fill),p.setItemVisual(t,{fromSymbolKeepAspect:h.getItemVisual(t,"symbolKeepAspect"),fromSymbolOffset:h.getItemVisual(t,"symbolOffset"),fromSymbolRotate:h.getItemVisual(t,"symbolRotate"),fromSymbolSize:h.getItemVisual(t,"symbolSize"),fromSymbol:h.getItemVisual(t,"symbol"),toSymbolKeepAspect:c.getItemVisual(t,"symbolKeepAspect"),toSymbolOffset:c.getItemVisual(t,"symbolOffset"),toSymbolRotate:c.getItemVisual(t,"symbolRotate"),toSymbolSize:c.getItemVisual(t,"symbolSize"),toSymbol:c.getItemVisual(t,"symbol"),style:e})})),l.updateData(p),u.line.eachItemGraphicEl((function(t,n){t.traverse((function(t){Ws(t).dataModel=e}))})),this.markKeep(l),l.group.silent=e.get("silent")||t.get("silent")},e.type="markLine",e}(UV);var nB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.createMarkerModelFromSeries=function(t,n,i){return new e(t,n,i)},e.type="markArea",e.defaultOption={z:1,tooltip:{trigger:"item"},animation:!1,label:{show:!0,position:"top"},itemStyle:{borderWidth:0},emphasis:{label:{show:!0,position:"top"}}},e}(NV),iB=So(),rB=function(t,e,n,i){var r=BV(t,i[0]),o=BV(t,i[1]),a=r.coord,s=o.coord;a[0]=it(a[0],-1/0),a[1]=it(a[1],-1/0),s[0]=it(s[0],1/0),s[1]=it(s[1],1/0);var l=D([{},r,o]);return l.coord=[r.coord,o.coord],l.x0=r.x,l.y0=r.y,l.x1=o.x,l.y1=o.y,l};function oB(t){return!isNaN(t)&&!isFinite(t)}function aB(t,e,n,i){var r=1-t;return oB(e[r])&&oB(n[r])}function sB(t,e){var n=e.coord[0],i=e.coord[1];return!!(sS(t,"cartesian2d")&&n&&i&&(aB(1,n,i)||aB(0,n,i)))||(GV(t,{coord:n,x:e.x0,y:e.y0})||GV(t,{coord:i,x:e.x1,y:e.y1}))}function lB(t,e,n,i,r){var o,a=i.coordinateSystem,s=t.getItemModel(e),l=Er(s.get(n[0]),r.getWidth()),u=Er(s.get(n[1]),r.getHeight());if(isNaN(l)||isNaN(u)){if(i.getMarkerPosition)o=i.getMarkerPosition(t.getValues(n,e));else{var h=[d=t.get(n[0],e),f=t.get(n[1],e)];a.clampData&&a.clampData(h,h),o=a.dataToPoint(h,!0)}if(sS(a,"cartesian2d")){var c=a.getAxis("x"),p=a.getAxis("y"),d=t.get(n[0],e),f=t.get(n[1],e);oB(d)?o[0]=c.toGlobalCoord(c.getExtent()["x0"===n[0]?0:1]):oB(f)&&(o[1]=p.toGlobalCoord(p.getExtent()["y0"===n[1]?0:1]))}isNaN(l)||(o[0]=l),isNaN(u)||(o[1]=u)}else o=[l,u];return o}var uB=[["x0","y0"],["x1","y0"],["x1","y1"],["x0","y1"]],hB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.updateTransform=function(t,e,n){e.eachSeries((function(t){var e=NV.getMarkerModelFromSeries(t,"markArea");if(e){var i=e.getData();i.each((function(e){var r=z(uB,(function(r){return lB(i,e,r,t,n)}));i.setItemLayout(e,r),i.getItemGraphicEl(e).setShape("points",r)}))}}),this)},e.prototype.renderSeries=function(t,e,n,i){var r=t.coordinateSystem,o=t.id,a=t.getData(),s=this.markerGroupMap,l=s.get(o)||s.set(o,{group:new Cr});this.group.add(l.group),this.markKeep(l);var u=function(t,e,n){var i,r,o=["x0","y0","x1","y1"];if(t){var a=z(t&&t.dimensions,(function(t){var n=e.getData();return A(A({},n.getDimensionInfo(n.mapDimension(t))||{}),{name:t,ordinalMeta:null})}));r=z(o,(function(t,e){return{name:t,type:a[e%2].type}})),i=new Zm(r,n)}else i=new Zm(r=[{name:"value",type:"float"}],n);var s=z(n.get("data"),H(rB,e,t,n));t&&(s=B(s,H(sB,t)));var l=t?function(t,e,n,i){return pf(t.coord[Math.floor(i/2)][i%2],r[i])}:function(t,e,n,i){return pf(t.value,r[i])};return i.initData(s,null,l),i.hasItemOption=!0,i}(r,t,e);e.setData(u),u.each((function(e){var n=z(uB,(function(n){return lB(u,e,n,t,i)})),o=r.getAxis("x").scale,s=r.getAxis("y").scale,l=o.getExtent(),h=s.getExtent(),c=[o.parse(u.get("x0",e)),o.parse(u.get("x1",e))],p=[s.parse(u.get("y0",e)),s.parse(u.get("y1",e))];Vr(c),Vr(p);var d=!!(l[0]>c[1]||l[1]p[1]||h[1]=0},e.prototype.getOrient=function(){return"vertical"===this.get("orient")?{index:1,name:"vertical"}:{index:0,name:"horizontal"}},e.type="legend.plain",e.dependencies=["series"],e.defaultOption={z:4,show:!0,orient:"horizontal",left:"center",top:0,align:"auto",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",borderRadius:0,borderWidth:0,padding:5,itemGap:10,itemWidth:25,itemHeight:14,symbolRotate:"inherit",symbolKeepAspect:!0,inactiveColor:"#ccc",inactiveBorderColor:"#ccc",inactiveBorderWidth:"auto",itemStyle:{color:"inherit",opacity:"inherit",borderColor:"inherit",borderWidth:"auto",borderCap:"inherit",borderJoin:"inherit",borderDashOffset:"inherit",borderMiterLimit:"inherit"},lineStyle:{width:"auto",color:"inherit",inactiveColor:"#ccc",inactiveWidth:2,opacity:"inherit",type:"inherit",cap:"inherit",join:"inherit",dashOffset:"inherit",miterLimit:"inherit"},textStyle:{color:"#333"},selectedMode:!0,selector:!1,selectorLabel:{show:!0,borderRadius:10,padding:[3,5,3,5],fontSize:12,fontFamily:"sans-serif",color:"#666",borderWidth:1,borderColor:"#666"},emphasis:{selectorLabel:{show:!0,color:"#eee",backgroundColor:"#666"}},selectorPosition:"auto",selectorItemGap:7,selectorButtonGap:10,tooltip:{show:!1}},e}(Ip),pB=H,dB=E,fB=Cr,gB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.newlineDisabled=!1,n}return n(e,t),e.prototype.init=function(){this.group.add(this._contentGroup=new fB),this.group.add(this._selectorGroup=new fB),this._isFirstRender=!0},e.prototype.getContentGroup=function(){return this._contentGroup},e.prototype.getSelectorGroup=function(){return this._selectorGroup},e.prototype.render=function(t,e,n){var i=this._isFirstRender;if(this._isFirstRender=!1,this.resetInner(),t.get("show",!0)){var r=t.get("align"),o=t.get("orient");r&&"auto"!==r||(r="right"===t.get("left")&&"vertical"===o?"right":"left");var a=t.get("selector",!0),s=t.get("selectorPosition",!0);!a||s&&"auto"!==s||(s="horizontal"===o?"end":"start"),this.renderInner(r,t,e,n,a,o,s);var l=t.getBoxLayoutParams(),u={width:n.getWidth(),height:n.getHeight()},h=t.get("padding"),c=mp(l,u,h),p=this.layoutInner(t,r,c,i,a,s),d=mp(k({width:p.width,height:p.height},l),u,h);this.group.x=d.x-p.x,this.group.y=d.y-p.y,this.group.markRedraw(),this.group.add(this._backgroundEl=UE(p,t))}},e.prototype.resetInner=function(){this.getContentGroup().removeAll(),this._backgroundEl&&this.group.remove(this._backgroundEl),this.getSelectorGroup().removeAll()},e.prototype.renderInner=function(t,e,n,i,r,o,a){var s=this.getContentGroup(),l=ft(),u=e.get("selectedMode"),h=[];n.eachRawSeries((function(t){!t.get("legendHoverLink")&&h.push(t.id)})),dB(e.getData(),(function(r,o){var a=r.get("name");if(!this.newlineDisabled&&(""===a||"\n"===a)){var c=new fB;return c.newline=!0,void s.add(c)}var p=n.getSeriesByName(a)[0];if(!l.get(a)){if(p){var d=p.getData(),f=d.getVisual("legendLineStyle")||{},g=d.getVisual("legendIcon"),y=d.getVisual("style");this._createItem(p,a,o,r,e,t,f,y,g,u).on("click",pB(yB,a,null,i,h)).on("mouseover",pB(mB,p.name,null,i,h)).on("mouseout",pB(xB,p.name,null,i,h)),l.set(a,!0)}else n.eachRawSeries((function(n){if(!l.get(a)&&n.legendVisualProvider){var s=n.legendVisualProvider;if(!s.containName(a))return;var c=s.indexOfName(a),p=s.getItemVisual(c,"style"),d=s.getItemVisual(c,"legendIcon"),f=bn(p.fill);f&&0===f[3]&&(f[3]=.2,p=A(A({},p),{fill:kn(f,"rgba")})),this._createItem(n,a,o,r,e,t,{},p,d,u).on("click",pB(yB,null,a,i,h)).on("mouseover",pB(mB,null,a,i,h)).on("mouseout",pB(xB,null,a,i,h)),l.set(a,!0)}}),this);0}}),this),r&&this._createSelector(r,e,i,o,a)},e.prototype._createSelector=function(t,e,n,i,r){var o=this.getSelectorGroup();dB(t,(function(t){var i=t.type,r=new As({style:{x:0,y:0,align:"center",verticalAlign:"middle"},onclick:function(){n.dispatchAction({type:"all"===i?"legendAllSelect":"legendInverseSelect"})}});o.add(r),Wh(r,{normal:e.getModel("selectorLabel"),emphasis:e.getModel(["emphasis","selectorLabel"])},{defaultText:t.title}),Pl(r)}))},e.prototype._createItem=function(t,e,n,i,r,o,a,s,l,u){var h=t.visualDrawType,c=r.get("itemWidth"),p=r.get("itemHeight"),d=r.isSelected(e),f=i.get("symbolRotate"),g=i.get("symbolKeepAspect"),y=i.get("icon"),v=function(t,e,n,i,r,o){function a(t,e){"auto"===t.lineWidth&&(t.lineWidth=e.lineWidth>0?2:0),dB(t,(function(n,i){"inherit"===t[i]&&(t[i]=e[i])}))}var s=e.getModel("itemStyle").getItemStyle(),l=0===t.lastIndexOf("empty",0)?"fill":"stroke";s.decal=i.decal,"inherit"===s.fill&&(s.fill=i[r]);"inherit"===s.stroke&&(s.stroke=i[l]);"inherit"===s.opacity&&(s.opacity=("fill"===r?i:n).opacity);a(s,i);var u=e.getModel("lineStyle"),h=u.getLineStyle();if(a(h,n),"auto"===s.fill&&(s.fill=i.fill),"auto"===s.stroke&&(s.stroke=i.fill),"auto"===h.stroke&&(h.stroke=i.fill),!o){var c=e.get("inactiveBorderWidth"),p=s[l];s.lineWidth="auto"===c?i.lineWidth>0&&p?2:0:s.lineWidth,s.fill=e.get("inactiveColor"),s.stroke=e.get("inactiveBorderColor"),h.stroke=u.get("inactiveColor"),h.lineWidth=u.get("inactiveWidth")}return{itemStyle:s,lineStyle:h}}(l=y||l||"roundRect",i,a,s,h,d),m=new fB,x=i.getModel("textStyle");if(!U(t.getLegendIcon)||y&&"inherit"!==y){var _="inherit"===y&&t.getData().getVisual("symbol")?"inherit"===f?t.getData().getVisual("symbolRotate"):f:0;m.add(function(t){var e=t.icon||"roundRect",n=ky(e,0,0,t.itemWidth,t.itemHeight,t.itemStyle.fill,t.symbolKeepAspect);n.setStyle(t.itemStyle),n.rotation=(t.iconRotate||0)*Math.PI/180,n.setOrigin([t.itemWidth/2,t.itemHeight/2]),e.indexOf("empty")>-1&&(n.style.stroke=n.style.fill,n.style.fill="#fff",n.style.lineWidth=2);return n}({itemWidth:c,itemHeight:p,icon:l,iconRotate:_,itemStyle:v.itemStyle,lineStyle:v.lineStyle,symbolKeepAspect:g}))}else m.add(t.getLegendIcon({itemWidth:c,itemHeight:p,icon:l,iconRotate:f,itemStyle:v.itemStyle,lineStyle:v.lineStyle,symbolKeepAspect:g}));var b="left"===o?c+5:-5,w=o,S=r.get("formatter"),M=e;X(S)&&S?M=S.replace("{name}",null!=e?e:""):U(S)&&(M=S(e));var I=i.get("inactiveColor");m.add(new As({style:Yh(x,{text:M,x:b,y:p/2,fill:d?x.getTextColor():I,align:w,verticalAlign:"middle"})}));var T=new Ts({shape:m.getBoundingRect(),invisible:!0}),C=i.getModel("tooltip");return C.get("show")&&Nh({el:T,componentModel:r,itemName:e,itemTooltipOption:C.option}),m.add(T),m.eachChild((function(t){t.silent=!0})),T.silent=!u,this.getContentGroup().add(m),Pl(m),m.__legendDataIndex=n,m},e.prototype.layoutInner=function(t,e,n,i,r,o){var a=this.getContentGroup(),s=this.getSelectorGroup();vp(t.get("orient"),a,t.get("itemGap"),n.width,n.height);var l=a.getBoundingRect(),u=[-l.x,-l.y];if(s.markRedraw(),a.markRedraw(),r){vp("horizontal",s,t.get("selectorItemGap",!0));var h=s.getBoundingRect(),c=[-h.x,-h.y],p=t.get("selectorButtonGap",!0),d=t.getOrient().index,f=0===d?"width":"height",g=0===d?"height":"width",y=0===d?"y":"x";"end"===o?c[d]+=l[f]+p:u[d]+=h[f]+p,c[1-d]+=l[g]/2-h[g]/2,s.x=c[0],s.y=c[1],a.x=u[0],a.y=u[1];var v={x:0,y:0};return v[f]=l[f]+p+h[f],v[g]=Math.max(l[g],h[g]),v[y]=Math.min(0,h[y]+c[1-d]),v}return a.x=u[0],a.y=u[1],this.group.getBoundingRect()},e.prototype.remove=function(){this.getContentGroup().removeAll(),this._isFirstRender=!0},e.type="legend.plain",e}(fg);function yB(t,e,n,i){xB(t,e,n,i),n.dispatchAction({type:"legendToggleSelect",name:null!=t?t:e}),mB(t,e,n,i)}function vB(t){for(var e,n=t.getZr().storage.getDisplayList(),i=0,r=n.length;in[r],f=[-c.x,-c.y];e||(f[i]=l[s]);var g=[0,0],y=[-p.x,-p.y],v=rt(t.get("pageButtonGap",!0),t.get("itemGap",!0));d&&("end"===t.get("pageButtonPosition",!0)?y[i]+=n[r]-p[r]:g[i]+=p[r]+v);y[1-i]+=c[o]/2-p[o]/2,l.setPosition(f),u.setPosition(g),h.setPosition(y);var m={x:0,y:0};if(m[r]=d?n[r]:c[r],m[o]=Math.max(c[o],p[o]),m[a]=Math.min(0,p[a]+y[1-i]),u.__rectSize=n[r],d){var x={x:0,y:0};x[r]=Math.max(n[r]-p[r]-v,0),x[o]=m[o],u.setClipPath(new Ts({shape:x})),u.__rectSize=x[r]}else h.eachChild((function(t){t.attr({invisible:!0,silent:!0})}));var _=this._getPageInfo(t);return null!=_.pageIndex&&ih(l,{x:_.contentPosition[0],y:_.contentPosition[1]},d?t:null),this._updatePageInfoView(t,_),m},e.prototype._pageGo=function(t,e,n){var i=this._getPageInfo(e)[t];null!=i&&n.dispatchAction({type:"legendScroll",scrollDataIndex:i,legendId:e.id})},e.prototype._updatePageInfoView=function(t,e){var n=this._controllerGroup;E(["pagePrev","pageNext"],(function(i){var r=null!=e[i+"DataIndex"],o=n.childOfName(i);o&&(o.setStyle("fill",r?t.get("pageIconColor",!0):t.get("pageIconInactiveColor",!0)),o.cursor=r?"pointer":"default")}));var i=n.childOfName("pageText"),r=t.get("pageFormatter"),o=e.pageIndex,a=null!=o?o+1:0,s=e.pageCount;i&&r&&i.setStyle("text",X(r)?r.replace("{current}",null==a?"":a+"").replace("{total}",null==s?"":s+""):r({current:a,total:s}))},e.prototype._getPageInfo=function(t){var e=t.get("scrollDataIndex",!0),n=this.getContentGroup(),i=this._containerGroup.__rectSize,r=t.getOrient().index,o=TB[r],a=CB[r],s=this._findTargetItemIndex(e),l=n.children(),u=l[s],h=l.length,c=h?1:0,p={contentPosition:[n.x,n.y],pageCount:c,pageIndex:c-1,pagePrevDataIndex:null,pageNextDataIndex:null};if(!u)return p;var d=m(u);p.contentPosition[r]=-d.s;for(var f=s+1,g=d,y=d,v=null;f<=h;++f)(!(v=m(l[f]))&&y.e>g.s+i||v&&!x(v,g.s))&&(g=y.i>g.i?y:v)&&(null==p.pageNextDataIndex&&(p.pageNextDataIndex=g.i),++p.pageCount),y=v;for(f=s-1,g=d,y=d,v=null;f>=-1;--f)(v=m(l[f]))&&x(y,v.s)||!(g.i=e&&t.s<=e+i}},e.prototype._findTargetItemIndex=function(t){return this._showController?(this.getContentGroup().eachChild((function(i,r){var o=i.__legendDataIndex;null==n&&null!=o&&(n=r),o===t&&(e=r)})),null!=e?e:n):0;var e,n},e.type="legend.scroll",e}(gB);function AB(t){_m(wB),t.registerComponentModel(SB),t.registerComponentView(DB),function(t){t.registerAction("legendScroll","legendscroll",(function(t,e){var n=t.scrollDataIndex;null!=n&&e.eachComponent({mainType:"legend",subType:"scroll",query:t},(function(t){t.setScrollDataIndex(n)}))}))}(t)}var kB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="dataZoom.inside",e.defaultOption=gc(DE.defaultOption,{disabled:!1,zoomLock:!1,zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!1,preventDefaultMouseMove:!0}),e}(DE),LB=So();function PB(t,e,n){LB(t).coordSysRecordMap.each((function(t){var i=t.dataZoomInfoMap.get(e.uid);i&&(i.getRange=n)}))}function OB(t,e){if(e){t.removeKey(e.model.uid);var n=e.controller;n&&n.dispose()}}function RB(t,e){t.isDisposed()||t.dispatchAction({type:"dataZoom",animation:{easing:"cubicOut",duration:100},batch:e})}function NB(t,e,n,i){return t.coordinateSystem.containPoint([n,i])}function EB(t){t.registerProcessor(t.PRIORITY.PROCESSOR.FILTER,(function(t,e){var n=LB(e),i=n.coordSysRecordMap||(n.coordSysRecordMap=ft());i.each((function(t){t.dataZoomInfoMap=null})),t.eachComponent({mainType:"dataZoom",subType:"inside"},(function(t){E(TE(t).infoList,(function(n){var r=n.model.uid,o=i.get(r)||i.set(r,function(t,e){var n={model:e,containsPoint:H(NB,e),dispatchAction:H(RB,t),dataZoomInfoMap:null,controller:null},i=n.controller=new DI(t.getZr());return E(["pan","zoom","scrollMove"],(function(t){i.on(t,(function(e){var i=[];n.dataZoomInfoMap.each((function(r){if(e.isAvailableBehavior(r.model.option)){var o=(r.getRange||{})[t],a=o&&o(r.dzReferCoordSysInfo,n.model.mainType,n.controller,e);!r.model.get("disabled",!0)&&a&&i.push({dataZoomId:r.model.id,start:a[0],end:a[1]})}})),i.length&&n.dispatchAction(i)}))})),n}(e,n.model));(o.dataZoomInfoMap||(o.dataZoomInfoMap=ft())).set(t.uid,{dzReferCoordSysInfo:n,model:t,getRange:null})}))})),i.each((function(t){var e,n=t.controller,r=t.dataZoomInfoMap;if(r){var o=r.keys()[0];null!=o&&(e=r.get(o))}if(e){var a=function(t){var e,n="type_",i={type_true:2,type_move:1,type_false:0,type_undefined:-1},r=!0;return t.each((function(t){var o=t.model,a=!o.get("disabled",!0)&&(!o.get("zoomLock",!0)||"move");i[n+a]>i[n+e]&&(e=a),r=r&&o.get("preventDefaultMouseMove",!0)})),{controlType:e,opt:{zoomOnMouseWheel:!0,moveOnMouseMove:!0,moveOnMouseWheel:!0,preventDefaultMouseMove:!!r}}}(r);n.enable(a.controlType,a.opt),n.setPointerChecker(t.containsPoint),Dg(t,"dispatchAction",e.model.get("throttle",!0),"fixRate")}else OB(i,t)}))}))}var zB=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.type="dataZoom.inside",e}return n(e,t),e.prototype.render=function(e,n,i){t.prototype.render.apply(this,arguments),e.noTarget()?this._clear():(this.range=e.getPercentRange(),PB(i,e,{pan:W(VB.pan,this),zoom:W(VB.zoom,this),scrollMove:W(VB.scrollMove,this)}))},e.prototype.dispose=function(){this._clear(),t.prototype.dispose.apply(this,arguments)},e.prototype._clear=function(){!function(t,e){for(var n=LB(t).coordSysRecordMap,i=n.keys(),r=0;r0?s.pixelStart+s.pixelLength-s.pixel:s.pixel-s.pixelStart)/s.pixelLength*(o[1]-o[0])+o[0],u=Math.max(1/i.scale,0);o[0]=(o[0]-l)*u+l,o[1]=(o[1]-l)*u+l;var h=this.dataZoomModel.findRepresentativeAxisProxy().getMinMaxSpan();return sk(0,o,[0,100],0,h.minSpan,h.maxSpan),this.range=o,r[0]!==o[0]||r[1]!==o[1]?o:void 0}},pan:BB((function(t,e,n,i,r,o){var a=FB[i]([o.oldX,o.oldY],[o.newX,o.newY],e,r,n);return a.signal*(t[1]-t[0])*a.pixel/a.pixelLength})),scrollMove:BB((function(t,e,n,i,r,o){return FB[i]([0,0],[o.scrollDelta,o.scrollDelta],e,r,n).signal*(t[1]-t[0])*o.scrollDelta}))};function BB(t){return function(e,n,i,r){var o=this.range,a=o.slice(),s=e.axisModels[0];if(s)return sk(t(a,s,e,n,i,r),a,[0,100],"all"),this.range=a,o[0]!==a[0]||o[1]!==a[1]?a:void 0}}var FB={grid:function(t,e,n,i,r){var o=n.axis,a={},s=r.model.coordinateSystem.getRect();return t=t||[0,0],"x"===o.dim?(a.pixel=e[0]-t[0],a.pixelLength=s.width,a.pixelStart=s.x,a.signal=o.inverse?1:-1):(a.pixel=e[1]-t[1],a.pixelLength=s.height,a.pixelStart=s.y,a.signal=o.inverse?-1:1),a},polar:function(t,e,n,i,r){var o=n.axis,a={},s=r.model.coordinateSystem,l=s.getRadiusAxis().getExtent(),u=s.getAngleAxis().getExtent();return t=t?s.pointToCoord(t):[0,0],e=s.pointToCoord(e),"radiusAxis"===n.mainType?(a.pixel=e[0]-t[0],a.pixelLength=l[1]-l[0],a.pixelStart=l[0],a.signal=o.inverse?1:-1):(a.pixel=e[1]-t[1],a.pixelLength=u[1]-u[0],a.pixelStart=u[0],a.signal=o.inverse?-1:1),a},singleAxis:function(t,e,n,i,r){var o=n.axis,a=r.model.coordinateSystem.getRect(),s={};return t=t||[0,0],"horizontal"===o.orient?(s.pixel=e[0]-t[0],s.pixelLength=a.width,s.pixelStart=a.x,s.signal=o.inverse?1:-1):(s.pixel=e[1]-t[1],s.pixelLength=a.height,s.pixelStart=a.y,s.signal=o.inverse?-1:1),s}};function GB(t){VE(t),t.registerComponentModel(kB),t.registerComponentView(zB),EB(t)}var WB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.type="dataZoom.slider",e.layoutMode="box",e.defaultOption=gc(DE.defaultOption,{show:!0,right:"ph",top:"ph",width:"ph",height:"ph",left:null,bottom:null,borderColor:"#d2dbee",borderRadius:3,backgroundColor:"rgba(47,69,84,0)",dataBackground:{lineStyle:{color:"#d2dbee",width:.5},areaStyle:{color:"#d2dbee",opacity:.2}},selectedDataBackground:{lineStyle:{color:"#8fb0f7",width:.5},areaStyle:{color:"#8fb0f7",opacity:.2}},fillerColor:"rgba(135,175,274,0.2)",handleIcon:"path://M-9.35,34.56V42m0-40V9.5m-2,0h4a2,2,0,0,1,2,2v21a2,2,0,0,1-2,2h-4a2,2,0,0,1-2-2v-21A2,2,0,0,1-11.35,9.5Z",handleSize:"100%",handleStyle:{color:"#fff",borderColor:"#ACB8D1"},moveHandleSize:7,moveHandleIcon:"path://M-320.9-50L-320.9-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-348-41-339-50-320.9-50z M-212.3-50L-212.3-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-239.4-41-230.4-50-212.3-50z M-103.7-50L-103.7-50c18.1,0,27.1,9,27.1,27.1V85.7c0,18.1-9,27.1-27.1,27.1l0,0c-18.1,0-27.1-9-27.1-27.1V-22.9C-130.9-41-121.8-50-103.7-50z",moveHandleStyle:{color:"#D2DBEE",opacity:.7},showDetail:!0,showDataShadow:"auto",realtime:!0,zoomLock:!1,textStyle:{color:"#6E7079"},brushSelect:!0,brushStyle:{color:"rgba(135,175,274,0.15)"},emphasis:{handleStyle:{borderColor:"#8FB0F7"},moveHandleStyle:{color:"#8FB0F7"}}}),e}(DE),HB=Ts,YB="horizontal",UB="vertical",XB=["line","bar","candlestick","scatter"],ZB={easing:"cubicOut",duration:100,delay:0},jB=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._displayables={},n}return n(e,t),e.prototype.init=function(t,e){this.api=e,this._onBrush=W(this._onBrush,this),this._onBrushEnd=W(this._onBrushEnd,this)},e.prototype.render=function(e,n,i,r){if(t.prototype.render.apply(this,arguments),Dg(this,"_dispatchZoomAction",e.get("throttle"),"fixRate"),this._orient=e.getOrient(),!1!==e.get("show")){if(e.noTarget())return this._clear(),void this.group.removeAll();r&&"dataZoom"===r.type&&r.from===this.uid||this._buildView(),this._updateView()}else this.group.removeAll()},e.prototype.dispose=function(){this._clear(),t.prototype.dispose.apply(this,arguments)},e.prototype._clear=function(){Ag(this,"_dispatchZoomAction");var t=this.api.getZr();t.off("mousemove",this._onBrush),t.off("mouseup",this._onBrushEnd)},e.prototype._buildView=function(){var t=this.group;t.removeAll(),this._brushing=!1,this._displayables.brushRect=null,this._resetLocation(),this._resetInterval();var e=this._displayables.sliderGroup=new Cr;this._renderBackground(),this._renderHandle(),this._renderDataShadow(),t.add(e),this._positionGroup()},e.prototype._resetLocation=function(){var t=this.dataZoomModel,e=this.api,n=t.get("brushSelect")?7:0,i=this._findCoordRect(),r={width:e.getWidth(),height:e.getHeight()},o=this._orient===YB?{right:r.width-i.x-i.width,top:r.height-30-7-n,width:i.width,height:30}:{right:7,top:i.y,width:30,height:i.height},a=wp(t.option);E(["right","top","width","height"],(function(t){"ph"===a[t]&&(a[t]=o[t])}));var s=mp(a,r);this._location={x:s.x,y:s.y},this._size=[s.width,s.height],this._orient===UB&&this._size.reverse()},e.prototype._positionGroup=function(){var t=this.group,e=this._location,n=this._orient,i=this.dataZoomModel.getFirstTargetAxisModel(),r=i&&i.get("inverse"),o=this._displayables.sliderGroup,a=(this._dataShadowInfo||{}).otherAxisInverse;o.attr(n!==YB||r?n===YB&&r?{scaleY:a?1:-1,scaleX:-1}:n!==UB||r?{scaleY:a?-1:1,scaleX:-1,rotation:Math.PI/2}:{scaleY:a?-1:1,scaleX:1,rotation:Math.PI/2}:{scaleY:a?1:-1,scaleX:1});var s=t.getBoundingRect([o]);t.x=e.x-s.x,t.y=e.y-s.y,t.markRedraw()},e.prototype._getViewExtent=function(){return[0,this._size[0]]},e.prototype._renderBackground=function(){var t=this.dataZoomModel,e=this._size,n=this._displayables.sliderGroup,i=t.get("brushSelect");n.add(new HB({silent:!0,shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:t.get("backgroundColor")},z2:-40}));var r=new HB({shape:{x:0,y:0,width:e[0],height:e[1]},style:{fill:"transparent"},z2:0,onclick:W(this._onClickPanel,this)}),o=this.api.getZr();i?(r.on("mousedown",this._onBrushStart,this),r.cursor="crosshair",o.on("mousemove",this._onBrush),o.on("mouseup",this._onBrushEnd)):(o.off("mousemove",this._onBrush),o.off("mouseup",this._onBrushEnd)),n.add(r)},e.prototype._renderDataShadow=function(){var t=this._dataShadowInfo=this._prepareDataShadowInfo();if(this._displayables.dataShadowSegs=[],t){var e=this._size,n=this._shadowSize||[],i=t.series,r=i.getRawData(),o=i.getShadowDim?i.getShadowDim():t.otherDim;if(null!=o){var a=this._shadowPolygonPts,s=this._shadowPolylinePts;if(r!==this._shadowData||o!==this._shadowDim||e[0]!==n[0]||e[1]!==n[1]){var l=r.getDataExtent(o),u=.3*(l[1]-l[0]);l=[l[0]-u,l[1]+u];var h,c=[0,e[1]],p=[0,e[0]],d=[[e[0],0],[0,0]],f=[],g=p[1]/(r.count()-1),y=0,v=Math.round(r.count()/e[0]);r.each([o],(function(t,e){if(v>0&&e%v)y+=g;else{var n=null==t||isNaN(t)||""===t,i=n?0:Nr(t,l,c,!0);n&&!h&&e?(d.push([d[d.length-1][0],0]),f.push([f[f.length-1][0],0])):!n&&h&&(d.push([y,0]),f.push([y,0])),d.push([y,i]),f.push([y,i]),y+=g,h=n}})),a=this._shadowPolygonPts=d,s=this._shadowPolylinePts=f}this._shadowData=r,this._shadowDim=o,this._shadowSize=[e[0],e[1]];for(var m=this.dataZoomModel,x=0;x<3;x++){var _=b(1===x);this._displayables.sliderGroup.add(_),this._displayables.dataShadowSegs.push(_)}}}function b(t){var e=m.getModel(t?"selectedDataBackground":"dataBackground"),n=new Cr,i=new Lu({shape:{points:a},segmentIgnoreThreshold:1,style:e.getModel("areaStyle").getAreaStyle(),silent:!0,z2:-20}),r=new Ou({shape:{points:s},segmentIgnoreThreshold:1,style:e.getModel("lineStyle").getLineStyle(),silent:!0,z2:-19});return n.add(i),n.add(r),n}},e.prototype._prepareDataShadowInfo=function(){var t=this.dataZoomModel,e=t.get("showDataShadow");if(!1!==e){var n,i=this.ecModel;return t.eachTargetAxis((function(r,o){E(t.getAxisProxy(r,o).getTargetSeriesModels(),(function(t){if(!(n||!0!==e&&P(XB,t.get("type"))<0)){var a,s=i.getComponent(ME(r),o).axis,l={x:"y",y:"x",radius:"angle",angle:"radius"}[r],u=t.coordinateSystem;null!=l&&u.getOtherAxis&&(a=u.getOtherAxis(s).inverse),l=t.getData().mapDimension(l),n={thisAxis:s,series:t,thisDim:r,otherDim:l,otherAxisInverse:a}}}),this)}),this),n}},e.prototype._renderHandle=function(){var t=this.group,e=this._displayables,n=e.handles=[null,null],i=e.handleLabels=[null,null],r=this._displayables.sliderGroup,o=this._size,a=this.dataZoomModel,s=this.api,l=a.get("borderRadius")||0,u=a.get("brushSelect"),h=e.filler=new HB({silent:u,style:{fill:a.get("fillerColor")},textConfig:{position:"inside"}});r.add(h),r.add(new HB({silent:!0,subPixelOptimize:!0,shape:{x:0,y:0,width:o[0],height:o[1],r:l},style:{stroke:a.get("dataBackgroundColor")||a.get("borderColor"),lineWidth:1,fill:"rgba(0,0,0,0)"}})),E([0,1],(function(e){var o=a.get("handleIcon");!Cy[o]&&o.indexOf("path://")<0&&o.indexOf("image://")<0&&(o="path://"+o);var s=ky(o,-1,0,2,2,null,!0);s.attr({cursor:qB(this._orient),draggable:!0,drift:W(this._onDragMove,this,e),ondragend:W(this._onDragEnd,this),onmouseover:W(this._showDataInfo,this,!0),onmouseout:W(this._showDataInfo,this,!1),z2:5});var l=s.getBoundingRect(),u=a.get("handleSize");this._handleHeight=Er(u,this._size[1]),this._handleWidth=l.width/l.height*this._handleHeight,s.setStyle(a.getModel("handleStyle").getItemStyle()),s.style.strokeNoScale=!0,s.rectHover=!0,s.ensureState("emphasis").style=a.getModel(["emphasis","handleStyle"]).getItemStyle(),Pl(s);var h=a.get("handleColor");null!=h&&(s.style.fill=h),r.add(n[e]=s);var c=a.getModel("textStyle");t.add(i[e]=new As({silent:!0,invisible:!0,style:Yh(c,{x:0,y:0,text:"",verticalAlign:"middle",align:"center",fill:c.getTextColor(),font:c.getFont()}),z2:10}))}),this);var c=h;if(u){var p=Er(a.get("moveHandleSize"),o[1]),d=e.moveHandle=new Ts({style:a.getModel("moveHandleStyle").getItemStyle(),silent:!0,shape:{r:[0,0,2,2],y:o[1]-.5,height:p}}),f=.8*p,g=e.moveHandleIcon=ky(a.get("moveHandleIcon"),-f/2,-f/2,f,f,"#fff",!0);g.silent=!0,g.y=o[1]+p/2-.5,d.ensureState("emphasis").style=a.getModel(["emphasis","moveHandleStyle"]).getItemStyle();var y=Math.min(o[1]/2,Math.max(p,10));(c=e.moveZone=new Ts({invisible:!0,shape:{y:o[1]-y,height:p+y}})).on("mouseover",(function(){s.enterEmphasis(d)})).on("mouseout",(function(){s.leaveEmphasis(d)})),r.add(d),r.add(g),r.add(c)}c.attr({draggable:!0,cursor:qB(this._orient),drift:W(this._onDragMove,this,"all"),ondragstart:W(this._showDataInfo,this,!0),ondragend:W(this._onDragEnd,this),onmouseover:W(this._showDataInfo,this,!0),onmouseout:W(this._showDataInfo,this,!1)})},e.prototype._resetInterval=function(){var t=this._range=this.dataZoomModel.getPercentRange(),e=this._getViewExtent();this._handleEnds=[Nr(t[0],[0,100],e,!0),Nr(t[1],[0,100],e,!0)]},e.prototype._updateInterval=function(t,e){var n=this.dataZoomModel,i=this._handleEnds,r=this._getViewExtent(),o=n.findRepresentativeAxisProxy().getMinMaxSpan(),a=[0,100];sk(e,i,r,n.get("zoomLock")?"all":t,null!=o.minSpan?Nr(o.minSpan,a,r,!0):null,null!=o.maxSpan?Nr(o.maxSpan,a,r,!0):null);var s=this._range,l=this._range=Vr([Nr(i[0],r,a,!0),Nr(i[1],r,a,!0)]);return!s||s[0]!==l[0]||s[1]!==l[1]},e.prototype._updateView=function(t){var e=this._displayables,n=this._handleEnds,i=Vr(n.slice()),r=this._size;E([0,1],(function(t){var i=e.handles[t],o=this._handleHeight;i.attr({scaleX:o/2,scaleY:o/2,x:n[t]+(t?-1:1),y:r[1]/2-o/2})}),this),e.filler.setShape({x:i[0],y:0,width:i[1]-i[0],height:r[1]});var o={x:i[0],width:i[1]-i[0]};e.moveHandle&&(e.moveHandle.setShape(o),e.moveZone.setShape(o),e.moveZone.getBoundingRect(),e.moveHandleIcon&&e.moveHandleIcon.attr("x",o.x+o.width/2));for(var a=e.dataShadowSegs,s=[0,i[0],i[1],r[0]],l=0;le[0]||n[1]<0||n[1]>e[1])){var i=this._handleEnds,r=(i[0]+i[1])/2,o=this._updateInterval("all",n[0]-r);this._updateView(),o&&this._dispatchZoomAction(!1)}},e.prototype._onBrushStart=function(t){var e=t.offsetX,n=t.offsetY;this._brushStart=new Ji(e,n),this._brushing=!0,this._brushStartTime=+new Date},e.prototype._onBrushEnd=function(t){if(this._brushing){var e=this._displayables.brushRect;if(this._brushing=!1,e){e.attr("ignore",!0);var n=e.shape;if(!(+new Date-this._brushStartTime<200&&Math.abs(n.width)<5)){var i=this._getViewExtent(),r=[0,100];this._range=Vr([Nr(n.x,i,r,!0),Nr(n.x+n.width,i,r,!0)]),this._handleEnds=[n.x,n.x+n.width],this._updateView(),this._dispatchZoomAction(!1)}}}},e.prototype._onBrush=function(t){this._brushing&&(se(t.event),this._updateBrushRect(t.offsetX,t.offsetY))},e.prototype._updateBrushRect=function(t,e){var n=this._displayables,i=this.dataZoomModel,r=n.brushRect;r||(r=n.brushRect=new HB({silent:!0,style:i.getModel("brushStyle").getItemStyle()}),n.sliderGroup.add(r)),r.attr("ignore",!1);var o=this._brushStart,a=this._displayables.sliderGroup,s=a.transformCoordToLocal(t,e),l=a.transformCoordToLocal(o.x,o.y),u=this._size;s[0]=Math.max(Math.min(u[0],s[0]),0),r.setShape({x:l[0],y:0,width:s[0]-l[0],height:u[1]})},e.prototype._dispatchZoomAction=function(t){var e=this._range;this.api.dispatchAction({type:"dataZoom",from:this.uid,dataZoomId:this.dataZoomModel.id,animation:t?ZB:null,start:e[0],end:e[1]})},e.prototype._findCoordRect=function(){var t,e=TE(this.dataZoomModel).infoList;if(!t&&e.length){var n=e[0].model.coordinateSystem;t=n.getRect&&n.getRect()}if(!t){var i=this.api.getWidth(),r=this.api.getHeight();t={x:.2*i,y:.2*r,width:.6*i,height:.6*r}}return t},e.type="dataZoom.slider",e}(LE);function qB(t){return"vertical"===t?"ns-resize":"ew-resize"}function KB(t){t.registerComponentModel(WB),t.registerComponentView(jB),VE(t)}var $B=function(t,e,n){var i=T((JB[t]||{})[e]);return n&&Y(i)?i[i.length-1]:i},JB={color:{active:["#006edd","#e0ffff"],inactive:["rgba(0,0,0,0)"]},colorHue:{active:[0,360],inactive:[0,0]},colorSaturation:{active:[.3,1],inactive:[0,0]},colorLightness:{active:[.9,.5],inactive:[0,0]},colorAlpha:{active:[.3,1],inactive:[0,0]},opacity:{active:[.3,1],inactive:[0,0]},symbol:{active:["circle","roundRect","diamond"],inactive:["none"]},symbolSize:{active:[10,50],inactive:[0,0]}},QB=eD.mapVisual,tF=eD.eachVisual,eF=Y,nF=E,iF=Vr,rF=Nr,oF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n.stateList=["inRange","outOfRange"],n.replacableOptionKeys=["inRange","outOfRange","target","controller","color"],n.layoutMode={type:"box",ignoreSize:!0},n.dataBound=[-1/0,1/0],n.targetVisuals={},n.controllerVisuals={},n}return n(e,t),e.prototype.init=function(t,e,n){this.mergeDefaultAndTheme(t,n)},e.prototype.optionUpdated=function(t,e){var n=this.option;!e&&tV(n,t,this.replacableOptionKeys),this.textStyleModel=this.getModel("textStyle"),this.resetItemSize(),this.completeVisualOption()},e.prototype.resetVisual=function(t){var e=this.stateList;t=W(t,this),this.controllerVisuals=Qz(this.option.controller,e,t),this.targetVisuals=Qz(this.option.target,e,t)},e.prototype.getItemSymbol=function(){return null},e.prototype.getTargetSeriesIndices=function(){var t=this.option.seriesIndex,e=[];return null==t||"all"===t?this.ecModel.eachSeries((function(t,n){e.push(n)})):e=ho(t),e},e.prototype.eachTargetSeries=function(t,e){E(this.getTargetSeriesIndices(),(function(n){var i=this.ecModel.getSeriesByIndex(n);i&&t.call(e,i)}),this)},e.prototype.isTargetSeries=function(t){var e=!1;return this.eachTargetSeries((function(n){n===t&&(e=!0)})),e},e.prototype.formatValueText=function(t,e,n){var i,r=this.option,o=r.precision,a=this.dataBound,s=r.formatter;n=n||["<",">"],Y(t)&&(t=t.slice(),i=!0);var l=e?t:i?[u(t[0]),u(t[1])]:u(t);return X(s)?s.replace("{value}",i?l[0]:l).replace("{value2}",i?l[1]:l):U(s)?i?s(t[0],t[1]):s(t):i?t[0]===a[0]?n[0]+" "+l[1]:t[1]===a[1]?n[1]+" "+l[0]:l[0]+" - "+l[1]:l;function u(t){return t===a[0]?"min":t===a[1]?"max":(+t).toFixed(Math.min(o,20))}},e.prototype.resetExtent=function(){var t=this.option,e=iF([t.min,t.max]);this._dataExtent=e},e.prototype.getDataDimensionIndex=function(t){var e=this.option.dimension;if(null!=e)return t.getDimensionIndex(e);for(var n=t.dimensions,i=n.length-1;i>=0;i--){var r=n[i],o=t.getDimensionInfo(r);if(!o.isCalculationCoord)return o.storeDimIndex}},e.prototype.getExtent=function(){return this._dataExtent.slice()},e.prototype.completeVisualOption=function(){var t=this.ecModel,e=this.option,n={inRange:e.inRange,outOfRange:e.outOfRange},i=e.target||(e.target={}),r=e.controller||(e.controller={});C(i,n),C(r,n);var o=this.isCategory();function a(n){eF(e.color)&&!n.inRange&&(n.inRange={color:e.color.slice().reverse()}),n.inRange=n.inRange||{color:t.get("gradientColor")}}a.call(this,i),a.call(this,r),function(t,e,n){var i=t[e],r=t[n];i&&!r&&(r=t[n]={},nF(i,(function(t,e){if(eD.isValidType(e)){var n=$B(e,"inactive",o);null!=n&&(r[e]=n,"color"!==e||r.hasOwnProperty("opacity")||r.hasOwnProperty("colorAlpha")||(r.opacity=[0,0]))}})))}.call(this,i,"inRange","outOfRange"),function(t){var e=(t.inRange||{}).symbol||(t.outOfRange||{}).symbol,n=(t.inRange||{}).symbolSize||(t.outOfRange||{}).symbolSize,i=this.get("inactiveColor"),r=this.getItemSymbol()||"roundRect";nF(this.stateList,(function(a){var s=this.itemSize,l=t[a];l||(l=t[a]={color:o?i:[i]}),null==l.symbol&&(l.symbol=e&&T(e)||(o?r:[r])),null==l.symbolSize&&(l.symbolSize=n&&T(n)||(o?s[0]:[s[0],s[0]])),l.symbol=QB(l.symbol,(function(t){return"none"===t?r:t}));var u=l.symbolSize;if(null!=u){var h=-1/0;tF(u,(function(t){t>h&&(h=t)})),l.symbolSize=QB(u,(function(t){return rF(t,[0,h],[0,s[0]],!0)}))}}),this)}.call(this,r)},e.prototype.resetItemSize=function(){this.itemSize=[parseFloat(this.get("itemWidth")),parseFloat(this.get("itemHeight"))]},e.prototype.isCategory=function(){return!!this.option.categories},e.prototype.setSelected=function(t){},e.prototype.getSelected=function(){return null},e.prototype.getValueState=function(t){return null},e.prototype.getVisualMeta=function(t){return null},e.type="visualMap",e.dependencies=["series"],e.defaultOption={show:!0,z:4,seriesIndex:"all",min:0,max:200,left:0,right:null,top:null,bottom:0,itemWidth:null,itemHeight:null,inverse:!1,orient:"vertical",backgroundColor:"rgba(0,0,0,0)",borderColor:"#ccc",contentColor:"#5793f3",inactiveColor:"#aaa",borderWidth:0,padding:5,textGap:10,precision:0,textStyle:{color:"#333"}},e}(Ip),aF=[20,140],sF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.optionUpdated=function(e,n){t.prototype.optionUpdated.apply(this,arguments),this.resetExtent(),this.resetVisual((function(t){t.mappingMethod="linear",t.dataExtent=this.getExtent()})),this._resetRange()},e.prototype.resetItemSize=function(){t.prototype.resetItemSize.apply(this,arguments);var e=this.itemSize;(null==e[0]||isNaN(e[0]))&&(e[0]=aF[0]),(null==e[1]||isNaN(e[1]))&&(e[1]=aF[1])},e.prototype._resetRange=function(){var t=this.getExtent(),e=this.option.range;!e||e.auto?(t.auto=1,this.option.range=t):Y(e)&&(e[0]>e[1]&&e.reverse(),e[0]=Math.max(e[0],t[0]),e[1]=Math.min(e[1],t[1]))},e.prototype.completeVisualOption=function(){t.prototype.completeVisualOption.apply(this,arguments),E(this.stateList,(function(t){var e=this.option.controller[t].symbolSize;e&&e[0]!==e[1]&&(e[0]=e[1]/3)}),this)},e.prototype.setSelected=function(t){this.option.range=t.slice(),this._resetRange()},e.prototype.getSelected=function(){var t=this.getExtent(),e=Vr((this.get("range")||[]).slice());return e[0]>t[1]&&(e[0]=t[1]),e[1]>t[1]&&(e[1]=t[1]),e[0]=n[1]||t<=e[1])?"inRange":"outOfRange"},e.prototype.findTargetDataIndices=function(t){var e=[];return this.eachTargetSeries((function(n){var i=[],r=n.getData();r.each(this.getDataDimensionIndex(r),(function(e,n){t[0]<=e&&e<=t[1]&&i.push(n)}),this),e.push({seriesId:n.id,dataIndex:i})}),this),e},e.prototype.getVisualMeta=function(t){var e=lF(this,"outOfRange",this.getExtent()),n=lF(this,"inRange",this.option.range.slice()),i=[];function r(e,n){i.push({value:e,color:t(e,n)})}for(var o=0,a=0,s=n.length,l=e.length;at[1])break;n.push({color:this.getControllerVisual(o,"color",e),offset:r/100})}return n.push({color:this.getControllerVisual(t[1],"color",e),offset:1}),n},e.prototype._createBarPoints=function(t,e){var n=this.visualMapModel.itemSize;return[[n[0]-e[0],t[0]],[n[0],t[0]],[n[0],t[1]],[n[0]-e[1],t[1]]]},e.prototype._createBarGroup=function(t){var e=this._orient,n=this.visualMapModel.get("inverse");return new Cr("horizontal"!==e||n?"horizontal"===e&&n?{scaleX:"bottom"===t?-1:1,rotation:-Math.PI/2}:"vertical"!==e||n?{scaleX:"left"===t?1:-1}:{scaleX:"left"===t?1:-1,scaleY:-1}:{scaleX:"bottom"===t?1:-1,rotation:Math.PI/2})},e.prototype._updateHandle=function(t,e){if(this._useHandle){var n=this._shapes,i=this.visualMapModel,r=n.handleThumbs,o=n.handleLabels,a=i.itemSize,s=i.getExtent();fF([0,1],(function(l){var u=r[l];u.setStyle("fill",e.handlesColor[l]),u.y=t[l];var h=dF(t[l],[0,a[1]],s,!0),c=this.getControllerVisual(h,"symbolSize");u.scaleX=u.scaleY=c/a[0],u.x=a[0]-c/2;var p=Ih(n.handleLabelPoints[l],Mh(u,this.group));o[l].setStyle({x:p[0],y:p[1],text:i.formatValueText(this._dataInterval[l]),verticalAlign:"middle",align:"vertical"===this._orient?this._applyTransform("left",n.mainGroup):"center"})}),this)}},e.prototype._showIndicator=function(t,e,n,i){var r=this.visualMapModel,o=r.getExtent(),a=r.itemSize,s=[0,a[1]],l=this._shapes,u=l.indicator;if(u){u.attr("invisible",!1);var h=this.getControllerVisual(t,"color",{convertOpacityToAlpha:!0}),c=this.getControllerVisual(t,"symbolSize"),p=dF(t,o,s,!0),d=a[0]-c/2,f={x:u.x,y:u.y};u.y=p,u.x=d;var g=Ih(l.indicatorLabelPoint,Mh(u,this.group)),y=l.indicatorLabel;y.attr("invisible",!1);var v=this._applyTransform("left",l.mainGroup),m="horizontal"===this._orient;y.setStyle({text:(n||"")+r.formatValueText(e),verticalAlign:m?v:"middle",align:m?"center":v});var x={x:d,y:p,style:{fill:h}},_={style:{x:g[0],y:g[1]}};if(r.ecModel.isAnimationEnabled()&&!this._firstShowIndicator){var b={duration:100,easing:"cubicInOut",additive:!0};u.x=f.x,u.y=f.y,u.animateTo(x,b),y.animateTo(_,b)}else u.attr(x),y.attr(_);this._firstShowIndicator=!1;var w=this._shapes.handleLabels;if(w)for(var S=0;Sr[1]&&(u[1]=1/0),e&&(u[0]===-1/0?this._showIndicator(l,u[1],"< ",a):u[1]===1/0?this._showIndicator(l,u[0],"> ",a):this._showIndicator(l,l,"≈ ",a));var h=this._hoverLinkDataIndices,c=[];(e||xF(n))&&(c=this._hoverLinkDataIndices=n.findTargetDataIndices(u));var p=function(t,e){var n={},i={};return r(t||[],n),r(e||[],i,n),[o(n),o(i)];function r(t,e,n){for(var i=0,r=t.length;i=0&&(r.dimension=o,i.push(r))}})),t.getData().setVisual("visualMeta",i)}}];function MF(t,e,n,i){for(var r=e.targetVisuals[i],o=eD.prepareVisualTypes(r),a={color:fy(t.getData(),"color")},s=0,l=o.length;s0:t.splitNumber>0)&&!t.calculable?"piecewise":"continuous"})),t.registerAction(bF,wF),E(SF,(function(e){t.registerVisual(t.PRIORITY.VISUAL.COMPONENT,e)})),t.registerPreprocessor(TF))}function kF(t){t.registerComponentModel(sF),t.registerComponentView(vF),AF(t)}var LF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n._pieceList=[],n}return n(e,t),e.prototype.optionUpdated=function(e,n){t.prototype.optionUpdated.apply(this,arguments),this.resetExtent();var i=this._mode=this._determineMode();this._pieceList=[],PF[this._mode].call(this,this._pieceList),this._resetSelected(e,n);var r=this.option.categories;this.resetVisual((function(t,e){"categories"===i?(t.mappingMethod="category",t.categories=T(r)):(t.dataExtent=this.getExtent(),t.mappingMethod="piecewise",t.pieceList=z(this._pieceList,(function(t){return t=T(t),"inRange"!==e&&(t.visual=null),t})))}))},e.prototype.completeVisualOption=function(){var e=this.option,n={},i=eD.listVisualTypes(),r=this.isCategory();function o(t,e,n){return t&&t[e]&&t[e].hasOwnProperty(n)}E(e.pieces,(function(t){E(i,(function(e){t.hasOwnProperty(e)&&(n[e]=1)}))})),E(n,(function(t,n){var i=!1;E(this.stateList,(function(t){i=i||o(e,t,n)||o(e.target,t,n)}),this),!i&&E(this.stateList,(function(t){(e[t]||(e[t]={}))[n]=$B(n,"inRange"===t?"active":"inactive",r)}))}),this),t.prototype.completeVisualOption.apply(this,arguments)},e.prototype._resetSelected=function(t,e){var n=this.option,i=this._pieceList,r=(e?n:t).selected||{};if(n.selected=r,E(i,(function(t,e){var n=this.getSelectedMapKey(t);r.hasOwnProperty(n)||(r[n]=!0)}),this),"single"===n.selectedMode){var o=!1;E(i,(function(t,e){var n=this.getSelectedMapKey(t);r[n]&&(o?r[n]=!1:o=!0)}),this)}},e.prototype.getItemSymbol=function(){return this.get("itemSymbol")},e.prototype.getSelectedMapKey=function(t){return"categories"===this._mode?t.value+"":t.index+""},e.prototype.getPieceList=function(){return this._pieceList},e.prototype._determineMode=function(){var t=this.option;return t.pieces&&t.pieces.length>0?"pieces":this.option.categories?"categories":"splitNumber"},e.prototype.setSelected=function(t){this.option.selected=T(t)},e.prototype.getValueState=function(t){var e=eD.findPieceIndex(t,this._pieceList);return null!=e&&this.option.selected[this.getSelectedMapKey(this._pieceList[e])]?"inRange":"outOfRange"},e.prototype.findTargetDataIndices=function(t){var e=[],n=this._pieceList;return this.eachTargetSeries((function(i){var r=[],o=i.getData();o.each(this.getDataDimensionIndex(o),(function(e,i){eD.findPieceIndex(e,n)===t&&r.push(i)}),this),e.push({seriesId:i.id,dataIndex:r})}),this),e},e.prototype.getRepresentValue=function(t){var e;if(this.isCategory())e=t.value;else if(null!=t.value)e=t.value;else{var n=t.interval||[];e=n[0]===-1/0&&n[1]===1/0?0:(n[0]+n[1])/2}return e},e.prototype.getVisualMeta=function(t){if(!this.isCategory()){var e=[],n=["",""],i=this,r=this._pieceList.slice();if(r.length){var o=r[0].interval[0];o!==-1/0&&r.unshift({interval:[-1/0,o]}),(o=r[r.length-1].interval[1])!==1/0&&r.push({interval:[o,1/0]})}else r.push({interval:[-1/0,1/0]});var a=-1/0;return E(r,(function(t){var e=t.interval;e&&(e[0]>a&&s([a,e[0]],"outOfRange"),s(e.slice()),a=e[1])}),this),{stops:e,outerColors:n}}function s(r,o){var a=i.getRepresentValue({interval:r});o||(o=i.getValueState(a));var s=t(a,o);r[0]===-1/0?n[0]=s:r[1]===1/0?n[1]=s:e.push({value:r[0],color:s},{value:r[1],color:s})}},e.type="visualMap.piecewise",e.defaultOption=gc(oF.defaultOption,{selected:null,minOpen:!1,maxOpen:!1,align:"auto",itemWidth:20,itemHeight:14,itemSymbol:"roundRect",pieces:null,categories:null,splitNumber:5,selectedMode:"multiple",itemGap:10,hoverLink:!0}),e}(oF),PF={splitNumber:function(t){var e=this.option,n=Math.min(e.precision,20),i=this.getExtent(),r=e.splitNumber;r=Math.max(parseInt(r,10),1),e.splitNumber=r;for(var o=(i[1]-i[0])/r;+o.toFixed(n)!==o&&n<5;)n++;e.precision=n,o=+o.toFixed(n),e.minOpen&&t.push({interval:[-1/0,i[0]],close:[0,0]});for(var a=0,s=i[0];a","≥"][e[0]]];t.text=t.text||this.formatValueText(null!=t.value?t.value:t.interval,!1,n)}),this)}};function OF(t,e){var n=t.inverse;("vertical"===t.orient?!n:n)&&e.reverse()}var RF=function(t){function e(){var n=null!==t&&t.apply(this,arguments)||this;return n.type=e.type,n}return n(e,t),e.prototype.doRender=function(){var t=this.group;t.removeAll();var e=this.visualMapModel,n=e.get("textGap"),i=e.textStyleModel,r=i.getFont(),o=i.getTextColor(),a=this._getItemAlign(),s=e.itemSize,l=this._getViewData(),u=l.endsText,h=it(e.get("showLabel",!0),!u);u&&this._renderEndsText(t,u[0],s,h,a),E(l.viewPieceList,(function(i){var l=i.piece,u=new Cr;u.onclick=W(this._onItemClick,this,l),this._enableHoverLink(u,i.indexInModelPieceList);var c=e.getRepresentValue(l);if(this._createItemSymbol(u,c,[0,0,s[0],s[1]]),h){var p=this.visualMapModel.getValueState(c);u.add(new As({style:{x:"right"===a?-n:s[0]+n,y:s[1]/2,text:l.text,verticalAlign:"middle",align:a,font:r,fill:o,opacity:"outOfRange"===p?.5:1}}))}t.add(u)}),this),u&&this._renderEndsText(t,u[1],s,h,a),vp(e.get("orient"),t,e.get("itemGap")),this.renderBackground(t),this.positionGroup(t)},e.prototype._enableHoverLink=function(t,e){var n=this;t.on("mouseover",(function(){return i("highlight")})).on("mouseout",(function(){return i("downplay")}));var i=function(t){var i=n.visualMapModel;i.option.hoverLink&&n.api.dispatchAction({type:t,batch:pF(i.findTargetDataIndices(e),i)})}},e.prototype._getItemAlign=function(){var t=this.visualMapModel,e=t.option;if("vertical"===e.orient)return cF(t,this.api,t.itemSize);var n=e.align;return n&&"auto"!==n||(n="left"),n},e.prototype._renderEndsText=function(t,e,n,i,r){if(e){var o=new Cr,a=this.visualMapModel.textStyleModel;o.add(new As({style:{x:i?"right"===r?n[0]:0:n[0]/2,y:n[1]/2,verticalAlign:"middle",align:i?r:"center",text:e,font:a.getFont(),fill:a.getTextColor()}})),t.add(o)}},e.prototype._getViewData=function(){var t=this.visualMapModel,e=z(t.getPieceList(),(function(t,e){return{piece:t,indexInModelPieceList:e}})),n=t.get("text"),i=t.get("orient"),r=t.get("inverse");return("horizontal"===i?r:!r)?e.reverse():n&&(n=n.slice().reverse()),{viewPieceList:e,endsText:n}},e.prototype._createItemSymbol=function(t,e,n){t.add(ky(this.getControllerVisual(e,"symbol"),n[0],n[1],n[2],n[3],this.getControllerVisual(e,"color")))},e.prototype._onItemClick=function(t){var e=this.visualMapModel,n=e.option,i=T(n.selected),r=e.getSelectedMapKey(t);"single"===n.selectedMode?(i[r]=!0,E(i,(function(t,e){i[e]=e===r}))):i[r]=!i[r],this.api.dispatchAction({type:"selectDataRange",from:this.uid,visualMapId:this.visualMapModel.id,selected:i})},e.type="visualMap.piecewise",e}(uF);function NF(t){t.registerComponentModel(LF),t.registerComponentView(RF),AF(t)}var EF={label:{enabled:!0},decal:{show:!1}},zF=So(),VF={};function BF(t,e){var n=t.getModel("aria");if(n.get("enabled")){var i=T(EF);C(i.label,t.getLocaleModel().get("aria"),!1),C(n.option,i,!1),function(){if(n.getModel("decal").get("show")){var e=ft();t.eachSeries((function(t){if(!t.isColorBySeries()){var n=e.get(t.type);n||(n={},e.set(t.type,n)),zF(t).scope=n}})),t.eachRawSeries((function(e){if(!t.isSeriesFiltered(e))if(U(e.enableAriaDecal))e.enableAriaDecal();else{var n=e.getData();if(e.isColorBySeries()){var i=td(e.ecModel,e.name,VF,t.getSeriesCount()),r=n.getVisual("decal");n.setVisual("decal",u(r,i))}else{var o=e.getRawData(),a={},s=zF(e).scope;n.each((function(t){var e=n.getRawIndex(t);a[e]=t}));var l=o.count();o.each((function(t){var i=a[t],r=o.getName(t)||t+"",h=td(e.ecModel,r,s,l),c=n.getItemVisual(i,"decal");n.setItemVisual(i,"decal",u(c,h))}))}}function u(t,e){var n=t?A(A({},e),t):e;return n.dirty=!0,n}}))}}(),function(){var i=t.getLocaleModel().get("aria"),o=n.getModel("label");if(o.option=k(o.option,i),!o.get("enabled"))return;var a=e.getZr().dom;if(o.get("description"))return void a.setAttribute("aria-label",o.get("description"));var s,l=t.getSeriesCount(),u=o.get(["data","maxCount"])||10,h=o.get(["series","maxCount"])||10,c=Math.min(l,h);if(l<1)return;var p=function(){var e=t.get("title");e&&e.length&&(e=e[0]);return e&&e.text}();if(p){var d=o.get(["general","withTitle"]);s=r(d,{title:p})}else s=o.get(["general","withoutTitle"]);var f=[],g=l>1?o.get(["series","multiple","prefix"]):o.get(["series","single","prefix"]);s+=r(g,{seriesCount:l}),t.eachSeries((function(e,n){if(n1?o.get(["series","multiple",a]):o.get(["series","single",a]),{seriesId:e.seriesIndex,seriesName:e.get("name"),seriesType:(x=e.subType,t.getLocaleModel().get(["series","typeNames"])[x]||"自定义图")});var s=e.getData();if(s.count()>u)i+=r(o.get(["data","partialData"]),{displayCnt:u});else i+=o.get(["data","allData"]);for(var h=o.get(["data","separator","middle"]),p=o.get(["data","separator","end"]),d=[],g=0;g":"gt",">=":"gte","=":"eq","!=":"ne","<>":"ne"},WF=function(){function t(t){if(null==(this._condVal=X(t)?new RegExp(t):et(t)?t:null)){var e="";0,ao(e)}}return t.prototype.evaluate=function(t){var e=typeof t;return X(e)?this._condVal.test(t):!!j(e)&&this._condVal.test(t+"")},t}(),HF=function(){function t(){}return t.prototype.evaluate=function(){return this.value},t}(),YF=function(){function t(){}return t.prototype.evaluate=function(){for(var t=this.children,e=0;e2&&l.push(e),e=[t,n]}function f(t,n,i,r){iG(t,i)&&iG(n,r)||e.push(t,n,i,r,i,r)}function g(t,n,i,r,o,a){var s=Math.abs(n-t),l=4*Math.tan(s/4)/3,u=nM:C2&&l.push(e),l}function oG(t,e,n,i,r,o,a,s,l,u){if(iG(t,n)&&iG(e,i)&&iG(r,a)&&iG(o,s))l.push(a,s);else{var h=2/u,c=h*h,p=a-t,d=s-e,f=Math.sqrt(p*p+d*d);p/=f,d/=f;var g=n-t,y=i-e,v=r-a,m=o-s,x=g*g+y*y,_=v*v+m*m;if(x=0&&_-w*w=0)l.push(a,s);else{var S=[],M=[];Ze(t,n,r,a,.5,S),Ze(e,i,o,s,.5,M),oG(S[0],M[0],S[1],M[1],S[2],M[2],S[3],M[3],l,u),oG(S[4],M[4],S[5],M[5],S[6],M[6],S[7],M[7],l,u)}}}}function aG(t,e,n){var i=t[e],r=t[1-e],o=Math.abs(i/r),a=Math.ceil(Math.sqrt(o*n)),s=Math.floor(n/a);0===s&&(s=1,a=n);for(var l=[],u=0;u0)for(u=0;uMath.abs(u),c=aG([l,u],h?0:1,e),p=(h?s:u)/c.length,d=0;d1?null:new Ji(d*l+t,d*u+e)}function hG(t,e,n){var i=new Ji;Ji.sub(i,n,e),i.normalize();var r=new Ji;return Ji.sub(r,t,e),r.dot(i)}function cG(t,e){var n=t[t.length-1];n&&n[0]===e[0]&&n[1]===e[1]||t.push(e)}function pG(t){var e=t.points,n=[],i=[];Ma(e,n,i);var r=new sr(n[0],n[1],i[0]-n[0],i[1]-n[1]),o=r.width,a=r.height,s=r.x,l=r.y,u=new Ji,h=new Ji;return o>a?(u.x=h.x=s+o/2,u.y=l,h.y=l+a):(u.y=h.y=l+a/2,u.x=s,h.x=s+o),function(t,e,n){for(var i=t.length,r=[],o=0;or,a=aG([i,r],o?0:1,e),s=o?"width":"height",l=o?"height":"width",u=o?"x":"y",h=o?"y":"x",c=t[s]/a.length,p=0;p0)for(var b=i/n,w=-i/2;w<=i/2;w+=b){var S=Math.sin(w),M=Math.cos(w),I=0;for(x=0;x0;l/=2){var u=0,h=0;(t&l)>0&&(u=1),(e&l)>0&&(h=1),s+=l*l*(3*u^h),0===h&&(1===u&&(t=l-1-t,e=l-1-e),a=t,t=e,e=a)}return s}function AG(t){var e=1/0,n=1/0,i=-1/0,r=-1/0,o=z(t,(function(t){var o=t.getBoundingRect(),a=t.getComputedTransform(),s=o.x+o.width/2+(a?a[4]:0),l=o.y+o.height/2+(a?a[5]:0);return e=Math.min(s,e),n=Math.min(l,n),i=Math.max(s,i),r=Math.max(l,r),[s,l]}));return z(o,(function(o,a){return{cp:o,z:DG(o[0],o[1],e,n,i,r),path:t[a]}})).sort((function(t,e){return t.z-e.z})).map((function(t){return t.path}))}function kG(t){return gG(t.path,t.count)}function LG(t){return Y(t[0])}function PG(t,e){for(var n=[],i=t.length,r=0;r=0;r--)if(!n[r].many.length){var l=n[s].many;if(l.length<=1){if(!s)return n;s=0}o=l.length;var u=Math.ceil(o/2);n[r].many=l.slice(u,o),n[s].many=l.slice(0,u),s++}return n}var OG={clone:function(t){for(var e=[],n=1-Math.pow(1-t.path.style.opacity,1/t.count),i=0;i0){var s,l,u=i.getModel("universalTransition").get("delay"),h=Object.assign({setToFinal:!0},a);LG(t)&&(s=t,l=e),LG(e)&&(s=e,l=t);for(var c=s?s===t:t.length>e.length,p=s?PG(l,s):PG(c?e:t,[c?t:e]),d=0,f=0;f1e4))for(var i=n.getIndices(),r=function(t){for(var e=t.dimensions,n=0;n0&&i.group.traverse((function(t){t instanceof fs&&!t.animators.length&&t.animateFrom({style:{opacity:0}},r)}))}))}function HG(t){var e=t.getModel("universalTransition").get("seriesKey");return e||t.id}function YG(t){return Y(t)?t.sort().join(","):t}function UG(t){if(t.hostModel)return t.hostModel.getModel("universalTransition").get("divideShape")}function XG(t,e){for(var n=0;n=0&&r.push({data:e.oldData[n],divide:UG(e.oldData[n]),dim:t.dimension})})),E(ho(t.to),(function(t){var e=XG(n.updatedSeries,t);if(e>=0){var i=n.updatedSeries[e].getData();o.push({data:i,divide:UG(i),dim:t.dimension})}})),r.length>0&&o.length>0&&WG(r,o,i)}(t,i,n,e)}));else{var o=function(t,e){var n=ft(),i=ft(),r=ft();return E(t.oldSeries,(function(e,n){var o=t.oldData[n],a=HG(e),s=YG(a);i.set(s,o),Y(a)&&E(a,(function(t){r.set(t,{data:o,key:s})}))})),E(e.updatedSeries,(function(t){if(t.isUniversalTransitionEnabled()&&t.isAnimationEnabled()){var e=t.getData(),o=HG(t),a=YG(o),s=i.get(a);if(s)n.set(a,{oldSeries:[{divide:UG(s),data:s}],newSeries:[{divide:UG(e),data:e}]});else if(Y(o)){var l=[];E(o,(function(t){var e=i.get(t);e&&l.push({divide:UG(e),data:e})})),l.length&&n.set(a,{oldSeries:l,newSeries:[{data:e,divide:UG(e)}]})}else{var u=r.get(o);if(u){var h=n.get(u.key);h||(h={oldSeries:[{data:u.data,divide:UG(u.data)}],newSeries:[]},n.set(u.key,h)),h.newSeries.push({data:e,divide:UG(e)})}}}})),n}(i,n);E(o.keys(),(function(t){var n=o.get(t);WG(n.oldSeries,n.newSeries,e)}))}E(n.updatedSeries,(function(t){t.__universalTransitionEnabled&&(t.__universalTransitionEnabled=!1)}))}for(var a=t.getSeries(),s=i.oldSeries=[],l=i.oldData=[],u=0;u+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0 + +Special thanks to the following individuals for their great contributions: + + * Aaditya Bagga + * Adam Števko + * Adrian + * Alexander Eifler + * Andreas Sommer + * Andreas Weigel + * Andrew Minion + * Antonio Terceiro + * Arnie97 + * Aslak Raanes + * Bjørnar Hansen + * Bo Cai + * Bob Black + * Chilledheart + * Chris Downs + * Christian Hermann + * Christian Moelders + * Christopher Meng + * Daniel (dmilith) Dettlaff + * Daniel Aleksandersen + * David Geistert + * Enrique Becerra + * Florian Forster + * Francisco Azevedo + * Frederic Cambus + * Genki Sugawara + * Jeffery Wilkins + * Jeremy Burks + * Joe Groocock + * Joe Winett + * Joona + * Julian Xhokaxhiu + * Justin Mills + * Kamino Hiroki <37243867+4f8p@users.noreply.github.com> + * Kit Westneat + * Maksim Losev + * Mark J. Berger + * Mathieu Aubin + * Mathieu Thoretton + * Max Christian Pohle + * Michael Vetter + * Nicolas + * Nicolas Le Manchet + * Otto Kekäläinen + * Sean Cross + * Sebastian Wiedenroth + * SjonHortensius + * Steely Wing + * Stoyan Dimov + * Stéphane Péchard + * Tatsuyuki Ishi + * Thomas Gläßle + * Tom Samstag + * Viktor Szépe + * Ville Skyttä + * Vladimir Pavljuchenkov + * Vladimir Pavljuchenkov + * Yuri D'Elia + * Yuriy M. Kaminskiy + * abgit + * as0n + * fqbuild + * holys + * kyle sloan + * m-r-r + * mynameiscfed + * pravdomil + * radoslawc + * radoslawc + * schoonc + * wodev + * woobee + * zeke diff --git a/goaccess++/COPYING b/goaccess++/COPYING new file mode 100644 index 0000000..8da9f1d --- /dev/null +++ b/goaccess++/COPYING @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2009-2016 Gerardo Orellana + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/goaccess++/ChangeLog b/goaccess++/ChangeLog new file mode 100644 index 0000000..5d0afb1 --- /dev/null +++ b/goaccess++/ChangeLog @@ -0,0 +1,705 @@ +Changes to GoAccess 1.3 - Friday, November 23, 2018 + + - Added ability to store accumulated processing time into DB_GEN_STATS tcb + file via '--accumulated-time' command line option. + - Added additional Apache status codes to the list. + - Added a few feed readers to the list. + - Added 'Android 8 Oreo' to the list of OSs. + - Added 'Android Pie 9' to the list of OSs. + - Added --anonymize-ip command line option to anonymize ip addresses. + - Added --browsers-file command line option to load a list of crawlers from a + text file. + - Added byte unit (PiB) to C formatter and refactored code. + - Added byte unit (PiB) to JS formatter. + - Added Chinese translation (i18n). + - Added French translation (i18n). + - Added '%h' date specifier to the allowed date character specifiers. + - Added "HeadlessChrome" to the list of browsers. + - Added --hide-referer command line option to hide referers from report. + - Added HTTP status code 429 (TOO MANY REQUESTS). + - Added IGNORE_LEVEL_PANEL and IGNORE_LEVEL_REQ definitions. + - Added --ignore-referer-report command line option to hide referers from + output. + - Added Japanese translation (i18n). + - Added macOS 10.14 Mojave to the list of OSs. + - Added "Mastodon" user-agent to the list of crawlers/unix-like. + - Added new fontawesome icons and use angle arrows in HTML paging. + - Added new purple theme to HTML report and default to it. + - Added --no-parsing-spinner command line option to switch off parsing + spinner. + - Added .ogv and ogg static file extension (ogg video, Ogg Vorbis audio). + - Added OS X version numbers when outputting with --real-os. + - Added parsing mechanism in an attempt capture more bots and to include + unspecified bots/crawlers. + - Added --pidfile command line option to the default config file. + - Added Spanish translation (i18n). + - Added SSL support for Docker goaccess build. + - Added support to the WebSocket server for openssl-1.1*. + - Added the ability to show/hide a chart per panel in the HTML report. + - Added transparency to the navigation bar of the HTML report. + - Added "WhatsApp" user-agent to the list of crawlers. + - Changed default db folder so it adds the process id (PID). --db-path is + required now when using --load-from-disk. + - Changed Dockerfile to build from the current source. + - Changed 'hits' to be right-aligned on TUI. + - Changed to use faster slide animations on HTML report. + - Changed wording from 'Bandwidth' to the proper term 'Tx. Amount'. + - Ensure database filenames used by btree are less predictable. + - Ensure HTML templates, CSS and JS files are minified when outputting + report. + - Ensure key phrases from Google are added even when https is used. + - Ensure live report updates data & charts if tab/document has focus. + - Ensure multiple 'Yandex' crawlers are properly parsed. + - Ensure Safari has priority over most crawlers except the ones that are + known to have it. + - Ensure the request protocol on its own is properly parsed. + - Ensure the right number of tests are performed against the given log. + - Ensure user configuration is parsed first when available. + - Ensure wss:// is used when connecting via HTTPS. + - Ensure XFF parser takes into account escaped braces. + - Fixed a regression where fifo-in/out would fail with ENXIO. + - Fixed a regression where it would return EXIT_FAILURE on an empty log. + - Fixed a (ssh) pipeline problem with fgetline()/fgets() when there is a race + for data on stdin. + - Fixed broken X-Forwarded-For (XFF) %~ specifier in certain parsing cases. + - Fixed conf.filenames duplication problem if logs are via pipe. + - Fixed float percent value on JSON/HTML output for locales using decimal comma. + - Fixed issue where it was not possible to establish a Web Socket connection + when attempting to parse and extract HTTP method. + - Fixed issue where log formats with pipe delimiter were not propely parsed. + - Fixed memory leak after config file path has been set (housekeeping). + - Fixed memory leak when adding host to holder introduced in c052d1ea. + - Fixed possible memory leak when hiding specific referrers. + - Fixed several JS jshint warnings. + - Fixed sudo installs on TravisCI. + - Fixed UNDEFINED time range in HTML report when VISITORS panel was ignored. + - Fixed unnecessary closing span tags from template. + - Fixed use-after-free when two color items were found on color_list. + +Changes to GoAccess 1.2 - Tuesday, March 07, 2017 + + - Added a Dockerfile. + - Added Amazon S3 bucket name as a VirtualHost (server block). + - Added a replacement for GNU getline() to dynamically expand line buffer + while maintaining real-time output. + - Added --daemonize command line option to run GoAccess as daemon. + - Added several improvements to the HTML report on small-screen devices. + - Added option to the HTML report to auto-hide tables on small-screen + devices. + - Added --process-and-exit command line option to parse log and exit. + - Added several feed readers to the list of browsers. + - Added "-" single dash per convention to read from the standard input. + - Added support for MaxMind GeoIP2. + - Added the ability to read and follow from a pipe such as + "tail -f access.log | goaccess -" + - Added the ability to specify multiple logs as input sources, e.g.: + "goaccess access.log access.log.1" while maintaining real-time output. + - Added time unit (seconds) to the processed time label in the HTML/terminal + output. + - Added visitors' percent column to the terminal dashboard. + - Changed D3 charts to dim Y-axis on mouseover. + - Changed D3 charts to reflect HTML column sort. + - Changed D3 charts to render only if within the viewport. This improves the + overall real-time HTML performance. + - Changed HTML report tables to render only if within the viewport. + - Changed percentage calculation to be based on the total within each panel. + - Ensure start/end dates are updated real-time in the HTML output. + - Ensure "window.location.hostname" is used as the default WS server host. + In most cases, this should avoid the need for specifying "--ws-url=host". + Simply using "--real-time-html" should suffice. + - Fixed issue on HTML report to avoid outputting scientific notation for all + byte sizes. + - Fixed integer overflow when calculating bar graph length on terminal + output. + - Fixed issue where global config file would override command line arguments. + - Fixed issue where it wouldn't allow loading from disk without specifying a + file when executed from the cron. + - Fixed issue where parser couldn't read some X-Forwarded-For (XFF) formats. + Note that this breaks compatibility with the original implementation of + parsing XFF, but at the same time it gives much more flexibility on different + formats. + - Fixed issue where specifying fifo-in/out wouldn't allow HTML real-time + output. + - Fixed issue where the wrong number of parsed lines upon erroring out was + displayed. + - Fixed issue where the WebSocket server prevented to establish a connection + with a client due to invalid UTF-8 sequences. + - Fixed percent issue when calculating visitors field. + - Updated the list of crawlers. + +Changes to GoAccess 1.1.1 - Wednesday, November 23, 2016 + + - Added data metric's "unique" count on each panel to the JSON/HTML outputs. + - Changed D3 bar charts to use .rangeBands and avoid extra outer padding. + - Fixed mouseover offset position issue on D3 bar charts. + - Fixed possible heap overflow when an invalid status code was parsed and + processed. This also ensures that only valid HTTP status codes are parsed + >=100 or <= 599. + - Fixed sluggish D3 chart re-rendering by changing how x-axis labels are + displayed in the HTML report. + +Changes to GoAccess 1.1 - Tuesday, November 08, 2016 + + - Added a new layout to the HTML report and additional settings and changes. + - Added --crawlers-only command line option to display crawlers/bots only. + - Added --fifo-in and --fifo-out command line options to set websocket FIFO + reader/writer. + - Added --no-html-last-updated command line option. + - Added --num-tests command line option. + - Added --html-prefs command line option to to set default preferences for + the HTML report. + - Added "Amazon S3" Log Format to the list of predefined options. + - Added "Android 7.1 Nougat" to the list of OSs. + - Added "Android Marshmallow 6.0.1" to the list of OSs. + - Added "Android Nougat 7.0" to the list of OSs. + - Added "Feed Wrangler" to the list of feeds. + - Added "Go-http-client" to the list of browsers. + - Added "MicroMessenger" (WeChat) to the list of browsers. + - Added "SemrushBot" to the list of crawlers. + - Added "Remote User" panel to capture HTTP authentication requests. Use %e + within the log-format variable to enable this panel. + - Added tebibyte unit to the byte to string function converter. + - Added the ability to parse reverse proxy logs that have multiple IPs. This + adds the ability to parse the "X-Forwarded-For" field in a reverse proxy + setup. + - Added the ability to show which token didn't match log/date/time pattern. + This also ensures that in the absence of data, its output is not treated as + error but instead it produces an empty report. + - Added the ability to specify a WebSocket protocol (ws|wss) through + --ws-url. + - Added the request query string to the W3C format. + - Added TLS/SSL support to the HTML real-time report. + - Changed browser classification for Google Cloud Clients. + - Changed how "Darwin" OS was reported to display AppName instead. + - Changed default W3C log format to use the URL path instead of full request. + - Changed HTML default number of items on each table to 7. + - Changed request parser to allow empty query strings. + - Changed default HTML output theme to darkBlue. + - Ensure every version of iOS is broken down under the OS panel. + - Ensure latest JSON data is fast-forwarded when connection is opened. + GoAccess now sends the latest JSON data to the client as soon as the + WebSocket connection is opened. + - Ensure localStorage is supported and enabled in the HTML report + - Ensure unknown coutries/continents are listed. + - Fixed D3 chart width overflow issue on Edge. + - Fixed integer to string key conversion for unique visitors. This fixes the + issue where resulting keys would collide with existing keys and thus not + keeping the right visitors count on certain panels. + - Fixed memory leak when unable to URL decode %q specifier. + - Fixed memory leak when unable to URL decode %U specifier. + - Fixed month name abbreviation on app.js. + - Fixed percentage integer overflow with large numbers on 32bits platforms. + - Fixed percent calculation due to integer division rounding to zero. + - Fixed possible code injection when outputting an HTML report. + - Fixed segfault when using options -H or -M without an argument. + - Removed timestamp from the HTML report title tag. + +Changes to GoAccess 1.0.2 - Tuesday, July 05, 2016 + + - Added minor changes to the HTML report stylesheet. + - Added the ability to specify the WebSocket port within --ws-url. + - Added the proper byte swap functions used by Sun Solaris. + - Added the proper default --http-method/protocol values on the config file. + - Changed bar transition to scale delay dynamically to the length of the + dataset. + - Fixed build issue on platforms lacking of open_memstream() by refactoring + the JSON module to use its own memory buffer. + - Fixed issue where the server wouldn't send cached buffer to slow clients. + - Fixed OS X build check of ncursesw. + - Implemented a throttle mechanism for slow clients to avoid caching too much + data on the server-side. + - Removed flickering on D3 line and bar chart redraw. + +Changes to GoAccess 1.0.1 - Friday, June 17, 2016 + + - Added Android version number along with the codename when using --real-os, + e.g., "Lollipop 5.1". + - Added some missing headers and function checks to configure.ac. + - Fixed a regression where it wouldn't allow abbreviated date and time + formats such as %F or %T. + - Fixed build issues on systems running GLIBC older than 2.9, such as RHEL <= 5. + - Fixed issue where it wouldn't send the whole buffer to a socket causing the + real-time-html WebSocket server to progressively consume a lot more memory. + - Fixed memory leak when using getline and follow mode enabled. + - Fixed some buffer initialization issues on read_line() and + perform_tail_follow(). + - Fixed uint types in sha1 files. + +Changes to GoAccess 1.0 - Thursday, June 09, 2016 + + - Added --enable-panel= command line option to display the given + module. + - Added --json-pretty-print command line option to output pretty json. + - Added --log-format= command-line shortcuts for standard log + formats. + - Added --origin command line option to match the origin WebSocket header. + - Added --output= as a shortcut to --output-format. + - Added a complete real-time functionality to the HTML output. + - Added an option to set the max number of items to show per panel. + - Added D3 Visualziations to the HTML dashboard. + - Added metadata metrics to the each of the panels (JSON output) + - Added option to specify time distribution specificity. + - Added the ability to download a JSON file from the HTML report. + - Added the ability to output multiple formats on a single log parse. + - Added the ability to set the date specificity in hours. + - Added the ability to sort all HTML tables on all panels. + - Added the ability to specify a custom CSS and JS file to the HTML report. + - Added user-agents to the JSON output per each host. + - Added "Vivaldi" to the list of browsers. + - Bootstrapify the HTML dashboard. + - Changed configure.ac to use LDFLAGS instead of CFLAGS where applicable. + - Changed default terminal color scheme to 256 Monokai if terminal supports 256 colors. + - Changed GoAccess license to The MIT License (MIT) + - Changed the visitors panel to display its dates continuously instead of top. + - Default to 256 Monokai color scheme if terminal supports 256 colors. + - Default to display HTTP method/protocol (if applicable). + - Display the children's Max. T.S. as the parent's top Max. T.S. + - Ensure the parent's Avg. T.S. displays parent's Cum. T.S. over parent's Hits. + - Fixed color issue when switching from the color scheme dialog. + - Fixed cross platform build issue when ncurses is built with and without + termlib=tinfo. + - Fixed curses header window issue where it wouldn't clear out on small + window sizes. + - Fixed issue where tail mode wouldn't parse full lines using getline(). + - Fixed minor background color issue when using ncurses 6. + - Fixed possible division by zero when calculating percentage. + - Fixed singly link list node removal. + - Fixed still reachable memory leak on GeoIP cleanup (geoip legacy >= 1.4.7). + - Fixed various Valgrind's still reachable memory leaks. + - Removed -Wredundant-decls. + +Changes to GoAccess 0.9.8 - Monday, February 29, 2016 + + - Added a more complete list of static extensions to the config file. + - Added "Android 6.0 Marshmallow" to the list of OSs. + - Added --no-tab-scroll command line option to disable scroll through panels + on TAB. + - Added the first and last log dates to the overall statistics panel. + - Ensure GoAccess links correctly against libtinfo. + - Ensure static content is case-insensitive verified. + - Fixed bandwidth overflow issue (numbers > 2GB on non-x86_64 arch). + - Fixed broken HTML layout when html-method/protocol is missing in config file. + - Refactored parsing and display of available modules/panels. + +Changes to GoAccess 0.9.7 - Monday, December 21, 2015 + + - Added "Squid native" log format to the config file. + - Fixed integer overflow when getting total bandwidth using the on-disk + storage. + - Fixed issue where a timestamp was stored as date under the visitors panel. + - Fixed issue where config dialog fields were not cleared out on select. + - Fixed issue where "Virtual Hosts" menu item wasn't shown in the HTML sidebar. + +Changes to GoAccess 0.9.6 - Tuesday, October 27, 2015 + + - Added --dcf command line option to view the default config file path. + - Added --ignore-status the ability to ignore parsing status codes. + - Added "Darwin" to the list of OSs. + - Fixed segfault when appending data to a log (follow) without virtualhosts. + +Changes to GoAccess 0.9.5 - Thursday, October 22, 2015 + + - Added major performance improvements to the default storage when parsing and + storing data (~%44 less memory, ~37% faster). + - Added the ability to parse virtual hosts and a new panel to display metrics + per virtual host. + - Added the ability to parse HTTP/2 requests. + - Added the ability to use GNU getline() to parse full line requests. + - Added the ability to output debug info if a log file is specified, even + without --enable-debug. + - Added OS X "El Capitan". + - Added WebDav HTTP methods and HTTP status from RFC 2518 and RFC 3253. + - Fixed detection of some Googlebots. + - Fixed issue where time served metrics were not shown when loading persisted + data. + - Fixed linker error on OSX: ld: library not found for -lrt. + - Fixed percentage on the HTML output when excluding IPs. + - Removed GLib dependency and refactored storage functionality. By removing + this dependency, GoAccess is able to store data in a more efficient manner, + for instance, it avoids storing integer data as void* (generic typing), thus + greatly improving memory consumption for integers. + +Changes to GoAccess 0.9.4 - Tuesday, September 08, 2015 + + - Added --all-static-files command line option to parse static files + containing a query string. + - Added --invalid-requests command line option to log invalid requests to a file. + - Added additional overall metric - total valid requests. + - Added "%~" specifier to move forward through a log string until a non-space + char is found. + - Added the ability to parse native Squid access.log format. + - Fixed a few issues in the configuration script. + - Fixed inability to parse color due to a missing POSIX extension. + "ERR:Invalid bg/fg color pairs" + +Changes to GoAccess 0.9.3 - Wednesday, August 26, 2015 + + - Added --no-column-names command line option to disable column name metrics. + - Added a default color palette (Monokai) to the config file. + - Added AWS Elastic Load Balancing to the list of predefined log/date/time + formats. + - Added CloudFlare status codes. + - Added column headers for every enabled metric on each panel. + - Added cumulative time served metric. + - Added "DragonFly" BSD to the list of OSs. + - Added maximum time served metric (slowest running requests). + - Added "Slackbot" to the list of crawlers/browsers. + - Added the ability to parse the query string specifier "%q" from a log file. + - Added the ability to process logs incrementally. + - Added the ability to set custom colors on the terminal output. + - Disabled REFERRERS by default. + - Ensure bandwidth metric is displayed only if %b specifier is parsed. + - Fixed issue where the --sort-panel option wouldn't sort certain panels. + - Fixed several compiler warnings. + - Set predefined static files when no config file is used. + - Updated "Windows 10" user agent from 6.4 (wrong) to 10.0.(actual) + +Changes to GoAccess 0.9.2 - Monday, July 06, 2015 + + - Added ability to fully parse browsers that contain spaces within a token. + - Added multiple user agents to the list of browsers. + - Added the ability to handle time served in milliseconds as a decimal number + `%L`. + - Added the ability to parse a timestamp in microseconds. + - Added the ability to parse Google Cloud Storage access logs. + - Added the ability to set a custom title and header in the HTML report. + - Added "%x" as timestamp log-format specifier. + - Ensure agents" hash table is destroyed upon exiting the program. + - Ensure "Game Systems" are processed correctly. + - Ensure visitors panel header is updated depending if crawlers are parsed or + not. + - Fixed issue where the date value was set as time value in the config + dialog. + - Fixed memory leak in the hits metrics when using the in-memory storage + (GLib). + +Changes to GoAccess 0.9.1 - Tuesday, May 26, 2015 + + - Added --hl-header command line option to highlight active panel. + - Added "Applebot" to the list of web crawlers. + - Added "Microsoft Edge" to the list of browsers. + - Added additional Nginx-specific status codes. + - Ensure dump_struct is used only if using __GLIBC__. + - Ensure goaccess image has an alt attribute on the HTML output for valid + HTML5. + - Ensure the config file path is displayed when something goes wrong (FATAL). + - Ensure there is a character indicator to see which panel is active. + - Fixed Cygwin compile issue attempting to use -rdynamic. + - Fixed issue where a single IP did not get excluded after an IP range. + - Fixed issue where requests showed up in the wrong view even when + --no-query-string was used. + - Fixed issue where some browsers were not recognized or marked as "unknown". + - Fixed memory leak when excluding an IP range. + - Fixed overflows on sort comparison functions. + - Fixed segfault when using on-disk storage and loading persisted data with -a. + - Removed keyphrases menu item from HTML output. + - Split iOS devices from Mac OS X. + +Changes to GoAccess 0.9 - Thursday, March 19, 2015 + + - Added --geoip-database command line option for GeoIP Country/City IPv6. + - Added "Windows 10 (v6.4)" to the real windows user agents. + - Added ability to double decode an HTTP referer and agent. + - Added ability to sort views through the command line on initial load. + - Added additional data values to the backtrace report. + - Added additional graph to represent the visitors metric on the HTML output. + - Added AM_PROG_CC_C_O to configure.ac + - Added "Android Lollipop" to the list of operating systems. + - Added "average time served" metric to all panels. + - Added "bandwidth" metric to all panels. + - Added command line option to disable summary metrics on the CSV output. + - Added numeric formatting to the HTML output to improve readability. + - Added request method specifier to the default W3C log format. + - Added the ability to ignore parsing and displaying given panel(s). + - Added the ability to ignore referer sites from being counted. A good case + scenario is to ignore own domains. i.e., owndomain.tld. This also allows + ignoring hosts using wildcards. For instance, *.mydomain.tld or www.mydomain.* + or www?.mydomain.tld + - Added time/hour distribution module. e.g., 00-23. + - Added "visitors" metrics to all panels. + - Changed AC_PREREQ macro version so it builds on old versions of autoconf. + - Changed GEOIP database load to GEOIP_MEMORY_CACHE for faster lookups. + - Changed maximum number of choices to display per panel to 366 fron 300. + - Ensure config file is read from home dir if unable to open it from + %sysconfdir% path. + - Fixed array overflows when exceeding MAX_* limits on command line options. + - Fixed a SEGFAULT where sscanf could not handle special chars within the + referer. + - Fixed character encoding on geolocation output (ISO-8859 to UTF8). + - Fixed issue on wild cards containing "?" at the end of the string. + - Fixed issue where a "Nothing valid to process" error was triggered when the + number of invalid hits was equal to the number of valid hits. + - Fixed issue where outputting to a file left a zero-byte file in pwd. + - Improved parsing of operating systems. + - Refactored log parser so it allows with ease the addition of new modules. + This also attempts to decouple the core functionality from the rendering + functions. It also gives the flexibility to add children metrics to root + metrics for any module. e.g., Request A was visited by IP1, IP2, IP3, etc. + - Restyled HTML output. + +Changes to GoAccess 0.8.5 - Sunday, September 14, 2014 + + - Fixed SEGFAULT when parsing a malformed request that doesn't have HTTP + status. + +Changes to GoAccess 0.8.4 - Monday, September 08, 2014 + + - Added --444-as-404 command line option to handle nginx non-standard status + code 444 as 404. + - Added --4xx-to-unique-count command line option to count client errors (4xx) + to the unique visitors count. Now by default it omits client errors (4xx) + from being added to the unique visitors count as they are probably not welcomed + visitors. 4xx errors are always counted in panels other than visitors, OS & + browsers. + - Added and updated operating systems, and browsers. + - Added excluded IP hits count to the general statistics panel on all reports. + - Added HTTP nonstandard code "444" to the status code list. + - Fixed compile error due to missing include for type + off_t (gcc 4.1). + - Fixed issue when excluding IPv4/v6 ranges. + - Removed request status field restriction. This allows parsing logs that + contain only a valid date, IPv4/6 and host. + +Changes to GoAccess 0.8.3 - Monday, July 28, 2014 + + - Fixed SEGFAULT when parsing a CLF log format and using --ignore-crawlers. + - Fixed parsing conflict between some Opera browsers and Chrome. + - Fixed parsing of several feed readers that are Firefox/Safari-based. + - Fixed Steam detection. + - Added Huawei to the browser's list and removed it from the OS's list. + +Changes to GoAccess 0.8.2 - Monday, July 20, 2014 + + - Added --version command line option. + - Added --ignore-crawlers command line option to ignore crawlers. + - Added ability to parse dates containing whitespaces in between, + e.g., "Jul 15 20:13:59" (syslog format). + - Added a variety of browsers, game systems, feed readers, and podcasts. + - Added missing up/down arrows to the help section. + - Added the ability to ignore multiple IPv4/v6 and IP ranges. + - Added the PATCH method according to RFC 5789. + - Fixed GeoLocation percent issue for the JSON, CSV and HTML outputs. + - Fixed memory leak when excluding one or multiple IPs. + +Changes to GoAccess 0.8.1 - Monday, June 16, 2014 + + - Added ability to add/remove static files by extension through the config + file. + - Added ability to print backtrace on segmentation fault. + - Escaped JSON strings correctly according to [RFC4627]. + - Fixed encoding issue when extracting keyphrases for some HTTP referers. + - Fixed issue where HTML bar graphs were not shown due to numeric locale. + - Fixed issue with URIs containing "\r?\n" thus breaking the corresponding + output. + - Make sure request string is URL decoded on all outputs. + +Changes to GoAccess 0.8 - Tuesday, May 20, 2014 + + - Added APT-HTTP to the list of browsers. + - Added data persistence and ability to load data from disk. + - Added IE11 to the list of browsers. + - Added IEMobile to the list of browsers. + - Added multiple command line options. + - Added Nagios check_http to the list of browsers. + - Added parsing progress metrics - total requests / requests per second. + - Added the ability to parse a GeoLiteCity.dat to get the city given an IPv4. + - Changed the way the configuration file is parsed. This will parse all + configuration options under ~/.goaccessrc or the specified config file and + will feed getopt_long with the extracted key/value pairs. This also allows the + ability to have comments on the config file which won't be overwritten. + - Ensure autoconf determines the location of ncurses headers. + - Fixed issue where geo_location_data was NULL. + - Fixed issue where GoAccess did not run without a tty allocated to it. + - Fixed potential memory leak on --log-file realpath(). + - Fixed Solaris build errors. + - Implemented an on-memory hash database using Tokyo Cabinet. This + implementation allows GoAccess not to rely on GLib's hash table if one is + needed. + - Implemented large file support using an on-disk B+ Tree database. This + implementation allows GoAccess not to hold everything in memory but instead + it uses an on-disk B+ Tree database. + - Trimmed leading and trailing whitespaces from keyphrases module. + +Changes to GoAccess 0.7.1 - Monday, February 17, 2014 + + - Added --no-color command line option to turn off color output. + - Added --real-os command line option to get real OS names, e.g., + "Android, Windows, Mac". + - Added ability to log debug messages to a file. + - Added ability to parse tab-separated log format strings. + - Added ability to support terminals without colors. + - Added command line option to append HTTP method to request. + - Added command line option to append HTTP protocol to request. + - Added long options to command-line. + - Added missing "Win 9x 4.90" (Windows Me) user-agent. + - Added missing Windows RT user-agent. + - Ensure mouse click does not reset expanded module if it is the same. + - Fixed Amazon CloudFront tab-separated log format. + - Fixed "FreeBSD style" ncursesw built into system. + - Fixed HTML report issue where data cell would not wrap. + - Fixed issue when isatty() could not find a valid file descriptor. + - Fixed SymbianOS user-agent and retrieve its version. + +Changes to GoAccess 0.7 - Monday, December 15, 2013 + + - Added a command line option to ignore request query strings. + - Added additional compiler flags & fixed several warnings. + - Added additional static file extensions. + - Added country per IP to HOSTS module (HTML & JSON). + - Added DEBUG mode to Makefile & -O2 to default release. + - Added GEOLOCATION report to all outputs - includes continents/countries. + - Added IP resolver to HTML and JSON output. + - Added module numbers to each module header. + - Added the ability to output JSON and CSV. + - Added Windows NT 6.3 (Win 8.1) to the list. + - Fixed buffer overflow issue with realpath. + - New HTML report - HTML5 + CSS styles. + - Properly split request line into the three request modules. + +Changes to GoAccess 0.6.1 - Monday, October 07, 2013 + + - Added active module indication by name. + - Added additional crawlers to the list. + - Added custom configuration file option. + - Added human-readable string when unable to open log. + - Added missing include when compiling on OSX 10.6. + - Added optional mouse support to the main dashboard. + - Added the ability to select active module by number (keys). + - Added the rest of HTTP methods according to RFC2616. + - Changed referring site sscanf format to process multiple URLs. + - Changed the default color scheme to monochrome. + - Fixed issue where %T was not processing floating-point numbers. + - Fixed percentage issue for browsers and os modules. + - Fixed SIGSEGV when reading from stdin to stdout. + - Improved performance when expanding a module. + - Reduced memory consumption by decreasing number of dns threads. + - Removed ^UP/^DOWN due to a key mapping conflict. + +Changes to GoAccess 0.6 - Monday, July 15, 2013 + + - Added a bunch of minor fixes and changes. + - Added and updated list of browsers and operating systems. + - Added a predefined log format/date for the Amazon CloudFront (Download + Distribution). + - Added parsing/processing indicators. + - Added the ability to independently sort each module. + - Added the ability to search across the whole dashboard with the option to + use regular expressions. + - Config window now accepts [ENTER] to continue or F10. + - Fixed issue where Opera +15 was identified as Chrome. + - Implemented the ability to parse the time taken to serve the request, in + microseconds and seconds. + - Improved memory usage and better performance in general. + - Moved away from the original pop-up UI to a new expandable dashboard + allowing data to be processed in real-time. + - Sanitized HTML output with html entities for special chars. + - Updated the hosts module so it shows the reverse DNS as a sub node. + +Changes to GoAccess 0.5 - Monday, June 04, 2012 + + - Added ability to output a full stats report to a file. + - Added a key shortcut to scroll top/bottom. + - Added a new include sys/socket.h - BSD + - Added support for IPv6 + - Added the ability to parse a custom format string. + - Fixed google cache key-phrases. + - Fixed issue on empty Google query strings. + - Fixed issue on Opera agents where version was not recognized correctly. + - Fixed other minor fixes and changes. + +Changes to GoAccess 0.4.2 - Monday, January 03, 2011 + + - Added UTF-8 support. Now it should handle properly wide-character/UTF-8. + Run ./configure --enable-utf8 + - Fixed a minor bug when adding monthly totals on visitors subwin. + - Removed -lrt since GoAccess does not link to librt. (OS X doesn't include + librt) + +Changes to GoAccess 0.4.1 - Monday, December 13, 2010 + + - Added more flexibility when resizing the terminal. Should work fine with + the standard 80x24. + - Added the ability to pass a flag to ./configure so GeoIP can be enabled if + needed. + - Implemented a pipeline from stdin, so the input doesn't have to be only a + file. + +Changes to GoAccess 0.4 - Tuesday, November 30, 2010 + + - Added graphs to the unique_visitors subwin. + - Implemented bandwidth per day, and host. + - Implemented list of agents for specific hosts. + - Rewrote hash tables iterative code to avoid the use of GHashTableIter, this + way it works with all GLib > 2.0.0. + - Various bug fixes and code cleanups (mainly in the subwin modules). + +Changes to GoAccess 0.3.3 - Monday, September 27, 2010 + + - Changed tarball's filename. + - Fixed a request size parsing issue. Due to malformed syntax on the HTTP + protocol, bandwidth was reset to 0. Ex. "HEAD /" 400 20392 + - Fixed a segfault when goaccess was executed without any options but with an + additional unknown argument. + +Changes to GoAccess 0.3.2 - Thursday, September 09, 2010 + + - Fixed an agent parsing issue. As a result, operating systems were not + properly counted. + +Changes to GoAccess 0.3.1 - Friday, September 03, 2010 + + - Added a color scheme implementation + +Changes to GoAccess 0.3 - Sunday, August 29, 2010 + + - Added a counter for total requests since initial parse was implemented + - Added a more detailed and comprehensive browser and os report + - Added bandwidth details for requested files + - Added percentage details on modules 2, 3, 4, 5, 10, 11 + - Code cleanups + - Fixed a potential segmentation fault when resizing main window + - Fixed a segmentation fault on pop-up window search if haystack was null + - Fixed invalid entries when parsing status codes + - Implemented a real support for LFS - Handles files larger than 2 GiB on + 32-bit systems + - Implemented support for "vhost_combined" log format + - Changed position of data/graphs depending on # of hits + +Changes to GoAccess 0.2 - Sunday, July 25, 2010 + + - Added a keyphrases report coming from Google search engine. This includes, + raw, cache, and translation queries. + - Fixed a memory leak when invalid entries were parsed + - Fixed a potential buffer overflow. + - Implemented real-time statistics (RTS). Data will be appended as the log + file grows. Equivalent to "tail -f" on Unix systems + - Implemented screen resize functionality + - Simpliflied creation of the "unique visitors" hash-key. + - Simpliflied the "process_unique_data" function + - Various small speed increases & code cleanup + +Changes to GoAccess 0.1.2 - Monday, July 12, 2010 + + - Fixed a segmentation fault when parsing logs with unusual request type. Ex. + "GET HTTP/1.1 HTTP/1.1" + +Changes to GoAccess 0.1.1 - Saturday, July 10, 2010 + + - Added an enhanced error handling + - Added an extra macro on configure.ac to check against GHashTableIter. + ./configure might not check for glib 2.16 that introduced "GHashTableIter". + - Added Glibc LFS + - Cleaned up code a little bit + - Fixed a segmentation fault when displaying the help text on x86_64. + - Fixed assignments in conditions. In case the assignment is actually intended + put extra parenthesis around it. This will shut GCC (and others) up. + - Fixed casts associated with "g_hash_table_iter_next". + - Fixed comparison between signed and unsigned integer types. + - Fixed function declarations. + - Fixed includes. + - Fixed two format strings. (If the error was ever triggered, it'd most + likely lead to a segfault) + +Changes to GoAccess 0.1 - Tuesday, July 06, 2010 + + - Initial release 0.1 diff --git a/goaccess++/INSTALL b/goaccess++/INSTALL new file mode 100644 index 0000000..a1e89e1 --- /dev/null +++ b/goaccess++/INSTALL @@ -0,0 +1,370 @@ +Installation Instructions +************************* + +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/goaccess++/Makefile b/goaccess++/Makefile new file mode 100644 index 0000000..a9a7d09 --- /dev/null +++ b/goaccess++/Makefile @@ -0,0 +1,1268 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + + +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/goaccess +pkgincludedir = $(includedir)/goaccess +pkglibdir = $(libdir)/goaccess +pkglibexecdir = $(libexecdir)/goaccess +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = x86_64-unknown-linux-gnu +host_triplet = x86_64-unknown-linux-gnu +bin_PROGRAMS = goaccess$(EXEEXT) +noinst_PROGRAMS = bin2c$(EXEEXT) +#am__append_1 = \ +# src/tcabdb.c \ +# src/tcabdb.h \ +# src/tcbtdb.c \ +# src/tcbtdb.h + +am__append_2 = \ + src/khash.h \ + src/gkhash.c \ + src/gkhash.h + +am__append_3 = \ + src/geoip1.c \ + src/geoip1.h + +#am__append_4 = \ +# src/geoip2.c \ +# src/geoip1.h + +subdir = . +DIST_COMMON = README $(am__configure_deps) $(dist_conf_DATA) \ + $(dist_man_MANS) $(dist_noinst_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/configure \ + $(top_srcdir)/src/config.h.in ABOUT-NLS AUTHORS COPYING \ + ChangeLog INSTALL NEWS TODO compile config.guess config.rpath \ + config.sub depcomp install-sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(confdir)" +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +am__dirstamp = $(am__leading_dot)dirstamp +am_bin2c_OBJECTS = src/bin2c.$(OBJEXT) +bin2c_OBJECTS = $(am_bin2c_OBJECTS) +bin2c_LDADD = $(LDADD) +am__goaccess_SOURCES_DIST = src/base64.c src/base64.h src/browsers.c \ + src/browsers.h src/color.c src/color.h src/commons.c \ + src/commons.h src/csv.c src/csv.h src/error.c src/error.h \ + src/gdashboard.c src/gdashboard.h src/gdns.c src/gdns.h \ + src/gholder.c src/gholder.h src/gmenu.c src/gmenu.h \ + src/goaccess.c src/goaccess.h src/gslist.c src/gslist.h \ + src/gstorage.c src/gstorage.h src/gwsocket.c src/gwsocket.h \ + src/json.c src/json.h src/labels.h src/opesys.c src/opesys.h \ + src/options.c src/options.h src/output.c src/output.h \ + src/parser.c src/parser.h src/settings.c src/settings.h \ + src/sha1.c src/sha1.h src/sort.c src/sort.h src/ui.c src/ui.h \ + src/util.c src/util.h src/websocket.c src/websocket.h \ + src/xmalloc.c src/xmalloc.h src/tcabdb.c src/tcabdb.h \ + src/tcbtdb.c src/tcbtdb.h src/khash.h src/gkhash.c \ + src/gkhash.h src/geoip1.c src/geoip1.h src/geoip2.c +#am__objects_1 = src/tcabdb.$(OBJEXT) src/tcbtdb.$(OBJEXT) +am__objects_2 = src/gkhash.$(OBJEXT) +am__objects_3 = src/geoip1.$(OBJEXT) +#am__objects_4 = src/geoip2.$(OBJEXT) +am_goaccess_OBJECTS = src/base64.$(OBJEXT) src/browsers.$(OBJEXT) \ + src/color.$(OBJEXT) src/commons.$(OBJEXT) src/csv.$(OBJEXT) \ + src/error.$(OBJEXT) src/gdashboard.$(OBJEXT) \ + src/gdns.$(OBJEXT) src/gholder.$(OBJEXT) src/gmenu.$(OBJEXT) \ + src/goaccess.$(OBJEXT) src/gslist.$(OBJEXT) \ + src/gstorage.$(OBJEXT) src/gwsocket.$(OBJEXT) \ + src/json.$(OBJEXT) src/opesys.$(OBJEXT) src/options.$(OBJEXT) \ + src/output.$(OBJEXT) src/parser.$(OBJEXT) \ + src/settings.$(OBJEXT) src/sha1.$(OBJEXT) src/sort.$(OBJEXT) \ + src/ui.$(OBJEXT) src/util.$(OBJEXT) src/websocket.$(OBJEXT) \ + src/xmalloc.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) +goaccess_OBJECTS = $(am_goaccess_OBJECTS) +goaccess_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(bin2c_SOURCES) $(goaccess_SOURCES) +DIST_SOURCES = $(bin2c_SOURCES) $(am__goaccess_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(dist_man_MANS) +DATA = $(dist_conf_DATA) $(dist_noinst_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = ${SHELL} /home/djq/goaccess-1.3/missing --run aclocal-1.11 +AMTAR = $${TAR-tar} +AUTOCONF = ${SHELL} /home/djq/goaccess-1.3/missing --run autoconf +AUTOHEADER = ${SHELL} /home/djq/goaccess-1.3/missing --run autoheader +AUTOMAKE = ${SHELL} /home/djq/goaccess-1.3/missing --run automake-1.11 +AWK = mawk +CC = gcc +CCDEPMODE = depmode=gcc3 +CFLAGS = -pthread +CPP = gcc -E +CPPFLAGS = +CYGPATH_W = echo +DEFS = -DLOCALEDIR=\"$(localedir)\" -DHAVE_CONFIG_H +DEPDIR = .deps +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /usr/bin/grep -E +EXEEXT = +GETTEXT_MACRO_VERSION = 0.18 +GMSGFMT = : +GMSGFMT_015 = : +GREP = /usr/bin/grep +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +INTLLIBS = +INTL_MACOSX_LIBS = +LDFLAGS = +LIBICONV = -liconv +LIBINTL = +LIBOBJS = +LIBS = -lnsl -lncursesw -lGeoIP -lpthread +LTLIBICONV = -liconv +LTLIBINTL = +LTLIBOBJS = +MAKEINFO = ${SHELL} /home/djq/goaccess-1.3/missing --run makeinfo +MKDIR_P = /usr/bin/mkdir -p +MSGFMT = : +MSGFMT_015 = : +MSGMERGE = : +OBJEXT = o +PACKAGE = goaccess +PACKAGE_BUGREPORT = goaccess@prosoftcorp.com +PACKAGE_NAME = goaccess +PACKAGE_STRING = goaccess 1.3 +PACKAGE_TARNAME = goaccess +PACKAGE_URL = http://goaccess.io +PACKAGE_VERSION = 1.3 +PATH_SEPARATOR = : +POSUB = po +POW_LIB = +SED_CHECK = yes +SET_MAKE = +SHELL = /bin/bash +STRIP = +TR_CHECK = yes +USE_NLS = yes +VERSION = 1.3 +XGETTEXT = : +XGETTEXT_015 = : +XGETTEXT_EXTRA_OPTIONS = +abs_builddir = /home/djq/goaccess-1.3 +abs_srcdir = /home/djq/goaccess-1.3 +abs_top_builddir = /home/djq/goaccess-1.3 +abs_top_srcdir = /home/djq/goaccess-1.3 +ac_ct_CC = gcc +am__include = include +am__leading_dot = . +am__quote = +am__tar = $${TAR-tar} chof - "$$tardir" +am__untar = $${TAR-tar} xf - +bindir = ${exec_prefix}/bin +build = x86_64-unknown-linux-gnu +build_alias = +build_cpu = x86_64 +build_os = linux-gnu +build_vendor = unknown +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = x86_64-unknown-linux-gnu +host_alias = +host_cpu = x86_64 +host_os = linux-gnu +host_vendor = unknown +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/djq/goaccess-1.3/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = /usr/bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target_alias = +top_build_prefix = +top_builddir = . +top_srcdir = . +AUTOMAKE_OPTIONS = subdir-objects +dist_noinst_DATA = \ + resources/tpls.html \ + resources/css/app.css \ + resources/css/bootstrap.min.css \ + resources/css/fa.min.css \ + resources/js/app.js \ + resources/js/charts.js \ + resources/js/d3.v3.min.js \ + resources/js/hogan.min.js + +bin2c_SOURCES = src/bin2c.c +BUILT_SOURCES = \ + tpls.h \ + bootstrapcss.h \ + facss.h \ + appcss.h \ + d3js.h \ + hoganjs.h \ + chartsjs.h \ + appjs.h + +CLEANFILES = \ + src/tpls.h \ + src/bootstrapcss.h \ + src/facss.h \ + src/appcss.h \ + src/d3js.h \ + src/hoganjs.h \ + src/chartsjs.h \ + src/appjs.h \ + resources/tpls.html.tmp \ + resources/css/bootstrap.min.css.tmp \ + resources/css/fa.min.css.tmp \ + resources/css/app.css.tmp \ + resources/js/d3.v3.min.js.tmp \ + resources/js/hogan.min.js.tmp \ + resources/js/charts.js.tmp \ + resources/js/app.js.tmp + +confdir = $(sysconfdir)/goaccess +dist_conf_DATA = config/goaccess.conf config/browsers.list +goaccess_SOURCES = src/base64.c src/base64.h src/browsers.c \ + src/browsers.h src/color.c src/color.h src/commons.c \ + src/commons.h src/csv.c src/csv.h src/error.c src/error.h \ + src/gdashboard.c src/gdashboard.h src/gdns.c src/gdns.h \ + src/gholder.c src/gholder.h src/gmenu.c src/gmenu.h \ + src/goaccess.c src/goaccess.h src/gslist.c src/gslist.h \ + src/gstorage.c src/gstorage.h src/gwsocket.c src/gwsocket.h \ + src/json.c src/json.h src/labels.h src/opesys.c src/opesys.h \ + src/options.c src/options.h src/output.c src/output.h \ + src/parser.c src/parser.h src/settings.c src/settings.h \ + src/sha1.c src/sha1.h src/sort.c src/sort.h src/ui.c src/ui.h \ + src/util.c src/util.h src/websocket.c src/websocket.h \ + src/xmalloc.c src/xmalloc.h $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) +AM_CFLAGS = -O2 -DSYSCONFDIR=\"$(sysconfdir)\" \ + -Wno-long-long -Wall -W -Wnested-externs \ + -Wformat=2 -Wmissing-prototypes \ + -Wstrict-prototypes -Wmissing-declarations \ + -Wwrite-strings -Wshadow -Wpointer-arith \ + -Wsign-compare -Wbad-function-cast -Winline \ + -Wcast-align -Wextra \ + -Wdeclaration-after-statement \ + -Wno-missing-field-initializers +#AM_CFLAGS = -DDEBUG -O0 -g -DSYSCONFDIR=\"$(sysconfdir)\" \ +# -Wno-long-long -Wall -W -Wnested-externs \ +# -Wformat=2 -Wmissing-prototypes \ +# -Wstrict-prototypes -Wmissing-declarations \ +# -Wwrite-strings -Wshadow -Wpointer-arith \ +# -Wsign-compare -Wbad-function-cast -Winline \ +# -Wcast-align -Wextra -Wdeclaration-after-statement \ +# -Wno-missing-field-initializers +AM_LDFLAGS = -rdynamic +dist_man_MANS = goaccess.1 +SUBDIRS = po +ACLOCAL_AMFLAGS = -I m4 +EXTRA_DIST = config.rpath +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +src/config.h: src/stamp-h1 + @if test ! -f $@; then rm -f src/stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1; else :; fi + +src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status + @rm -f src/stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status src/config.h +$(top_srcdir)/src/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f src/stamp-h1 + touch $@ + +distclean-hdr: + -rm -f src/config.h src/stamp-h1 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) +src/bin2c.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +bin2c$(EXEEXT): $(bin2c_OBJECTS) $(bin2c_DEPENDENCIES) $(EXTRA_bin2c_DEPENDENCIES) + @rm -f bin2c$(EXEEXT) + $(LINK) $(bin2c_OBJECTS) $(bin2c_LDADD) $(LIBS) +src/base64.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/browsers.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/color.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/commons.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/csv.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/error.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/gdashboard.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gdns.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/gholder.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gmenu.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/goaccess.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gslist.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gstorage.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gwsocket.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/json.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/opesys.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/options.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/output.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/parser.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/settings.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/sha1.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/sort.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/ui.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/util.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/websocket.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/xmalloc.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/tcabdb.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/tcbtdb.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gkhash.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/geoip1.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/geoip2.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +goaccess$(EXEEXT): $(goaccess_OBJECTS) $(goaccess_DEPENDENCIES) $(EXTRA_goaccess_DEPENDENCIES) + @rm -f goaccess$(EXEEXT) + $(LINK) $(goaccess_OBJECTS) $(goaccess_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f src/base64.$(OBJEXT) + -rm -f src/bin2c.$(OBJEXT) + -rm -f src/browsers.$(OBJEXT) + -rm -f src/color.$(OBJEXT) + -rm -f src/commons.$(OBJEXT) + -rm -f src/csv.$(OBJEXT) + -rm -f src/error.$(OBJEXT) + -rm -f src/gdashboard.$(OBJEXT) + -rm -f src/gdns.$(OBJEXT) + -rm -f src/geoip1.$(OBJEXT) + -rm -f src/geoip2.$(OBJEXT) + -rm -f src/gholder.$(OBJEXT) + -rm -f src/gkhash.$(OBJEXT) + -rm -f src/gmenu.$(OBJEXT) + -rm -f src/goaccess.$(OBJEXT) + -rm -f src/gslist.$(OBJEXT) + -rm -f src/gstorage.$(OBJEXT) + -rm -f src/gwsocket.$(OBJEXT) + -rm -f src/json.$(OBJEXT) + -rm -f src/opesys.$(OBJEXT) + -rm -f src/options.$(OBJEXT) + -rm -f src/output.$(OBJEXT) + -rm -f src/parser.$(OBJEXT) + -rm -f src/settings.$(OBJEXT) + -rm -f src/sha1.$(OBJEXT) + -rm -f src/sort.$(OBJEXT) + -rm -f src/tcabdb.$(OBJEXT) + -rm -f src/tcbtdb.$(OBJEXT) + -rm -f src/ui.$(OBJEXT) + -rm -f src/util.$(OBJEXT) + -rm -f src/websocket.$(OBJEXT) + -rm -f src/xmalloc.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include src/$(DEPDIR)/base64.Po +include src/$(DEPDIR)/bin2c.Po +include src/$(DEPDIR)/browsers.Po +include src/$(DEPDIR)/color.Po +include src/$(DEPDIR)/commons.Po +include src/$(DEPDIR)/csv.Po +include src/$(DEPDIR)/error.Po +include src/$(DEPDIR)/gdashboard.Po +include src/$(DEPDIR)/gdns.Po +include src/$(DEPDIR)/geoip1.Po +include src/$(DEPDIR)/geoip2.Po +include src/$(DEPDIR)/gholder.Po +include src/$(DEPDIR)/gkhash.Po +include src/$(DEPDIR)/gmenu.Po +include src/$(DEPDIR)/goaccess.Po +include src/$(DEPDIR)/gslist.Po +include src/$(DEPDIR)/gstorage.Po +include src/$(DEPDIR)/gwsocket.Po +include src/$(DEPDIR)/json.Po +include src/$(DEPDIR)/opesys.Po +include src/$(DEPDIR)/options.Po +include src/$(DEPDIR)/output.Po +include src/$(DEPDIR)/parser.Po +include src/$(DEPDIR)/settings.Po +include src/$(DEPDIR)/sha1.Po +include src/$(DEPDIR)/sort.Po +include src/$(DEPDIR)/tcabdb.Po +include src/$(DEPDIR)/tcbtdb.Po +include src/$(DEPDIR)/ui.Po +include src/$(DEPDIR)/util.Po +include src/$(DEPDIR)/websocket.Po +include src/$(DEPDIR)/xmalloc.Po + +.c.o: + depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ + $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c -o $@ $< + +.c.obj: + depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ + $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ + $(am__mv) $$depbase.Tpo $$depbase.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-man1: $(dist_man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-dist_confDATA: $(dist_conf_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_conf_DATA)'; test -n "$(confdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(confdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(confdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(confdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(confdir)" || exit $$?; \ + done + +uninstall-dist_confDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_conf_DATA)'; test -n "$(confdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(confdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod u+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(confdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf src/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-dist_confDATA install-man + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf src/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-dist_confDATA \ + uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ + ctags-recursive install install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-binPROGRAMS \ + clean-generic clean-noinstPROGRAMS ctags ctags-recursive dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am \ + install-dist_confDATA install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-man1 install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-dist_confDATA uninstall-man \ + uninstall-man1 + + +# Tpls +tpls.h: bin2c$(EXEEXT) resources/tpls.html + cat resources/tpls.html | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/tpls.html.tmp + ./bin2c resources/tpls.html.tmp src/tpls.h tpls +# ./bin2c resources/tpls.html src/tpls.h tpls +# Bootstrap +bootstrapcss.h: bin2c$(EXEEXT) resources/css/bootstrap.min.css + cat resources/css/bootstrap.min.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/bootstrap.min.css.tmp + ./bin2c resources/css/bootstrap.min.css.tmp src/bootstrapcss.h bootstrap_css +# ./bin2c resources/css/bootstrap.min.css src/bootstrapcss.h bootstrap_css +# Font Awesome +facss.h: bin2c$(EXEEXT) resources/css/fa.min.css + cat resources/css/fa.min.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/fa.min.css.tmp + ./bin2c resources/css/fa.min.css.tmp src/facss.h fa_css +# ./bin2c resources/css/fa.min.css src/facss.h fa_css +# App.css +appcss.h: bin2c$(EXEEXT) resources/css/app.css + cat resources/css/app.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/app.css.tmp + ./bin2c resources/css/app.css.tmp src/appcss.h app_css +# ./bin2c resources/css/app.css src/appcss.h app_css +# D3.js +d3js.h: bin2c$(EXEEXT) resources/js/d3.v3.min.js + cat resources/js/d3.v3.min.js | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/d3.v3.min.js.tmp + ./bin2c resources/js/d3.v3.min.js.tmp src/d3js.h d3_js +# ./bin2c resources/js/d3.v3.min.js src/d3js.h d3_js +# Hogan.js +hoganjs.h: bin2c$(EXEEXT) resources/js/hogan.min.js + cat resources/js/hogan.min.js | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/hogan.min.js.tmp + ./bin2c resources/js/hogan.min.js.tmp src/hoganjs.h hogan_js +# ./bin2c resources/js/hogan.min.js src/hoganjs.h hogan_js +# Charts.js +chartsjs.h: bin2c$(EXEEXT) resources/js/charts.js + cat resources/js/charts.js | sed -E "s@(,|;)[[:space:]]*//..*@\1@g" | sed -E "s@^[[:space:]]*//..*@@g" | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/charts.js.tmp + ./bin2c resources/js/charts.js.tmp src/chartsjs.h charts_js +# ./bin2c resources/js/charts.js src/chartsjs.h charts_js +# App.js +appjs.h: bin2c$(EXEEXT) resources/js/app.js + cat resources/js/app.js | sed -E "s@(,|;)[[:space:]]*//..*@\1@g" | sed -E "s@^[[:space:]]*//..*@@g" | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/app.js.tmp + ./bin2c resources/js/app.js.tmp src/appjs.h app_js +# ./bin2c resources/js/app.js src/appjs.h app_js + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/goaccess++/Makefile.am b/goaccess++/Makefile.am new file mode 100644 index 0000000..ec26f9b --- /dev/null +++ b/goaccess++/Makefile.am @@ -0,0 +1,219 @@ +#AUTOMAKE_OPTIONS = foreign +bin_PROGRAMS = goaccess +AUTOMAKE_OPTIONS = subdir-objects + +dist_noinst_DATA = \ + resources/tpls.html \ + resources/css/app.css \ + resources/css/bootstrap.min.css \ + resources/css/fa.min.css \ + resources/js/app.js \ + resources/js/charts.js \ + resources/js/d3.v3.min.js \ + resources/js/hogan.min.js + +noinst_PROGRAMS = bin2c +bin2c_SOURCES = src/bin2c.c + +BUILT_SOURCES = \ + tpls.h \ + bootstrapcss.h \ + facss.h \ + appcss.h \ + d3js.h \ + hoganjs.h \ + chartsjs.h \ + appjs.h + +CLEANFILES = \ + src/tpls.h \ + src/bootstrapcss.h \ + src/facss.h \ + src/appcss.h \ + src/d3js.h \ + src/hoganjs.h \ + src/chartsjs.h \ + src/appjs.h \ + resources/tpls.html.tmp \ + resources/css/bootstrap.min.css.tmp \ + resources/css/fa.min.css.tmp \ + resources/css/app.css.tmp \ + resources/js/d3.v3.min.js.tmp \ + resources/js/hogan.min.js.tmp \ + resources/js/charts.js.tmp \ + resources/js/app.js.tmp + +# Tpls +tpls.h: bin2c$(EXEEXT) resources/tpls.html +if HAS_SEDTR + cat resources/tpls.html | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/tpls.html.tmp + ./bin2c resources/tpls.html.tmp src/tpls.h tpls +else + ./bin2c resources/tpls.html src/tpls.h tpls +endif +# Bootstrap +bootstrapcss.h: bin2c$(EXEEXT) resources/css/bootstrap.min.css +if HAS_SEDTR + cat resources/css/bootstrap.min.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/bootstrap.min.css.tmp + ./bin2c resources/css/bootstrap.min.css.tmp src/bootstrapcss.h bootstrap_css +else + ./bin2c resources/css/bootstrap.min.css src/bootstrapcss.h bootstrap_css +endif +# Font Awesome +facss.h: bin2c$(EXEEXT) resources/css/fa.min.css +if HAS_SEDTR + cat resources/css/fa.min.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/fa.min.css.tmp + ./bin2c resources/css/fa.min.css.tmp src/facss.h fa_css +else + ./bin2c resources/css/fa.min.css src/facss.h fa_css +endif +# App.css +appcss.h: bin2c$(EXEEXT) resources/css/app.css +if HAS_SEDTR + cat resources/css/app.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/app.css.tmp + ./bin2c resources/css/app.css.tmp src/appcss.h app_css +else + ./bin2c resources/css/app.css src/appcss.h app_css +endif +# D3.js +d3js.h: bin2c$(EXEEXT) resources/js/d3.v3.min.js +if HAS_SEDTR + cat resources/js/d3.v3.min.js | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/d3.v3.min.js.tmp + ./bin2c resources/js/d3.v3.min.js.tmp src/d3js.h d3_js +else + ./bin2c resources/js/d3.v3.min.js src/d3js.h d3_js +endif +# Hogan.js +hoganjs.h: bin2c$(EXEEXT) resources/js/hogan.min.js +if HAS_SEDTR + cat resources/js/hogan.min.js | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/hogan.min.js.tmp + ./bin2c resources/js/hogan.min.js.tmp src/hoganjs.h hogan_js +else + ./bin2c resources/js/hogan.min.js src/hoganjs.h hogan_js +endif +# Charts.js +chartsjs.h: bin2c$(EXEEXT) resources/js/charts.js +if HAS_SEDTR + cat resources/js/charts.js | sed -E "s@(,|;)[[:space:]]*//..*@\1@g" | sed -E "s@^[[:space:]]*//..*@@g" | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/charts.js.tmp + ./bin2c resources/js/charts.js.tmp src/chartsjs.h charts_js +else + ./bin2c resources/js/charts.js src/chartsjs.h charts_js +endif +# App.js +appjs.h: bin2c$(EXEEXT) resources/js/app.js +if HAS_SEDTR + cat resources/js/app.js | sed -E "s@(,|;)[[:space:]]*//..*@\1@g" | sed -E "s@^[[:space:]]*//..*@@g" | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/app.js.tmp + ./bin2c resources/js/app.js.tmp src/appjs.h app_js +else + ./bin2c resources/js/app.js src/appjs.h app_js +endif + +confdir = $(sysconfdir)/goaccess +dist_conf_DATA = config/goaccess.conf +dist_conf_DATA += config/browsers.list + +goaccess_SOURCES = \ + src/base64.c \ + src/base64.h \ + src/browsers.c \ + src/browsers.h \ + src/color.c \ + src/color.h \ + src/commons.c \ + src/commons.h \ + src/csv.c \ + src/csv.h \ + src/error.c \ + src/error.h \ + src/gdashboard.c \ + src/gdashboard.h \ + src/gdns.c \ + src/gdns.h \ + src/gholder.c \ + src/gholder.h \ + src/gmenu.c \ + src/gmenu.h \ + src/goaccess.c \ + src/goaccess.h \ + src/gslist.c \ + src/gslist.h \ + src/gstorage.c \ + src/gstorage.h \ + src/gwsocket.c \ + src/gwsocket.h \ + src/json.c \ + src/json.h \ + src/labels.h \ + src/opesys.c \ + src/opesys.h \ + src/options.c \ + src/options.h \ + src/output.c \ + src/output.h \ + src/parser.c \ + src/parser.h \ + src/settings.c \ + src/settings.h \ + src/sha1.c \ + src/sha1.h \ + src/sort.c \ + src/sort.h \ + src/ui.c \ + src/ui.h \ + src/util.c \ + src/util.h \ + src/websocket.c \ + src/websocket.h \ + src/xmalloc.c \ + src/xmalloc.h + +if TCB +goaccess_SOURCES += \ + src/tcabdb.c \ + src/tcabdb.h \ + src/tcbtdb.c \ + src/tcbtdb.h +else +goaccess_SOURCES += \ + src/khash.h \ + src/gkhash.c \ + src/gkhash.h +endif + +if GEOIP_LEGACY +goaccess_SOURCES += \ + src/geoip1.c \ + src/geoip1.h +endif + +if GEOIP_MMDB +goaccess_SOURCES += \ + src/geoip2.c \ + src/geoip1.h +endif + +if DEBUG +AM_CFLAGS = -DDEBUG -O0 -g -DSYSCONFDIR=\"$(sysconfdir)\" +else +AM_CFLAGS = -O2 -DSYSCONFDIR=\"$(sysconfdir)\" +endif + +if WITH_RDYNAMIC +AM_LDFLAGS = -rdynamic +endif + +AM_CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2 +AM_CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations +AM_CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare +AM_CFLAGS += -Wbad-function-cast -Winline -Wcast-align -Wextra +AM_CFLAGS += -Wdeclaration-after-statement -Wno-missing-field-initializers + +dist_man_MANS = goaccess.1 + +SUBDIRS = po + +ACLOCAL_AMFLAGS = -I m4 + +DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ + +EXTRA_DIST = config.rpath diff --git a/goaccess++/Makefile.in b/goaccess++/Makefile.in new file mode 100644 index 0000000..6ac1f92 --- /dev/null +++ b/goaccess++/Makefile.in @@ -0,0 +1,1268 @@ +# Makefile.in generated by automake 1.11.6 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__make_dryrun = \ + { \ + am__dry=no; \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ + test $$am__dry = yes; \ + } +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +bin_PROGRAMS = goaccess$(EXEEXT) +noinst_PROGRAMS = bin2c$(EXEEXT) +@TCB_TRUE@am__append_1 = \ +@TCB_TRUE@ src/tcabdb.c \ +@TCB_TRUE@ src/tcabdb.h \ +@TCB_TRUE@ src/tcbtdb.c \ +@TCB_TRUE@ src/tcbtdb.h + +@TCB_FALSE@am__append_2 = \ +@TCB_FALSE@ src/khash.h \ +@TCB_FALSE@ src/gkhash.c \ +@TCB_FALSE@ src/gkhash.h + +@GEOIP_LEGACY_TRUE@am__append_3 = \ +@GEOIP_LEGACY_TRUE@ src/geoip1.c \ +@GEOIP_LEGACY_TRUE@ src/geoip1.h + +@GEOIP_MMDB_TRUE@am__append_4 = \ +@GEOIP_MMDB_TRUE@ src/geoip2.c \ +@GEOIP_MMDB_TRUE@ src/geoip1.h + +subdir = . +DIST_COMMON = README $(am__configure_deps) $(dist_conf_DATA) \ + $(dist_man_MANS) $(dist_noinst_DATA) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(top_srcdir)/configure \ + $(top_srcdir)/src/config.h.in ABOUT-NLS AUTHORS COPYING \ + ChangeLog INSTALL NEWS TODO compile config.guess config.rpath \ + config.sub depcomp install-sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(confdir)" +PROGRAMS = $(bin_PROGRAMS) $(noinst_PROGRAMS) +am__dirstamp = $(am__leading_dot)dirstamp +am_bin2c_OBJECTS = src/bin2c.$(OBJEXT) +bin2c_OBJECTS = $(am_bin2c_OBJECTS) +bin2c_LDADD = $(LDADD) +am__goaccess_SOURCES_DIST = src/base64.c src/base64.h src/browsers.c \ + src/browsers.h src/color.c src/color.h src/commons.c \ + src/commons.h src/csv.c src/csv.h src/error.c src/error.h \ + src/gdashboard.c src/gdashboard.h src/gdns.c src/gdns.h \ + src/gholder.c src/gholder.h src/gmenu.c src/gmenu.h \ + src/goaccess.c src/goaccess.h src/gslist.c src/gslist.h \ + src/gstorage.c src/gstorage.h src/gwsocket.c src/gwsocket.h \ + src/json.c src/json.h src/labels.h src/opesys.c src/opesys.h \ + src/options.c src/options.h src/output.c src/output.h \ + src/parser.c src/parser.h src/settings.c src/settings.h \ + src/sha1.c src/sha1.h src/sort.c src/sort.h src/ui.c src/ui.h \ + src/util.c src/util.h src/websocket.c src/websocket.h \ + src/xmalloc.c src/xmalloc.h src/tcabdb.c src/tcabdb.h \ + src/tcbtdb.c src/tcbtdb.h src/khash.h src/gkhash.c \ + src/gkhash.h src/geoip1.c src/geoip1.h src/geoip2.c +@TCB_TRUE@am__objects_1 = src/tcabdb.$(OBJEXT) src/tcbtdb.$(OBJEXT) +@TCB_FALSE@am__objects_2 = src/gkhash.$(OBJEXT) +@GEOIP_LEGACY_TRUE@am__objects_3 = src/geoip1.$(OBJEXT) +@GEOIP_MMDB_TRUE@am__objects_4 = src/geoip2.$(OBJEXT) +am_goaccess_OBJECTS = src/base64.$(OBJEXT) src/browsers.$(OBJEXT) \ + src/color.$(OBJEXT) src/commons.$(OBJEXT) src/csv.$(OBJEXT) \ + src/error.$(OBJEXT) src/gdashboard.$(OBJEXT) \ + src/gdns.$(OBJEXT) src/gholder.$(OBJEXT) src/gmenu.$(OBJEXT) \ + src/goaccess.$(OBJEXT) src/gslist.$(OBJEXT) \ + src/gstorage.$(OBJEXT) src/gwsocket.$(OBJEXT) \ + src/json.$(OBJEXT) src/opesys.$(OBJEXT) src/options.$(OBJEXT) \ + src/output.$(OBJEXT) src/parser.$(OBJEXT) \ + src/settings.$(OBJEXT) src/sha1.$(OBJEXT) src/sort.$(OBJEXT) \ + src/ui.$(OBJEXT) src/util.$(OBJEXT) src/websocket.$(OBJEXT) \ + src/xmalloc.$(OBJEXT) $(am__objects_1) $(am__objects_2) \ + $(am__objects_3) $(am__objects_4) +goaccess_OBJECTS = $(am_goaccess_OBJECTS) +goaccess_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +SOURCES = $(bin2c_SOURCES) $(goaccess_SOURCES) +DIST_SOURCES = $(bin2c_SOURCES) $(am__goaccess_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(dist_man_MANS) +DATA = $(dist_conf_DATA) $(dist_noinst_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POSUB = @POSUB@ +POW_LIB = @POW_LIB@ +SED_CHECK = @SED_CHECK@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +TR_CHECK = @TR_CHECK@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = subdir-objects +dist_noinst_DATA = \ + resources/tpls.html \ + resources/css/app.css \ + resources/css/bootstrap.min.css \ + resources/css/fa.min.css \ + resources/js/app.js \ + resources/js/charts.js \ + resources/js/d3.v3.min.js \ + resources/js/hogan.min.js + +bin2c_SOURCES = src/bin2c.c +BUILT_SOURCES = \ + tpls.h \ + bootstrapcss.h \ + facss.h \ + appcss.h \ + d3js.h \ + hoganjs.h \ + chartsjs.h \ + appjs.h + +CLEANFILES = \ + src/tpls.h \ + src/bootstrapcss.h \ + src/facss.h \ + src/appcss.h \ + src/d3js.h \ + src/hoganjs.h \ + src/chartsjs.h \ + src/appjs.h \ + resources/tpls.html.tmp \ + resources/css/bootstrap.min.css.tmp \ + resources/css/fa.min.css.tmp \ + resources/css/app.css.tmp \ + resources/js/d3.v3.min.js.tmp \ + resources/js/hogan.min.js.tmp \ + resources/js/charts.js.tmp \ + resources/js/app.js.tmp + +confdir = $(sysconfdir)/goaccess +dist_conf_DATA = config/goaccess.conf config/browsers.list +goaccess_SOURCES = src/base64.c src/base64.h src/browsers.c \ + src/browsers.h src/color.c src/color.h src/commons.c \ + src/commons.h src/csv.c src/csv.h src/error.c src/error.h \ + src/gdashboard.c src/gdashboard.h src/gdns.c src/gdns.h \ + src/gholder.c src/gholder.h src/gmenu.c src/gmenu.h \ + src/goaccess.c src/goaccess.h src/gslist.c src/gslist.h \ + src/gstorage.c src/gstorage.h src/gwsocket.c src/gwsocket.h \ + src/json.c src/json.h src/labels.h src/opesys.c src/opesys.h \ + src/options.c src/options.h src/output.c src/output.h \ + src/parser.c src/parser.h src/settings.c src/settings.h \ + src/sha1.c src/sha1.h src/sort.c src/sort.h src/ui.c src/ui.h \ + src/util.c src/util.h src/websocket.c src/websocket.h \ + src/xmalloc.c src/xmalloc.h $(am__append_1) $(am__append_2) \ + $(am__append_3) $(am__append_4) +@DEBUG_FALSE@AM_CFLAGS = -O2 -DSYSCONFDIR=\"$(sysconfdir)\" \ +@DEBUG_FALSE@ -Wno-long-long -Wall -W -Wnested-externs \ +@DEBUG_FALSE@ -Wformat=2 -Wmissing-prototypes \ +@DEBUG_FALSE@ -Wstrict-prototypes -Wmissing-declarations \ +@DEBUG_FALSE@ -Wwrite-strings -Wshadow -Wpointer-arith \ +@DEBUG_FALSE@ -Wsign-compare -Wbad-function-cast -Winline \ +@DEBUG_FALSE@ -Wcast-align -Wextra \ +@DEBUG_FALSE@ -Wdeclaration-after-statement \ +@DEBUG_FALSE@ -Wno-missing-field-initializers +@DEBUG_TRUE@AM_CFLAGS = -DDEBUG -O0 -g -DSYSCONFDIR=\"$(sysconfdir)\" \ +@DEBUG_TRUE@ -Wno-long-long -Wall -W -Wnested-externs \ +@DEBUG_TRUE@ -Wformat=2 -Wmissing-prototypes \ +@DEBUG_TRUE@ -Wstrict-prototypes -Wmissing-declarations \ +@DEBUG_TRUE@ -Wwrite-strings -Wshadow -Wpointer-arith \ +@DEBUG_TRUE@ -Wsign-compare -Wbad-function-cast -Winline \ +@DEBUG_TRUE@ -Wcast-align -Wextra -Wdeclaration-after-statement \ +@DEBUG_TRUE@ -Wno-missing-field-initializers +@WITH_RDYNAMIC_TRUE@AM_LDFLAGS = -rdynamic +dist_man_MANS = goaccess.1 +SUBDIRS = po +ACLOCAL_AMFLAGS = -I m4 +EXTRA_DIST = config.rpath +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .o .obj +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +src/config.h: src/stamp-h1 + @if test ! -f $@; then rm -f src/stamp-h1; else :; fi + @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) src/stamp-h1; else :; fi + +src/stamp-h1: $(top_srcdir)/src/config.h.in $(top_builddir)/config.status + @rm -f src/stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status src/config.h +$(top_srcdir)/src/config.h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f src/stamp-h1 + touch $@ + +distclean-hdr: + -rm -f src/config.h src/stamp-h1 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +clean-noinstPROGRAMS: + -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) +src/$(am__dirstamp): + @$(MKDIR_P) src + @: > src/$(am__dirstamp) +src/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) src/$(DEPDIR) + @: > src/$(DEPDIR)/$(am__dirstamp) +src/bin2c.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +bin2c$(EXEEXT): $(bin2c_OBJECTS) $(bin2c_DEPENDENCIES) $(EXTRA_bin2c_DEPENDENCIES) + @rm -f bin2c$(EXEEXT) + $(LINK) $(bin2c_OBJECTS) $(bin2c_LDADD) $(LIBS) +src/base64.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/browsers.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/color.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/commons.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/csv.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/error.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/gdashboard.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gdns.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/gholder.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gmenu.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/goaccess.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gslist.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gstorage.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gwsocket.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/json.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/opesys.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/options.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/output.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/parser.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/settings.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/sha1.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/sort.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/ui.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/util.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/websocket.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/xmalloc.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/tcabdb.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/tcbtdb.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/gkhash.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/geoip1.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +src/geoip2.$(OBJEXT): src/$(am__dirstamp) \ + src/$(DEPDIR)/$(am__dirstamp) +goaccess$(EXEEXT): $(goaccess_OBJECTS) $(goaccess_DEPENDENCIES) $(EXTRA_goaccess_DEPENDENCIES) + @rm -f goaccess$(EXEEXT) + $(LINK) $(goaccess_OBJECTS) $(goaccess_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f src/base64.$(OBJEXT) + -rm -f src/bin2c.$(OBJEXT) + -rm -f src/browsers.$(OBJEXT) + -rm -f src/color.$(OBJEXT) + -rm -f src/commons.$(OBJEXT) + -rm -f src/csv.$(OBJEXT) + -rm -f src/error.$(OBJEXT) + -rm -f src/gdashboard.$(OBJEXT) + -rm -f src/gdns.$(OBJEXT) + -rm -f src/geoip1.$(OBJEXT) + -rm -f src/geoip2.$(OBJEXT) + -rm -f src/gholder.$(OBJEXT) + -rm -f src/gkhash.$(OBJEXT) + -rm -f src/gmenu.$(OBJEXT) + -rm -f src/goaccess.$(OBJEXT) + -rm -f src/gslist.$(OBJEXT) + -rm -f src/gstorage.$(OBJEXT) + -rm -f src/gwsocket.$(OBJEXT) + -rm -f src/json.$(OBJEXT) + -rm -f src/opesys.$(OBJEXT) + -rm -f src/options.$(OBJEXT) + -rm -f src/output.$(OBJEXT) + -rm -f src/parser.$(OBJEXT) + -rm -f src/settings.$(OBJEXT) + -rm -f src/sha1.$(OBJEXT) + -rm -f src/sort.$(OBJEXT) + -rm -f src/tcabdb.$(OBJEXT) + -rm -f src/tcbtdb.$(OBJEXT) + -rm -f src/ui.$(OBJEXT) + -rm -f src/util.$(OBJEXT) + -rm -f src/websocket.$(OBJEXT) + -rm -f src/xmalloc.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/base64.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/bin2c.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/browsers.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/color.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/commons.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/csv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gdashboard.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gdns.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/geoip1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/geoip2.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gholder.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gkhash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gmenu.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/goaccess.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gslist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gstorage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/gwsocket.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/json.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/opesys.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/options.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/output.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/parser.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/settings.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/sha1.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/sort.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/tcabdb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/tcbtdb.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/ui.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/util.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/websocket.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/xmalloc.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` +install-man1: $(dist_man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(dist_man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-dist_confDATA: $(dist_conf_DATA) + @$(NORMAL_INSTALL) + @list='$(dist_conf_DATA)'; test -n "$(confdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(confdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(confdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(confdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(confdir)" || exit $$?; \ + done + +uninstall-dist_confDATA: + @$(NORMAL_UNINSTALL) + @list='$(dist_conf_DATA)'; test -n "$(confdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(confdir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @list='$(MANS)'; if test -n "$$list"; then \ + list=`for p in $$list; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ + if test -n "$$list" && \ + grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ + echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ + grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ + echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ + echo " typically \`make maintainer-clean' will remove them" >&2; \ + exit 1; \ + else :; fi; \ + else :; fi + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod u+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(confdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f src/$(DEPDIR)/$(am__dirstamp) + -rm -f src/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf src/$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-dist_confDATA install-man + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf src/$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-dist_confDATA \ + uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \ + ctags-recursive install install-am install-strip \ + tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-binPROGRAMS \ + clean-generic clean-noinstPROGRAMS ctags ctags-recursive dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-lzma dist-shar \ + dist-tarZ dist-xz dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am \ + install-dist_confDATA install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-man1 install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \ + tags tags-recursive uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-dist_confDATA uninstall-man \ + uninstall-man1 + + +# Tpls +tpls.h: bin2c$(EXEEXT) resources/tpls.html +@HAS_SEDTR_TRUE@ cat resources/tpls.html | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/tpls.html.tmp +@HAS_SEDTR_TRUE@ ./bin2c resources/tpls.html.tmp src/tpls.h tpls +@HAS_SEDTR_FALSE@ ./bin2c resources/tpls.html src/tpls.h tpls +# Bootstrap +bootstrapcss.h: bin2c$(EXEEXT) resources/css/bootstrap.min.css +@HAS_SEDTR_TRUE@ cat resources/css/bootstrap.min.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/bootstrap.min.css.tmp +@HAS_SEDTR_TRUE@ ./bin2c resources/css/bootstrap.min.css.tmp src/bootstrapcss.h bootstrap_css +@HAS_SEDTR_FALSE@ ./bin2c resources/css/bootstrap.min.css src/bootstrapcss.h bootstrap_css +# Font Awesome +facss.h: bin2c$(EXEEXT) resources/css/fa.min.css +@HAS_SEDTR_TRUE@ cat resources/css/fa.min.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/fa.min.css.tmp +@HAS_SEDTR_TRUE@ ./bin2c resources/css/fa.min.css.tmp src/facss.h fa_css +@HAS_SEDTR_FALSE@ ./bin2c resources/css/fa.min.css src/facss.h fa_css +# App.css +appcss.h: bin2c$(EXEEXT) resources/css/app.css +@HAS_SEDTR_TRUE@ cat resources/css/app.css | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/css/app.css.tmp +@HAS_SEDTR_TRUE@ ./bin2c resources/css/app.css.tmp src/appcss.h app_css +@HAS_SEDTR_FALSE@ ./bin2c resources/css/app.css src/appcss.h app_css +# D3.js +d3js.h: bin2c$(EXEEXT) resources/js/d3.v3.min.js +@HAS_SEDTR_TRUE@ cat resources/js/d3.v3.min.js | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/d3.v3.min.js.tmp +@HAS_SEDTR_TRUE@ ./bin2c resources/js/d3.v3.min.js.tmp src/d3js.h d3_js +@HAS_SEDTR_FALSE@ ./bin2c resources/js/d3.v3.min.js src/d3js.h d3_js +# Hogan.js +hoganjs.h: bin2c$(EXEEXT) resources/js/hogan.min.js +@HAS_SEDTR_TRUE@ cat resources/js/hogan.min.js | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/hogan.min.js.tmp +@HAS_SEDTR_TRUE@ ./bin2c resources/js/hogan.min.js.tmp src/hoganjs.h hogan_js +@HAS_SEDTR_FALSE@ ./bin2c resources/js/hogan.min.js src/hoganjs.h hogan_js +# Charts.js +chartsjs.h: bin2c$(EXEEXT) resources/js/charts.js +@HAS_SEDTR_TRUE@ cat resources/js/charts.js | sed -E "s@(,|;)[[:space:]]*//..*@\1@g" | sed -E "s@^[[:space:]]*//..*@@g" | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/charts.js.tmp +@HAS_SEDTR_TRUE@ ./bin2c resources/js/charts.js.tmp src/chartsjs.h charts_js +@HAS_SEDTR_FALSE@ ./bin2c resources/js/charts.js src/chartsjs.h charts_js +# App.js +appjs.h: bin2c$(EXEEXT) resources/js/app.js +@HAS_SEDTR_TRUE@ cat resources/js/app.js | sed -E "s@(,|;)[[:space:]]*//..*@\1@g" | sed -E "s@^[[:space:]]*//..*@@g" | sed "s/^[[:space:]]*//" | sed "/^$$/d" | tr -d "\r\n" > resources/js/app.js.tmp +@HAS_SEDTR_TRUE@ ./bin2c resources/js/app.js.tmp src/appjs.h app_js +@HAS_SEDTR_FALSE@ ./bin2c resources/js/app.js src/appjs.h app_js + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/goaccess++/NEWS b/goaccess++/NEWS new file mode 100644 index 0000000..072705c --- /dev/null +++ b/goaccess++/NEWS @@ -0,0 +1,80 @@ +Copyright (C) 2009-2018 +Gerardo Orellana + +* Version history: + - 1.3 [Friday, November 23, 2018] + . GoAccess 1.3 Released. See ChangeLog for new features/bug-fixes. + - 1.2 [Tuesday, March 07, 2017] + . GoAccess 1.2 Released. See ChangeLog for new features/bug-fixes. + - 1.1.1 [Wednesday, November 23, 2016] + . GoAccess 1.1.1 Released. See ChangeLog for new features/bug-fixes. + - 1.1 [Tuesday, November 08, 2016] + . GoAccess 1.1 Released. See ChangeLog for new features/bug-fixes. + - 1.0.2 [Tuesday, July 05, 2016] + . GoAccess 1.0.2 Released. See ChangeLog for new features/bug-fixes. + - 1.0.1 [Friday, June 17, 2016] + . GoAccess 1.0.1 Released. See ChangeLog for new features/bug-fixes. + - 1.0 [Thursday, June 09, 2016] + . GoAccess 1.0 Released. See ChangeLog for new features/bug-fixes. + - 0.9.8 [Monday, February 29, 2016] + . GoAccess 0.9.8 Released. See ChangeLog for new features/bug-fixes. + - 0.9.7 [Monday, December 21, 2015] + . GoAccess 0.9.7 Released. See ChangeLog for new features/bug-fixes. + - 0.9.6 [Tuesday, October 27, 2015] + . GoAccess 0.9.6 Released. See ChangeLog for new features/bug-fixes. + - 0.9.5 [Thursday, October 22, 2015] + . GoAccess 0.9.5 Released. See ChangeLog for new features/bug-fixes. + - 0.9.4 [Tuesday, September 08 , 2015] + . GoAccess 0.9.4 Released. See ChangeLog for new features/bug-fixes. + - 0.9.3 [Wednesday, August 28, 2015] + . GoAccess 0.9.3 Released. See ChangeLog for new features/bug-fixes. + - 0.9.2 [Monday, July 06, 2015] + . GoAccess 0.9.2 Released. See ChangeLog for new features/bug-fixes. + - 0.9.1 [Tuesday, May 26, 2015] + . GoAccess 0.9.1 Released. See ChangeLog for new features/bug-fixes. + - 0.9 [Thursday, March 19, 2015] + . GoAccess 0.9 Released. See ChangeLog for new features/bug-fixes. + - 0.8.5 [Sunday, September 14, 2014] + . GoAccess 0.8.5 Released. See ChangeLog for new features/bug-fixes. + - 0.8.4 [Monday, September 08, 2014] + . GoAccess 0.8.4 Released. See ChangeLog for new features/bug-fixes. + - 0.8.3 [Monday, July 28, 2014] + . GoAccess 0.8.3 Released. See ChangeLog for new features/bug-fixes. + - 0.8.2 [Monday, July 21, 2014] + . GoAccess 0.8.2 Released. See ChangeLog for new features/bug-fixes. + - 0.8.1 [Monday, June 16, 2014] + . GoAccess 0.8.1 Released. See ChangeLog for new features/bug-fixes. + - 0.8 [Monday, May 20, 2013] + . GoAccess 0.8 Released. See ChangeLog for new features/bug-fixes. + - 0.7.1 [Monday, February 17, 2014] + . GoAccess 0.7.1 Released. See ChangeLog for new features/bug-fixes. + - 0.7 [Monday, December 16, 2013] + . GoAccess 0.7 Released. See ChangeLog for new features/bug-fixes. + - 0.6.1 [Monday, October 07, 2013] + . GoAccess 0.6.1 Released. See ChangeLog for new features/bug-fixes. + - 0.6 [Monday, July 15, 2013] + . GoAccess 0.6 Released. See ChangeLog for new features/bug-fixes. + - 0.5 [Monday, June 04, 2012] + . GoAccess 0.5 Released. See ChangeLog for new features/bug-fixes. + - 0.4.2 [Monday, January 03, 2011] + . GoAccess 0.4.2 Released. See ChangeLog for new features/bug-fixes. + - 0.4.1 [Monday, December 13, 2010] + . GoAccess 0.4.1 Released. See ChangeLog for new features/bug-fixes. + - 0.4 [Tuesday, November 30, 2010] + . GoAccess 0.4 Released. See ChangeLog for new features/bug-fixes. + - 0.3.3 [Monday, September 27, 2010] + . GoAccess 0.3.3 Released. See ChangeLog for new features/bug-fixes. + - 0.3.2 [Thursday, September 09 2010] + . GoAccess 0.3.2 Released. See ChangeLog for new features/bug-fixes. + - 0.3.1 [Friday, September 03, 2010] + . GoAccess 0.3.1 Released. See ChangeLog for new features/bug-fixes. + - 0.3 [Sunday, August 29, 2010] + . GoAccess 0.3 Released. See ChangeLog for new features/bug-fixes. + - 0.2 [Sunday, July 25, 2010] + . GoAccess 0.2 Released. See ChangeLog for new features/bug-fixes. + - 0.1.2 [Tuesday, July 13, 2010] + . GoAccess 0.1.2 Released. See ChangeLog for new features/bug-fixes. + - 0.1.1 [Saturday, July 10, 2010] + . GoAccess 0.1.1 Released. See ChangeLog for new features/bug-fixes. + - 0.1 [Wednesday, July 07, 2010] + . Welcome to the GoAccess 0.1 Released. diff --git a/goaccess++/README b/goaccess++/README new file mode 100644 index 0000000..c573004 --- /dev/null +++ b/goaccess++/README @@ -0,0 +1,100 @@ +What is it? +------------- +GoAccess is an open source real-time web log analyzer and interactive viewer +that runs in a terminal in *nix systems or through your browser. + +It provides fast and valuable HTTP statistics for system administrators that +require a visual server report on the fly. + +Features +------------------------------- +GoAccess parses the specified web log file and +outputs the data to the X terminal. Features include: + + * Completely Real Time + All panels and metrics are timed to be updated every 200 ms on the terminal + output and every second on the HTML output. + + * No configuration needed + You can just run it against your access log file, pick the log format and + let GoAccess parse the access log and show you the stats. + + * Track Application Response Time + Track the time taken to serve the request. Extremely useful if you want to + track pages that are slowing down your site. + + * Nearly All Web Log Formats + GoAccess allows any custom log format string. Predefined options include, + Apache, Nginx, Amazon S3, Elastic Load Balancing, CloudFront, etc + + * Incremental Log Processing + Need data persistence? GoAccess has the ability to process logs incrementally + through the on-disk B+Tree database. + + * Only one dependency + GoAccess is written in C. To run it, you only need ncurses as a dependency. + That's it. It even has its own Web Socket server - http://gwsocket.io/. + + * Visitors + Determine the amount of hits, visitors, bandwidth, and metrics for slowest + running requests by the hour, or date. + + * Metrics per Virtual Host + Have multiple Virtual Hosts (Server Blocks)? A panel that displays which + virtual host is consuming most of the web server resources. + + * Color Scheme Customizable + Tailor GoAccess to suit your own color taste/schemes. Either through the + terminal, or by simply updating the stylesheet on the HTML output. + + * Support for large datasets + GoAccess features an on-disk B+Tree storage for large datasets where it is not + possible to fit everything in memory. + + * Docker support + GoAccess comes with a default Docker (https://hub.docker.com/r/allinurl/goaccess/) + that will listen for HTTP connections on port 7890. Although, you can still + fully configure it, by using Volume mapping and editing goaccess.conf. + + * and more... visit https://goaccess.io for more details. + + +Why GoAccess? +------------- +GoAccess was designed to be a fast, terminal-based log analyzer. Its core idea +is to quickly analyze and view web server statistics in real time without +needing to use your browser (great if you want to do a quick analysis of your +access log via SSH, or if you simply love working in the terminal). + +While the terminal output is the default output, it has the capability to +generate a complete real-time HTML report, as well as a JSON, and CSV report. + +You can see it more of a monitor command tool than anything else. + +Keys +---- +The user can make use of the following keys: + + * ^F1^ or ^h^ Main help, + * ^F5^ Redraw [main window], + * ^q^ Quit the program, current window or module, + * ^o^ or ^ENTER^ Expand selected module, + * ^[Shift]0-9^ Set selected module to active, + * ^Up^ arrow Scroll up main dashboard, + * ^Down^ arrow Scroll down main dashboard, + * ^j^ Scroll down within expanded module, + * ^k^ Scroll up within expanded module, + * ^c^ Set or change scheme color, + * ^CTRL^ + ^f^ Scroll forward one screen within, + * active module, + * ^CTRL^ + ^b^ Scroll backward one screen within, + * active module, + * ^TAB^ Iterate modules (forward), + * ^SHIFT^ + ^TAB^ Iterate modules (backward), + * ^s^ Sort options for current module, + * ^/^ Search across all modules, + * ^n^ Find position of the next occurrence, + * ^g^ Move to the first item or top of screen, + * ^G^ Move to the last item or bottom of screen, + +Examples can be found by running `man goaccess`. diff --git a/goaccess++/TODO b/goaccess++/TODO new file mode 100644 index 0000000..d9abf21 --- /dev/null +++ b/goaccess++/TODO @@ -0,0 +1,10 @@ +1Copyright (C) 2009-2018 +6erardo Orellana + +For a more comprehensive list of to-do items, please refer to the GitHub site. +https://github.com/allinurl/goaccess/issues + +or visit http://goaccess.io/faq#todo + +If you are interested in working on any of the items listed in there, email +goaccess@prosoftcorp.com or better, open a new issue: diff --git a/goaccess++/aclocal.m4 b/goaccess++/aclocal.m4 new file mode 100644 index 0000000..b04779f --- /dev/null +++ b/goaccess++/aclocal.m4 @@ -0,0 +1,1015 @@ +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, +# Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, +[m4_warning([this file was generated for autoconf 2.69. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.6], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.6])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009, +# 2010, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_PROG_CC_C_O +# -------------- +# Like AC_PROG_CC_C_O, but changed for automake. +AC_DEFUN([AM_PROG_CC_C_O], +[AC_REQUIRE([AC_PROG_CC_C_O])dnl +AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +dnl Make sure AC_PROG_CC is never called again, or it will override our +dnl setting of CC. +m4_define([AC_PROG_CC], + [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation, +# Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software +# Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/gettext.m4]) +m4_include([m4/iconv.m4]) +m4_include([m4/intlmacosx.m4]) +m4_include([m4/lib-ld.m4]) +m4_include([m4/lib-link.m4]) +m4_include([m4/lib-prefix.m4]) +m4_include([m4/nls.m4]) +m4_include([m4/po.m4]) +m4_include([m4/progtest.m4]) diff --git a/goaccess++/bin2c b/goaccess++/bin2c new file mode 100644 index 0000000..7a5bd87 Binary files /dev/null and b/goaccess++/bin2c differ diff --git a/goaccess++/compile b/goaccess++/compile new file mode 100644 index 0000000..862a14e --- /dev/null +++ b/goaccess++/compile @@ -0,0 +1,343 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2012-03-05.13; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free +# Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/goaccess++/config.guess b/goaccess++/config.guess new file mode 100644 index 0000000..d622a44 --- /dev/null +++ b/goaccess++/config.guess @@ -0,0 +1,1530 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-02-10' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/goaccess++/config.log b/goaccess++/config.log new file mode 100644 index 0000000..4cbbf00 --- /dev/null +++ b/goaccess++/config.log @@ -0,0 +1,1751 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by goaccess configure 1.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ ./configure --enable-utf8 --enable-geoip=legacy + +## --------- ## +## Platform. ## +## --------- ## + +hostname = ubuntu +uname -m = x86_64 +uname -r = 5.15.0-105-generic +uname -s = Linux +uname -v = #115~20.04.1-Ubuntu SMP Mon Apr 15 17:33:04 UTC 2024 + +/usr/bin/uname -p = x86_64 +/bin/uname -X = unknown + +/bin/arch = x86_64 +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /usr/local/sbin +PATH: /usr/local/bin +PATH: /usr/sbin +PATH: /usr/bin +PATH: /sbin +PATH: /bin +PATH: /usr/games +PATH: /usr/local/games +PATH: /snap/bin + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:2443: checking for a BSD-compatible install +configure:2511: result: /usr/bin/install -c +configure:2522: checking whether build environment is sane +configure:2572: result: yes +configure:2713: checking for a thread-safe mkdir -p +configure:2752: result: /usr/bin/mkdir -p +configure:2765: checking for gawk +configure:2795: result: no +configure:2765: checking for mawk +configure:2781: found /usr/bin/mawk +configure:2792: result: mawk +configure:2803: checking whether make sets $(MAKE) +configure:2825: result: yes +configure:2964: checking for gcc +configure:2980: found /usr/bin/gcc +configure:2991: result: gcc +configure:3220: checking for C compiler version +configure:3229: gcc --version >&5 +gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0 +Copyright (C) 2019 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +configure:3240: $? = 0 +configure:3229: gcc -v >&5 +Using built-in specs. +COLLECT_GCC=gcc +COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper +OFFLOAD_TARGET_NAMES=nvptx-none:hsa +OFFLOAD_TARGET_DEFAULT=1 +Target: x86_64-linux-gnu +Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.2' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-9QDOt0/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu +Thread model: posix +gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2) +configure:3240: $? = 0 +configure:3229: gcc -V >&5 +gcc: error: unrecognized command line option '-V' +gcc: fatal error: no input files +compilation terminated. +configure:3240: $? = 1 +configure:3229: gcc -qversion >&5 +gcc: error: unrecognized command line option '-qversion'; did you mean '--version'? +gcc: fatal error: no input files +compilation terminated. +configure:3240: $? = 1 +configure:3260: checking whether the C compiler works +configure:3282: gcc conftest.c >&5 +configure:3286: $? = 0 +configure:3334: result: yes +configure:3337: checking for C compiler default output file name +configure:3339: result: a.out +configure:3345: checking for suffix of executables +configure:3352: gcc -o conftest conftest.c >&5 +configure:3356: $? = 0 +configure:3378: result: +configure:3400: checking whether we are cross compiling +configure:3408: gcc -o conftest conftest.c >&5 +configure:3412: $? = 0 +configure:3419: ./conftest +configure:3423: $? = 0 +configure:3411: result: no +configure:3416: checking for suffix of object files +configure:3438: gcc -c conftest.c >&5 +configure:3442: $? = 0 +configure:3463: result: o +configure:3467: checking whether we are using the GNU C compiler +configure:3486: gcc -c conftest.c >&5 +configure:3486: $? = 0 +configure:3495: result: yes +configure:3504: checking whether gcc accepts -g +configure:3524: gcc -c -g conftest.c >&5 +configure:3524: $? = 0 +configure:3565: result: yes +configure:3582: checking for gcc option to accept ISO C89 +configure:3645: gcc -c conftest.c >&5 +configure:3645: $? = 0 +configure:3658: result: none needed +configure:3689: checking for style of include used by make +configure:3717: result: GNU +configure:3743: checking dependency style of gcc +configure:3854: result: gcc3 +configure:3870: checking whether gcc and cc understand -c and -o together +configure:3901: gcc -c conftest.c -o conftest2.o >&5 +configure:3905: $? = 0 +configure:3911: gcc -c conftest.c -o conftest2.o >&5 +configure:3915: $? = 0 +configure:3926: cc -c conftest.c >&5 +configure:3930: $? = 0 +configure:3938: cc -c conftest.c -o conftest2.o >&5 +configure:3942: $? = 0 +configure:3948: cc -c conftest.c -o conftest2.o >&5 +configure:3952: $? = 0 +configure:3970: result: yes +configure:3997: checking whether NLS is requested +configure:4006: result: yes +configure:4047: checking for msgfmt +configure:4082: result: no +configure:4088: checking for gmsgfmt +configure:4119: result: : +configure:4170: checking for xgettext +configure:4205: result: no +configure:4248: checking for msgmerge +configure:4282: result: no +configure:4316: checking build system type +configure:4330: result: x86_64-unknown-linux-gnu +configure:4350: checking host system type +configure:4363: result: x86_64-unknown-linux-gnu +configure:4407: checking for ld used by GCC +configure:4471: result: /usr/bin/ld +configure:4478: checking if the linker (/usr/bin/ld) is GNU ld +configure:4491: result: yes +configure:4498: checking for shared library run path origin +configure:4511: result: done +configure:4536: checking how to run the C preprocessor +configure:4567: gcc -E conftest.c +configure:4567: $? = 0 +configure:4581: gcc -E conftest.c +conftest.c:11:10: fatal error: ac_nonexistent.h: No such file or directory + 11 | #include + | ^~~~~~~~~~~~~~~~~~ +compilation terminated. +configure:4581: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| /* end confdefs.h. */ +| #include +configure:4606: result: gcc -E +configure:4626: gcc -E conftest.c +configure:4626: $? = 0 +configure:4640: gcc -E conftest.c +conftest.c:11:10: fatal error: ac_nonexistent.h: No such file or directory + 11 | #include + | ^~~~~~~~~~~~~~~~~~ +compilation terminated. +configure:4640: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| /* end confdefs.h. */ +| #include +configure:4669: checking for grep that handles long lines and -e +configure:4727: result: /usr/bin/grep +configure:4732: checking for egrep +configure:4794: result: /usr/bin/grep -E +configure:5352: checking for CFPreferencesCopyAppValue +configure:5370: gcc -o conftest conftest.c -Wl,-framework -Wl,CoreFoundation >&5 +conftest.c:11:10: fatal error: CoreFoundation/CFPreferences.h: No such file or directory + 11 | #include + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +compilation terminated. +configure:5370: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| /* end confdefs.h. */ +| #include +| int +| main () +| { +| CFPreferencesCopyAppValue(NULL, NULL) +| ; +| return 0; +| } +configure:5379: result: no +configure:5386: checking for CFLocaleCopyCurrent +configure:5404: gcc -o conftest conftest.c -Wl,-framework -Wl,CoreFoundation >&5 +conftest.c:11:10: fatal error: CoreFoundation/CFLocale.h: No such file or directory + 11 | #include + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ +compilation terminated. +configure:5404: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| /* end confdefs.h. */ +| #include +| int +| main () +| { +| CFLocaleCopyCurrent(); +| ; +| return 0; +| } +configure:5413: result: no +configure:5462: checking for GNU gettext in libc +configure:5482: gcc -o conftest conftest.c >&5 +configure:5482: $? = 0 +configure:5491: result: yes +configure:6282: checking whether to use NLS +configure:6284: result: yes +configure:6287: checking where the gettext function comes from +configure:6298: result: libc +configure:6357: checking for libintl_dgettext in -lintl +configure:6382: gcc -o conftest conftest.c -lintl >&5 +/usr/bin/ld: cannot find -lintl +collect2: error: ld returned 1 exit status +configure:6382: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| #define ENABLE_NLS 1 +| #define HAVE_GETTEXT 1 +| #define HAVE_DCGETTEXT 1 +| /* end confdefs.h. */ +| +| /* Override any GCC internal prototype to avoid an error. +| Use char because int might match the return type of a GCC +| builtin and then its argument prototype would still apply. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| char libintl_dgettext (); +| int +| main () +| { +| return libintl_dgettext (); +| ; +| return 0; +| } +configure:6391: result: no +configure:6404: checking for pthread_create in -lpthread +configure:6429: gcc -o conftest conftest.c -lpthread >&5 +configure:6429: $? = 0 +configure:6438: result: yes +configure:6478: checking whether to build with rdynamic for GNU ld +configure:6485: result: yes +configure:6668: checking for GeoIP_new in -lGeoIP +configure:6693: gcc -o conftest -pthread conftest.c -lGeoIP -lpthread >&5 +configure:6693: $? = 0 +configure:6702: result: yes +configure:6773: checking for mvaddwstr in -lncursesw +configure:6798: gcc -o conftest -pthread conftest.c -lncursesw -lGeoIP -lpthread >&5 +configure:6798: $? = 0 +configure:6808: result: yes +configure:6821: checking for library containing tputs +configure:6852: gcc -o conftest -pthread conftest.c -lncursesw -lGeoIP -lpthread >&5 +configure:6852: $? = 0 +configure:6869: result: none required +configure:6886: checking for ncursesw/ncurses.h +configure:6886: gcc -c -pthread conftest.c >&5 +configure:6886: $? = 0 +configure:6886: result: yes +configure:6904: checking for ncurses.h +configure:6904: gcc -c -pthread conftest.c >&5 +configure:6904: $? = 0 +configure:6904: result: yes +configure:7314: checking for sed +configure:7330: found /usr/bin/sed +configure:7342: result: yes +configure:7353: checking for tr +configure:7369: found /usr/bin/tr +configure:7381: result: yes +configure:7403: checking for gethostbyname in -lnsl +configure:7428: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:7428: $? = 0 +configure:7437: result: yes +configure:7448: checking for socket in -lsocket +configure:7473: gcc -o conftest -pthread conftest.c -lsocket -lnsl -lncursesw -lGeoIP -lpthread >&5 +/usr/bin/ld: cannot find -lsocket +collect2: error: ld returned 1 exit status +configure:7473: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| #define ENABLE_NLS 1 +| #define HAVE_GETTEXT 1 +| #define HAVE_DCGETTEXT 1 +| #define HAVE_LIBPTHREAD 1 +| #define HAVE_LIBGEOIP 1 +| #define HAVE_GEOLOCATION 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_NCURSESW_NCURSES_H 1 +| #define HAVE_NCURSES_H 1 +| #define HAVE_LIBNSL 1 +| /* end confdefs.h. */ +| +| /* Override any GCC internal prototype to avoid an error. +| Use char because int might match the return type of a GCC +| builtin and then its argument prototype would still apply. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| char socket (); +| int +| main () +| { +| return socket (); +| ; +| return 0; +| } +configure:7482: result: no +configure:7495: checking for ANSI C header files +configure:7515: gcc -c -pthread conftest.c >&5 +configure:7515: $? = 0 +configure:7588: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:7588: $? = 0 +configure:7588: ./conftest +configure:7588: $? = 0 +configure:7599: result: yes +configure:7612: checking for sys/types.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7612: checking for sys/stat.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7612: checking for stdlib.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7612: checking for string.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7612: checking for memory.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7612: checking for strings.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7612: checking for inttypes.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7612: checking for stdint.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7612: checking for unistd.h +configure:7612: gcc -c -pthread conftest.c >&5 +configure:7612: $? = 0 +configure:7612: result: yes +configure:7626: checking arpa/inet.h usability +configure:7626: gcc -c -pthread conftest.c >&5 +configure:7626: $? = 0 +configure:7626: result: yes +configure:7626: checking arpa/inet.h presence +configure:7626: gcc -E conftest.c +configure:7626: $? = 0 +configure:7626: result: yes +configure:7626: checking for arpa/inet.h +configure:7626: result: yes +configure:7638: checking fcntl.h usability +configure:7638: gcc -c -pthread conftest.c >&5 +configure:7638: $? = 0 +configure:7638: result: yes +configure:7638: checking fcntl.h presence +configure:7638: gcc -E conftest.c +configure:7638: $? = 0 +configure:7638: result: yes +configure:7638: checking for fcntl.h +configure:7638: result: yes +configure:7650: checking for inttypes.h +configure:7650: result: yes +configure:7662: checking limits.h usability +configure:7662: gcc -c -pthread conftest.c >&5 +configure:7662: $? = 0 +configure:7662: result: yes +configure:7662: checking limits.h presence +configure:7662: gcc -E conftest.c +configure:7662: $? = 0 +configure:7662: result: yes +configure:7662: checking for limits.h +configure:7662: result: yes +configure:7674: checking locale.h usability +configure:7674: gcc -c -pthread conftest.c >&5 +configure:7674: $? = 0 +configure:7674: result: yes +configure:7674: checking locale.h presence +configure:7674: gcc -E conftest.c +configure:7674: $? = 0 +configure:7674: result: yes +configure:7674: checking for locale.h +configure:7674: result: yes +configure:7686: checking netdb.h usability +configure:7686: gcc -c -pthread conftest.c >&5 +configure:7686: $? = 0 +configure:7686: result: yes +configure:7686: checking netdb.h presence +configure:7686: gcc -E conftest.c +configure:7686: $? = 0 +configure:7686: result: yes +configure:7686: checking for netdb.h +configure:7686: result: yes +configure:7698: checking netinet/in.h usability +configure:7698: gcc -c -pthread conftest.c >&5 +configure:7698: $? = 0 +configure:7698: result: yes +configure:7698: checking netinet/in.h presence +configure:7698: gcc -E conftest.c +configure:7698: $? = 0 +configure:7698: result: yes +configure:7698: checking for netinet/in.h +configure:7698: result: yes +configure:7710: checking stddef.h usability +configure:7710: gcc -c -pthread conftest.c >&5 +configure:7710: $? = 0 +configure:7710: result: yes +configure:7710: checking stddef.h presence +configure:7710: gcc -E conftest.c +configure:7710: $? = 0 +configure:7710: result: yes +configure:7710: checking for stddef.h +configure:7710: result: yes +configure:7722: checking for stdint.h +configure:7722: result: yes +configure:7734: checking for stdlib.h +configure:7734: result: yes +configure:7746: checking for string.h +configure:7746: result: yes +configure:7758: checking for strings.h +configure:7758: result: yes +configure:7770: checking sys/socket.h usability +configure:7770: gcc -c -pthread conftest.c >&5 +configure:7770: $? = 0 +configure:7770: result: yes +configure:7770: checking sys/socket.h presence +configure:7770: gcc -E conftest.c +configure:7770: $? = 0 +configure:7770: result: yes +configure:7770: checking for sys/socket.h +configure:7770: result: yes +configure:7782: checking sys/time.h usability +configure:7782: gcc -c -pthread conftest.c >&5 +configure:7782: $? = 0 +configure:7782: result: yes +configure:7782: checking sys/time.h presence +configure:7782: gcc -E conftest.c +configure:7782: $? = 0 +configure:7782: result: yes +configure:7782: checking for sys/time.h +configure:7782: result: yes +configure:7794: checking for unistd.h +configure:7794: result: yes +configure:7806: checking for an ANSI C-conforming const +configure:7872: gcc -c -pthread conftest.c >&5 +configure:7872: $? = 0 +configure:7879: result: yes +configure:7887: checking for ptrdiff_t +configure:7887: gcc -c -pthread conftest.c >&5 +configure:7887: $? = 0 +configure:7887: gcc -c -pthread conftest.c >&5 +conftest.c: In function 'main': +conftest.c:83:24: error: expected expression before ')' token + 83 | if (sizeof ((ptrdiff_t))) + | ^ +configure:7887: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| #define ENABLE_NLS 1 +| #define HAVE_GETTEXT 1 +| #define HAVE_DCGETTEXT 1 +| #define HAVE_LIBPTHREAD 1 +| #define HAVE_LIBGEOIP 1 +| #define HAVE_GEOLOCATION 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_NCURSESW_NCURSES_H 1 +| #define HAVE_NCURSES_H 1 +| #define HAVE_LIBNSL 1 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_LOCALE_H 1 +| #define HAVE_NETDB_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_SYS_SOCKET_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((ptrdiff_t))) +| return 0; +| ; +| return 0; +| } +configure:7887: result: yes +configure:7897: checking whether struct tm is in sys/time.h or time.h +configure:7917: gcc -c -pthread conftest.c >&5 +configure:7917: $? = 0 +configure:7924: result: time.h +configure:7932: checking for int64_t +configure:7932: gcc -c -pthread conftest.c >&5 +configure:7932: $? = 0 +configure:7932: gcc -c -pthread conftest.c >&5 +conftest.c: In function 'main': +conftest.c:86:53: warning: integer overflow in expression of type 'long int' results in '-9223372036854775808' [-Woverflow] + 86 | < (int64_t) (((((int64_t) 1 << N) << N) - 1) * 2 + 2))]; + | ^ +conftest.c:85:12: error: storage size of 'test_array' isn't constant + 85 | static int test_array [1 - 2 * !((int64_t) (((((int64_t) 1 << N) << N) - 1) * 2 + 1) + | ^~~~~~~~~~ +configure:7932: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| #define ENABLE_NLS 1 +| #define HAVE_GETTEXT 1 +| #define HAVE_DCGETTEXT 1 +| #define HAVE_LIBPTHREAD 1 +| #define HAVE_LIBGEOIP 1 +| #define HAVE_GEOLOCATION 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_NCURSESW_NCURSES_H 1 +| #define HAVE_NCURSES_H 1 +| #define HAVE_LIBNSL 1 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_LOCALE_H 1 +| #define HAVE_NETDB_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_SYS_SOCKET_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_PTRDIFF_T 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| enum { N = 64 / 2 - 1 }; +| int +| main () +| { +| static int test_array [1 - 2 * !((int64_t) (((((int64_t) 1 << N) << N) - 1) * 2 + 1) +| < (int64_t) (((((int64_t) 1 << N) << N) - 1) * 2 + 2))]; +| test_array [0] = 0; +| return test_array [0]; +| +| ; +| return 0; +| } +configure:7932: result: yes +configure:7943: checking for int8_t +configure:7943: gcc -c -pthread conftest.c >&5 +configure:7943: $? = 0 +configure:7943: gcc -c -pthread conftest.c >&5 +conftest.c: In function 'main': +conftest.c:85:12: error: size of array 'test_array' is negative + 85 | static int test_array [1 - 2 * !((int8_t) (((((int8_t) 1 << N) << N) - 1) * 2 + 1) + | ^~~~~~~~~~ +configure:7943: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| #define ENABLE_NLS 1 +| #define HAVE_GETTEXT 1 +| #define HAVE_DCGETTEXT 1 +| #define HAVE_LIBPTHREAD 1 +| #define HAVE_LIBGEOIP 1 +| #define HAVE_GEOLOCATION 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_NCURSESW_NCURSES_H 1 +| #define HAVE_NCURSES_H 1 +| #define HAVE_LIBNSL 1 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_LOCALE_H 1 +| #define HAVE_NETDB_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_SYS_SOCKET_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_PTRDIFF_T 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| enum { N = 8 / 2 - 1 }; +| int +| main () +| { +| static int test_array [1 - 2 * !((int8_t) (((((int8_t) 1 << N) << N) - 1) * 2 + 1) +| < (int8_t) (((((int8_t) 1 << N) << N) - 1) * 2 + 2))]; +| test_array [0] = 0; +| return test_array [0]; +| +| ; +| return 0; +| } +configure:7943: result: yes +configure:7954: checking for off_t +configure:7954: gcc -c -pthread conftest.c >&5 +configure:7954: $? = 0 +configure:7954: gcc -c -pthread conftest.c >&5 +conftest.c: In function 'main': +conftest.c:84:20: error: expected expression before ')' token + 84 | if (sizeof ((off_t))) + | ^ +configure:7954: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| #define ENABLE_NLS 1 +| #define HAVE_GETTEXT 1 +| #define HAVE_DCGETTEXT 1 +| #define HAVE_LIBPTHREAD 1 +| #define HAVE_LIBGEOIP 1 +| #define HAVE_GEOLOCATION 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_NCURSESW_NCURSES_H 1 +| #define HAVE_NCURSES_H 1 +| #define HAVE_LIBNSL 1 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_LOCALE_H 1 +| #define HAVE_NETDB_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_SYS_SOCKET_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_PTRDIFF_T 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((off_t))) +| return 0; +| ; +| return 0; +| } +configure:7954: result: yes +configure:7965: checking for size_t +configure:7965: gcc -c -pthread conftest.c >&5 +configure:7965: $? = 0 +configure:7965: gcc -c -pthread conftest.c >&5 +conftest.c: In function 'main': +conftest.c:84:21: error: expected expression before ')' token + 84 | if (sizeof ((size_t))) + | ^ +configure:7965: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| #define ENABLE_NLS 1 +| #define HAVE_GETTEXT 1 +| #define HAVE_DCGETTEXT 1 +| #define HAVE_LIBPTHREAD 1 +| #define HAVE_LIBGEOIP 1 +| #define HAVE_GEOLOCATION 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_NCURSESW_NCURSES_H 1 +| #define HAVE_NCURSES_H 1 +| #define HAVE_LIBNSL 1 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_LOCALE_H 1 +| #define HAVE_NETDB_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_SYS_SOCKET_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_PTRDIFF_T 1 +| /* end confdefs.h. */ +| #include +| #ifdef HAVE_SYS_TYPES_H +| # include +| #endif +| #ifdef HAVE_SYS_STAT_H +| # include +| #endif +| #ifdef STDC_HEADERS +| # include +| # include +| #else +| # ifdef HAVE_STDLIB_H +| # include +| # endif +| #endif +| #ifdef HAVE_STRING_H +| # if !defined STDC_HEADERS && defined HAVE_MEMORY_H +| # include +| # endif +| # include +| #endif +| #ifdef HAVE_STRINGS_H +| # include +| #endif +| #ifdef HAVE_INTTYPES_H +| # include +| #endif +| #ifdef HAVE_STDINT_H +| # include +| #endif +| #ifdef HAVE_UNISTD_H +| # include +| #endif +| int +| main () +| { +| if (sizeof ((size_t))) +| return 0; +| ; +| return 0; +| } +configure:7965: result: yes +configure:7976: checking for uint32_t +configure:7976: gcc -c -pthread conftest.c >&5 +configure:7976: $? = 0 +configure:7976: result: yes +configure:7990: checking for uint64_t +configure:7990: gcc -c -pthread conftest.c >&5 +configure:7990: $? = 0 +configure:7990: result: yes +configure:8004: checking for uint8_t +configure:8004: gcc -c -pthread conftest.c >&5 +configure:8004: $? = 0 +configure:8004: result: yes +configure:8020: checking for _LARGEFILE_SOURCE value needed for large files +configure:8039: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8039: $? = 0 +configure:8067: result: no +configure:8088: checking for working memcmp +configure:8131: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8131: $? = 0 +configure:8131: ./conftest +configure:8131: $? = 0 +configure:8141: result: yes +configure:8150: checking whether time.h and sys/time.h may both be included +configure:8170: gcc -c -pthread conftest.c >&5 +configure:8170: $? = 0 +configure:8177: result: yes +configure:8191: checking for sys/time.h +configure:8191: result: yes +configure:8191: checking for unistd.h +configure:8191: result: yes +configure:8212: checking for alarm +configure:8212: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8212: $? = 0 +configure:8212: result: yes +configure:8225: checking for working mktime +configure:8427: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8427: $? = 0 +configure:8427: ./conftest +configure:8427: $? = 0 +configure:8437: result: yes +configure:8448: checking whether lstat correctly handles trailing slash +configure:8474: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8474: $? = 0 +configure:8474: ./conftest +configure:8474: $? = 0 +configure:8491: result: yes +configure:8510: checking whether stat accepts an empty string +configure:8530: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8530: $? = 0 +configure:8530: ./conftest +configure:8530: $? = 0 +configure:8540: result: no +configure:8558: checking for strftime +configure:8558: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:77:6: warning: conflicting types for built-in function 'strftime'; expected 'long unsigned int(char *, long unsigned int, const char *, const void *)' [-Wbuiltin-declaration-mismatch] + 77 | char strftime (); + | ^~~~~~~~ +conftest.c:65:1: note: 'strftime' is declared in header '' + 64 | # include + 65 | #else +configure:8558: $? = 0 +configure:8558: result: yes +configure:8611: checking for working strtod +configure:8652: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8652: $? = 0 +configure:8652: ./conftest +configure:8652: $? = 0 +configure:8662: result: yes +configure:8726: checking for floor +configure:8726: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:78:6: warning: conflicting types for built-in function 'floor'; expected 'double(double)' [-Wbuiltin-declaration-mismatch] + 78 | char floor (); + | ^~~~~ +conftest.c:66:1: note: 'floor' is declared in header '' + 65 | # include + 66 | #else +/usr/bin/ld: /tmp/ccTMARdc.o: in function `main': +conftest.c:(.text+0xe): undefined reference to `floor' +collect2: error: ld returned 1 exit status +configure:8726: $? = 1 +configure: failed program was: +| /* confdefs.h */ +| #define PACKAGE_NAME "goaccess" +| #define PACKAGE_TARNAME "goaccess" +| #define PACKAGE_VERSION "1.3" +| #define PACKAGE_STRING "goaccess 1.3" +| #define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +| #define PACKAGE_URL "http://goaccess.io" +| #define PACKAGE "goaccess" +| #define VERSION "1.3" +| #define ENABLE_NLS 1 +| #define HAVE_GETTEXT 1 +| #define HAVE_DCGETTEXT 1 +| #define HAVE_LIBPTHREAD 1 +| #define HAVE_LIBGEOIP 1 +| #define HAVE_GEOLOCATION 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_LIBNCURSESW 1 +| #define HAVE_NCURSESW_NCURSES_H 1 +| #define HAVE_NCURSES_H 1 +| #define HAVE_LIBNSL 1 +| #define STDC_HEADERS 1 +| #define HAVE_SYS_TYPES_H 1 +| #define HAVE_SYS_STAT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_MEMORY_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ARPA_INET_H 1 +| #define HAVE_FCNTL_H 1 +| #define HAVE_INTTYPES_H 1 +| #define HAVE_LIMITS_H 1 +| #define HAVE_LOCALE_H 1 +| #define HAVE_NETDB_H 1 +| #define HAVE_NETINET_IN_H 1 +| #define HAVE_STDDEF_H 1 +| #define HAVE_STDINT_H 1 +| #define HAVE_STDLIB_H 1 +| #define HAVE_STRING_H 1 +| #define HAVE_STRINGS_H 1 +| #define HAVE_SYS_SOCKET_H 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_PTRDIFF_T 1 +| #define HAVE_FSEEKO 1 +| #define TIME_WITH_SYS_TIME 1 +| #define HAVE_SYS_TIME_H 1 +| #define HAVE_UNISTD_H 1 +| #define HAVE_ALARM 1 +| #define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 +| #define HAVE_STRFTIME 1 +| /* end confdefs.h. */ +| /* Define floor to an innocuous variant, in case declares floor. +| For example, HP-UX 11i declares gettimeofday. */ +| #define floor innocuous_floor +| +| /* System header to define __stub macros and hopefully few prototypes, +| which can conflict with char floor (); below. +| Prefer to if __STDC__ is defined, since +| exists even on freestanding compilers. */ +| +| #ifdef __STDC__ +| # include +| #else +| # include +| #endif +| +| #undef floor +| +| /* Override any GCC internal prototype to avoid an error. +| Use char because int might match the return type of a GCC +| builtin and then its argument prototype would still apply. */ +| #ifdef __cplusplus +| extern "C" +| #endif +| char floor (); +| /* The GNU C library defines this for functions which it implements +| to always fail with ENOSYS. Some functions are actually named +| something starting with __ and the normal name is an alias. */ +| #if defined __stub_floor || defined __stub___floor +| choke me +| #endif +| +| int +| main () +| { +| return floor (); +| ; +| return 0; +| } +configure:8726: result: no +configure:8737: checking for gethostbyaddr +configure:8737: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8737: $? = 0 +configure:8737: result: yes +configure:8748: checking for gethostbyname +configure:8748: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8748: $? = 0 +configure:8748: result: yes +configure:8759: checking for gettimeofday +configure:8759: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8759: $? = 0 +configure:8759: result: yes +configure:8770: checking for malloc +configure:8770: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:81:6: warning: conflicting types for built-in function 'malloc'; expected 'void *(long unsigned int)' [-Wbuiltin-declaration-mismatch] + 81 | char malloc (); + | ^~~~~~ +conftest.c:69:1: note: 'malloc' is declared in header '' + 68 | # include + 69 | #else +configure:8770: $? = 0 +configure:8770: result: yes +configure:8781: checking for memmove +configure:8781: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:82:6: warning: conflicting types for built-in function 'memmove'; expected 'void *(void *, const void *, long unsigned int)' [-Wbuiltin-declaration-mismatch] + 82 | char memmove (); + | ^~~~~~~ +conftest.c:70:1: note: 'memmove' is declared in header '' + 69 | # include + 70 | #else +configure:8781: $? = 0 +configure:8781: result: yes +configure:8792: checking for memset +configure:8792: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:83:6: warning: conflicting types for built-in function 'memset'; expected 'void *(void *, int, long unsigned int)' [-Wbuiltin-declaration-mismatch] + 83 | char memset (); + | ^~~~~~ +conftest.c:71:1: note: 'memset' is declared in header '' + 70 | # include + 71 | #else +configure:8792: $? = 0 +configure:8792: result: yes +configure:8803: checking for mkfifo +configure:8803: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8803: $? = 0 +configure:8803: result: yes +configure:8814: checking for realloc +configure:8814: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:85:6: warning: conflicting types for built-in function 'realloc'; expected 'void *(void *, long unsigned int)' [-Wbuiltin-declaration-mismatch] + 85 | char realloc (); + | ^~~~~~~ +conftest.c:73:1: note: 'realloc' is declared in header '' + 72 | # include + 73 | #else +configure:8814: $? = 0 +configure:8814: result: yes +configure:8825: checking for realpath +configure:8825: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8825: $? = 0 +configure:8825: result: yes +configure:8836: checking for regcomp +configure:8836: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8836: $? = 0 +configure:8836: result: yes +configure:8847: checking for select +configure:8847: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8847: $? = 0 +configure:8847: result: yes +configure:8858: checking for setlocale +configure:8858: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8858: $? = 0 +configure:8858: result: yes +configure:8869: checking for socket +configure:8869: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8869: $? = 0 +configure:8869: result: yes +configure:8880: checking for strcasecmp +configure:8880: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:91:6: warning: conflicting types for built-in function 'strcasecmp'; expected 'int(const char *, const char *)' [-Wbuiltin-declaration-mismatch] + 91 | char strcasecmp (); + | ^~~~~~~~~~ +configure:8880: $? = 0 +configure:8880: result: yes +configure:8891: checking for strchr +configure:8891: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:92:6: warning: conflicting types for built-in function 'strchr'; expected 'char *(const char *, int)' [-Wbuiltin-declaration-mismatch] + 92 | char strchr (); + | ^~~~~~ +conftest.c:80:1: note: 'strchr' is declared in header '' + 79 | # include + 80 | #else +configure:8891: $? = 0 +configure:8891: result: yes +configure:8902: checking for strcspn +configure:8902: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:93:6: warning: conflicting types for built-in function 'strcspn'; expected 'long unsigned int(const char *, const char *)' [-Wbuiltin-declaration-mismatch] + 93 | char strcspn (); + | ^~~~~~~ +conftest.c:81:1: note: 'strcspn' is declared in header '' + 80 | # include + 81 | #else +configure:8902: $? = 0 +configure:8902: result: yes +configure:8913: checking for strdup +configure:8913: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:94:6: warning: conflicting types for built-in function 'strdup'; expected 'char *(const char *)' [-Wbuiltin-declaration-mismatch] + 94 | char strdup (); + | ^~~~~~ +configure:8913: $? = 0 +configure:8913: result: yes +configure:8924: checking for strerror +configure:8924: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8924: $? = 0 +configure:8924: result: yes +configure:8935: checking for strncasecmp +configure:8935: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:96:6: warning: conflicting types for built-in function 'strncasecmp'; expected 'int(const char *, const char *, long unsigned int)' [-Wbuiltin-declaration-mismatch] + 96 | char strncasecmp (); + | ^~~~~~~~~~~ +configure:8935: $? = 0 +configure:8935: result: yes +configure:8946: checking for strpbrk +configure:8946: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:97:6: warning: conflicting types for built-in function 'strpbrk'; expected 'char *(const char *, const char *)' [-Wbuiltin-declaration-mismatch] + 97 | char strpbrk (); + | ^~~~~~~ +conftest.c:85:1: note: 'strpbrk' is declared in header '' + 84 | # include + 85 | #else +configure:8946: $? = 0 +configure:8946: result: yes +configure:8957: checking for strrchr +configure:8957: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:98:6: warning: conflicting types for built-in function 'strrchr'; expected 'char *(const char *, int)' [-Wbuiltin-declaration-mismatch] + 98 | char strrchr (); + | ^~~~~~~ +conftest.c:86:1: note: 'strrchr' is declared in header '' + 85 | # include + 86 | #else +configure:8957: $? = 0 +configure:8957: result: yes +configure:8968: checking for strspn +configure:8968: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:99:6: warning: conflicting types for built-in function 'strspn'; expected 'long unsigned int(const char *, const char *)' [-Wbuiltin-declaration-mismatch] + 99 | char strspn (); + | ^~~~~~ +conftest.c:87:1: note: 'strspn' is declared in header '' + 86 | # include + 87 | #else +configure:8968: $? = 0 +configure:8968: result: yes +configure:8979: checking for strstr +configure:8979: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +conftest.c:100:6: warning: conflicting types for built-in function 'strstr'; expected 'char *(const char *, const char *)' [-Wbuiltin-declaration-mismatch] + 100 | char strstr (); + | ^~~~~~ +conftest.c:88:1: note: 'strstr' is declared in header '' + 87 | # include + 88 | #else +configure:8979: $? = 0 +configure:8979: result: yes +configure:8990: checking for strtol +configure:8990: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:8990: $? = 0 +configure:8990: result: yes +configure:9001: checking for strtoull +configure:9001: gcc -o conftest -pthread conftest.c -lnsl -lncursesw -lGeoIP -lpthread >&5 +configure:9001: $? = 0 +configure:9001: result: yes +configure:9159: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by goaccess config.status 1.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on ubuntu + +config.status:953: creating Makefile +config.status:953: creating po/Makefile.in +config.status:953: creating src/config.h +config.status:1182: executing depfiles commands +config.status:1182: executing po-directories commands + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_build=x86_64-unknown-linux-gnu +ac_cv_c_compiler_gnu=yes +ac_cv_c_const=yes +ac_cv_c_int64_t=yes +ac_cv_c_int8_t=yes +ac_cv_c_uint32_t=yes +ac_cv_c_uint64_t=yes +ac_cv_c_uint8_t=yes +ac_cv_env_CC_set= +ac_cv_env_CC_value= +ac_cv_env_CFLAGS_set= +ac_cv_env_CFLAGS_value= +ac_cv_env_CPPFLAGS_set= +ac_cv_env_CPPFLAGS_value= +ac_cv_env_CPP_set= +ac_cv_env_CPP_value= +ac_cv_env_LDFLAGS_set= +ac_cv_env_LDFLAGS_value= +ac_cv_env_LIBS_set= +ac_cv_env_LIBS_value= +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_func_alarm=yes +ac_cv_func_floor=no +ac_cv_func_gethostbyaddr=yes +ac_cv_func_gethostbyname=yes +ac_cv_func_gettimeofday=yes +ac_cv_func_lstat_dereferences_slashed_symlink=yes +ac_cv_func_malloc=yes +ac_cv_func_memcmp_working=yes +ac_cv_func_memmove=yes +ac_cv_func_memset=yes +ac_cv_func_mkfifo=yes +ac_cv_func_realloc=yes +ac_cv_func_realpath=yes +ac_cv_func_regcomp=yes +ac_cv_func_select=yes +ac_cv_func_setlocale=yes +ac_cv_func_socket=yes +ac_cv_func_stat_empty_string_bug=no +ac_cv_func_strcasecmp=yes +ac_cv_func_strchr=yes +ac_cv_func_strcspn=yes +ac_cv_func_strdup=yes +ac_cv_func_strerror=yes +ac_cv_func_strftime=yes +ac_cv_func_strncasecmp=yes +ac_cv_func_strpbrk=yes +ac_cv_func_strrchr=yes +ac_cv_func_strspn=yes +ac_cv_func_strstr=yes +ac_cv_func_strtod=yes +ac_cv_func_strtol=yes +ac_cv_func_strtoull=yes +ac_cv_func_working_mktime=yes +ac_cv_header_arpa_inet_h=yes +ac_cv_header_fcntl_h=yes +ac_cv_header_inttypes_h=yes +ac_cv_header_limits_h=yes +ac_cv_header_locale_h=yes +ac_cv_header_memory_h=yes +ac_cv_header_ncurses_h=yes +ac_cv_header_ncursesw_ncurses_h=yes +ac_cv_header_netdb_h=yes +ac_cv_header_netinet_in_h=yes +ac_cv_header_stdc=yes +ac_cv_header_stddef_h=yes +ac_cv_header_stdint_h=yes +ac_cv_header_stdlib_h=yes +ac_cv_header_string_h=yes +ac_cv_header_strings_h=yes +ac_cv_header_sys_socket_h=yes +ac_cv_header_sys_stat_h=yes +ac_cv_header_sys_time_h=yes +ac_cv_header_sys_types_h=yes +ac_cv_header_time=yes +ac_cv_header_unistd_h=yes +ac_cv_host=x86_64-unknown-linux-gnu +ac_cv_lib_GeoIP_GeoIP_new=yes +ac_cv_lib_intl_libintl_dgettext=no +ac_cv_lib_ncursesw___mvaddwstr=yes +ac_cv_lib_nsl_gethostbyname=yes +ac_cv_lib_pthread_pthread_create=yes +ac_cv_lib_socket_socket=no +ac_cv_objext=o +ac_cv_path_EGREP='/usr/bin/grep -E' +ac_cv_path_GMSGFMT=: +ac_cv_path_GREP=/usr/bin/grep +ac_cv_path_MSGFMT=: +ac_cv_path_MSGMERGE=: +ac_cv_path_XGETTEXT=: +ac_cv_path_install='/usr/bin/install -c' +ac_cv_path_mkdir=/usr/bin/mkdir +ac_cv_prog_AWK=mawk +ac_cv_prog_CPP='gcc -E' +ac_cv_prog_SED_CHECK=yes +ac_cv_prog_TR_CHECK=yes +ac_cv_prog_ac_ct_CC=gcc +ac_cv_prog_cc_c89= +ac_cv_prog_cc_g=yes +ac_cv_prog_cc_gcc_c_o=yes +ac_cv_prog_make_make_set=yes +ac_cv_search_tputs='none required' +ac_cv_struct_tm=time.h +ac_cv_sys_largefile_source=no +ac_cv_type_off_t=yes +ac_cv_type_ptrdiff_t=yes +ac_cv_type_size_t=yes +acl_cv_hardcode_direct=no +acl_cv_hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' +acl_cv_hardcode_libdir_separator= +acl_cv_hardcode_minus_L=no +acl_cv_libext=a +acl_cv_libname_spec='lib$name' +acl_cv_library_names_spec='$libname$shrext' +acl_cv_path_LD=/usr/bin/ld +acl_cv_prog_gnu_ld=yes +acl_cv_rpath=done +acl_cv_shlibext=so +acl_cv_wl=-Wl, +am_cv_CC_dependencies_compiler_type=gcc3 +gt_cv_func_CFLocaleCopyCurrent=no +gt_cv_func_CFPreferencesCopyAppValue=no +gt_cv_func_gnugettext1_libc=yes + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +ACLOCAL='${SHELL} /home/djq/goaccess-1.3/missing --run aclocal-1.11' +AMDEPBACKSLASH='\' +AMDEP_FALSE='#' +AMDEP_TRUE='' +AMTAR='$${TAR-tar}' +AUTOCONF='${SHELL} /home/djq/goaccess-1.3/missing --run autoconf' +AUTOHEADER='${SHELL} /home/djq/goaccess-1.3/missing --run autoheader' +AUTOMAKE='${SHELL} /home/djq/goaccess-1.3/missing --run automake-1.11' +AWK='mawk' +CC='gcc' +CCDEPMODE='depmode=gcc3' +CFLAGS=' -pthread' +CPP='gcc -E' +CPPFLAGS='' +CYGPATH_W='echo' +DEBUG_FALSE='' +DEBUG_TRUE='#' +DEFS='-DHAVE_CONFIG_H' +DEPDIR='.deps' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +EGREP='/usr/bin/grep -E' +EXEEXT='' +GEOIP_LEGACY_FALSE='#' +GEOIP_LEGACY_TRUE='' +GEOIP_MMDB_FALSE='' +GEOIP_MMDB_TRUE='#' +GETTEXT_MACRO_VERSION='0.18' +GMSGFMT=':' +GMSGFMT_015=':' +GREP='/usr/bin/grep' +HAS_SEDTR_FALSE='#' +HAS_SEDTR_TRUE='' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +INSTALL_STRIP_PROGRAM='$(install_sh) -c -s' +INTLLIBS='' +INTL_MACOSX_LIBS='' +LDFLAGS='' +LIBICONV='-liconv' +LIBINTL='' +LIBOBJS='' +LIBS='-lnsl -lncursesw -lGeoIP -lpthread ' +LTLIBICONV='-liconv' +LTLIBINTL='' +LTLIBOBJS='' +MAKEINFO='${SHELL} /home/djq/goaccess-1.3/missing --run makeinfo' +MKDIR_P='/usr/bin/mkdir -p' +MSGFMT=':' +MSGFMT_015=':' +MSGMERGE=':' +OBJEXT='o' +PACKAGE='goaccess' +PACKAGE_BUGREPORT='goaccess@prosoftcorp.com' +PACKAGE_NAME='goaccess' +PACKAGE_STRING='goaccess 1.3' +PACKAGE_TARNAME='goaccess' +PACKAGE_URL='http://goaccess.io' +PACKAGE_VERSION='1.3' +PATH_SEPARATOR=':' +POSUB='po' +POW_LIB='' +SED_CHECK='yes' +SET_MAKE='' +SHELL='/bin/bash' +STRIP='' +TCB_FALSE='' +TCB_TRUE='#' +TR_CHECK='yes' +USE_NLS='yes' +VERSION='1.3' +WITH_RDYNAMIC_FALSE='#' +WITH_RDYNAMIC_TRUE='' +XGETTEXT=':' +XGETTEXT_015=':' +XGETTEXT_EXTRA_OPTIONS='' +ac_ct_CC='gcc' +am__EXEEXT_FALSE='' +am__EXEEXT_TRUE='#' +am__fastdepCC_FALSE='#' +am__fastdepCC_TRUE='' +am__include='include' +am__isrc='' +am__leading_dot='.' +am__nodep='_no' +am__quote='' +am__tar='$${TAR-tar} chof - "$$tardir"' +am__untar='$${TAR-tar} xf -' +bindir='${exec_prefix}/bin' +build='x86_64-unknown-linux-gnu' +build_alias='' +build_cpu='x86_64' +build_os='linux-gnu' +build_vendor='unknown' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +dvidir='${docdir}' +exec_prefix='${prefix}' +host='x86_64-unknown-linux-gnu' +host_alias='' +host_cpu='x86_64' +host_os='linux-gnu' +host_vendor='unknown' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +install_sh='${SHELL} /home/djq/goaccess-1.3/install-sh' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +mkdir_p='/usr/bin/mkdir -p' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +/* confdefs.h */ +#define PACKAGE_NAME "goaccess" +#define PACKAGE_TARNAME "goaccess" +#define PACKAGE_VERSION "1.3" +#define PACKAGE_STRING "goaccess 1.3" +#define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" +#define PACKAGE_URL "http://goaccess.io" +#define PACKAGE "goaccess" +#define VERSION "1.3" +#define ENABLE_NLS 1 +#define HAVE_GETTEXT 1 +#define HAVE_DCGETTEXT 1 +#define HAVE_LIBPTHREAD 1 +#define HAVE_LIBGEOIP 1 +#define HAVE_GEOLOCATION 1 +#define HAVE_LIBNCURSESW 1 +#define HAVE_LIBNCURSESW 1 +#define HAVE_NCURSESW_NCURSES_H 1 +#define HAVE_NCURSES_H 1 +#define HAVE_LIBNSL 1 +#define STDC_HEADERS 1 +#define HAVE_SYS_TYPES_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_MEMORY_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_ARPA_INET_H 1 +#define HAVE_FCNTL_H 1 +#define HAVE_INTTYPES_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_LOCALE_H 1 +#define HAVE_NETDB_H 1 +#define HAVE_NETINET_IN_H 1 +#define HAVE_STDDEF_H 1 +#define HAVE_STDINT_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_STRING_H 1 +#define HAVE_STRINGS_H 1 +#define HAVE_SYS_SOCKET_H 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_PTRDIFF_T 1 +#define HAVE_FSEEKO 1 +#define TIME_WITH_SYS_TIME 1 +#define HAVE_SYS_TIME_H 1 +#define HAVE_UNISTD_H 1 +#define HAVE_ALARM 1 +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 +#define HAVE_STRFTIME 1 +#define HAVE_GETHOSTBYADDR 1 +#define HAVE_GETHOSTBYNAME 1 +#define HAVE_GETTIMEOFDAY 1 +#define HAVE_MALLOC 1 +#define HAVE_MEMMOVE 1 +#define HAVE_MEMSET 1 +#define HAVE_MKFIFO 1 +#define HAVE_REALLOC 1 +#define HAVE_REALPATH 1 +#define HAVE_REGCOMP 1 +#define HAVE_SELECT 1 +#define HAVE_SETLOCALE 1 +#define HAVE_SOCKET 1 +#define HAVE_STRCASECMP 1 +#define HAVE_STRCHR 1 +#define HAVE_STRCSPN 1 +#define HAVE_STRDUP 1 +#define HAVE_STRERROR 1 +#define HAVE_STRNCASECMP 1 +#define HAVE_STRPBRK 1 +#define HAVE_STRRCHR 1 +#define HAVE_STRSPN 1 +#define HAVE_STRSTR 1 +#define HAVE_STRTOL 1 +#define HAVE_STRTOULL 1 + +configure: exit 0 diff --git a/goaccess++/config.rpath b/goaccess++/config.rpath new file mode 100644 index 0000000..17298f2 --- /dev/null +++ b/goaccess++/config.rpath @@ -0,0 +1,672 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2010 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + darwin*) + case $cc_basename in + xlc*) + wl='-Wl,' + ;; + esac + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + newsos6) + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + pgcc | pgf77 | pgf90) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + wl='-Wl,' + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we cannot use + # them. + ld_shlibs=no + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if test "$GCC" = yes ; then + : + else + case $cc_basename in + xlc*) + ;; + *) + ld_shlibs=no + ;; + esac + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd1*) + ld_shlibs=no + ;; + freebsd2.2*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + freebsd2*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + library_names_spec='$libname.a' + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd1*) + ;; + freebsd* | dragonfly*) + case "$host_os" in + freebsd[123]*) + library_names_spec='$libname$shrext$versuffix' ;; + *) + library_names_spec='$libname$shrext' ;; + esac + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + nto-qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' </dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by goaccess $as_me 1.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +# Files that config.status was made for. +config_files=" Makefile po/Makefile.in" +config_headers=" src/config.h" +config_commands=" depfiles po-directories" + +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to . +goaccess home page: ." + +ac_cs_config="'--enable-utf8' '--enable-geoip=legacy'" +ac_cs_version="\ +goaccess config.status 1.3 +configured by ./configure, generated by GNU Autoconf 2.69, + with options \"$ac_cs_config\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='/home/djq/goaccess-1.3' +srcdir='.' +INSTALL='/usr/bin/install -c' +MKDIR_P='/usr/bin/mkdir -p' +AWK='mawk' +test -n "$AWK" || AWK=awk +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + set X /bin/bash './configure' '--enable-utf8' '--enable-geoip=legacy' $ac_configure_extra_args --no-create --no-recursion + shift + $as_echo "running CONFIG_SHELL=/bin/bash $*" >&6 + CONFIG_SHELL='/bin/bash' + export CONFIG_SHELL + exec "$@" +fi + +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +# +# INIT-COMMANDS +# +AMDEP_TRUE="" ac_aux_dir="." +# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it + # from automake < 1.5. + eval 'OBSOLETE_ALL_LINGUAS''=""' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="%UNSET%" + + + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +cat >>"$ac_tmp/subs1.awk" <<\_ACAWK && +S["am__EXEEXT_FALSE"]="" +S["am__EXEEXT_TRUE"]="#" +S["LTLIBOBJS"]="" +S["POW_LIB"]="" +S["LIBOBJS"]="" +S["HAS_SEDTR_FALSE"]="#" +S["HAS_SEDTR_TRUE"]="" +S["TR_CHECK"]="yes" +S["SED_CHECK"]="yes" +S["TCB_FALSE"]="" +S["TCB_TRUE"]="#" +S["GEOIP_MMDB_FALSE"]="" +S["GEOIP_MMDB_TRUE"]="#" +S["GEOIP_LEGACY_FALSE"]="#" +S["GEOIP_LEGACY_TRUE"]="" +S["WITH_RDYNAMIC_FALSE"]="#" +S["WITH_RDYNAMIC_TRUE"]="" +S["DEBUG_FALSE"]="" +S["DEBUG_TRUE"]="#" +S["POSUB"]="po" +S["LTLIBINTL"]="" +S["LIBINTL"]="" +S["INTLLIBS"]="" +S["LTLIBICONV"]="-liconv" +S["LIBICONV"]="-liconv" +S["INTL_MACOSX_LIBS"]="" +S["EGREP"]="/usr/bin/grep -E" +S["GREP"]="/usr/bin/grep" +S["CPP"]="gcc -E" +S["host_os"]="linux-gnu" +S["host_vendor"]="unknown" +S["host_cpu"]="x86_64" +S["host"]="x86_64-unknown-linux-gnu" +S["build_os"]="linux-gnu" +S["build_vendor"]="unknown" +S["build_cpu"]="x86_64" +S["build"]="x86_64-unknown-linux-gnu" +S["XGETTEXT_EXTRA_OPTIONS"]="" +S["MSGMERGE"]=":" +S["XGETTEXT_015"]=":" +S["XGETTEXT"]=":" +S["GMSGFMT_015"]=":" +S["MSGFMT_015"]=":" +S["GMSGFMT"]=":" +S["MSGFMT"]=":" +S["GETTEXT_MACRO_VERSION"]="0.18" +S["USE_NLS"]="yes" +S["am__fastdepCC_FALSE"]="#" +S["am__fastdepCC_TRUE"]="" +S["CCDEPMODE"]="depmode=gcc3" +S["am__nodep"]="_no" +S["AMDEPBACKSLASH"]="\\" +S["AMDEP_FALSE"]="#" +S["AMDEP_TRUE"]="" +S["am__quote"]="" +S["am__include"]="include" +S["DEPDIR"]=".deps" +S["OBJEXT"]="o" +S["EXEEXT"]="" +S["ac_ct_CC"]="gcc" +S["CPPFLAGS"]="" +S["LDFLAGS"]="" +S["CFLAGS"]=" -pthread" +S["CC"]="gcc" +S["am__untar"]="$${TAR-tar} xf -" +S["am__tar"]="$${TAR-tar} chof - \"$$tardir\"" +S["AMTAR"]="$${TAR-tar}" +S["am__leading_dot"]="." +S["SET_MAKE"]="" +S["AWK"]="mawk" +S["mkdir_p"]="/usr/bin/mkdir -p" +S["MKDIR_P"]="/usr/bin/mkdir -p" +S["INSTALL_STRIP_PROGRAM"]="$(install_sh) -c -s" +S["STRIP"]="" +S["install_sh"]="${SHELL} /home/djq/goaccess-1.3/install-sh" +S["MAKEINFO"]="${SHELL} /home/djq/goaccess-1.3/missing --run makeinfo" +S["AUTOHEADER"]="${SHELL} /home/djq/goaccess-1.3/missing --run autoheader" +S["AUTOMAKE"]="${SHELL} /home/djq/goaccess-1.3/missing --run automake-1.11" +S["AUTOCONF"]="${SHELL} /home/djq/goaccess-1.3/missing --run autoconf" +S["ACLOCAL"]="${SHELL} /home/djq/goaccess-1.3/missing --run aclocal-1.11" +S["VERSION"]="1.3" +S["PACKAGE"]="goaccess" +S["CYGPATH_W"]="echo" +S["am__isrc"]="" +S["INSTALL_DATA"]="${INSTALL} -m 644" +S["INSTALL_SCRIPT"]="${INSTALL}" +S["INSTALL_PROGRAM"]="${INSTALL}" +S["target_alias"]="" +S["host_alias"]="" +S["build_alias"]="" +S["LIBS"]="-lnsl -lncursesw -lGeoIP -lpthread " +S["ECHO_T"]="" +S["ECHO_N"]="-n" +S["ECHO_C"]="" +S["DEFS"]="-DHAVE_CONFIG_H" +S["mandir"]="${datarootdir}/man" +S["localedir"]="${datarootdir}/locale" +S["libdir"]="${exec_prefix}/lib" +S["psdir"]="${docdir}" +S["pdfdir"]="${docdir}" +S["dvidir"]="${docdir}" +S["htmldir"]="${docdir}" +S["infodir"]="${datarootdir}/info" +S["docdir"]="${datarootdir}/doc/${PACKAGE_TARNAME}" +S["oldincludedir"]="/usr/include" +S["includedir"]="${prefix}/include" +S["localstatedir"]="${prefix}/var" +S["sharedstatedir"]="${prefix}/com" +S["sysconfdir"]="${prefix}/etc" +S["datadir"]="${datarootdir}" +S["datarootdir"]="${prefix}/share" +S["libexecdir"]="${exec_prefix}/libexec" +S["sbindir"]="${exec_prefix}/sbin" +S["bindir"]="${exec_prefix}/bin" +S["program_transform_name"]="s,x,x," +S["prefix"]="/usr/local" +S["exec_prefix"]="${prefix}" +S["PACKAGE_URL"]="http://goaccess.io" +S["PACKAGE_BUGREPORT"]="goaccess@prosoftcorp.com" +S["PACKAGE_STRING"]="goaccess 1.3" +S["PACKAGE_VERSION"]="1.3" +S["PACKAGE_TARNAME"]="goaccess" +S["PACKAGE_NAME"]="goaccess" +S["PATH_SEPARATOR"]=":" +S["SHELL"]="/bin/bash" +_ACAWK +cat >>"$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +D["PACKAGE_NAME"]=" \"goaccess\"" +D["PACKAGE_TARNAME"]=" \"goaccess\"" +D["PACKAGE_VERSION"]=" \"1.3\"" +D["PACKAGE_STRING"]=" \"goaccess 1.3\"" +D["PACKAGE_BUGREPORT"]=" \"goaccess@prosoftcorp.com\"" +D["PACKAGE_URL"]=" \"http://goaccess.io\"" +D["PACKAGE"]=" \"goaccess\"" +D["VERSION"]=" \"1.3\"" +D["ENABLE_NLS"]=" 1" +D["HAVE_GETTEXT"]=" 1" +D["HAVE_DCGETTEXT"]=" 1" +D["HAVE_LIBPTHREAD"]=" 1" +D["HAVE_LIBGEOIP"]=" 1" +D["HAVE_GEOLOCATION"]=" 1" +D["HAVE_LIBNCURSESW"]=" 1" +D["HAVE_LIBNCURSESW"]=" 1" +D["HAVE_NCURSESW_NCURSES_H"]=" 1" +D["HAVE_NCURSES_H"]=" 1" +D["HAVE_LIBNSL"]=" 1" +D["STDC_HEADERS"]=" 1" +D["HAVE_SYS_TYPES_H"]=" 1" +D["HAVE_SYS_STAT_H"]=" 1" +D["HAVE_STDLIB_H"]=" 1" +D["HAVE_STRING_H"]=" 1" +D["HAVE_MEMORY_H"]=" 1" +D["HAVE_STRINGS_H"]=" 1" +D["HAVE_INTTYPES_H"]=" 1" +D["HAVE_STDINT_H"]=" 1" +D["HAVE_UNISTD_H"]=" 1" +D["HAVE_ARPA_INET_H"]=" 1" +D["HAVE_FCNTL_H"]=" 1" +D["HAVE_INTTYPES_H"]=" 1" +D["HAVE_LIMITS_H"]=" 1" +D["HAVE_LOCALE_H"]=" 1" +D["HAVE_NETDB_H"]=" 1" +D["HAVE_NETINET_IN_H"]=" 1" +D["HAVE_STDDEF_H"]=" 1" +D["HAVE_STDINT_H"]=" 1" +D["HAVE_STDLIB_H"]=" 1" +D["HAVE_STRING_H"]=" 1" +D["HAVE_STRINGS_H"]=" 1" +D["HAVE_SYS_SOCKET_H"]=" 1" +D["HAVE_SYS_TIME_H"]=" 1" +D["HAVE_UNISTD_H"]=" 1" +D["HAVE_PTRDIFF_T"]=" 1" +D["HAVE_FSEEKO"]=" 1" +D["TIME_WITH_SYS_TIME"]=" 1" +D["HAVE_SYS_TIME_H"]=" 1" +D["HAVE_UNISTD_H"]=" 1" +D["HAVE_ALARM"]=" 1" +D["LSTAT_FOLLOWS_SLASHED_SYMLINK"]=" 1" +D["HAVE_STRFTIME"]=" 1" +D["HAVE_GETHOSTBYADDR"]=" 1" +D["HAVE_GETHOSTBYNAME"]=" 1" +D["HAVE_GETTIMEOFDAY"]=" 1" +D["HAVE_MALLOC"]=" 1" +D["HAVE_MEMMOVE"]=" 1" +D["HAVE_MEMSET"]=" 1" +D["HAVE_MKFIFO"]=" 1" +D["HAVE_REALLOC"]=" 1" +D["HAVE_REALPATH"]=" 1" +D["HAVE_REGCOMP"]=" 1" +D["HAVE_SELECT"]=" 1" +D["HAVE_SETLOCALE"]=" 1" +D["HAVE_SOCKET"]=" 1" +D["HAVE_STRCASECMP"]=" 1" +D["HAVE_STRCHR"]=" 1" +D["HAVE_STRCSPN"]=" 1" +D["HAVE_STRDUP"]=" 1" +D["HAVE_STRERROR"]=" 1" +D["HAVE_STRNCASECMP"]=" 1" +D["HAVE_STRPBRK"]=" 1" +D["HAVE_STRRCHR"]=" 1" +D["HAVE_STRSPN"]=" 1" +D["HAVE_STRSTR"]=" 1" +D["HAVE_STRTOL"]=" 1" +D["HAVE_STRTOULL"]=" 1" + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+[_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ][_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]*([\t (]|$)/ { + line = $ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + ac_datarootdir_hack=' + s&@datadir@&${datarootdir}&g + s&@docdir@&${datarootdir}/doc/${PACKAGE_TARNAME}&g + s&@infodir@&${datarootdir}/info&g + s&@localedir@&${datarootdir}/locale&g + s&@mandir@&${datarootdir}/man&g + s&\${datarootdir}&${prefix}/share&g' ;; +esac +ac_sed_extra="/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "po-directories":C) + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done ;; + + esac +done # for ac_tag + + +as_fn_exit 0 diff --git a/goaccess++/config.sub b/goaccess++/config.sub new file mode 100644 index 0000000..6205f84 --- /dev/null +++ b/goaccess++/config.sub @@ -0,0 +1,1782 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +timestamp='2012-04-18' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 \ + | ns16k | ns32k \ + | open8 \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i386-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/goaccess++/config/browsers.list b/goaccess++/config/browsers.list new file mode 100644 index 0000000..267fa9e --- /dev/null +++ b/goaccess++/config/browsers.list @@ -0,0 +1,102 @@ +# List of browsers and their categories +# e.g., WORD delimited by tab(s) TYPE +# +# **IMPORTANT NOTE**: +# --------------------- +# The SIZE of the list is proportional to the run time. +# Thus, the longer the list, the more time GoAccess will take to parse it. +# +# Also, you should note that the higher the browser/item is on the list, the +# faster the parsing will be. +# +# The list needs to be specified using --browsers-file=. This file is not +# parsed by default. +# +# The items below are sample crawlers, adjust as needed. + +Chef Client Crawlers +Abonti Crawlers +SISTRIX Crawlers +DotBot Crawlers +Speedy Spider Crawlers +Sosospider Crawlers +BPImageWalker Crawlers +DoCoMo Crawlers +GSLFbot Crawlers +YodaoBot Crawlers +AddThis Crawlers +Purebot Crawlers +CCBot Crawlers +findlinks Crawlers +ichiro Crawlers +Linguee Bot Crawlers +Gigabot Crawlers +BacklinkCrawler Crawlers +distilator Crawlers +Aboundex Crawlers +UnwindFetchor Crawlers +SBIder Crawlers +TestNutch Crawlers +DomainCrawler Crawlers +NextGenSearchBot Crawlers +SEOENGWorldBot Crawlers +Cityreview Crawlers +PagePeeker Crawlers +JS-Kit Crawlers +ScreenerBot Crawlers +ShowyouBot Crawlers +SolomonoBot Crawlers +Domnutch Crawlers +MaxPoint Crawlers +NCBot Crawlers +TosCrawler Crawlers +Updownerbot Crawlers +OpenWebSpider Crawlers +WordPress Crawlers +PEAR Crawlers +ZumBot Crawlers +YisouSpider Crawlers +W3C Crawlers +vcheck Crawlers +PercolateCrawler Crawlers +NING Crawlers +gvfs Crawlers +CatchBot Crawlers +Combine Crawlers +A6-Indexer Crawlers +Altresium Crawlers +Comodo Crawlers +crawler4j Crawlers +Cricket Crawlers +EC2LinkFinder Crawlers +envolk Crawlers +GeoHasher Crawlers +HTMLParser Crawlers +MLBot Crawlers +Jaxified Crawlers +LinkWalker Crawlers +nutch Crawlers +PostRank Crawlers +keybase-proofs Crawlers +CommonCrawler Crawlers +X-CAD-SE Crawlers +Safeassign Crawlers +Nmap Crawlers +sqlmap Crawlers +Jorgee Crawlers +PxBroker Crawlers +Seekport Crawlers +adscanner Crawlers +AfD-Verbotsverfahren_JETZT! Crawlers + +Vienna Feeds +Windows-RSS-Platform Feeds +newsbeuter Feeds +Wrangler Feeds +Fever Feeds +Tiny Feeds +FreshRSS Feeds +KrISS Feeds +SimplePie Feeds +Feedsubs Feeds +UniversalFeedParser Feeds diff --git a/goaccess++/config/goaccess.conf b/goaccess++/config/goaccess.conf new file mode 100644 index 0000000..e0ebe34 --- /dev/null +++ b/goaccess++/config/goaccess.conf @@ -0,0 +1,766 @@ +###################################### +# Time Format Options (required) +###################################### +# +# The hour (24-hour clock) [00,23]; leading zeros are permitted but not required. +# The minute [00,59]; leading zeros are permitted but not required. +# The seconds [00,60]; leading zeros are permitted but not required. +# See `man strftime` for more details +# +# The following time format works with any of the +# Apache/NGINX's log formats below. +# +#time-format %H:%M:%S +# +# Google Cloud Storage or +# The time in microseconds since the Unix epoch. +# +#time-format %f + +# Squid native log format +# +#time-format %s + +###################################### +# Date Format Options (required) +###################################### +# +# The date-format variable followed by a space, specifies +# the log format date containing any combination of regular +# characters and special format specifiers. They all begin with a +# percentage (%) sign. See `man strftime` +# +# The following date format works with any of the +# Apache/NGINX's log formats below. +# +#date-format %d/%b/%Y +# +# AWS | Amazon CloudFront (Download Distribution) +# AWS | Elastic Load Balancing +# W3C (IIS) +# +#date-format %Y-%m-%d +# +# Google Cloud Storage or +# The time in microseconds since the Unix epoch. +# +#date-format %f + +# Squid native log format +# +#date-format %s + +###################################### +# Log Format Options (required) +###################################### +# +# The log-format variable followed by a space or \t for +# tab-delimited, specifies the log format string. +# +# NOTE: If the time/date is a timestamp in seconds or microseconds +# %x must be used instead of %d & %t to represent the date & time. + +# NCSA Combined Log Format +#log-format %h %^[%d:%t %^] "%r" %s %b "%R" "%u" + +# NCSA Combined Log Format with Virtual Host +#log-format %v:%^ %h %^[%d:%t %^] "%r" %s %b "%R" "%u" + +# Common Log Format (CLF) +#log-format %h %^[%d:%t %^] "%r" %s %b + +# Common Log Format (CLF) with Virtual Host +#log-format %v:%^ %h %^[%d:%t %^] "%r" %s %b + +# W3C +#log-format %d %t %h %^ %^ %^ %^ %r %^ %s %b %^ %^ %u %R + +# Squid native log format +#log-format %^ %^ %^ %v %^: %x.%^ %~%L %h %^/%s %b %m %U + +# AWS | Amazon CloudFront (Download Distribution) +#log-format %d\t%t\t%^\t%b\t%h\t%m\t%^\t%r\t%s\t%R\t%u\t%^ + +# Google Cloud Storage +#log-format "%x","%h",%^,%^,"%m","%U","%s",%^,"%b","%D",%^,"%R","%u" + +# AWS | Elastic Load Balancing +#log-format %dT%t.%^ %^ %h:%^ %^ %T %^ %^ %^ %s %^ %b "%r" "%u" + +# AWSS3 | Amazon Simple Storage Service (S3) +#log-format %^[%d:%t %^] %h %^"%r" %s %^ %b %^ %L %^ "%R" "%u" + +# Virtualmin Log Format with Virtual Host +#log-format %h %^ %v %^[%d:%t %^] "%r" %s %b "%R" "%u" + +# In addition to specifying the raw log/date/time formats, for +# simplicity, any of the following predefined log format names can be +# supplied to the log/date/time-format variables. GoAccess can also +# handle one predefined name in one variable and another predefined +# name in another variable. +# +#log-format COMBINED +#log-format VCOMBINED +#log-format COMMON +#log-format VCOMMON +#log-format W3C +#log-format SQUID +#log-format CLOUDFRONT +#log-format CLOUDSTORAGE +#log-format AWSELB +#log-format AWSS3 + +###################################### +# UI Options +###################################### + +# Choose among color schemes +# 1 : Monochrome +# 2 : Green +# 3 : Monokai (if 256-colors supported) +# +#color-scheme 3 + +# Prompt log/date configuration window on program start. +# +config-dialog false + +# Color highlight active panel. +# +hl-header true + +# Specify a custom CSS file in the HTML report. +# +#html-custom-css /path/file.css + +# Specify a custom JS file in the HTML report. +# +#html-custom-js /path/file.js + +# Set default HTML preferences. +# +# NOTE: A valid JSON object is required. +# DO NOT USE A MULTILINE JSON OBJECT. +# The parser will only parse the value next to `html-prefs` (single line) +# It allows the ability to customize each panel plot. See example below. +# +#html-prefs {"theme":"bright","perPage":5,"layout":"horizontal","showTables":true,"visitors":{"plot":{"chartType":"bar"}}} + +# Set HTML report page title and header. +# +#html-report-title My Awesome Web Stats + +# Format JSON output using tabs and newlines. +# +json-pretty-print false + +# Turn off colored output. This is the default output on +# terminals that do not support colors. +# true : for no color output +# false : use color-scheme +# +no-color false + +# Don't write column names in the terminal output. By default, it displays +# column names for each available metric in every panel. +# +no-column-names false + +# Disable summary metrics on the CSV output. +# +no-csv-summary false + +# Disable progress metrics. +# +no-progress false + +# Disable scrolling through panels on TAB. +# +no-tab-scroll false + +# Disable progress metrics and parsing spinner. +# +#no-parsing-spinner true + +# Do not show the last updated field displayed in the HTML generated report. +# +#no-html-last-updated true + +# Enable mouse support on main dashboard. +# +with-mouse false + +# Maximum number of items to show per panel. +# Note: Only the CSV and JSON outputs allow a maximum greater than the +# default value of 366. +# +#max-items 366 + +# Custom colors for the terminal output +# Tailor GoAccess to suit your own tastes. +# +# Color Syntax: +# DEFINITION space/tab colorFG#:colorBG# [[attributes,] PANEL] +# +# FG# = foreground color number [-1...255] (-1 = default terminal color) +# BG# = background color number [-1...255] (-1 = default terminal color) +# +# Optionally: +# +# It is possible to apply color attributes, such as: +# bold,underline,normal,reverse,blink. +# Multiple attributes are comma separated +# +# If desired, it is possible to apply custom colors per panel, that is, a +# metric in the REQUESTS panel can be of color A, while the same metric in the +# BROWSERS panel can be of color B. +# +# The following is a 256 color scheme (hybrid palette) +# +#color COLOR_MTRC_HITS color110:color-1 +#color COLOR_MTRC_VISITORS color173:color-1 +#color COLOR_MTRC_DATA color221:color-1 +#color COLOR_MTRC_BW color167:color-1 +#color COLOR_MTRC_AVGTS color143:color-1 +#color COLOR_MTRC_CUMTS color247:color-1 +#color COLOR_MTRC_MAXTS color186:color-1 +#color COLOR_MTRC_PROT color109:color-1 +#color COLOR_MTRC_MTHD color139:color-1 +#color COLOR_MTRC_HITS_PERC color186:color-1 +#color COLOR_MTRC_HITS_PERC_MAX color139:color-1 +#color COLOR_MTRC_HITS_PERC_MAX color139:color-1 VISITORS +#color COLOR_MTRC_HITS_PERC_MAX color139:color-1 OS +#color COLOR_MTRC_HITS_PERC_MAX color139:color-1 BROWSERS +#color COLOR_MTRC_HITS_PERC_MAX color139:color-1 VISIT_TIMES +#color COLOR_MTRC_VISITORS_PERC color186:color-1 +#color COLOR_MTRC_VISITORS_PERC_MAX color139:color-1 +#color COLOR_PANEL_COLS color243:color-1 +#color COLOR_BARS color250:color-1 +#color COLOR_ERROR color231:color167 +#color COLOR_SELECTED color7:color167 +#color COLOR_PANEL_ACTIVE color7:color237 +#color COLOR_PANEL_HEADER color250:color235 +#color COLOR_PANEL_DESC color242:color-1 +#color COLOR_OVERALL_LBLS color243:color-1 +#color COLOR_OVERALL_VALS color167:color-1 +#color COLOR_OVERALL_PATH color186:color-1 +#color COLOR_ACTIVE_LABEL color139:color235 bold underline +#color COLOR_BG color250:color-1 +#color COLOR_DEFAULT color243:color-1 +#color COLOR_PROGRESS color7:color110 + +###################################### +# Server Options +###################################### + +# Specify IP address to bind server to. +# +#addr 0.0.0.0 + +# Run GoAccess as daemon (if --real-time-html enabled). +# +#daemonize false + +# Ensure clients send the specified origin header upon the WebSocket +# handshake. +# +#origin http://example.org + +# The port to which the connection is being attempted to connect. +# By default GoAccess' WebSocket server listens on port 7890 +# See man page or http://gwsocket.io for details. +# +#port 7890 + +# Write the PID to a file when used along the daemonize option. +# +#pid-file /var/run/goaccess.pid + +# Enable real-time HTML output. +# +#real-time-html true + +# Path to TLS/SSL certificate. +# Note that ssl-cert and ssl-key need to be used to enable TLS/SSL. +# +#ssl-cert /path/ssl/domain.crt + +# Path to TLS/SSL private key. +# Note that ssl-cert and ssl-key need to be used to enable TLS/SSL. +# +#ssl-key /path/ssl/domain.key + +# URL to which the WebSocket server responds. This is the URL supplied +# to the WebSocket constructor on the client side. +# +# Optionally, it is possible to specify the WebSocket URI scheme, such as ws:// +# or wss:// for unencrypted and encrypted connections. +# e.g., ws-url wss://goaccess.io +# +# If GoAccess is running behind a proxy, you could set the client side +# to connect to a different port by specifying the host followed by a +# colon and the port. +# e.g., ws-url goaccess.io:9999 +# +# By default, it will attempt to connect to localhost. If GoAccess is +# running on a remote server, the host of the remote server should be +# specified here. Also, make sure it is a valid host and NOT an http +# address. +# +#ws-url goaccess.io + +# Path to read named pipe (FIFO). +# +#fifo-in /tmp/wspipein.fifo + +# Path to write named pipe (FIFO). +# +#fifo-in /tmp/wspipeout.fifo + +###################################### +# File Options +###################################### + +# Specify the path to the input log file. If set, it will take +# priority over -f from the command line. +# +#log-file /var/log/apache2/access.log + +# Send all debug messages to the specified file. +# +#debug-file debug.log + +# Specify a custom configuration file to use. If set, it will take +# priority over the global configuration file (if any). +# +#config-file + +# Log invalid requests to the specified file. +# +#invalid-requests + +# Do not load the global configuration file. +# +#no-global-config false + +###################################### +# Parse Options +###################################### + +# Enable a list of user-agents by host. For faster parsing, do not +# enable this flag. +# +agent-list false + +# Enable IP resolver on HTML|JSON|CSV output. +# +with-output-resolver false + +# Exclude an IPv4 or IPv6 from being counted. +# Ranges can be included as well using a dash in between +# the IPs (start-end). +# +#exclude-ip 127.0.0.1 +#exclude-ip 192.168.0.1-192.168.0.100 +#exclude-ip ::1 +#exclude-ip 0:0:0:0:0:ffff:808:804-0:0:0:0:0:ffff:808:808 + +# Include HTTP request method if found. This will create a +# request key containing the request method + the actual request. +# +# [default: yes] +# +http-method yes + +# Include HTTP request protocol if found. This will create a +# request key containing the request protocol + the actual request. +# +# [default: yes] +# +http-protocol yes + +# Write output to stdout given one of the following files and the +# corresponding extension for the output format: +# +# /path/file.csv - Comma-separated values (CSV) +# /path/file.json - JSON (JavaScript Object Notation) +# /path/file.html - HTML +# +# output /path/file.html + +# Ignore request's query string. +# i.e., www.google.com/page.htm?query => www.google.com/page.htm +# +# Note: Removing the query string can greatly decrease memory +# consumption, especially on timestamped requests. +# +no-query-string false + +# Disable IP resolver on terminal output. +# +no-term-resolver false + +# Treat non-standard status code 444 as 404. +# +444-as-404 false + +# Add 4xx client errors to the unique visitors count. +# +4xx-to-unique-count false + +# Store accumulated processing time from parsing day-by-day logs. +# Only if configured with --enable-tcb=btree +# +#accumulated-time false + +# IP address anonymization +# The IP anonymization option sets the last octet of IPv4 user IP addresses and +# the last 80 bits of IPv6 addresses to zeros. +# e.g., 192.168.20.100 => 192.168.20.0 +# e.g., 2a03:2880:2110:df07:face:b00c::1 => 2a03:2880:2110:df07:: +# +#anonymize-ip false + +# Include static files that contain a query string in the static files +# panel. +# e.g., /fonts/fontawesome-webfont.woff?v=4.0.3 +# +all-static-files false + +# Include an additional delimited list of browsers/crawlers/feeds etc. +# See config/browsers.list for an example or +# https://raw.githubusercontent.com/allinurl/goaccess/master/config/browsers.list +# +#browsers-file + +# Date specificity. Possible values: `date` (default), or `hr`. +# +#date-spec hr + +# Decode double-encoded values. +# +double-decode false + +# Enable parsing/displaying the given panel. +# +#enable-panel VISITORS +#enable-panel REQUESTS +#enable-panel REQUESTS_STATIC +#enable-panel NOT_FOUND +#enable-panel HOSTS +#enable-panel OS +#enable-panel BROWSERS +#enable-panel VISIT_TIMES +#enable-panel VIRTUAL_HOSTS +#enable-panel REFERRERS +#enable-panel REFERRING_SITES +#enable-panel KEYPHRASES +#enable-panel STATUS_CODES +#enable-panel REMOTE_USER +#enable-panel GEO_LOCATION + +# Hide a referer but still count it. Wild cards are allowed. i.e., *.bing.com +# +#hide-referer *.google.com +#hide-referer bing.com + +# Hour specificity. Possible values: `hr` (default), or `min` (tenth +# of a minute). +# +#hour-spec min + +# Ignore crawlers from being counted. +# This will ignore robots listed under browsers.c +# Note that it will count them towards the total +# number of requests, but excluded from any of the panels. +# +ignore-crawlers false + +# Parse and display crawlers only. +# This will ignore robots listed under browsers.c +# Note that it will count them towards the total +# number of requests, but excluded from any of the panels. +# +crawlers-only false + +# Ignore static file requests. +# req : Only ignore request from valid requests +# panels : Ignore request from panels. +# Note that it will count them towards the total number of requests +# ignore-statics req + +# Ignore parsing and displaying the given panel. +# +#ignore-panel VISITORS +#ignore-panel REQUESTS +#ignore-panel REQUESTS_STATIC +#ignore-panel NOT_FOUND +#ignore-panel HOSTS +#ignore-panel OS +#ignore-panel BROWSERS +#ignore-panel VISIT_TIMES +#ignore-panel VIRTUAL_HOSTS +ignore-panel REFERRERS +#ignore-panel REFERRING_SITES +ignore-panel KEYPHRASES +#ignore-panel STATUS_CODES +#ignore-panel REMOTE_USER +#ignore-panel GEO_LOCATION + +# Ignore referers from being counted. +# This supports wild cards. For instance, +# '*' matches 0 or more characters (including spaces) +# '?' matches exactly one character +# +#ignore-referer *.domain.com +#ignore-referer ww?.domain.* + +# Ignore parsing and displaying one or multiple status code(s) +# +#ignore-status 400 +#ignore-status 502 + +# Number of lines from the access log to test against the provided +# log/date/time format. By default, the parser is set to test 10 +# lines. If set to 0, the parser won't test any lines and will parse +# the whole access log. +# +#num-tests 10 + +# Parse log and exit without outputting data. +# +#process-and-exit false + +# Display real OS names. e.g, Windows XP, Snow Leopard. +# +real-os true + +# Sort panel on initial load. +# Sort options are separated by comma. +# Options are in the form: PANEL,METRIC,ORDER +# +# Available metrics: +# BY_HITS - Sort by hits +# BY_VISITORS - Sort by unique visitors +# BY_DATA - Sort by data +# BY_BW - Sort by bandwidth +# BY_AVGTS - Sort by average time served +# BY_CUMTS - Sort by cumulative time served +# BY_MAXTS - Sort by maximum time served +# BY_PROT - Sort by http protocol +# BY_MTHD - Sort by http method +# Available orders: +# ASC +# DESC +# +#sort-panel VISITORS,BY_DATA,ASC +#sort-panel REQUESTS,BY_HITS,ASC +#sort-panel REQUESTS_STATIC,BY_HITS,ASC +#sort-panel NOT_FOUND,BY_HITS,ASC +#sort-panel HOSTS,BY_HITS,ASC +#sort-panel OS,BY_HITS,ASC +#sort-panel BROWSERS,BY_HITS,ASC +#sort-panel VISIT_TIMES,BY_DATA,DESC +#sort-panel VIRTUAL_HOSTS,BY_HITS,ASC +#sort-panel REFERRERS,BY_HITS,ASC +#sort-panel REFERRING_SITES,BY_HITS,ASC +#sort-panel KEYPHRASES,BY_HITS,ASC +#sort-panel STATUS_CODES,BY_HITS,ASC +#sort-panel REMOTE_USER,BY_HITS,ASC +#sort-panel GEO_LOCATION,BY_HITS,ASC + +# Consider the following extensions as static files +# The actual '.' is required and extensions are case sensitive +# For a full list, uncomment the less common static extensions below. +# +static-file .css +static-file .js +static-file .jpg +static-file .png +static-file .gif +static-file .ico +static-file .jpeg +static-file .pdf +static-file .csv +static-file .mpeg +static-file .mpg +static-file .swf +static-file .woff +static-file .woff2 +static-file .xls +static-file .xlsx +static-file .doc +static-file .docx +static-file .ppt +static-file .pptx +static-file .txt +static-file .zip +static-file .ogg +static-file .mp3 +static-file .mp4 +static-file .exe +static-file .iso +static-file .gz +static-file .rar +static-file .svg +static-file .bmp +static-file .tar +static-file .tgz +static-file .tiff +static-file .tif +static-file .ttf +static-file .flv +#static-file .less +#static-file .ac3 +#static-file .avi +#static-file .bz2 +#static-file .class +#static-file .cue +#static-file .dae +#static-file .dat +#static-file .dts +#static-file .ejs +#static-file .eot +#static-file .eps +#static-file .img +#static-file .jar +#static-file .map +#static-file .mid +#static-file .midi +#static-file .ogv +#static-file .webm +#static-file .mkv +#static-file .odp +#static-file .ods +#static-file .odt +#static-file .otf +#static-file .pict +#static-file .pls +#static-file .ps +#static-file .qt +#static-file .rm +#static-file .svgz +#static-file .wav +#static-file .webp + +###################################### +# GeoIP Options +# Only if configured with --enable-geoip +###################################### + +# Standard GeoIP database for less memory usage. +# +#std-geoip false + +# Specify path to GeoIP database file. i.e., GeoLiteCity.dat +# .dat file needs to be downloaded from maxmind.com. +# +# For IPv4 City database: +# wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz +# gunzip GeoLiteCity.dat.gz +# +# For IPv6 City database: +# wget -N http://geolite.maxmind.com/download/geoip/database/GeoLiteCityv6-beta/GeoLiteCityv6.dat.gz +# gunzip GeoLiteCityv6.dat.gz +# +# For IPv6 Country database: +# wget -N http://geolite.maxmind.com/download/geoip/database/GeoIPv6.dat.gz +# gunzip GeoIPv6.dat.gz +# +# For GeoIP2 City database: +# wget -N http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz +# gunzip GeoLite2-City.mmdb.gz +# +# For GeoIP2 Country database: +# wget -N http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz +# gunzip GeoLite2-Country.mmdb.gz +# +# Note: `geoip-city-data` is an alias of `geoip-database` +# +#geoip-database /usr/local/share/GeoIP/GeoLiteCity.dat + +###################################### +# Tokyo Cabinet Options +# Only if configured with --enable-tcb=btree +###################################### + +# GoAccess has the ability to process logs incrementally through the on-disk +# B+Tree database. +# +# It works in the following way: +# - A data set must be persisted first with --keep-db-files, then the same data +# set can be loaded with --load-from-disk. +# - If new data is passed (piped or through a log file), it will append it to +# the original data set. +# - To preserve the data at all times, --keep-db-files must be used. +# - If --load-from-disk is used without --keep-db-files, database files will be +# deleted upon closing the program. + +# On-disk B+ Tree +# Persist parsed data into disk. This should be set to +# the first dataset prior to use `load-from-disk`. +# Setting it to false will delete all database files +# when exiting the program. +#keep-db-files true + +# On-disk B+ Tree +# Load previously stored data from disk. +# Database files need to exist. See `keep-db-files`. +#load-from-disk false + +# On-disk B+ Tree +# Path where the on-disk database files are stored. +# The default value is the /tmp/ directory +# Note the trailing forward-slash. +# +#db-path /tmp/ + +# On-disk B+ Tree +# Set the size in bytes of the extra mapped memory. +# The default value is 0. +# +#xmmap 0 + +# On-disk B+ Tree +# Max number of leaf nodes to be cached. +# Specifies the maximum number of leaf nodes to be cached. +# If it is not more than 0, the default value is specified. +# The default value is 1024. +# +#cache-lcnum 1024 + +# On-disk B+ Tree +# Specifies the maximum number of non-leaf nodes to be cached. +# If it is not more than 0, the default value is specified. +# The default value is 512. +# +#cache-ncnum 512 + +# On-disk B+ Tree +# Specifies the number of members in each leaf page. +# If it is not more than 0, the default value is specified. +# The default value is 128. +# +#tune-lmemb 128 + +# On-disk B+ Tree +# Specifies the number of members in each non-leaf page. +# If it is not more than 0, the default value is specified. +# The default value is 256. +# +#tune-nmemb 256 + +# On-disk B+ Tree +# Specifies the number of elements of the bucket array. +# If it is not more than 0, the default value is specified. +# The default value is 32749. +# Suggested size of the bucket array is about from 1 to 4 +# times of the number of all pages to be stored. +# +#tune-bnum 32749 + +# On-disk B+ Tree +# Specifies that each page is compressed with ZLIB|BZ2 encoding. +# Disabled by default. +# +#compression zlib diff --git a/goaccess++/configure b/goaccess++/configure new file mode 100644 index 0000000..2829f1f --- /dev/null +++ b/goaccess++/configure @@ -0,0 +1,10655 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for goaccess 1.3. +# +# Report bugs to . +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: goaccess@prosoftcorp.com about your system, including +$0: any error possibly output before this message. Then +$0: install a modern shell, or manually run the script +$0: under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +test -n "$DJDIR" || exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='goaccess' +PACKAGE_TARNAME='goaccess' +PACKAGE_VERSION='1.3' +PACKAGE_STRING='goaccess 1.3' +PACKAGE_BUGREPORT='goaccess@prosoftcorp.com' +PACKAGE_URL='http://goaccess.io' + +ac_unique_file="src/goaccess.c" +gt_needs= +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_header_list= +ac_func_list= +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +POW_LIB +LIBOBJS +HAS_SEDTR_FALSE +HAS_SEDTR_TRUE +TR_CHECK +SED_CHECK +TCB_FALSE +TCB_TRUE +GEOIP_MMDB_FALSE +GEOIP_MMDB_TRUE +GEOIP_LEGACY_FALSE +GEOIP_LEGACY_TRUE +WITH_RDYNAMIC_FALSE +WITH_RDYNAMIC_TRUE +DEBUG_FALSE +DEBUG_TRUE +POSUB +LTLIBINTL +LIBINTL +INTLLIBS +LTLIBICONV +LIBICONV +INTL_MACOSX_LIBS +EGREP +GREP +CPP +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +XGETTEXT_EXTRA_OPTIONS +MSGMERGE +XGETTEXT_015 +XGETTEXT +GMSGFMT_015 +MSGFMT_015 +GMSGFMT +MSGFMT +GETTEXT_MACRO_VERSION +USE_NLS +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_dependency_tracking +enable_nls +with_gnu_ld +enable_rpath +with_libiconv_prefix +with_libintl_prefix +enable_debug +with_openssl +enable_geoip +with_getline +enable_utf8 +enable_tcb +enable_zlib +enable_bzip +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures goaccess 1.3 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/goaccess] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of goaccess 1.3:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --disable-nls do not use Native Language Support + --disable-rpath do not hardcode runtime library paths + --enable-debug Create a debug build. Default is disabled + --enable-geoip Enable GeoIP country lookup. Default is disabled + --enable-utf8 Enable ncurses library that handles wide characters + --enable-tcb Enable TokyoCabinet database. Default is disabled + --disable-zlib Build without ZLIB compression + --disable-bzip Build without BZIP2 compression + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-gnu-ld assume the C compiler uses GNU ld default=no + --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib + --without-libiconv-prefix don't search for libiconv in includedir and libdir + --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib + --without-libintl-prefix don't search for libintl in includedir and libdir + --with-openssl build with OpenSSL support + --with-getline Build using dynamic line buffer. + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +goaccess home page: . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +goaccess configure 1.3 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## --------------------------------------- ## +## Report this to goaccess@prosoftcorp.com ## +## --------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_find_intX_t LINENO BITS VAR +# ----------------------------------- +# Finds a signed integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_intX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5 +$as_echo_n "checking for int$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in int$2_t 'int' 'long int' \ + 'long long int' 'short int' 'signed char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + enum { N = $2 / 2 - 1 }; +int +main () +{ +static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) + < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + case $ac_type in #( + int$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_intX_t + +# ac_fn_c_find_uintX_t LINENO BITS VAR +# ------------------------------------ +# Finds an unsigned integer type with width BITS, setting cache variable VAR +# accordingly. +ac_fn_c_find_uintX_t () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uint$2_t" >&5 +$as_echo_n "checking for uint$2_t... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + # Order is important - never check a type that is potentially smaller + # than half of the expected target width. + for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \ + 'unsigned long long int' 'unsigned short int' 'unsigned char'; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + case $ac_type in #( + uint$2_t) : + eval "$3=yes" ;; #( + *) : + eval "$3=\$ac_type" ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + if eval test \"x\$"$3"\" = x"no"; then : + +else + break +fi + done +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_find_uintX_t + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case declares $2. + For example, HP-UX 11i declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by goaccess $as_me 1.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +gt_needs="$gt_needs " +as_fn_append ac_header_list " sys/time.h" +as_fn_append ac_header_list " unistd.h" +as_fn_append ac_func_list " alarm" +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +am__api_version='1.11' + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='goaccess' + VERSION='1.3' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +ac_config_headers="$ac_config_headers src/config.h" + + +# Use empty CFLAGS by default so autoconf does not add +# CFLAGS="-O2 -g" +# NOTE: Needs to go after AC_INIT and before AC_PROG_CC to select an +# empty default instead. +: ${CFLAGS=""} + +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + +if test "x$CC" != xcc; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +fi +set dummy $CC; ac_cc=`$as_echo "$2" | + sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +# Make sure it works both with $CC and with simple cc. +# We do the test twice because some compilers refuse to overwrite an +# existing .o file with -o, though they will create one. +ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +rm -f conftest2.* +if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; +then + eval ac_cv_prog_cc_${ac_cc}_c_o=yes + if test "x$CC" != xcc; then + # Test first that cc exists at all. + if { ac_try='cc -c conftest.$ac_ext >&5' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' + rm -f conftest2.* + if { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && + test -f conftest2.$ac_objext && { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; + then + # cc works too. + : + else + # cc exists but doesn't like -o. + eval ac_cv_prog_cc_${ac_cc}_c_o=no + fi + fi + fi +else + eval ac_cv_prog_cc_${ac_cc}_c_o=no +fi +rm -f core conftest* + +fi +if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h + +fi + +# FIXME: we rely on the cache variable name because +# there is no other way. +set dummy $CC +am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +if test "$am_t" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 +$as_echo_n "checking whether NLS is requested... " >&6; } + # Check whether --enable-nls was given. +if test "${enable_nls+set}" = set; then : + enableval=$enable_nls; USE_NLS=$enableval +else + USE_NLS=yes +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + + + + + GETTEXT_MACRO_VERSION=0.18 + + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "msgfmt", so it can be a program name with args. +set dummy msgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGFMT" in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test "$MSGFMT" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 +$as_echo "$MSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + # Extract the first word of "gmsgfmt", so it can be a program name with args. +set dummy gmsgfmt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_GMSGFMT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $GMSGFMT in + [\\/]* | ?:[\\/]*) + ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" + ;; +esac +fi +GMSGFMT=$ac_cv_path_GMSGFMT +if test -n "$GMSGFMT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 +$as_echo "$GMSGFMT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; + *) MSGFMT_015=$MSGFMT ;; + esac + + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "xgettext", so it can be a program name with args. +set dummy xgettext; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_XGETTEXT+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$XGETTEXT" in + [\\/]* | ?:[\\/]*) + ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" + ;; +esac +fi +XGETTEXT="$ac_cv_path_XGETTEXT" +if test "$XGETTEXT" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 +$as_echo "$XGETTEXT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + rm -f messages.po + + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac + + + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "msgmerge", so it can be a program name with args. +set dummy msgmerge; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_MSGMERGE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$MSGMERGE" in + [\\/]* | ?:[\\/]*) + ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&5 + if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then + ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" + test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" + ;; +esac +fi +MSGMERGE="$ac_cv_path_MSGMERGE" +if test "$MSGMERGE" != ":"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 +$as_echo "$MSGMERGE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$localedir" || localedir='${datadir}/locale' + + + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + + + ac_config_commands="$ac_config_commands po-directories" + + + + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by GCC" >&5 +$as_echo_n "checking for ld used by GCC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$acl_cv_path_LD" +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 &5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + + + + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 +$as_echo_n "checking for 64-bit host... " >&6; } +if ${gl_cv_solaris_64bit+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef _LP64 +sixtyfour bits +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "sixtyfour bits" >/dev/null 2>&1; then : + gl_cv_solaris_64bit=yes +else + gl_cv_solaris_64bit=no +fi +rm -f conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 +$as_echo "$gl_cv_solaris_64bit" >&6; } + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + + + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libiconv-prefix was given. +if test "${with_libiconv_prefix+set}" = set; then : + withval=$with_libiconv_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi + +fi + + LIBICONV= + LTLIBICONV= + INCICONV= + LIBICONV_PREFIX= + HAVE_LIBICONV= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='iconv ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$acl_hardcode_direct" = yes; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = 'iconv'; then + LIBICONV_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBICONV; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" + ;; + esac + done + fi + else + LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" + done + fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 +$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } +if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +CFPreferencesCopyAppValue(NULL, NULL) + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_CFPreferencesCopyAppValue=yes +else + gt_cv_func_CFPreferencesCopyAppValue=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$gt_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 +$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + +$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 +$as_echo_n "checking for CFLocaleCopyCurrent... " >&6; } +if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +CFLocaleCopyCurrent(); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + gt_cv_func_CFLocaleCopyCurrent=yes +else + gt_cv_func_CFLocaleCopyCurrent=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$gt_save_LIBS" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 +$as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; } + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + +$as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h + + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + + + + + + + LIBINTL= + LTLIBINTL= + POSUB= + + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 +$as_echo_n "checking for GNU gettext in libc... " >&6; } +if eval \${$gt_func_gnugettext_libc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings; +int +main () +{ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$gt_func_gnugettext_libc=yes" +else + eval "$gt_func_gnugettext_libc=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$gt_func_gnugettext_libc + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + + + + + + am_save_CPPFLAGS="$CPPFLAGS" + + for element in $INCICONV; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 +$as_echo_n "checking for iconv... " >&6; } +if ${am_cv_func_iconv+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +int +main () +{ +iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + am_cv_lib_iconv=yes + am_cv_func_iconv=yes +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LIBS="$am_save_LIBS" + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 +$as_echo "$am_cv_func_iconv" >&6; } + if test "$am_cv_func_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 +$as_echo_n "checking for working iconv... " >&6; } +if ${am_cv_func_iconv_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + if test "$cross_compiling" = yes; then : + case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +int main () +{ + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\263"; + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + return 1; + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + return 1; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + am_cv_func_iconv_works=yes +else + am_cv_func_iconv_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + LIBS="$am_save_LIBS" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 +$as_echo "$am_cv_func_iconv_works" >&6; } + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + +$as_echo "#define HAVE_ICONV 1" >>confdefs.h + + fi + if test "$am_cv_lib_iconv" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 +$as_echo_n "checking how to link with libiconv... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 +$as_echo "$LIBICONV" >&6; } + else + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + + + + + + + + + + + + use_additional=yes + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + +# Check whether --with-libintl-prefix was given. +if test "${with_libintl_prefix+set}" = set; then : + withval=$with_libintl_prefix; + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi + +fi + + LIBINTL= + LTLIBINTL= + INCINTL= + LIBINTL_PREFIX= + HAVE_LIBINTL= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='intl ' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" + else + : + fi + else + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + if test "$acl_hardcode_direct" = yes; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" + fi + fi + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = 'intl'; then + LIBINTL_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = 'intl'; then + LIBINTL_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INCINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + if test -n "$found_la"; then + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIBINTL; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" + ;; + esac + done + fi + else + LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + else + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + for found_dir in $ltrpathdirs; do + LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" + done + fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 +$as_echo_n "checking for GNU gettext in libintl... " >&6; } +if eval \${$gt_func_gnugettext_libintl+:} false; then : + $as_echo_n "(cached) " >&6 +else + gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +int +main () +{ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$gt_func_gnugettext_libintl=yes" +else + eval "$gt_func_gnugettext_libintl=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *); +int +main () +{ +bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS" +fi +eval ac_res=\$$gt_func_gnugettext_libintl + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + fi + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + + else + USE_NLS=no + fi + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 +$as_echo_n "checking whether to use NLS... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 +$as_echo "$USE_NLS" >&6; } + if test "$USE_NLS" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 +$as_echo_n "checking where the gettext function comes from... " >&6; } + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 +$as_echo "$gt_source" >&6; } + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 +$as_echo_n "checking how to link with libintl... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 +$as_echo "$LIBINTL" >&6; } + + for element in $INCINTL; do + haveit= + for x in $CPPFLAGS; do + + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + eval x=\"$x\" + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" + + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" + fi + done + + fi + + +$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h + + +$as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h + + fi + + POSUB=po + fi + + + + INTLLIBS="$LIBINTL" + + + + + + + +# Fix `undefined reference to `libintl_gettext'` on docker: +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libintl_dgettext in -lintl" >&5 +$as_echo_n "checking for libintl_dgettext in -lintl... " >&6; } +if ${ac_cv_lib_intl_libintl_dgettext+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char libintl_dgettext (); +int +main () +{ +return libintl_dgettext (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_intl_libintl_dgettext=yes +else + ac_cv_lib_intl_libintl_dgettext=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_libintl_dgettext" >&5 +$as_echo "$ac_cv_lib_intl_libintl_dgettext" >&6; } +if test "x$ac_cv_lib_intl_libintl_dgettext" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBINTL 1 +_ACEOF + + LIBS="-lintl $LIBS" + +fi + + +# pthread +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 +$as_echo_n "checking for pthread_create in -lpthread... " >&6; } +if ${ac_cv_lib_pthread_pthread_create+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpthread $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_create (); +int +main () +{ +return pthread_create (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_pthread_pthread_create=yes +else + ac_cv_lib_pthread_pthread_create=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 +$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } +if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPTHREAD 1 +_ACEOF + + LIBS="-lpthread $LIBS" + +else + as_fn_error $? "pthread is missing" "$LINENO" 5 +fi + +CFLAGS="$CFLAGS -pthread" + +# DEBUG +# Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; debug="$enableval" +else + debug=no +fi + + +if test "$debug" = "yes"; then + +$as_echo "#define _DEBUG 1" >>confdefs.h + +fi + if test "x$debug" = "xyes"; then + DEBUG_TRUE= + DEBUG_FALSE='#' +else + DEBUG_TRUE='#' + DEBUG_FALSE= +fi + + +# Handle rdynamic only on systems using GNU ld + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with rdynamic for GNU ld" >&5 +$as_echo_n "checking whether to build with rdynamic for GNU ld... " >&6; } +with_rdyanimc=yes +case "$host_os" in + *darwin*|*cygwin*|*aix*|*mingw*) with_rdyanimc=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_rdyanimc" >&5 +$as_echo "$with_rdyanimc" >&6; } + if test "x$with_rdyanimc" = "xyes"; then + WITH_RDYNAMIC_TRUE= + WITH_RDYNAMIC_FALSE='#' +else + WITH_RDYNAMIC_TRUE='#' + WITH_RDYNAMIC_FALSE= +fi + + +# Build with OpenSSL + +# Check whether --with-openssl was given. +if test "${with_openssl+set}" = set; then : + withval=$with_openssl; openssl="$withval" +else + openssl="no" +fi + + +if test "$openssl" = 'yes'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_new in -lssl" >&5 +$as_echo_n "checking for SSL_CTX_new in -lssl... " >&6; } +if ${ac_cv_lib_ssl_SSL_CTX_new+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lssl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char SSL_CTX_new (); +int +main () +{ +return SSL_CTX_new (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ssl_SSL_CTX_new=yes +else + ac_cv_lib_ssl_SSL_CTX_new=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_CTX_new" >&5 +$as_echo "$ac_cv_lib_ssl_SSL_CTX_new" >&6; } +if test "x$ac_cv_lib_ssl_SSL_CTX_new" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSSL 1 +_ACEOF + + LIBS="-lssl $LIBS" + +else + as_fn_error $? "ssl library missing" "$LINENO" 5 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CRYPTO_free in -lcrypto" >&5 +$as_echo_n "checking for CRYPTO_free in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_CRYPTO_free+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char CRYPTO_free (); +int +main () +{ +return CRYPTO_free (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_CRYPTO_free=yes +else + ac_cv_lib_crypto_CRYPTO_free=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_CRYPTO_free" >&5 +$as_echo "$ac_cv_lib_crypto_CRYPTO_free" >&6; } +if test "x$ac_cv_lib_crypto_CRYPTO_free" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBCRYPTO 1 +_ACEOF + + LIBS="-lcrypto $LIBS" + +else + as_fn_error $? "crypto library missing" "$LINENO" 5 +fi + +fi + +# GeoIP +# Check whether --enable-geoip was given. +if test "${enable_geoip+set}" = set; then : + enableval=$enable_geoip; geoip="$enableval" +else + geoip=no +fi + + +geolocation="N/A" +if test "$geoip" = "mmdb"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MMDB_open in -lmaxminddb" >&5 +$as_echo_n "checking for MMDB_open in -lmaxminddb... " >&6; } +if ${ac_cv_lib_maxminddb_MMDB_open+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmaxminddb $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char MMDB_open (); +int +main () +{ +return MMDB_open (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_maxminddb_MMDB_open=yes +else + ac_cv_lib_maxminddb_MMDB_open=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_maxminddb_MMDB_open" >&5 +$as_echo "$ac_cv_lib_maxminddb_MMDB_open" >&6; } +if test "x$ac_cv_lib_maxminddb_MMDB_open" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBMAXMINDDB 1 +_ACEOF + + LIBS="-lmaxminddb $LIBS" + +else + as_fn_error $? " + *** Missing development files for libmaxminddb library. + " "$LINENO" 5 +fi + + geolocation="GeoIP2" + +$as_echo "#define HAVE_GEOLOCATION 1" >>confdefs.h + +elif test "$geoip" = "legacy"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GeoIP_new in -lGeoIP" >&5 +$as_echo_n "checking for GeoIP_new in -lGeoIP... " >&6; } +if ${ac_cv_lib_GeoIP_GeoIP_new+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lGeoIP $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char GeoIP_new (); +int +main () +{ +return GeoIP_new (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_GeoIP_GeoIP_new=yes +else + ac_cv_lib_GeoIP_GeoIP_new=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GeoIP_GeoIP_new" >&5 +$as_echo "$ac_cv_lib_GeoIP_GeoIP_new" >&6; } +if test "x$ac_cv_lib_GeoIP_GeoIP_new" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGEOIP 1 +_ACEOF + + LIBS="-lGeoIP $LIBS" + +else + as_fn_error $? " + *** Missing development files for the GeoIP library + " "$LINENO" 5 +fi + + geolocation="GeoIP Legacy" + +$as_echo "#define HAVE_GEOLOCATION 1" >>confdefs.h + +fi + if test "x$geoip" = "xlegacy"; then + GEOIP_LEGACY_TRUE= + GEOIP_LEGACY_FALSE='#' +else + GEOIP_LEGACY_TRUE='#' + GEOIP_LEGACY_FALSE= +fi + + if test "x$geoip" = "xmmdb"; then + GEOIP_MMDB_TRUE= + GEOIP_MMDB_FALSE='#' +else + GEOIP_MMDB_TRUE='#' + GEOIP_MMDB_FALSE= +fi + + +# GNU getline / POSIX.1-2008 + +# Check whether --with-getline was given. +if test "${with_getline+set}" = set; then : + withval=$with_getline; with_getline=$withval +else + with_getline=no +fi + + +if test "$with_getline" = "yes"; then + +$as_echo "#define WITH_GETLINE 1" >>confdefs.h + +fi + +# UTF8 +# Check whether --enable-utf8 was given. +if test "${enable_utf8+set}" = set; then : + enableval=$enable_utf8; utf8="$enableval" +else + utf8=no +fi + + +if test "$utf8" = "yes"; then + libncursesw=ncursesw + # Simply called libncurses on OS X + case "$host_os" in + *darwin*) libncursesw=ncurses + ;; + esac + + as_ac_Lib=`$as_echo "ac_cv_lib_$libncursesw''_mvaddwstr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mvaddwstr in -l$libncursesw" >&5 +$as_echo_n "checking for mvaddwstr in -l$libncursesw... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l$libncursesw $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char mvaddwstr (); +int +main () +{ +return mvaddwstr (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_LIB$libncursesw" | $as_tr_cpp` 1 +_ACEOF + + LIBS="-l$libncursesw $LIBS" + +else + as_fn_error $? "*** Missing development libraries for ncursesw" "$LINENO" 5 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tputs" >&5 +$as_echo_n "checking for library containing tputs... " >&6; } +if ${ac_cv_search_tputs+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tputs (); +int +main () +{ +return tputs (); + ; + return 0; +} +_ACEOF +for ac_lib in '' tinfow; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_tputs=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_tputs+:} false; then : + break +fi +done +if ${ac_cv_search_tputs+:} false; then : + +else + ac_cv_search_tputs=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tputs" >&5 +$as_echo "$ac_cv_search_tputs" >&6; } +ac_res=$ac_cv_search_tputs +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "Cannot find a library providing tputs" "$LINENO" 5 +fi + + +$as_echo "#define HAVE_LIBNCURSESW 1" >>confdefs.h + + + have_ncurses="yes" + for ac_header in ncursesw/ncurses.h +do : + ac_fn_c_check_header_compile "$LINENO" "ncursesw/ncurses.h" "ac_cv_header_ncursesw_ncurses_h" " + #ifdef HAVE_NCURSESW_NCURSES_H + #include + #endif + +" +if test "x$ac_cv_header_ncursesw_ncurses_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NCURSESW_NCURSES_H 1 +_ACEOF + have_ncurses=yes +fi + +done + + + for ac_header in ncurses.h +do : + ac_fn_c_check_header_compile "$LINENO" "ncurses.h" "ac_cv_header_ncurses_h" " + #ifdef HAVE_NCURSES_H + #include + #endif + +" +if test "x$ac_cv_header_ncurses_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NCURSES_H 1 +_ACEOF + have_ncurses=yes +fi + +done + + + if test "$have_ncurses" != "yes"; then + as_fn_error $? "Missing ncursesw header file" "$LINENO" 5 + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for refresh in -lncurses" >&5 +$as_echo_n "checking for refresh in -lncurses... " >&6; } +if ${ac_cv_lib_ncurses_refresh+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lncurses $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char refresh (); +int +main () +{ +return refresh (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_ncurses_refresh=yes +else + ac_cv_lib_ncurses_refresh=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_refresh" >&5 +$as_echo "$ac_cv_lib_ncurses_refresh" >&6; } +if test "x$ac_cv_lib_ncurses_refresh" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNCURSES 1 +_ACEOF + + LIBS="-lncurses $LIBS" + +else + as_fn_error $? "*** Missing development libraries for ncurses" "$LINENO" 5 +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tputs" >&5 +$as_echo_n "checking for library containing tputs... " >&6; } +if ${ac_cv_search_tputs+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tputs (); +int +main () +{ +return tputs (); + ; + return 0; +} +_ACEOF +for ac_lib in '' tinfo; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_tputs=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_tputs+:} false; then : + break +fi +done +if ${ac_cv_search_tputs+:} false; then : + +else + ac_cv_search_tputs=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tputs" >&5 +$as_echo "$ac_cv_search_tputs" >&6; } +ac_res=$ac_cv_search_tputs +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + as_fn_error $? "Cannot find a library providing tputs" "$LINENO" 5 +fi + + + have_ncurses="yes" + for ac_header in ncurses/ncurses.h +do : + ac_fn_c_check_header_compile "$LINENO" "ncurses/ncurses.h" "ac_cv_header_ncurses_ncurses_h" " + #ifdef HAVE_NCURSES_NCURSES_H + #include + #endif + +" +if test "x$ac_cv_header_ncurses_ncurses_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NCURSES_NCURSES_H 1 +_ACEOF + have_ncurses=yes +fi + +done + + + for ac_header in ncurses.h +do : + ac_fn_c_check_header_compile "$LINENO" "ncurses.h" "ac_cv_header_ncurses_h" " + #ifdef HAVE_NCURSES_H + #include + #endif + +" +if test "x$ac_cv_header_ncurses_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NCURSES_H 1 +_ACEOF + have_ncurses=yes +fi + +done + + + for ac_header in curses.h +do : + ac_fn_c_check_header_compile "$LINENO" "curses.h" "ac_cv_header_curses_h" " + #ifdef HAVE_CURSES_H + #include + #endif + +" +if test "x$ac_cv_header_curses_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_CURSES_H 1 +_ACEOF + have_ncurses=yes +fi + +done + + + if test "$have_ncurses" != "yes"; then + as_fn_error $? "Missing ncursesw header file" "$LINENO" 5 + fi +fi + +# Tokyo Cabinet +# Check whether --enable-tcb was given. +if test "${enable_tcb+set}" = set; then : + enableval=$enable_tcb; tcb="$enableval" +else + tcb=no +fi + + +WITH_TC=no +if test "$tcb" = "memhash"; then + WITH_TC=yes + +$as_echo "#define TCB_MEMHASH 1" >>confdefs.h + +elif test "$tcb" = "btree"; then + +$as_echo "#define TCB_BTREE 1" >>confdefs.h + + WITH_TC=yes +fi + +if test "$WITH_TC" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tchdbnew in -ltokyocabinet" >&5 +$as_echo_n "checking for tchdbnew in -ltokyocabinet... " >&6; } +if ${ac_cv_lib_tokyocabinet_tchdbnew+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ltokyocabinet $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char tchdbnew (); +int +main () +{ +return tchdbnew (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_tokyocabinet_tchdbnew=yes +else + ac_cv_lib_tokyocabinet_tchdbnew=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tokyocabinet_tchdbnew" >&5 +$as_echo "$ac_cv_lib_tokyocabinet_tchdbnew" >&6; } +if test "x$ac_cv_lib_tokyocabinet_tchdbnew" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBTOKYOCABINET 1 +_ACEOF + + LIBS="-ltokyocabinet $LIBS" + +else + as_fn_error $? "*** Missing development libraries for Tokyo Cabinet Database" "$LINENO" 5 +fi + + + # Check whether --enable-zlib was given. +if test "${enable_zlib+set}" = set; then : + enableval=$enable_zlib; zlib="$enableval" +else + zlib=yes +fi + + + if test "$zlib" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzread in -lz" >&5 +$as_echo_n "checking for gzread in -lz... " >&6; } +if ${ac_cv_lib_z_gzread+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lz $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gzread (); +int +main () +{ +return gzread (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_z_gzread=yes +else + ac_cv_lib_z_gzread=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzread" >&5 +$as_echo "$ac_cv_lib_z_gzread" >&6; } +if test "x$ac_cv_lib_z_gzread" = xyes; then : + Z_FLAG=-lz +else + as_fn_error $? " + *** zlib is required. If zlib compression is not needed + *** you can use --disable-zlib. + *** Debian based distributions zlib1g-dev + *** Red Hat based distributions zlib-devel + " "$LINENO" 5 +fi + + +$as_echo "#define HAVE_ZLIB 1" >>confdefs.h + + LDFLAGS="$LDFLAGS $Z_FLAG" + fi + + # Check whether --enable-bzip was given. +if test "${enable_bzip+set}" = set; then : + enableval=$enable_bzip; bz2="$enableval" +else + bz2=yes +fi + + + if test "$bz2" = "yes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BZ2_bzopen in -lbz2" >&5 +$as_echo_n "checking for BZ2_bzopen in -lbz2... " >&6; } +if ${ac_cv_lib_bz2_BZ2_bzopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lbz2 $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char BZ2_bzopen (); +int +main () +{ +return BZ2_bzopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_bz2_BZ2_bzopen=yes +else + ac_cv_lib_bz2_BZ2_bzopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_BZ2_bzopen" >&5 +$as_echo "$ac_cv_lib_bz2_BZ2_bzopen" >&6; } +if test "x$ac_cv_lib_bz2_BZ2_bzopen" = xyes; then : + BZ2_FLAG=-lbz2 +else + as_fn_error $? " + *** BZIP2 is required. If BZIP2 compression is not needed + *** you can use --disable-bzip. + *** Debian based distributions libbz2-dev + *** Red Hat based distributions bzip2-devel + " "$LINENO" 5 +fi + + +$as_echo "#define HAVE_BZ2 1" >>confdefs.h + + LDFLAGS="$LDFLAGS $BZ2_FLAG" + fi + + case "$host_os" in + *darwin*|*bsd*) + LDFLAGS="$LDFLAGS -ltokyocabinet -lc" + ;; + *) + LDFLAGS="$LDFLAGS -ltokyocabinet -lrt -lc" + ;; + esac +fi + if test "$WITH_TC" = "yes"; then + TCB_TRUE= + TCB_FALSE='#' +else + TCB_TRUE='#' + TCB_FALSE= +fi + + +if test "$tcb" = "memhash"; then + storage="In-memory Hash Database (Tokyo Cabinet)" +elif test "$tcb" = "btree"; then + storage="On-disk B+ Tree Database (Tokyo Cabinet)" +else + storage="In-memory Hash Database (Default)" +fi + +HAS_SEDTR=no +# Extract the first word of "sed", so it can be a program name with args. +set dummy sed; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_SED_CHECK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$SED_CHECK"; then + ac_cv_prog_SED_CHECK="$SED_CHECK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_SED_CHECK="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_SED_CHECK" && ac_cv_prog_SED_CHECK="no" +fi +fi +SED_CHECK=$ac_cv_prog_SED_CHECK +if test -n "$SED_CHECK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED_CHECK" >&5 +$as_echo "$SED_CHECK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +if test x"$SED_CHECK" == x"yes" ; then + # Extract the first word of "tr", so it can be a program name with args. +set dummy tr; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_TR_CHECK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$TR_CHECK"; then + ac_cv_prog_TR_CHECK="$TR_CHECK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_TR_CHECK="yes" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_TR_CHECK" && ac_cv_prog_TR_CHECK="no" +fi +fi +TR_CHECK=$ac_cv_prog_TR_CHECK +if test -n "$TR_CHECK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TR_CHECK" >&5 +$as_echo "$TR_CHECK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + if test x"$TR_CHECK" == x"yes" ; then + HAS_SEDTR=yes + fi +fi + if test "x$HAS_SEDTR" = xyes; then + HAS_SEDTR_TRUE= + HAS_SEDTR_FALSE='#' +else + HAS_SEDTR_TRUE='#' + HAS_SEDTR_FALSE= +fi + + +# Solaris +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5 +$as_echo_n "checking for gethostbyname in -lnsl... " >&6; } +if ${ac_cv_lib_nsl_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_nsl_gethostbyname=yes +else + ac_cv_lib_nsl_gethostbyname=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5 +$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; } +if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 +$as_echo_n "checking for socket in -lsocket... " >&6; } +if ${ac_cv_lib_socket_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char socket (); +int +main () +{ +return socket (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_socket_socket=yes +else + ac_cv_lib_socket_socket=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 +$as_echo "$ac_cv_lib_socket_socket" >&6; } +if test "x$ac_cv_lib_socket_socket" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + +# Checks for header files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +for ac_header in arpa/inet.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "arpa/inet.h" "ac_cv_header_arpa_inet_h" "$ac_includes_default" +if test "x$ac_cv_header_arpa_inet_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_ARPA_INET_H 1 +_ACEOF + +fi + +done + +for ac_header in fcntl.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "fcntl.h" "ac_cv_header_fcntl_h" "$ac_includes_default" +if test "x$ac_cv_header_fcntl_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FCNTL_H 1 +_ACEOF + +fi + +done + +for ac_header in inttypes.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default" +if test "x$ac_cv_header_inttypes_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_INTTYPES_H 1 +_ACEOF + +fi + +done + +for ac_header in limits.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "limits.h" "ac_cv_header_limits_h" "$ac_includes_default" +if test "x$ac_cv_header_limits_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIMITS_H 1 +_ACEOF + +fi + +done + +for ac_header in locale.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "locale.h" "ac_cv_header_locale_h" "$ac_includes_default" +if test "x$ac_cv_header_locale_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LOCALE_H 1 +_ACEOF + +fi + +done + +for ac_header in netdb.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default" +if test "x$ac_cv_header_netdb_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NETDB_H 1 +_ACEOF + +fi + +done + +for ac_header in netinet/in.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default" +if test "x$ac_cv_header_netinet_in_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_NETINET_IN_H 1 +_ACEOF + +fi + +done + +for ac_header in stddef.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default" +if test "x$ac_cv_header_stddef_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDDEF_H 1 +_ACEOF + +fi + +done + +for ac_header in stdint.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdint.h" "ac_cv_header_stdint_h" "$ac_includes_default" +if test "x$ac_cv_header_stdint_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDINT_H 1 +_ACEOF + +fi + +done + +for ac_header in stdlib.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" +if test "x$ac_cv_header_stdlib_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STDLIB_H 1 +_ACEOF + +fi + +done + +for ac_header in string.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default" +if test "x$ac_cv_header_string_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRING_H 1 +_ACEOF + +fi + +done + +for ac_header in strings.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default" +if test "x$ac_cv_header_strings_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRINGS_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/socket.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_socket_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_SOCKET_H 1 +_ACEOF + +fi + +done + +for ac_header in sys/time.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_time_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_TIME_H 1 +_ACEOF + +fi + +done + +for ac_header in unistd.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default" +if test "x$ac_cv_header_unistd_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_UNISTD_H 1 +_ACEOF + +fi + +done + + +# Checks for typedefs, structures, and compiler characteristics. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" +if test "x$ac_cv_type_ptrdiff_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_PTRDIFF_T 1 +_ACEOF + + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5 +$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; } +if ${ac_cv_struct_tm+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include + +int +main () +{ +struct tm tm; + int *p = &tm.tm_sec; + return !p; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_struct_tm=time.h +else + ac_cv_struct_tm=sys/time.h +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5 +$as_echo "$ac_cv_struct_tm" >&6; } +if test $ac_cv_struct_tm = sys/time.h; then + +$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h + +fi + +ac_fn_c_find_intX_t "$LINENO" "64" "ac_cv_c_int64_t" +case $ac_cv_c_int64_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int64_t $ac_cv_c_int64_t +_ACEOF +;; +esac + +ac_fn_c_find_intX_t "$LINENO" "8" "ac_cv_c_int8_t" +case $ac_cv_c_int8_t in #( + no|yes) ;; #( + *) + +cat >>confdefs.h <<_ACEOF +#define int8_t $ac_cv_c_int8_t +_ACEOF +;; +esac + +ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default" +if test "x$ac_cv_type_off_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define off_t long int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" +case $ac_cv_c_uint32_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT32_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint32_t $ac_cv_c_uint32_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" +case $ac_cv_c_uint64_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT64_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint64_t $ac_cv_c_uint64_t +_ACEOF +;; + esac + +ac_fn_c_find_uintX_t "$LINENO" "8" "ac_cv_c_uint8_t" +case $ac_cv_c_uint8_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT8_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint8_t $ac_cv_c_uint8_t +_ACEOF +;; + esac + + +# Checks for library functions. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 +$as_echo_n "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } +if ${ac_cv_sys_largefile_source+:} false; then : + $as_echo_n "(cached) " >&6 +else + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include /* for off_t */ + #include +int +main () +{ +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sys_largefile_source=no; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#define _LARGEFILE_SOURCE 1 +#include /* for off_t */ + #include +int +main () +{ +int (*fp) (FILE *, off_t, int) = fseeko; + return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_sys_largefile_source=1; break +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_cv_sys_largefile_source=unknown + break +done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 +$as_echo "$ac_cv_sys_largefile_source" >&6; } +case $ac_cv_sys_largefile_source in #( + no | unknown) ;; + *) +cat >>confdefs.h <<_ACEOF +#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source +_ACEOF +;; +esac +rm -rf conftest* + +# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug +# in glibc 2.1.3, but that breaks too many other things. +# If you want fseeko and ftello with glibc, upgrade to a fixed glibc. +if test $ac_cv_sys_largefile_source != unknown; then + +$as_echo "#define HAVE_FSEEKO 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5 +$as_echo_n "checking for working memcmp... " >&6; } +if ${ac_cv_func_memcmp_working+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_memcmp_working=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* Some versions of memcmp are not 8-bit clean. */ + char c0 = '\100', c1 = '\200', c2 = '\201'; + if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0) + return 1; + + /* The Next x86 OpenStep bug shows up only when comparing 16 bytes + or more and with at least one buffer not starting on a 4-byte boundary. + William Lewis provided this test program. */ + { + char foo[21]; + char bar[21]; + int i; + for (i = 0; i < 4; i++) + { + char *a = foo + i; + char *b = bar + i; + strcpy (a, "--------01111111"); + strcpy (b, "--------10000000"); + if (memcmp (a, b, 16) >= 0) + return 1; + } + return 0; + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_memcmp_working=yes +else + ac_cv_func_memcmp_working=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5 +$as_echo "$ac_cv_func_memcmp_working" >&6; } +test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in + *" memcmp.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" + ;; +esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } +if ${ac_cv_header_time+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_time=yes +else + ac_cv_header_time=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } +if test $ac_cv_header_time = yes; then + +$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h + +fi + + + + + for ac_header in $ac_header_list +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + for ac_func in $ac_func_list +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working mktime" >&5 +$as_echo_n "checking for working mktime... " >&6; } +if ${ac_cv_func_working_mktime+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_working_mktime=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Test program from Paul Eggert and Tony Leneis. */ +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#include +#include + +#ifdef HAVE_UNISTD_H +# include +#endif + +#ifndef HAVE_ALARM +# define alarm(X) /* empty */ +#endif + +/* Work around redefinition to rpl_putenv by other config tests. */ +#undef putenv + +static time_t time_t_max; +static time_t time_t_min; + +/* Values we'll use to set the TZ environment variable. */ +static const char *tz_strings[] = { + (const char *) 0, "TZ=GMT0", "TZ=JST-9", + "TZ=EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00" +}; +#define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0])) + +/* Return 0 if mktime fails to convert a date in the spring-forward gap. + Based on a problem report from Andreas Jaeger. */ +static int +spring_forward_gap () +{ + /* glibc (up to about 1998-10-07) failed this test. */ + struct tm tm; + + /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0" + instead of "TZ=America/Vancouver" in order to detect the bug even + on systems that don't support the Olson extension, or don't have the + full zoneinfo tables installed. */ + putenv ((char*) "TZ=PST8PDT,M4.1.0,M10.5.0"); + + tm.tm_year = 98; + tm.tm_mon = 3; + tm.tm_mday = 5; + tm.tm_hour = 2; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_isdst = -1; + return mktime (&tm) != (time_t) -1; +} + +static int +mktime_test1 (time_t now) +{ + struct tm *lt; + return ! (lt = localtime (&now)) || mktime (lt) == now; +} + +static int +mktime_test (time_t now) +{ + return (mktime_test1 (now) + && mktime_test1 ((time_t) (time_t_max - now)) + && mktime_test1 ((time_t) (time_t_min + now))); +} + +static int +irix_6_4_bug () +{ + /* Based on code from Ariel Faigon. */ + struct tm tm; + tm.tm_year = 96; + tm.tm_mon = 3; + tm.tm_mday = 0; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_isdst = -1; + mktime (&tm); + return tm.tm_mon == 2 && tm.tm_mday == 31; +} + +static int +bigtime_test (int j) +{ + struct tm tm; + time_t now; + tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = j; + now = mktime (&tm); + if (now != (time_t) -1) + { + struct tm *lt = localtime (&now); + if (! (lt + && lt->tm_year == tm.tm_year + && lt->tm_mon == tm.tm_mon + && lt->tm_mday == tm.tm_mday + && lt->tm_hour == tm.tm_hour + && lt->tm_min == tm.tm_min + && lt->tm_sec == tm.tm_sec + && lt->tm_yday == tm.tm_yday + && lt->tm_wday == tm.tm_wday + && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) + == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) + return 0; + } + return 1; +} + +static int +year_2050_test () +{ + /* The correct answer for 2050-02-01 00:00:00 in Pacific time, + ignoring leap seconds. */ + unsigned long int answer = 2527315200UL; + + struct tm tm; + time_t t; + tm.tm_year = 2050 - 1900; + tm.tm_mon = 2 - 1; + tm.tm_mday = 1; + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + tm.tm_isdst = -1; + + /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0" + instead of "TZ=America/Vancouver" in order to detect the bug even + on systems that don't support the Olson extension, or don't have the + full zoneinfo tables installed. */ + putenv ((char*) "TZ=PST8PDT,M4.1.0,M10.5.0"); + + t = mktime (&tm); + + /* Check that the result is either a failure, or close enough + to the correct answer that we can assume the discrepancy is + due to leap seconds. */ + return (t == (time_t) -1 + || (0 < t && answer - 120 <= t && t <= answer + 120)); +} + +int +main () +{ + time_t t, delta; + int i, j; + + /* This test makes some buggy mktime implementations loop. + Give up after 60 seconds; a mktime slower than that + isn't worth using anyway. */ + alarm (60); + + for (;;) + { + t = (time_t_max << 1) + 1; + if (t <= time_t_max) + break; + time_t_max = t; + } + time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max; + + delta = time_t_max / 997; /* a suitable prime number */ + for (i = 0; i < N_STRINGS; i++) + { + if (tz_strings[i]) + putenv ((char*) tz_strings[i]); + + for (t = 0; t <= time_t_max - delta; t += delta) + if (! mktime_test (t)) + return 1; + if (! (mktime_test ((time_t) 1) + && mktime_test ((time_t) (60 * 60)) + && mktime_test ((time_t) (60 * 60 * 24)))) + return 1; + + for (j = 1; ; j <<= 1) + if (! bigtime_test (j)) + return 1; + else if (INT_MAX / 2 < j) + break; + if (! bigtime_test (INT_MAX)) + return 1; + } + return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ()); +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_working_mktime=yes +else + ac_cv_func_working_mktime=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_working_mktime" >&5 +$as_echo "$ac_cv_func_working_mktime" >&6; } +if test $ac_cv_func_working_mktime = no; then + case " $LIBOBJS " in + *" mktime.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS mktime.$ac_objext" + ;; +esac + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5 +$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; } +if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f conftest.sym conftest.file +echo >conftest.file +if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then + if test "$cross_compiling" = yes; then : + ac_cv_func_lstat_dereferences_slashed_symlink=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + /* Linux will dereference the symlink and fail, as required by POSIX. + That is better in the sense that it means we will not + have to compile and use the lstat wrapper. */ + return lstat ("conftest.sym/", &sbuf) == 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_lstat_dereferences_slashed_symlink=yes +else + ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +else + # If the `ln -s' command failed, then we probably don't even + # have an lstat function. + ac_cv_func_lstat_dereferences_slashed_symlink=no +fi +rm -f conftest.sym conftest.file + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5 +$as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; } + +test $ac_cv_func_lstat_dereferences_slashed_symlink = yes && + +cat >>confdefs.h <<_ACEOF +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 +_ACEOF + + +if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then + case " $LIBOBJS " in + *" lstat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS lstat.$ac_objext" + ;; +esac + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5 +$as_echo_n "checking whether stat accepts an empty string... " >&6; } +if ${ac_cv_func_stat_empty_string_bug+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_stat_empty_string_bug=yes +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +struct stat sbuf; + return stat ("", &sbuf) == 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_stat_empty_string_bug=no +else + ac_cv_func_stat_empty_string_bug=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5 +$as_echo "$ac_cv_func_stat_empty_string_bug" >&6; } +if test $ac_cv_func_stat_empty_string_bug = yes; then + case " $LIBOBJS " in + *" stat.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS stat.$ac_objext" + ;; +esac + + +cat >>confdefs.h <<_ACEOF +#define HAVE_STAT_EMPTY_STRING_BUG 1 +_ACEOF + +fi + +for ac_func in strftime +do : + ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime" +if test "x$ac_cv_func_strftime" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRFTIME 1 +_ACEOF + +else + # strftime is in -lintl on SCO UNIX. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5 +$as_echo_n "checking for strftime in -lintl... " >&6; } +if ${ac_cv_lib_intl_strftime+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char strftime (); +int +main () +{ +return strftime (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_intl_strftime=yes +else + ac_cv_lib_intl_strftime=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5 +$as_echo "$ac_cv_lib_intl_strftime" >&6; } +if test "x$ac_cv_lib_intl_strftime" = xyes; then : + $as_echo "#define HAVE_STRFTIME 1" >>confdefs.h + +LIBS="-lintl $LIBS" +fi + +fi +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working strtod" >&5 +$as_echo_n "checking for working strtod... " >&6; } +if ${ac_cv_func_strtod+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_strtod=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +$ac_includes_default +#ifndef strtod +double strtod (); +#endif +int +main() +{ + { + /* Some versions of Linux strtod mis-parse strings with leading '+'. */ + char *string = " +69"; + char *term; + double value; + value = strtod (string, &term); + if (value != 69 || term != (string + 4)) + return 1; + } + + { + /* Under Solaris 2.4, strtod returns the wrong value for the + terminating character under some conditions. */ + char *string = "NaN"; + char *term; + strtod (string, &term); + if (term != string && *(term - 1) == 0) + return 1; + } + return 0; +} + +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_strtod=yes +else + ac_cv_func_strtod=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strtod" >&5 +$as_echo "$ac_cv_func_strtod" >&6; } +if test $ac_cv_func_strtod = no; then + case " $LIBOBJS " in + *" strtod.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtod.$ac_objext" + ;; +esac + +ac_fn_c_check_func "$LINENO" "pow" "ac_cv_func_pow" +if test "x$ac_cv_func_pow" = xyes; then : + +fi + +if test $ac_cv_func_pow = no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pow in -lm" >&5 +$as_echo_n "checking for pow in -lm... " >&6; } +if ${ac_cv_lib_m_pow+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pow (); +int +main () +{ +return pow (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_pow=yes +else + ac_cv_lib_m_pow=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_pow" >&5 +$as_echo "$ac_cv_lib_m_pow" >&6; } +if test "x$ac_cv_lib_m_pow" = xyes; then : + POW_LIB=-lm +else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find library containing definition of pow" >&5 +$as_echo "$as_me: WARNING: cannot find library containing definition of pow" >&2;} +fi + +fi + +fi + +for ac_func in floor +do : + ac_fn_c_check_func "$LINENO" "floor" "ac_cv_func_floor" +if test "x$ac_cv_func_floor" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_FLOOR 1 +_ACEOF + +fi +done + +for ac_func in gethostbyaddr +do : + ac_fn_c_check_func "$LINENO" "gethostbyaddr" "ac_cv_func_gethostbyaddr" +if test "x$ac_cv_func_gethostbyaddr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETHOSTBYADDR 1 +_ACEOF + +fi +done + +for ac_func in gethostbyname +do : + ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname" +if test "x$ac_cv_func_gethostbyname" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETHOSTBYNAME 1 +_ACEOF + +fi +done + +for ac_func in gettimeofday +do : + ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday" +if test "x$ac_cv_func_gettimeofday" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_GETTIMEOFDAY 1 +_ACEOF + +fi +done + +for ac_func in malloc +do : + ac_fn_c_check_func "$LINENO" "malloc" "ac_cv_func_malloc" +if test "x$ac_cv_func_malloc" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MALLOC 1 +_ACEOF + +fi +done + +for ac_func in memmove +do : + ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove" +if test "x$ac_cv_func_memmove" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MEMMOVE 1 +_ACEOF + +fi +done + +for ac_func in memset +do : + ac_fn_c_check_func "$LINENO" "memset" "ac_cv_func_memset" +if test "x$ac_cv_func_memset" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MEMSET 1 +_ACEOF + +fi +done + +for ac_func in mkfifo +do : + ac_fn_c_check_func "$LINENO" "mkfifo" "ac_cv_func_mkfifo" +if test "x$ac_cv_func_mkfifo" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_MKFIFO 1 +_ACEOF + +fi +done + +for ac_func in realloc +do : + ac_fn_c_check_func "$LINENO" "realloc" "ac_cv_func_realloc" +if test "x$ac_cv_func_realloc" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_REALLOC 1 +_ACEOF + +fi +done + +for ac_func in realpath +do : + ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath" +if test "x$ac_cv_func_realpath" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_REALPATH 1 +_ACEOF + +fi +done + +for ac_func in regcomp +do : + ac_fn_c_check_func "$LINENO" "regcomp" "ac_cv_func_regcomp" +if test "x$ac_cv_func_regcomp" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_REGCOMP 1 +_ACEOF + +fi +done + +for ac_func in select +do : + ac_fn_c_check_func "$LINENO" "select" "ac_cv_func_select" +if test "x$ac_cv_func_select" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SELECT 1 +_ACEOF + +fi +done + +for ac_func in setlocale +do : + ac_fn_c_check_func "$LINENO" "setlocale" "ac_cv_func_setlocale" +if test "x$ac_cv_func_setlocale" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SETLOCALE 1 +_ACEOF + +fi +done + +for ac_func in socket +do : + ac_fn_c_check_func "$LINENO" "socket" "ac_cv_func_socket" +if test "x$ac_cv_func_socket" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SOCKET 1 +_ACEOF + +fi +done + +for ac_func in strcasecmp +do : + ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" +if test "x$ac_cv_func_strcasecmp" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRCASECMP 1 +_ACEOF + +fi +done + +for ac_func in strchr +do : + ac_fn_c_check_func "$LINENO" "strchr" "ac_cv_func_strchr" +if test "x$ac_cv_func_strchr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRCHR 1 +_ACEOF + +fi +done + +for ac_func in strcspn +do : + ac_fn_c_check_func "$LINENO" "strcspn" "ac_cv_func_strcspn" +if test "x$ac_cv_func_strcspn" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRCSPN 1 +_ACEOF + +fi +done + +for ac_func in strdup +do : + ac_fn_c_check_func "$LINENO" "strdup" "ac_cv_func_strdup" +if test "x$ac_cv_func_strdup" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRDUP 1 +_ACEOF + +fi +done + +for ac_func in strerror +do : + ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror" +if test "x$ac_cv_func_strerror" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRERROR 1 +_ACEOF + +fi +done + +for ac_func in strncasecmp +do : + ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" +if test "x$ac_cv_func_strncasecmp" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRNCASECMP 1 +_ACEOF + +fi +done + +for ac_func in strpbrk +do : + ac_fn_c_check_func "$LINENO" "strpbrk" "ac_cv_func_strpbrk" +if test "x$ac_cv_func_strpbrk" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRPBRK 1 +_ACEOF + +fi +done + +for ac_func in strrchr +do : + ac_fn_c_check_func "$LINENO" "strrchr" "ac_cv_func_strrchr" +if test "x$ac_cv_func_strrchr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRRCHR 1 +_ACEOF + +fi +done + +for ac_func in strspn +do : + ac_fn_c_check_func "$LINENO" "strspn" "ac_cv_func_strspn" +if test "x$ac_cv_func_strspn" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRSPN 1 +_ACEOF + +fi +done + +for ac_func in strstr +do : + ac_fn_c_check_func "$LINENO" "strstr" "ac_cv_func_strstr" +if test "x$ac_cv_func_strstr" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRSTR 1 +_ACEOF + +fi +done + +for ac_func in strtol +do : + ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol" +if test "x$ac_cv_func_strtol" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRTOL 1 +_ACEOF + +fi +done + +for ac_func in strtoull +do : + ac_fn_c_check_func "$LINENO" "strtoull" "ac_cv_func_strtoull" +if test "x$ac_cv_func_strtoull" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRTOULL 1 +_ACEOF + +fi +done + + +ac_config_files="$ac_config_files Makefile po/Makefile.in" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DEBUG_TRUE}" && test -z "${DEBUG_FALSE}"; then + as_fn_error $? "conditional \"DEBUG\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${WITH_RDYNAMIC_TRUE}" && test -z "${WITH_RDYNAMIC_FALSE}"; then + as_fn_error $? "conditional \"WITH_RDYNAMIC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GEOIP_LEGACY_TRUE}" && test -z "${GEOIP_LEGACY_FALSE}"; then + as_fn_error $? "conditional \"GEOIP_LEGACY\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GEOIP_MMDB_TRUE}" && test -z "${GEOIP_MMDB_FALSE}"; then + as_fn_error $? "conditional \"GEOIP_MMDB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${TCB_TRUE}" && test -z "${TCB_FALSE}"; then + as_fn_error $? "conditional \"TCB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAS_SEDTR_TRUE}" && test -z "${HAS_SEDTR_FALSE}"; then + as_fn_error $? "conditional \"HAS_SEDTR\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by goaccess $as_me 1.3, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to . +goaccess home page: ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +goaccess config.status 1.3 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it + # from automake < 1.5. + eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir=$dirpart/$fdir; as_fn_mkdir_p + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + "po-directories":C) + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +cat << EOF + +Your build configuration: + + Prefix : $prefix + Package : $PACKAGE_NAME + Version : $VERSION + Compiler flags : $CFLAGS + Linker flags : $LIBS $LDFLAGS + Dynamic buffer : $with_getline + Geolocation : $geolocation + Storage method : $storage + TLS/SSL : $openssl + Bugs : $PACKAGE_BUGREPORT + +EOF diff --git a/goaccess++/configure.ac b/goaccess++/configure.ac new file mode 100644 index 0000000..9c5822c --- /dev/null +++ b/goaccess++/configure.ac @@ -0,0 +1,309 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) +AC_INIT([goaccess], [1.3], [goaccess@prosoftcorp.com], [], [http://goaccess.io]) +AM_INIT_AUTOMAKE +AC_CONFIG_SRCDIR([src/goaccess.c]) +AC_CONFIG_HEADERS([src/config.h]) + +# Use empty CFLAGS by default so autoconf does not add +# CFLAGS="-O2 -g" +# NOTE: Needs to go after AC_INIT and before AC_PROG_CC to select an +# empty default instead. +: ${CFLAGS=""} + +# Checks for programs. +AC_PROG_CC +AM_PROG_CC_C_O + +AM_GNU_GETTEXT([external]) +AM_GNU_GETTEXT_VERSION([0.18]) +# Fix `undefined reference to `libintl_gettext'` on docker: +AC_CHECK_LIB([intl], [libintl_dgettext]) + +# pthread +AC_CHECK_LIB([pthread], [pthread_create], [], [AC_MSG_ERROR([pthread is missing])]) +CFLAGS="$CFLAGS -pthread" + +# DEBUG +AC_ARG_ENABLE(debug, [ --enable-debug Create a debug build. Default is disabled], + [debug="$enableval"], debug=no) + +if test "$debug" = "yes"; then + AC_DEFINE([_DEBUG], 1, [Debug option]) +fi +AM_CONDITIONAL([DEBUG], [test "x$debug" = "xyes"]) + +# Handle rdynamic only on systems using GNU ld +AC_CANONICAL_HOST +AC_MSG_CHECKING([whether to build with rdynamic for GNU ld]) +with_rdyanimc=yes +case "$host_os" in + *darwin*|*cygwin*|*aix*|*mingw*) with_rdyanimc=no + ;; +esac +AC_MSG_RESULT([$with_rdyanimc]) +AM_CONDITIONAL([WITH_RDYNAMIC], [test "x$with_rdyanimc" = "xyes"]) + +# Build with OpenSSL +AC_ARG_WITH([openssl],AC_HELP_STRING([--with-openssl], [build with OpenSSL support]), + [openssl="$withval"],[openssl="no"]) + +if test "$openssl" = 'yes'; then + AC_CHECK_LIB([ssl], [SSL_CTX_new],,[AC_MSG_ERROR([ssl library missing])]) + AC_CHECK_LIB([crypto], [CRYPTO_free],,[AC_MSG_ERROR([crypto library missing])]) +fi + +# GeoIP +AC_ARG_ENABLE(geoip, [ --enable-geoip Enable GeoIP country lookup. Default is disabled], + [geoip="$enableval"], geoip=no) + +geolocation="N/A" +if test "$geoip" = "mmdb"; then + AC_CHECK_LIB([maxminddb], [MMDB_open], [], [AC_MSG_ERROR([ + *** Missing development files for libmaxminddb library. + ])]) + geolocation="GeoIP2" + AC_DEFINE([HAVE_GEOLOCATION], 1, [Build using GeoIP.]) +elif test "$geoip" = "legacy"; then + AC_CHECK_LIB([GeoIP], [GeoIP_new], [], [AC_MSG_ERROR([ + *** Missing development files for the GeoIP library + ])]) + geolocation="GeoIP Legacy" + AC_DEFINE([HAVE_GEOLOCATION], 1, [Build using GeoIP.]) +fi +AM_CONDITIONAL([GEOIP_LEGACY], [test "x$geoip" = "xlegacy"]) +AM_CONDITIONAL([GEOIP_MMDB], [test "x$geoip" = "xmmdb"]) + +# GNU getline / POSIX.1-2008 +AC_ARG_WITH(getline, [ --with-getline Build using dynamic line buffer.], + [with_getline=$withval], [with_getline=no]) + +if test "$with_getline" = "yes"; then + AC_DEFINE([WITH_GETLINE], 1, [Build using GNU getline.]) +fi + +# UTF8 +AC_ARG_ENABLE(utf8, [ --enable-utf8 Enable ncurses library that handles wide characters], + [utf8="$enableval"], utf8=no) + +if test "$utf8" = "yes"; then + libncursesw=ncursesw + # Simply called libncurses on OS X + case "$host_os" in + *darwin*) libncursesw=ncurses + ;; + esac + + AC_CHECK_LIB([$libncursesw], [mvaddwstr], [], + [AC_MSG_ERROR([*** Missing development libraries for ncursesw])]) + AC_SEARCH_LIBS([tputs], [tinfow], ,[AC_MSG_ERROR([Cannot find a library providing tputs])]) + AC_DEFINE([HAVE_LIBNCURSESW], [1], ["ncursesw is present."]) + + have_ncurses="yes" + AC_CHECK_HEADERS([ncursesw/ncurses.h],[have_ncurses=yes], [], [ + #ifdef HAVE_NCURSESW_NCURSES_H + #include + #endif + ]) + + AC_CHECK_HEADERS([ncurses.h],[have_ncurses=yes], [], [ + #ifdef HAVE_NCURSES_H + #include + #endif + ]) + + if test "$have_ncurses" != "yes"; then + AC_MSG_ERROR([Missing ncursesw header file]) + fi +else + AC_CHECK_LIB([ncurses], [refresh], [], + [AC_MSG_ERROR([*** Missing development libraries for ncurses])]) + AC_SEARCH_LIBS([tputs], [tinfo], ,[AC_MSG_ERROR([Cannot find a library providing tputs])]) + + have_ncurses="yes" + AC_CHECK_HEADERS([ncurses/ncurses.h],[have_ncurses=yes], [], [ + #ifdef HAVE_NCURSES_NCURSES_H + #include + #endif + ]) + + AC_CHECK_HEADERS([ncurses.h],[have_ncurses=yes], [], [ + #ifdef HAVE_NCURSES_H + #include + #endif + ]) + + AC_CHECK_HEADERS([curses.h],[have_ncurses=yes], [], [ + #ifdef HAVE_CURSES_H + #include + #endif + ]) + + if test "$have_ncurses" != "yes"; then + AC_MSG_ERROR([Missing ncursesw header file]) + fi +fi + +# Tokyo Cabinet +AC_ARG_ENABLE(tcb, [ --enable-tcb Enable TokyoCabinet database. Default is disabled], + [tcb="$enableval"], tcb=no) + +WITH_TC=no +if test "$tcb" = "memhash"; then + WITH_TC=yes + AC_DEFINE([TCB_MEMHASH], [1], ["Build using on-memory hash database"]) +elif test "$tcb" = "btree"; then + AC_DEFINE([TCB_BTREE], [1], ["Build using on-disk B+ Tree database"]) + WITH_TC=yes +fi + +if test "$WITH_TC" = "yes"; then + AC_CHECK_LIB([tokyocabinet], [tchdbnew], [], + [AC_MSG_ERROR([*** Missing development libraries for Tokyo Cabinet Database])]) + + AC_ARG_ENABLE([zlib], [ --disable-zlib Build without ZLIB compression], + [zlib="$enableval"], zlib=yes) + + if test "$zlib" = "yes"; then + AC_CHECK_LIB(z, gzread, [Z_FLAG=-lz], AC_MSG_ERROR([ + *** zlib is required. If zlib compression is not needed + *** you can use --disable-zlib. + *** Debian based distributions zlib1g-dev + *** Red Hat based distributions zlib-devel + ])) + AC_DEFINE([HAVE_ZLIB], [1], ["Build using ZLIB"]) + LDFLAGS="$LDFLAGS $Z_FLAG" + fi + + AC_ARG_ENABLE([bzip], [ --disable-bzip Build without BZIP2 compression], + [bz2="$enableval"], bz2=yes) + + if test "$bz2" = "yes"; then + AC_CHECK_LIB(bz2, BZ2_bzopen, [BZ2_FLAG=-lbz2], AC_MSG_ERROR([ + *** BZIP2 is required. If BZIP2 compression is not needed + *** you can use --disable-bzip. + *** Debian based distributions libbz2-dev + *** Red Hat based distributions bzip2-devel + ])) + AC_DEFINE([HAVE_BZ2], [1], ["Build using BZ2"]) + LDFLAGS="$LDFLAGS $BZ2_FLAG" + fi + + case "$host_os" in + *darwin*|*bsd*) + LDFLAGS="$LDFLAGS -ltokyocabinet -lc" + ;; + *) + LDFLAGS="$LDFLAGS -ltokyocabinet -lrt -lc" + ;; + esac +fi +AM_CONDITIONAL([TCB], [test "$WITH_TC" = "yes"]) + +if test "$tcb" = "memhash"; then + storage="In-memory Hash Database (Tokyo Cabinet)" +elif test "$tcb" = "btree"; then + storage="On-disk B+ Tree Database (Tokyo Cabinet)" +else + storage="In-memory Hash Database (Default)" +fi + +HAS_SEDTR=no +AC_CHECK_PROG([SED_CHECK],[sed],[yes],[no]) +if test x"$SED_CHECK" == x"yes" ; then + AC_CHECK_PROG([TR_CHECK],[tr],[yes],[no]) + if test x"$TR_CHECK" == x"yes" ; then + HAS_SEDTR=yes + fi +fi +AM_CONDITIONAL([HAS_SEDTR], [test "x$HAS_SEDTR" = xyes]) + +# Solaris +AC_CHECK_LIB([nsl], [gethostbyname]) +AC_CHECK_LIB([socket], [socket]) + +# Checks for header files. +AC_HEADER_STDC +AC_CHECK_HEADERS([arpa/inet.h]) +AC_CHECK_HEADERS([fcntl.h]) +AC_CHECK_HEADERS([inttypes.h]) +AC_CHECK_HEADERS([limits.h]) +AC_CHECK_HEADERS([locale.h]) +AC_CHECK_HEADERS([netdb.h]) +AC_CHECK_HEADERS([netinet/in.h]) +AC_CHECK_HEADERS([stddef.h]) +AC_CHECK_HEADERS([stdint.h]) +AC_CHECK_HEADERS([stdlib.h]) +AC_CHECK_HEADERS([string.h]) +AC_CHECK_HEADERS([strings.h]) +AC_CHECK_HEADERS([sys/socket.h]) +AC_CHECK_HEADERS([sys/time.h]) +AC_CHECK_HEADERS([unistd.h]) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_CHECK_TYPES([ptrdiff_t]) +AC_STRUCT_TM +AC_TYPE_INT64_T +AC_TYPE_INT8_T +AC_TYPE_OFF_T +AC_TYPE_SIZE_T +AC_TYPE_UINT32_T +AC_TYPE_UINT64_T +AC_TYPE_UINT8_T + +# Checks for library functions. +AC_FUNC_FSEEKO +AC_FUNC_MEMCMP +AC_FUNC_MKTIME +AC_FUNC_STAT +AC_FUNC_STRFTIME +AC_FUNC_STRTOD +AC_CHECK_FUNCS([floor]) +AC_CHECK_FUNCS([gethostbyaddr]) +AC_CHECK_FUNCS([gethostbyname]) +AC_CHECK_FUNCS([gettimeofday]) +AC_CHECK_FUNCS([malloc]) +AC_CHECK_FUNCS([memmove]) +AC_CHECK_FUNCS([memset]) +AC_CHECK_FUNCS([mkfifo]) +AC_CHECK_FUNCS([realloc]) +AC_CHECK_FUNCS([realpath]) +AC_CHECK_FUNCS([regcomp]) +AC_CHECK_FUNCS([select]) +AC_CHECK_FUNCS([setlocale]) +AC_CHECK_FUNCS([socket]) +AC_CHECK_FUNCS([strcasecmp]) +AC_CHECK_FUNCS([strchr]) +AC_CHECK_FUNCS([strcspn]) +AC_CHECK_FUNCS([strdup]) +AC_CHECK_FUNCS([strerror]) +AC_CHECK_FUNCS([strncasecmp]) +AC_CHECK_FUNCS([strpbrk]) +AC_CHECK_FUNCS([strrchr]) +AC_CHECK_FUNCS([strspn]) +AC_CHECK_FUNCS([strstr]) +AC_CHECK_FUNCS([strtol]) +AC_CHECK_FUNCS([strtoull]) + +AC_CONFIG_FILES([Makefile po/Makefile.in]) +AC_OUTPUT + +cat << EOF + +Your build configuration: + + Prefix : $prefix + Package : $PACKAGE_NAME + Version : $VERSION + Compiler flags : $CFLAGS + Linker flags : $LIBS $LDFLAGS + Dynamic buffer : $with_getline + Geolocation : $geolocation + Storage method : $storage + TLS/SSL : $openssl + Bugs : $PACKAGE_BUGREPORT + +EOF diff --git a/goaccess++/depcomp b/goaccess++/depcomp new file mode 100644 index 0000000..25a39e6 --- /dev/null +++ b/goaccess++/depcomp @@ -0,0 +1,708 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2012-03-27.16; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' "$nl" < "$tmpdepfile" | +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependent.h'. + # Do two passes, one to just change these to + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'. + # However on + # $CC -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\': + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + # tcc 0.9.26 (FIXME still under development at the moment of writing) + # will emit a similar output, but also prepend the continuation lines + # with horizontal tabulation characters. + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form 'foo.o: dependent.h', + # or 'foo.o: dep1.h dep2.h \', or ' dep3.h dep4.h \'. + # Do two passes, one to just change these to + # '$object: dependent.h' and one to simply 'dependent.h:'. + sed -e "s/^[ $tab][ $tab]*/ /" -e "s,^[^:]*:,$object :," \ + < "$tmpdepfile" > "$depfile" + sed ' + s/[ '"$tab"'][ '"$tab"']*/ /g + s/^ *// + s/ *\\*$// + s/^[^:]*: *// + /^$/d + /:$/d + s/$/ :/ + ' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test "$stat" = 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' "$nl" < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/goaccess++/goaccess b/goaccess++/goaccess new file mode 100644 index 0000000..66ff7bf Binary files /dev/null and b/goaccess++/goaccess differ diff --git a/goaccess++/goaccess.1 b/goaccess++/goaccess.1 new file mode 100644 index 0000000..78d35ee --- /dev/null +++ b/goaccess++/goaccess.1 @@ -0,0 +1,1166 @@ +.TH goaccess 1 "NOVEMBER 2018" Linux "User Manuals" +.SH NAME +goaccess \- fast web log analyzer and interactive viewer. +.SH SYNOPSIS +.LP +.B goaccess [filename] [options...] [-c][-M][-H][-q][-d][...] +.SH DESCRIPTION +.B goaccess +GoAccess is an open source real-time web log analyzer and interactive viewer +that runs in a +.I terminal +in *nix systems or through your +.I browser. +.P +It provides fast and valuable HTTP statistics for system administrators that +require a visual server report on the fly. +.P +GoAccess parses the specified web log file and outputs the data to the X +terminal. Features include: + +.IP "General Statistics:" +This panel gives a summary of several metrics, such as the number of valid and +invalid requests, time taken to analyze the dataset, unique visitors, requested +files, static files (CSS, ICO, JPG, etc) HTTP referrers, 404s, size of the +parsed log file and bandwidth consumption. +.IP "Unique visitors" +This panel shows metrics such as hits, unique visitors and cumulative bandwidth +per date. HTTP requests containing the same IP, the same date, and the same +user agent are considered a unique visitor. By default, it includes web +crawlers/spiders. +.IP +Optionally, date specificity can be set to the hour level using +.I --date-spec=hr +which will display dates such as 05/Jun/2016:16. This is great if you want to +track your daily traffic at the hour level. +.IP "Requested files" +This panel displays the most requested files on your web server. It shows hits, +unique visitors, and percentage, along with the cumulative bandwidth, protocol, +and the request method used. +.IP "Requested static files" +Lists the most frequently static files such as: JPG, CSS, SWF, JS, GIF, and PNG +file types, along with the same metrics as the last panel. Additional static +files can be added to the configuration file. +.IP "404 or Not Found" +Displays the same metrics as the previous request panels, however, its data +contains all pages that were not found on the server, or commonly known as 404 +status code. +.IP "Hosts" +This panel has detailed information on the hosts themselves. This is great for +spotting aggressive crawlers and identifying who's eating your bandwidth. + +Expanding the panel can display more information such as host's reverse DNS +lookup result, country of origin and city. If the +.I -a +argument is enabled, a list of user agents can be displayed by selecting the +desired IP address, and then pressing ENTER. +.IP "Operating Systems" +This panel will report which operating system the host used when it hit the +server. It attempts to provide the most specific version of each operating +system. +.IP "Browsers" +This panel will report which browser the host used when it hit the server. It +attempts to provide the most specific version of each browser. +.IP "Visit Times" +This panel will display an hourly report. This option displays 24 data points, +one for each hour of the day. +.IP +Optionally, hour specificity can be set to the tenth of an hour level using +.I --hour-spec=min +which will display hours as 16:4 This is great if you want to spot peaks of +traffic on your server. +.IP "Virtual Hosts" +This panel will display all the different virtual hosts parsed from the access +log. This panel is displayed if +.I %v +is used within the log-format string. +.IP "Referrers URLs" +If the host in question accessed the site via another resource, or was +linked/diverted to you from another host, the URL they were referred from will +be provided in this panel. See `--ignore-panel` in your configuration file to +enable it. +.I disabled +by default. +.IP "Referring Sites" +This panel will display only the host part but not the whole URL. The URL where +the request came from. +.IP "Keyphrases" +It reports keyphrases used on Google search, Google cache, and Google translate +that have lead to your web server. At present, it only supports Google search +queries via HTTP. See `--ignore-panel` in your configuration file to enable it. +.I disabled +by default. +.IP "Geo Location" +Determines where an IP address is geographically located. Statistics are broken +down by continent and country. It needs to be compiled with GeoLocation +support. +.IP "HTTP Status Codes" +The values of the numeric status code to HTTP requests. +.IP "Remote User (HTTP authentication)" +This is the userid of the person requesting the document as determined by HTTP +authentication. If the document is not password protected, this part will be +"-" just like the previous one. This panel is not enabled unless +.I %e +is given within the log-format variable. + +.P +.I NOTE: +Optionally and if configured, all panels can display the average time taken to +serve the request. + +.SH STORAGE +.P +There are three storage options that can be used with GoAccess. Choosing one +will depend on your environment and needs. +.TP +Default Hash Tables +In-memory storage provides better performance at the cost of limiting the +dataset size to the amount of available physical memory. By default GoAccess +uses in-memory hash tables. If your dataset can fit in memory, then this will +perform fine. It has very good memory usage and pretty good performance. +.TP +Tokyo Cabinet On-Disk B+ Tree +Use this storage method for large datasets where it is not possible to fit +everything in memory. The B+ tree database is slower than any of the hash +databases since data has to be committed to disk. However, using an SSD greatly +increases the performance. You may also use this storage method if you need +data persistence to quickly load statistics at a later date. +.TP +Tokyo Cabinet In-memory Hash Database +An alternative to the default hash tables. It uses generic typing and thus it's +performance in terms of memory and speed is average. +.SH CONFIGURATION +.P +Multiple options can be used to configure GoAccess. For a complete up-to-date +list of configure options, run +.I ./configure --help +.TP +\fB\-\-enable-debug +Compile with debugging symbols and turn off compiler optimizations. +.TP +\fB\-\-enable-utf8 +Compile with wide character support. Ncursesw is required. +.TP +\fB\-\-enable-geoip= +Compile with GeoLocation support. MaxMind's GeoIP is required. +.I legacy +will utilize the original GeoIP databases. +.I mmdb +will utilize the enhanced GeoIP2 databases. +.TP +\fB\-\-enable-tcb= +Compile with Tokyo Cabinet storage support. +.I memhash +will utilize Tokyo Cabinet's on-memory hash database. +.I btree +will utilize Tokyo Cabinet's on-disk B+ Tree database. +.TP +\fB\-\-disable-zlib +Disable zlib compression on B+ Tree database. +.TP +\fB\-\-disable-bzip +Disable bzip2 compression on B+ Tree database. +.TP +\fB\-\-with-getline +Dynamically expands line buffer in order to parse full line requests instead of +using a fixed size buffer of 4096. +.TP +\fB\-\-with-openssl +Compile GoAccess with OpenSSL support for its WebSocket server. +.SH OPTIONS +.P +The following options can be supplied to the command or specified in the +configuration file. If specified in the configuration file, long options need +to be used without prepending -- and without using the equal sign =. +.SS +LOG/DATE/TIME FORMAT +.TP +\fB\-\-time-format= +The time-format variable followed by a space, specifies the log format time +containing either a name of a predefined format (see options below) or any +combination of regular characters and special format specifiers. +.IP +They all begin with a percentage (%) sign. See `man strftime`. +.I %T or %H:%M:%S. +.IP +Note that if a timestamp is given in microseconds, +.I %f +must be used as time-format +.TP +\fB\-\-date-format= +The date-format variable followed by a space, specifies the log format time +containing either a name of a predefined format (see options below) or any +combination of regular characters and special format specifiers. +.IP +They all begin with a percentage (%) sign. See `man strftime`. +.I %Y-%m-%d. +.IP +Note that if a timestamp is given in microseconds, +.I +%f +must be used as date-format +.TP +\fB\-\-log-format= +The log-format variable followed by a space or +.I \\\\t +for tab-delimited, specifies the log format string. + +Note that if there are spaces within the format, the string needs to be +enclosed in single/double quotes. Inner quotes need to be escaped. +.IP +In addition to specifying the raw log/date/time formats, for simplicity, any of +the following predefined log format names can be supplied to the +log/date/time-format variables. GoAccess can also handle one predefined name in +one variable and another predefined name in another variable. +.IP + COMBINED - Combined Log Format, + VCOMBINED - Combined Log Format with Virtual Host, + COMMON - Common Log Format, + VCOMMON - Common Log Format with Virtual Host, + W3C - W3C Extended Log File Format, + SQUID - Native Squid Log Format, + CLOUDFRONT - Amazon CloudFront Web Distribution, + CLOUDSTORAGE - Google Cloud Storage, + AWSELB - Amazon Elastic Load Balancing, + AWSS3 - Amazon Simple Storage Service (S3) +.IP +.I Note: +Piping data into GoAccess won't prompt a log/date/time configuration dialog, +you will need to previously define it in your configuration file or in the +command line. +.SS +USER INTERFACE OPTIONS +.TP +\fB\-c \-\-config-dialog +Prompt log/time/date configuration window on program start. Only when curses is +initialized. +.TP +\fB\-i \-\-hl-header +Color highlight active terminal panel. +.TP +\fB\-m \-\-with-mouse +Enable mouse support on main terminal dashboard. +.TP +\fB\-\-\-color= +Specify custom colors for the terminal output. + +.I Color Syntax + DEFINITION space/tab colorFG#:colorBG# [attributes,PANEL] + + FG# = foreground color [-1...255] (-1 = default term color) + BG# = background color [-1...255] (-1 = default term color) + +Optionally, it is possible to apply color attributes (multiple attributes are +comma separated), such as: +.I bold, +.I underline, +.I normal, +.I reverse, +.I blink + +If desired, it is possible to apply custom colors per panel, that is, a metric +in the REQUESTS panel can be of color A, while the same metric in the BROWSERS +panel can be of color B. + +.I Available color definitions: + COLOR_MTRC_HITS + COLOR_MTRC_VISITORS + COLOR_MTRC_DATA + COLOR_MTRC_BW + COLOR_MTRC_AVGTS + COLOR_MTRC_CUMTS + COLOR_MTRC_MAXTS + COLOR_MTRC_PROT + COLOR_MTRC_MTHD + COLOR_MTRC_HITS_PERC + COLOR_MTRC_HITS_PERC_MAX + COLOR_MTRC_VISITORS_PERC + COLOR_MTRC_VISITORS_PERC_MAX + COLOR_PANEL_COLS + COLOR_BARS + COLOR_ERROR + COLOR_SELECTED + COLOR_PANEL_ACTIVE + COLOR_PANEL_HEADER + COLOR_PANEL_DESC + COLOR_OVERALL_LBLS + COLOR_OVERALL_VALS + COLOR_OVERALL_PATH + COLOR_ACTIVE_LABEL + COLOR_BG + COLOR_DEFAULT + COLOR_PROGRESS + +See configuration file for a sample color scheme. +.TP +\fB\-\-color-scheme=<1|2|3> +Choose among color schemes. +.I 1 +for the default grey scheme. +.I 2 +for the green scheme. +.I 3 +for the Monokai scheme (shown only if terminal supports 256 colors). +.TP +\fB\-\-crawlers-only +Parse and display only crawlers (bots). +.TP +\fB\-\-html-custom-css= +Specifies a custom CSS file path to load in the HTML report. +.TP +\fB\-\-html-custom-js= +Specifies a custom JS file path to load in the HTML report. +.TP +\fB\-\-html-report-title= +Set HTML report page title and header. +.TP +\fB\-\-html-prefs=<JSON> +Set HTML report default preferences. Supply a valid JSON object containing the +HTML preferences. It allows the ability to customize each panel plot. See +example below. +.IP +.I Note: +The JSON object passed needs to be a one line JSON string. For instance, +.IP +\-\-html-prefs='{"theme":"bright","perPage":5,"layout":"horizontal","showTables":true,"visitors":{"plot":{"chartType":"bar"}}}' +.TP +\fB\-\-json-pretty-print +Format JSON output using tabs and newlines. +.IP +.I Note: +This is not recommended when outputting a real-time HTML report since the +WebSocket payload will much much larger. +.TP +\fB\-\-max-items=<number> +The maximum number of items to display per panel. The maximum can be a number +between 1 and n. +.IP +.I Note: +Only the CSV and JSON output allow a maximum number greater than the default +value of 366 (or 50 in the real-time HTML output) items per panel. +.TP +\fB\-\-no-color +Turn off colored output. This is the default output on terminals that do not +support colors. +.TP +\fB\-\-no-column-names +Don't write column names in the terminal output. By default, it displays column +names for each available metric in every panel. +.TP +\fB\-\-no-csv-summary +Disable summary metrics on the CSV output. +.TP +\fB\-\-no-progress +Disable progress metrics [total requests/requests per second]. +.TP +\fB\-\-no-tab-scroll +Disable scrolling through panels when TAB is pressed or when a panel is +selected using a numeric key. +.TP +\fB\-\-no-html-last-updated +Do not show the last updated field displayed in the HTML generated report. +.TP +\fB\-\-no-parsing-spinner +Do now show the progress metrics and parsing spinner. +.SS +SERVER OPTIONS +.TP +\fB\-\-addr +Specify IP address to bind the server to. Otherwise it binds to 0.0.0.0. +.IP +Usually there is no need to specify the address, unless you intentionally would +like to bind the server to a different address within your server. +.TP +\fB\-\-daemonize +Run GoAccess as daemon (only if \fB\-\-real-time-html enabled). +.IP +Note: It's important to make use of absolute paths across GoAccess' +configuration. +.TP +\fB\-\-origin=<url> +Ensure clients send the specified origin header upon the WebSocket handshake. +.TP +\fB\-\-pid-file=<path/goaccess.pid> +Write the daemon PID to a file when used along the --daemonize option. +.TP +\fB\-\-port=<port> +Specify the port to use. By default GoAccess' WebSocket server listens on port +7890. +.TP +\fB\-\-real-time-html +Enable real-time HTML output. +.IP +GoAccess uses its own WebSocket server to push the data from the server to the +client. See http://gwsocket.io for more details how the WebSocket server works. +.TP +\fB\-\-ws-url=<[scheme://]url[:port]> +URL to which the WebSocket server responds. This is the URL supplied to the +WebSocket constructor on the client side. +.IP +Optionally, it is possible to specify the WebSocket URI scheme, such as +.I ws:// +or +.I wss:// +for unencrypted and encrypted connections. e.g., +.I +wss://goaccess.io +.IP +If GoAccess is running behind a proxy, you could set the client side to connect +to a different port by specifying the host followed by a colon and the port. +e.g., +.I goaccess.io:9999 +. e.g., +.IP +By default, it will attempt to connect to the generated report's hostname. If +GoAccess is running on a remote server, the host of the remote server should be +specified here. Also, make sure it is a valid host and NOT an http address. +.TP +\fB\-\-fifo-in=<path/file> +Creates a named pipe (FIFO) that reads from on the given path/file. +.TP +\fB\-\-fifo-out=<path/file> +Creates a named pipe (FIFO) that writes to the given path/file. +.TP +\fB\-\-ssl-cert=<cert.crt> +Path to TLS/SSL certificate. In order to enable TLS/SSL support, GoAccess +requires that \-\-ssl-cert and \-\-ssl-key are used. + +Only if configured using --with-openssl +.TP +\fB\-\-ssl-key=<priv.key> +Path to TLS/SSL private key. In order to enable TLS/SSL support, GoAccess +requires that \-\-ssl-cert and \-\-ssl-key are used. + +Only if configured using --with-openssl +.SS +FILE OPTIONS +.TP +\fB\-f \-\-log-file=<logfile> +Specify the path to the input log file. If set in the config file, it will take +priority over -f from the command line. +.TP +\fB\-S \-\-log-size=<bytes> +Specify the log size in bytes. This is useful when piping in logs for +processing in which the log size can be explicitly set. +.TP +\fB\-l \-\-debug-file=<debugfile> +Send all debug messages to the specified file. +.TP +\fB\-p \-\-config-file=<configfile> +Specify a custom configuration file to use. If set, it will take priority over +the global configuration file (if any). +.TP +\fB\-\-invalid-requests=<filename> +Log invalid requests to the specified file. +.TP +\fB\-\-no-global-config +Do not load the global configuration file. This directory should normally be +/usr/local/etc, unless specified with +.I --sysconfdir=/dir. +See --dcf option for finding the default configuration file. +.SS +PARSE OPTIONS +.TP +\fB\-a \-\-agent-list +Enable a list of user-agents by host. For faster parsing, do not enable this +flag. +.TP +\fB\-d \-\-with-output-resolver +Enable IP resolver on HTML|JSON output. +.TP +\fB\-e \-\-exclude-ip=<IP|IP-range> +Exclude an IPv4 or IPv6 from being counted. +Ranges can be included as well using a dash in between the IPs (start-end). +.IP +.I Examples: + exclude-ip 127.0.0.1 + exclude-ip 192.168.0.1-192.168.0.100 + exclude-ip ::1 + exclude-ip 0:0:0:0:0:ffff:808:804-0:0:0:0:0:ffff:808:808 +.TP +\fB\-H \-\-http-protocol=<yes|no> +Set/unset HTTP request protocol. This will create a request key containing the +request protocol + the actual request. +.TP +\fB\-M \-\-http-method=<yes|no> +Set/unset HTTP request method. This will create a request key containing the +request method + the actual request. +.TP +\fB\-o \-\-output=<path/file.[json|csv|html]> +Write output to stdout given one of the following files and the corresponding +extension for the output format: +.IP + /path/file.csv - Comma-separated values (CSV) + /path/file.json - JSON (JavaScript Object Notation) + /path/file.html - HTML +.TP +\fB\-q \-\-no-query-string +Ignore request's query string. i.e., www.google.com/page.htm?query => +www.google.com/page.htm. +.IP +.I Note: +Removing the query string can greatly decrease memory consumption, especially +on timestamped requests. +.TP +\fB\-r \-\-no-term-resolver +Disable IP resolver on terminal output. +.TP +\fB\-\-444-as-404 +Treat non-standard status code 444 as 404. +.TP +\fB\-\-4xx-to-unique-count +Add 4xx client errors to the unique visitors count. +.TP +\fB\-\-accumulated-time +Store accumulated processing time from parsing day-by-day logs. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-anonymize-ip +Anonymize the client IP address. The IP anonymization option sets the last +octet of IPv4 user IP addresses and the last 80 bits of IPv6 addresses to +zeros. +e.g., 192.168.20.100 => 192.168.20.0 +e.g., 2a03:2880:2110:df07:face:b00c::1 => 2a03:2880:2110:df07:: +.TP +\fB\-\-all-static-files +Include static files that contain a query string. e.g., +/fonts/fontawesome-webfont.woff?v=4.0.3 +.TP +\fB\-\-browsers-file=<path> +Include an additional delimited list of browsers/crawlers/feeds etc. +See config/browsers.list for an example or +https://raw.githubusercontent.com/allinurl/goaccess/master/config/browsers.list +.TP +\fB\-\-date-spec=<date|hr> +Set the date specificity to either date (default) or hr to display hours +appended to the date. +.IP +This is used in the visitors panel. It's useful for tracking visitors at the +hour level. For instance, an hour specificity would yield to display traffic as +18/Dec/2010:19 +.TP +\fB\-\-double-decode +Decode double-encoded values. This includes, user-agent, request, and referer. +.TP +\fB\-\-enable-panel=<PANEL> +Enable parsing and displaying the given panel. +.IP +.I Available panels: + VISITORS + REQUESTS + REQUESTS_STATIC + NOT_FOUND + HOSTS + OS + BROWSERS + VISIT_TIMES + VIRTUAL_HOSTS + REFERRERS + REFERRING_SITES + KEYPHRASES + STATUS_CODES + REMOTE_USER + GEO_LOCATION +.TP +\fB\-\-hide-referer=<NEEDLE> +Hide a referer but still count it. Wild cards are allowed in the needle. i.e., +*.bing.com. +.TP +\fB\-\-hour-spec=<hr|min> +Set the time specificity to either hour (default) or min to display the tenth +of an hour appended to the hour. +.IP +This is used in the time distribution panel. It's useful for tracking peaks of +traffic on your server at specific times. +.TP +\fB\-\-ignore-crawlers +Ignore crawlers from being counted. +.TP +\fB\-\-ignore-panel=<PANEL> +Ignore parsing and displaying the given panel. +.IP +.I Available panels: + VISITORS + REQUESTS + REQUESTS_STATIC + NOT_FOUND + HOSTS + OS + BROWSERS + VISIT_TIMES + VIRTUAL_HOSTS + REFERRERS + REFERRING_SITES + KEYPHRASES + STATUS_CODES + REMOTE_USER +.TP +\fB\-\-ignore-referer=<referer> +Ignore referers from being counted. Wildcards allowed. e.g., +.I +*.domain.com +.I +ww?.domain.* +.TP +\fB\-\-ignore-status=<CODE> +Ignore parsing and displaying one or multiple status code(s). For multiple +status codes, use this option multiple times. +.TP +\fB\-\-num-tests=<number> +Number of lines from the access log to test against the provided log/date/time +format. By default, the parser is set to test 10 lines. If set to 0, the parser +won't test any lines and will parse the whole access log. If a line matches the +given log/date/time format before it reaches +.I <number>, +the parser will consider the log to be valid, otherwise GoAccess will return +EXIT_FAILURE and display the relevant error messages. +.TP +\fB\-\-process-and-exit +Parse log and exit without outputting data. Useful if we are looking to only +add new data to the on-disk database without outputting to a file or a +terminal. +.TP +\fB\-\-real-os +Display real OS names. e.g, Windows XP, Snow Leopard. +.TP +\fB\-\-sort-panel=<PANEL,FIELD,ORDER> +Sort panel on initial load. Sort options are separated by comma. Options are in +the form: PANEL,METRIC,ORDER +.IP +.I Available metrics: + BY_HITS - Sort by hits + BY_VISITORS - Sort by unique visitors + BY_DATA - Sort by data + BY_BW - Sort by bandwidth + BY_AVGTS - Sort by average time served + BY_CUMTS - Sort by cumulative time served + BY_MAXTS - Sort by maximum time served + BY_PROT - Sort by http protocol + BY_MTHD - Sort by http method +.IP +.I Available orders: + ASC + DESC +.TP +\fB\-\-static-file=<extension> +Add static file extension. e.g.: +.I .mp3 +Extensions are case sensitive. +.SS +GEOLOCATION OPTIONS +.TP +\fB\-g \-\-std-geoip +Standard GeoIP database for less memory usage. +.TP +\fB\-\-geoip-database=<geofile> +Specify path to GeoIP database file. i.e., GeoLiteCity.dat. + +If using GeoIP2, you will need to download the GeoLite2 City or Country +database from MaxMind.com and use the option --geoip-database to specify the +database. You can also get updated database files for GeoIP legacy, you can +find these as GeoLite Legacy Databases from MaxMind.com. IPv4 and IPv6 files +are supported as well. For updated DB URLs, please see the default GoAccess +configuration file. + +.I Note: +--geoip-city-data is an alias of --geoip-database. +.SS +OTHER OPTIONS +.TP +\fB\-h \-\-help +The help. +.TP +\fB\-s \-\-storage +Display current storage method. i.e., B+ Tree, Hash. +.TP +\fB\-V \-\-version +Display version information and exit. +.TP +\fB\-\-dcf +Display the path of the default config file when `-p` is not used. +.SS +ON-DISK STORAGE OPTIONS +.TP +\fB\-\-keep-db-files +Persist parsed data into disk. If database files exist, files will be +overwritten. This should be set to the first dataset. Setting it to false will +delete all database files when exiting the program. See examples below. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-load-from-disk +Load previously stored data from disk. If reading persisted data only, the +database files need to exist. See +.I keep-db-files +and examples below. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-db-path=<dir> +Path where the on-disk database files are stored. The default value is the +.I /tmp/goaccess<PID> +directory (created on-demand). + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-xmmap=<num> +Set the size in bytes of the extra mapped memory. The default value is 0. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-cache-lcnum=<num> +Specifies the maximum number of leaf nodes to be cached. If it is not more than +0, the default value is specified. The default value is 1024. Setting a larger +value will increase speed performance, however, memory consumption will +increase. Lower value will decrease memory consumption. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-cache-ncnum=<num> +Specifies the maximum number of non-leaf nodes to be cached. If it is not more +than 0, the default value is specified. The default value is 512. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-tune-lmemb=<num> +Specifies the number of members in each leaf page. If it is not more than 0, +the default value is specified. The default value is 128. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-tune-nmemb=<num> +Specifies the number of members in each non-leaf page. If it is not more than +0, the default value is specified. The default value is 256. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-tune-bnum=<num> +Specifies the number of elements of the bucket array. If it is not more than 0, +the default value is specified. The default value is 32749. Suggested size of +the bucket array is about from 1 to 4 times of the number of all pages to be +stored. + +Only if configured with --enable-tcb=btree +.TP +\fB\-\-compression=<zlib|bz2> +Specifies that each page is compressed with ZLIB|BZ2 encoding. + +Only if configured with --enable-tcb=btree + +.SH CUSTOM LOG/DATE FORMAT +GoAccess can parse virtually any web log format. +.P +Predefined options include, Common Log Format (CLF), Combined Log Format +(XLF/ELF), including virtual host, Amazon CloudFront (Download Distribution), +Google Cloud Storage and W3C format (IIS). +.P +GoAccess allows any custom format string as well. +.P +There are two ways to configure the log format. +The easiest is to run GoAccess with +.I -c +to prompt a configuration window. Otherwise, it can be configured under +~/.goaccessrc or the %sysconfdir%. +.IP "time-format" +The +.I time-format +variable followed by a space, specifies the log format time +containing any combination of regular characters and special format specifiers. +They all begin with a percentage (%) sign. See `man strftime`. +.I %T or %H:%M:%S. +.IP +.I Note: +If a timestamp is given in microseconds, +.I +%f +must be used as +.I +time-format +.IP "date-format" +The +.I date-format +variable followed by a space, specifies the log format date containing any +combination of regular characters and special format specifiers. They all begin +with a percentage (%) sign. See `man strftime`. e.g., +.I %Y-%m-%d. +.IP +.I Note: +If a timestamp is given in microseconds, +.I +%f +must be used as +.I +date-format +.IP "log-format" +The +.I log-format +variable followed by a space or +.I \\\\t +, specifies the log format string. +.IP %x +A date and time field matching the +.I time-format +and +.I date-format +variables. This is used when given a timestamp or the date & time are +concatenated as a single string (e.g., 1501647332 or 20170801235000) instead of +the date and time being in two separated variables. +.IP %t +time field matching the +.I time-format +variable. +.IP %d +date field matching the +.I date-format +variable. +.IP %v +The canonical Server Name of the server serving the request (Virtual Host). +.IP %e +This is the userid of the person requesting the document as determined by HTTP +authentication. +.IP %h +host (the client IP address, either IPv4 or IPv6) +.IP %r +The request line from the client. This requires specific delimiters around the +request (as single quotes, double quotes, or anything else) to be parsable. If +not, we have to use a combination of special format specifiers as %m %U %H. +.IP %q +The query string. +.IP %m +The request method. +.IP %U +The URL path requested. + +.I Note: +If the query string is in %U, there is no need to use +.I %q. +However, if the URL path, does not include any query string, you may use +.I %q +and the query string will be appended to the request. +.IP %H +The request protocol. +.IP %s +The status code that the server sends back to the client. +.IP %b +The size of the object returned to the client. +.IP %R +The "Referrer" HTTP request header. +.IP %u +The user-agent HTTP request header. +.IP %D +The time taken to serve the request, in microseconds as a decimal number. +.IP %T +The time taken to serve the request, in seconds with milliseconds resolution. +.IP %L +The time taken to serve the request, in milliseconds as a decimal number. +.IP %^ +Ignore this field. +.IP %~ +Move forward through the log string until a non-space (!isspace) char is found. +.IP ~h +The host (the client IP address, either IPv4 or IPv6) in a X-Forwarded-For (XFF) field. + +It uses a special specifier which consists of a tilde before the host +specifier, followed by the character(s) that delimit the XFF field, which are +enclosed by curly braces (i.e., ~h{," }) + +For example, ~h{," } is used in order to parse "11.25.11.53, 17.68.33.17" field +which is delimited by a double quote, a comma, and a space. +.P +.I Note: +In order to get the average, cumulative and maximum time served in GoAccess, +you will need to start logging response times in your web server. In Nginx you +can add +.I $request_time +to your log format, or +.I %D +in Apache. +.P +.I Important: +If multiple time served specifiers are used at the same time, the first option +specified in the format string will take priority over the other specifiers. +.P +GoAccess +.I requires +the following fields: +.IP +.I %h +a valid IPv4/6 +.IP +.I %d +a valid date +.IP +.I %r +the request +.SH INTERACTIVE MENU +.IP "F1 or h" +Main help. +.IP "F5" +Redraw main window. +.IP "q" +Quit the program, current window or collapse active module +.IP "o or ENTER" +Expand selected module or open window +.IP "0-9 and Shift + 0" +Set selected module to active +.IP "j" +Scroll down within expanded module +.IP "k" +Scroll up within expanded module +.IP "c" +Set or change scheme color. +.IP "TAB" +Forward iteration of modules. Starts from current active module. +.IP "SHIFT + TAB" +Backward iteration of modules. Starts from current active module. +.IP "^f" +Scroll forward one screen within an active module. +.IP "^b" +Scroll backward one screen within an active module. +.IP "s" +Sort options for active module +.IP "/" +Search across all modules (regex allowed) +.IP "n" +Find the position of the next occurrence across all modules. +.IP "g" +Move to the first item or top of screen. +.IP "G" +Move to the last item or bottom of screen. +.SH EXAMPLES +.I Note: +Piping data into GoAccess won't prompt a log/date/time configuration dialog, +you will need to previously define it in your configuration file or in the +command line. + +.SS +DIFFERENT OUTPUTS +.P +To output to a terminal and generate an interactive report: +.IP +# goaccess access.log +.P +To generate an HTML report: +.IP +# goaccess access.log -a -o report.html +.P +To generate a JSON report: +.IP +# goaccess access.log -a -d -o report.json +.P +To generate a CSV file: +.IP +# goaccess access.log --no-csv-summary -o report.csv +.P +GoAccess also allows great flexibility for real-time filtering and parsing. For +instance, to quickly diagnose issues by monitoring logs since goaccess was +started: +.IP +# tail -f access.log | goaccess - +.P +And even better, to filter while maintaining opened a pipe to preserve +real-time analysis, we can make use of +.I tail -f +and +a matching pattern tool such as +.I grep, awk, sed, +etc: +.IP +# tail -f access.log | grep -i --line-buffered 'firefox' | goaccess --log-format=COMBINED - +.P +or to parse from the beginning of the file while maintaining the pipe opened +and applying a filter +.IP +# tail -f -n +0 access.log | grep -i --line-buffered 'firefox' | goaccess --log-format=COMBINED -o report.html --real-time-html - +.SS +MULTIPLE LOG FILES +.P +There are several ways to parse multiple logs with GoAccess. The simplest is to +pass multiple log files to the command line: +.IP +# goaccess access.log access.log.1 +.P +It's even possible to parse files from a pipe while reading regular files: +.IP +# cat access.log.2 | goaccess access.log access.log.1 - +.P +.I Note +that the single dash is appended to the command line to let GoAccess know that +it should read from the pipe. +.P +Now if we want to add more flexibility to GoAccess, we can do a series of +pipes. For instance, if we would like to process all compressed log files +.I access.log.*.gz +in addition to the current log file, we can do: +.IP +# zcat access.log.*.gz | goaccess access.log - +.P +.I Note: +On Mac OS X, use gunzip -c instead of zcat. +.SS +REAL TIME HTML OUTPUT +.P +GoAccess has the ability to output real-time data in the HTML report. You can +even email the HTML file since it is composed of a single file with no external +file dependencies, how neat is that! +.P +The process of generating a real-time HTML report is very similar to the +process of creating a static report. Only --real-time-html is needed to make it +real-time. +.IP +# goaccess access.log -o /usr/share/nginx/html/site/report.html --real-time-html +.P +By default, GoAccess will use the host name of the generated report. +Optionally, you can specify the URL to which the client's browser will connect +to. See https://goaccess.io/faq for a more detailed example. +.IP +# goaccess access.log -o report.html --real-time-html --ws-url=goaccess.io +.P +By default, GoAccess listens on port 7890, to use a different port other than +7890, you can specify it as (make sure the port is opened): +.IP +# goaccess access.log -o report.html --real-time-html --port=9870 +.P +And to bind the WebSocket server to a different address other than 0.0.0.0, you +can specify it as: +.IP +# goaccess access.log -o report.html --real-time-html --addr=127.0.0.1 +.P +.I Note: +To output real time data over a TLS/SSL connection, you need to use +.I --ssl-cert=<cert.crt> +and +.I --ssl-key=<priv.key>. +.SS +WORKING WITH DATES +.P +Another useful pipe would be filtering dates out of the web log +.P +The following will get all HTTP requests starting on 05/Dec/2010 until the end +of the file. +.IP +# sed -n '/05\/Dec\/2010/,$ p' access.log | goaccess -a - +.P +or using relative dates such as yesterdays or tomorrows day: +.IP +# sed -n '/'$(date '+%d\/%b\/%Y' -d '1 week ago')'/,$ p' access.log | goaccess -a - +.P +If we want to parse only a certain time-frame from DATE a to DATE b, we can do: +.IP +# sed -n '/5\/Nov\/2010/,/5\/Dec\/2010/ p' access.log | goaccess -a - +.SS +VIRTUAL HOSTS +.P +Assuming your log contains the virtual host (server blocks) field. For +instance: +.IP +vhost.com:80 10.131.40.139 - - [02/Mar/2016:08:14:04 -0600] "GET /shop/bag-p-20 +HTTP/1.1" 200 6715 "-" "Apache (internal dummy connection)" +.P +And you would like to append the virtual host to the request in order to see +which virtual host the top urls belong to +.IP +awk '$8=$1$8' access.log | goaccess -a - +.P +To exclude a list of virtual hosts you can do the following: +.IP +# grep -v "`cat exclude_vhost_list_file`" vhost_access.log | goaccess - +.SS +FILES & STATUS CODES +.P +To parse specific pages, e.g., page views, html, htm, php, etc. within a +request: +.IP +# awk '$7~/\.html|\.htm|\.php/' access.log | goaccess - +.P +Note, +.I $7 +is the request field for the common and combined log format, (without Virtual +Host), if your log includes Virtual Host, then you probably want to use +.I $8 +instead. It's best to check which field you are shooting for, e.g.: +.IP +# tail -10 access.log | awk '{print $8}' +.P +Or to parse a specific status code, e.g., 500 (Internal Server Error): +.IP +# awk '$9~/500/' access.log | goaccess - +.SS +SERVER +.P +Also, it is worth pointing out that if we want to run GoAccess at lower +priority, we can run it as: +.IP +# nice -n 19 goaccess -f access.log -a +.P +and if you don't want to install it on your server, you can still run it from +your local machine: +.IP +# ssh root@server 'cat /var/log/apache2/access.log' | goaccess -a - +.SS +INCREMENTAL LOG PROCESSING +.P +GoAccess has the ability to process logs incrementally through the on-disk +B+Tree database. It works in the following way: + +.nr step 1 1 +.IP \n[step] 3 +A dataset must be persisted first with +.I --keep-db-files, +then the same dataset can be loaded with +.I --load-from-disk. +.IP \n+[step] +If new data is passed (piped or through a log file), it will append it to the +original dataset. +.IP \n+[step] +To preserve the data at all times, +.I --keep-db-files +must be used. +.IP \n+[step] +If +.I --load-from-disk +is used without +.I --keep-db-files, +database files will be deleted upon closing the program. +.P +For instance: +.IP +// last month access log +.br +goaccess access.log.1 --keep-db-files +.P +then, load it with +.IP +// append this month access log, and preserve new data +.br +goaccess access.log --load-from-disk --keep-db-files +.P +To read persisted data only (without parsing new data) +.IP +goaccess --load-from-disk --keep-db-files +.P +.SH NOTES +Each active panel has a total of 366 items or 50 in the real-time HTML report. +The number of items is customizable using +.I max-items +However, only the CSV and JSON output allow a maximum number greater than the +default value of 366 items per panel. +.P +When analyzing the same log file twice using the on-disk B+Tree and using +.I --keep-db-files +and +.I --load-from-disk +on each run, GoAccess will count each entry twice. Issue #334 will address this +issue. +.P +A hit is a request (line in the access log), e.g., 10 requests = 10 hits. HTTP +requests with the same IP, date, and user agent are considered a unique visit. +.SH BUGS +If you think you have found a bug, please send me an email to +.I goaccess@prosoftcorp.com +or use the issue tracker in https://github.com/allinurl/goaccess/issues +.SH AUTHOR +Gerardo Orellana <goaccess@prosoftcorp.com> +For more details about it, or new releases, please visit +https://goaccess.io diff --git a/goaccess++/install-sh b/goaccess++/install-sh new file mode 100644 index 0000000..a9244eb --- /dev/null +++ b/goaccess++/install-sh @@ -0,0 +1,527 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2011-01-19.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for `test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for `test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/goaccess++/m4/gettext.m4 b/goaccess++/m4/gettext.m4 new file mode 100644 index 0000000..f84e6a5 --- /dev/null +++ b/goaccess++/m4/gettext.m4 @@ -0,0 +1,383 @@ +# gettext.m4 serial 63 (gettext-0.18) +dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2006, 2008-2010. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The +dnl default (if it is not specified or empty) is 'no-libtool'. +dnl INTLSYMBOL should be 'external' for packages with no intl directory, +dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library +dnl $(top_builddir)/intl/libintl.a will be created. +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value `$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old], + [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is deprecated.])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define([gt_included_intl], + ifelse([$1], [external], + ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]), + [yes])) + define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], [])) + gt_NEEDS_INIT + AM_GNU_GETTEXT_NEED([$2]) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not + dnl documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation. + gt_INTL_MACOSX + + dnl Set USE_NLS. + AC_REQUIRE([AM_NLS]) + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl Add a version number to the cache macros. + case " $gt_needs " in + *" need-formatstring-macros "*) gt_api_version=3 ;; + *" need-ngettext "*) gt_api_version=2 ;; + *) gt_api_version=1 ;; + esac + gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" + gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH([included-gettext], + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext]) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + if test $gt_api_version -ge 3; then + gt_revision_test_code=' +#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +' + else + gt_revision_test_code= + fi + if test $gt_api_version -ge 2; then + gt_expression_test_code=' + * ngettext ("", "", 0)' + else + gt_expression_test_code= + fi + + AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc], + [AC_TRY_LINK([#include <libintl.h> +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings;], + [bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings], + [eval "$gt_func_gnugettext_libc=yes"], + [eval "$gt_func_gnugettext_libc=no"])]) + + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + [$gt_func_gnugettext_libintl], + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_TRY_LINK([#include <libintl.h> +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *);], + [bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")], + [eval "$gt_func_gnugettext_libintl=yes"], + [eval "$gt_func_gnugettext_libintl=no"]) + dnl Now see whether libintl exists and depends on libiconv. + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include <libintl.h> +$gt_revision_test_code +extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias (const char *);], + [bindtextdomain ("", ""); +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("")], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + eval "$gt_func_gnugettext_libintl=yes" + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ + || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ + && test "$PACKAGE" != gettext-runtime \ + && test "$PACKAGE" != gettext-tools; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV $LIBTHREAD" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV $LTLIBTHREAD" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + CATOBJEXT= + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test -n "$INTL_MACOSX_LIBS"; then + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Some extra flags are needed during linking. + LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" + LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" + fi + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE([ENABLE_NLS], [1], + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + AC_MSG_CHECKING([whether to use NLS]) + AC_MSG_RESULT([$USE_NLS]) + if test "$USE_NLS" = "yes"; then + AC_MSG_CHECKING([where the gettext function comes from]) + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + gt_source="external libintl" + else + gt_source="libc" + fi + else + gt_source="included intl directory" + fi + AC_MSG_RESULT([$gt_source]) + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE([HAVE_GETTEXT], [1], + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE([HAVE_DCGETTEXT], [1], + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL + dnl to 'yes' because some of the testsuite requires it. + if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" = gettext-tools; then + BUILD_INCLUDED_LIBINTL=yes + fi + + dnl Make all variables we use known to autoconf. + AC_SUBST([BUILD_INCLUDED_LIBINTL]) + AC_SUBST([USE_INCLUDED_LIBINTL]) + AC_SUBST([CATOBJEXT]) + + dnl For backward compatibility. Some configure.ins may be using this. + nls_cv_header_intl= + nls_cv_header_libgt= + + dnl For backward compatibility. Some Makefiles may be using this. + DATADIRNAME=share + AC_SUBST([DATADIRNAME]) + + dnl For backward compatibility. Some Makefiles may be using this. + INSTOBJEXT=.mo + AC_SUBST([INSTOBJEXT]) + + dnl For backward compatibility. Some Makefiles may be using this. + GENCAT=gencat + AC_SUBST([GENCAT]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLOBJS= + if test "$USE_INCLUDED_LIBINTL" = yes; then + INTLOBJS="\$(GETTOBJS)" + fi + AC_SUBST([INTLOBJS]) + + dnl Enable libtool support if the surrounding package wishes it. + INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix + AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX]) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST([INTLLIBS]) + + dnl Make all documented variables known to autoconf. + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + AC_SUBST([POSUB]) +]) + + +dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized. +m4_define([gt_NEEDS_INIT], +[ + m4_divert_text([DEFAULTS], [gt_needs=]) + m4_define([gt_NEEDS_INIT], []) +]) + + +dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL]) +AC_DEFUN([AM_GNU_GETTEXT_NEED], +[ + m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"]) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/goaccess++/m4/iconv.m4 b/goaccess++/m4/iconv.m4 new file mode 100644 index 0000000..f46ff14 --- /dev/null +++ b/goaccess++/m4/iconv.m4 @@ -0,0 +1,199 @@ +# iconv.m4 serial 9 (gettext-0.18) +dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include <stdlib.h> +#include <iconv.h>], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + [am_cv_func_iconv=yes]) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include <stdlib.h> +#include <iconv.h>], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + [am_cv_lib_iconv=yes] + [am_cv_func_iconv=yes]) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [ + dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10. + am_save_LIBS="$LIBS" + if test $am_cv_lib_iconv = yes; then + LIBS="$LIBS $LIBICONV" + fi + AC_TRY_RUN([ +#include <iconv.h> +#include <string.h> +int main () +{ + /* Test against AIX 5.1 bug: Failures are not distinguishable from successful + returns. */ + { + iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); + if (cd_utf8_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\342\202\254"; /* EURO SIGN */ + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_utf8_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } + /* Test against Solaris 10 bug: Failures are not distinguishable from + successful returns. */ + { + iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); + if (cd_ascii_to_88591 != (iconv_t)(-1)) + { + static const char input[] = "\263"; + char buf[10]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_ascii_to_88591, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if (res == 0) + return 1; + } + } +#if 0 /* This bug could be worked around by the caller. */ + /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ + { + iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); + if (cd_88591_to_utf8 != (iconv_t)(-1)) + { + static const char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; + char buf[50]; + const char *inptr = input; + size_t inbytesleft = strlen (input); + char *outptr = buf; + size_t outbytesleft = sizeof (buf); + size_t res = iconv (cd_88591_to_utf8, + (char **) &inptr, &inbytesleft, + &outptr, &outbytesleft); + if ((int)res > 0) + return 1; + } + } +#endif + /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is + provided. */ + if (/* Try standardized names. */ + iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) + /* Try IRIX, OSF/1 names. */ + && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) + /* Try AIX names. */ + && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) + /* Try HP-UX names. */ + && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) + return 1; + return 0; +}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no], + [case "$host_os" in + aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; + *) am_cv_func_iconv_works="guessing yes" ;; + esac]) + LIBS="$am_save_LIBS" + ]) + case "$am_cv_func_iconv_works" in + *no) am_func_iconv=no am_cv_lib_iconv=no ;; + *) am_func_iconv=yes ;; + esac + else + am_func_iconv=no am_cv_lib_iconv=no + fi + if test "$am_func_iconv" = yes; then + AC_DEFINE([HAVE_ICONV], [1], + [Define if you have the iconv() function and it works.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST([LIBICONV]) + AC_SUBST([LTLIBICONV]) +]) + +AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL([am_cv_proto_iconv], [ + AC_TRY_COMPILE([ +#include <stdlib.h> +#include <iconv.h> +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], [am_cv_proto_iconv_arg1=""], [am_cv_proto_iconv_arg1="const"]) + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([ + $am_cv_proto_iconv]) + AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1], + [Define as const if the declaration of iconv() needs const.]) + fi +]) diff --git a/goaccess++/m4/intlmacosx.m4 b/goaccess++/m4/intlmacosx.m4 new file mode 100644 index 0000000..dd91025 --- /dev/null +++ b/goaccess++/m4/intlmacosx.m4 @@ -0,0 +1,51 @@ +# intlmacosx.m4 serial 3 (gettext-0.18) +dnl Copyright (C) 2004-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Checks for special options needed on MacOS X. +dnl Defines INTL_MACOSX_LIBS. +AC_DEFUN([gt_INTL_MACOSX], +[ + dnl Check for API introduced in MacOS X 10.2. + AC_CACHE_CHECK([for CFPreferencesCopyAppValue], + [gt_cv_func_CFPreferencesCopyAppValue], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>], + [CFPreferencesCopyAppValue(NULL, NULL)], + [gt_cv_func_CFPreferencesCopyAppValue=yes], + [gt_cv_func_CFPreferencesCopyAppValue=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then + AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1], + [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the CoreFoundation framework.]) + fi + dnl Check for API introduced in MacOS X 10.3. + AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent], + [gt_save_LIBS="$LIBS" + LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" + AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();], + [gt_cv_func_CFLocaleCopyCurrent=yes], + [gt_cv_func_CFLocaleCopyCurrent=no]) + LIBS="$gt_save_LIBS"]) + if test $gt_cv_func_CFLocaleCopyCurrent = yes; then + AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1], + [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the CoreFoundation framework.]) + fi + INTL_MACOSX_LIBS= + if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then + INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" + fi + AC_SUBST([INTL_MACOSX_LIBS]) +]) diff --git a/goaccess++/m4/lib-ld.m4 b/goaccess++/m4/lib-ld.m4 new file mode 100644 index 0000000..ebb3052 --- /dev/null +++ b/goaccess++/m4/lib-ld.m4 @@ -0,0 +1,110 @@ +# lib-ld.m4 serial 4 (gettext-0.18) +dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl Subroutines of libtool.m4, +dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision +dnl with libtool.m4. + +dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + acl_cv_prog_gnu_ld=yes ;; +*) + acl_cv_prog_gnu_ld=no ;; +esac]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-1.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_ARG_WITH([gnu-ld], +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]* | [A-Za-z]:[\\/]*)] + [re_direlt='/[^/][^/]*/\.\./'] + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL([acl_cv_path_LD], +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break ;; + *) + test "$with_gnu_ld" != yes && break ;; + esac + fi + done + IFS="$ac_save_ifs" +else + acl_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$acl_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT([$LD]) +else + AC_MSG_RESULT([no]) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_LIB_PROG_LD_GNU +]) diff --git a/goaccess++/m4/lib-link.m4 b/goaccess++/m4/lib-link.m4 new file mode 100644 index 0000000..c73bd8e --- /dev/null +++ b/goaccess++/m4/lib-link.m4 @@ -0,0 +1,774 @@ +# lib-link.m4 serial 21 (gettext-0.18) +dnl Copyright (C) 2001-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_PREREQ([2.54]) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[translit([$1],[./-], [___])]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + popdef([NAME]) + popdef([Name]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message]) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. The missing-message +dnl defaults to 'no' and may contain additional hints for the user. +dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} +dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[translit([$1],[./-], [___])]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS, + dnl because these -l options might require -L options that are present in + dnl LIBS. -l options benefit only from the -L options listed before it. + dnl Otherwise, add it to the front of LIBS, because it may be a static + dnl library that depends on another static library that is present in LIBS. + dnl Static libraries benefit only from the static libraries listed after + dnl it. + case " $LIB[]NAME" in + *" -l"*) LIBS="$LIBS $LIB[]NAME" ;; + *) LIBS="$LIB[]NAME $LIBS" ;; + esac + AC_TRY_LINK([$3], [$4], + [ac_cv_lib[]Name=yes], + [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])']) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + LIB[]NAME[]_PREFIX= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + popdef([NAME]) + popdef([Name]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl acl_libext, +dnl acl_shlibext, +dnl acl_hardcode_libdir_flag_spec, +dnl acl_hardcode_libdir_separator, +dnl acl_hardcode_direct, +dnl acl_hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl Autoconf >= 2.61 supports dots in --with options. + pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH(P_A_C_K[-prefix], +[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && ! test -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been + dnl computed. So it has to be reset here. + HAVE_LIB[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([P_A_C_K]) + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/goaccess++/m4/lib-prefix.m4 b/goaccess++/m4/lib-prefix.m4 new file mode 100644 index 0000000..1601cea --- /dev/null +++ b/goaccess++/m4/lib-prefix.m4 @@ -0,0 +1,224 @@ +# lib-prefix.m4 serial 7 (gettext-0.18) +dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a variable acl_libdirstem, containing the basename of the libdir, either +dnl "lib" or "lib64" or "lib/64", +dnl - a variable acl_libdirstem2, as a secondary possible value for +dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or +dnl "lib/amd64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. + dnl On glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine + dnl the compiler's default mode by looking at the compiler's library search + dnl path. If at least one of its elements ends in /lib64 or points to a + dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. + dnl Otherwise we use the default, namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl <http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>. + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], + [AC_EGREP_CPP([sixtyfour bits], [ +#ifdef _LP64 +sixtyfour bits +#endif + ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no]) + ]) + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" +]) diff --git a/goaccess++/m4/nls.m4 b/goaccess++/m4/nls.m4 new file mode 100644 index 0000000..003704c --- /dev/null +++ b/goaccess++/m4/nls.m4 @@ -0,0 +1,32 @@ +# nls.m4 serial 5 (gettext-0.18) +dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. + +AC_PREREQ([2.50]) + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE([nls], + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT([$USE_NLS]) + AC_SUBST([USE_NLS]) +]) diff --git a/goaccess++/m4/po.m4 b/goaccess++/m4/po.m4 new file mode 100644 index 0000000..47f36a4 --- /dev/null +++ b/goaccess++/m4/po.m4 @@ -0,0 +1,449 @@ +# po.m4 serial 17 (gettext-0.18) +dnl Copyright (C) 1995-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000. +dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003. + +AC_PREREQ([2.50]) + +dnl Checks for all prerequisites of the po subdirectory. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake + AC_REQUIRE([AM_NLS])dnl + + dnl Release version of the gettext macros. This is used to ensure that + dnl the gettext macros and po/Makefile.in.in are in sync. + AC_SUBST([GETTEXT_MACRO_VERSION], [0.18]) + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT]) + + dnl Test whether it is GNU msgfmt >= 0.15. +changequote(,)dnl + case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; + *) MSGFMT_015=$MSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([MSGFMT_015]) +changequote(,)dnl + case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; + *) GMSGFMT_015=$GMSGFMT ;; + esac +changequote([,])dnl + AC_SUBST([GMSGFMT_015]) + + dnl Search for GNU xgettext 0.12 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Test whether it is GNU xgettext >= 0.15. +changequote(,)dnl + case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; + *) XGETTEXT_015=$XGETTEXT ;; + esac +changequote([,])dnl + AC_SUBST([XGETTEXT_015]) + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :) + + dnl Installation directories. + dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we + dnl have to define it here, so that it can be used in po/Makefile. + test -n "$localedir" || localedir='${datadir}/locale' + AC_SUBST([localedir]) + + dnl Support for AM_XGETTEXT_OPTION. + test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= + AC_SUBST([XGETTEXT_EXTRA_OPTIONS]) + + AC_CONFIG_COMMANDS([po-directories], [[ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + # Treat a directory as a PO directory if and only if it has a + # POTFILES.in file. This allows packages to have multiple PO + # directories under different names or in different locations. + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + POMAKEFILEDEPS="POTFILES.in" + # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # The set of available languages was given in configure.in. + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' + fi + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done]], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it + # from automake < 1.5. + eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + +dnl Postprocesses a Makefile in a directory containing PO files. +AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE], +[ + # When this code is run, in config.status, two variables have already been + # set: + # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in, + # - LINGUAS is the value of the environment variable LINGUAS at configure + # time. + +changequote(,)dnl + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + # Find a way to echo strings without interpreting backslash. + if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='echo' + else + if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then + gt_echo='printf %s\n' + else + echo_func () { + cat <<EOT +$* +EOT + } + gt_echo='echo_func' + fi + fi + + # A sed script that extracts the value of VARIABLE from a Makefile. + sed_x_variable=' +# Test if the hold space is empty. +x +s/P/P/ +x +ta +# Yes it was empty. Look if we have the expected variable definition. +/^[ ]*VARIABLE[ ]*=/{ + # Seen the first line of the variable definition. + s/^[ ]*VARIABLE[ ]*=// + ba +} +bd +:a +# Here we are processing a line from the variable definition. +# Remove comment, more precisely replace it with a space. +s/#.*$/ / +# See if the line ends in a backslash. +tb +:b +s/\\$// +# Print the line, without the trailing backslash. +p +tc +# There was no trailing backslash. The end of the variable definition is +# reached. Clear the hold space. +s/^.*$// +x +bd +:c +# A trailing backslash means that the variable definition continues in the +# next line. Put a nonempty string into the hold space to indicate this. +s/^.*$/P/ +x +:d +' +changequote([,])dnl + + # Set POTFILES to the value of the Makefile variable POTFILES. + sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'` + POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"` + # Compute POTFILES_DEPS as + # $(foreach file, $(POTFILES), $(top_srcdir)/$(file)) + POTFILES_DEPS= + for file in $POTFILES; do + POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file" + done + POMAKEFILEDEPS="" + + if test -n "$OBSOLETE_ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` + POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" + else + # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS. + sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'` + ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"` + fi + # Hide the ALL_LINGUAS assigment from automake < 1.5. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + # Compute POFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) + # Compute UPDATEPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) + # Compute DUMMYPOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) + # Compute GMOFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) + # Compute PROPERTIESFILES + # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties) + # Compute CLASSFILES + # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class) + # Compute QMFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm) + # Compute MSGFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg) + # Compute RESOURCESDLLFILES + # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll) + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + UPDATEPOFILES= + DUMMYPOFILES= + GMOFILES= + PROPERTIESFILES= + CLASSFILES= + QMFILES= + MSGFILES= + RESOURCESDLLFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties" + CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class" + QMFILES="$QMFILES $srcdirpre$lang.qm" + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg" + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + JAVACATALOGS= + QTCATALOGS= + TCLCATALOGS= + CSHARPCATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties" + QTCATALOGS="$QTCATALOGS $lang.qm" + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg" + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll" + done + fi + + sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp" + if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'` + cat >> "$ac_file.tmp" <<EOF +$frobbedlang.msg: $lang.po + @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \ + \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; } +EOF + done + fi + if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then + # Add dependencies that cannot be formulated as a simple suffix rule. + for lang in $ALL_LINGUAS; do + frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'` + cat >> "$ac_file.tmp" <<EOF +$frobbedlang/\$(DOMAIN).resources.dll: $lang.po + @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \ + \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; } +EOF + done + fi + if test -n "$POMAKEFILEDEPS"; then + cat >> "$ac_file.tmp" <<EOF +Makefile: $POMAKEFILEDEPS +EOF + fi + mv "$ac_file.tmp" "$ac_file" +]) + +dnl Initializes the accumulator used by AM_XGETTEXT_OPTION. +AC_DEFUN([AM_XGETTEXT_OPTION_INIT], +[ + XGETTEXT_EXTRA_OPTIONS= +]) + +dnl Registers an option to be passed to xgettext in the po subdirectory. +AC_DEFUN([AM_XGETTEXT_OPTION], +[ + AC_REQUIRE([AM_XGETTEXT_OPTION_INIT]) + XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1" +]) diff --git a/goaccess++/m4/progtest.m4 b/goaccess++/m4/progtest.m4 new file mode 100644 index 0000000..2d804ac --- /dev/null +++ b/goaccess++/m4/progtest.m4 @@ -0,0 +1,92 @@ +# progtest.m4 serial 6 (gettext-0.18) +dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper <drepper@cygnus.com>, 1996. + +AC_PREREQ([2.50]) + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[ +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Find out how to test for executable files. Don't use a zero-byte file, +# as systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + ac_executable_p="test -x" +else + ac_executable_p="test -f" +fi +rm -f conf$$.file + +# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL([ac_cv_path_$1], +[case "[$]$1" in + [[\\/]]* | ?:[[\\/]]*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in ifelse([$5], , $PATH, [$5]); do + IFS="$ac_save_IFS" + test -z "$ac_dir" && ac_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then + echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext" + break 2 + fi + fi + done + done + IFS="$ac_save_IFS" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$][$1]) +else + AC_MSG_RESULT([no]) +fi +AC_SUBST([$1])dnl +]) diff --git a/goaccess++/missing b/goaccess++/missing new file mode 100644 index 0000000..86a8fc3 --- /dev/null +++ b/goaccess++/missing @@ -0,0 +1,331 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2012-01-06.13; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG=\${$#} + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/goaccess++/po/LINGUAS b/goaccess++/po/LINGUAS new file mode 100644 index 0000000..9595d03 --- /dev/null +++ b/goaccess++/po/LINGUAS @@ -0,0 +1,4 @@ +fr +es +zh_CN +ja diff --git a/goaccess++/po/Makefile b/goaccess++/po/Makefile new file mode 100644 index 0000000..c310cb8 --- /dev/null +++ b/goaccess++/po/Makefile @@ -0,0 +1,571 @@ +# Makefile for PO directory in any package using GNU gettext. +# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu> +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU General Public +# License but which still want to provide support for the GNU gettext +# functionality. +# Please note that the actual code of GNU gettext is covered by the GNU +# General Public License and is *not* in the public domain. +# +# Origin: gettext-0.18 +GETTEXT_MACRO_VERSION = 0.18 + +PACKAGE = goaccess +VERSION = 1.3 +PACKAGE_BUGREPORT = goaccess@prosoftcorp.com + +SHELL = /bin/sh + + +srcdir = . +top_srcdir = .. + + +prefix = /usr/local +exec_prefix = ${prefix} +datarootdir = ${prefix}/share +datadir = ${datarootdir} +localedir = ${datarootdir}/locale +gettextsrcdir = $(datadir)/gettext/po + +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 + +# We use $(mkdir_p). +# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as +# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, +# ${SHELL} /home/djq/goaccess-1.3/install-sh does not start with $(SHELL), so we add it. +# In automake >= 1.10, /usr/bin/mkdir -p is derived from ${MKDIR_P}, which is defined +# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake +# versions, $(mkinstalldirs) and $(install_sh) are unused. +mkinstalldirs = $(SHELL) ${SHELL} /home/djq/goaccess-1.3/install-sh -d +install_sh = $(SHELL) ${SHELL} /home/djq/goaccess-1.3/install-sh +MKDIR_P = /usr/bin/mkdir -p +mkdir_p = /usr/bin/mkdir -p + +GMSGFMT_ = : +GMSGFMT_no = : +GMSGFMT_yes = : +GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) +MSGFMT_ = : +MSGFMT_no = : +MSGFMT_yes = : +MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) +XGETTEXT_ = : +XGETTEXT_no = : +XGETTEXT_yes = : +XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +MSGMERGE = msgmerge +MSGMERGE_UPDATE = : --update +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +POFILES = fr.po es.po zh_CN.po ja.po +GMOFILES = fr.gmo es.gmo zh_CN.gmo ja.gmo +UPDATEPOFILES = fr.po-update es.po-update zh_CN.po-update ja.po-update +DUMMYPOFILES = fr.nop es.nop zh_CN.nop ja.nop +DISTFILES.common = Makefile.in.in remove-potcdate.sin \ +$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) +DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ +$(POFILES) $(GMOFILES) \ +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) + +POTFILES = \ + ../src/labels.h + +CATALOGS = fr.gmo es.gmo zh_CN.gmo ja.gmo + +# Makevars gets inserted here. (Don't remove this line!) +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. +AM_CPPFLAGS = -I. -I$(srcdir) + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Free Software Foundation, Inc. + +# This tells whether or not to prepend "GNU " prefix to the package +# name that gets inserted into the header of the $(DOMAIN).pot file. +# Possible values are "yes", "no", or empty. If it is empty, try to +# detect it automatically by scanning the files in $(top_srcdir) for +# "GNU packagename" string. +PACKAGE_GNU = + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = hello@goaccess.io + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = + +# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' +# context. Possible values are "yes" and "no". Set this to yes if the +# package uses functions taking also a message context, like pgettext(), or +# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. +USE_MSGCTXT = no + +# These options get passed to msgmerge. +# Useful options are in particular: +# --previous to keep previous msgids of translated messages, +# --quiet to reduce the verbosity. +MSGMERGE_OPTIONS = + +# These options get passed to msginit. +# If you want to disable line wrapping when writing PO files, add +# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and +# MSGINIT_OPTIONS. +MSGINIT_OPTIONS = + +# This tells whether or not to regenerate a PO file when $(DOMAIN).pot +# has changed. Possible values are "yes" and "no". Set this to no if +# the POT file is checked in the repository and the version control +# program ignores timestamps. +PO_DEPENDS_ON_POT = yes + +# This tells whether or not to forcibly update $(DOMAIN).pot and +# regenerate PO files on "make dist". Possible values are "yes" and +# "no". Set this to no if the POT file and PO files are maintained +# externally. +DIST_DEPENDS_ON_UPDATE_PO = yes + +.SUFFIXES: +.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update + +.po.mo: + @echo "$(MSGFMT) -c -o $@ $<"; \ + $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ + +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ + cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + +.sin.sed: + sed -e '/^#/d' $< > t-$@ + mv t-$@ $@ + + +all: check-macro-version all-yes + +all-yes: stamp-po +all-no: + +# Ensure that the gettext macros and this Makefile.in.in are in sync. +check-macro-version: + @test "$(GETTEXT_MACRO_VERSION)" = "0.18" \ + || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version 0.18" 1>&2; \ + exit 1; \ + } + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, stamp-po is a nop (i.e. a phony target). + +# stamp-po is a timestamp denoting the last time at which the CATALOGS have +# been loosely updated. Its purpose is that when a developer or translator +# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, +# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent +# invocations of "make" will do nothing. This timestamp would not be necessary +# if updating the $(CATALOGS) would always touch them; however, the rule for +# $(POFILES) has been designed to not touch files that don't need to be +# changed. +stamp-po: $(srcdir)/$(DOMAIN).pot + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch stamp-po" && \ + echo timestamp > stamp-poT && \ + mv stamp-poT stamp-po; \ + } + +# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', +# otherwise packages like GCC can not be built if only parts of the source +# have been downloaded. + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed + if LC_ALL=C grep 'GNU goaccess' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \ + package_gnu='GNU '; \ + else \ + package_gnu=''; \ + fi; \ + if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_gnu}goaccess" \ + --package-version='1.3' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + esac + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) \ + && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ + esac; \ + }; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-yes + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + for file in $(DISTFILES.common) Makevars.template; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + for file in Makevars; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +install-data-no: all +install-data-yes: all + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +install-strip: install + +installdirs: installdirs-exec installdirs-data +installdirs-exec: +installdirs-data: installdirs-data-yes + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi +installdirs-data-no: +installdirs-data-yes: + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: uninstall-exec uninstall-data +uninstall-exec: +uninstall-data: uninstall-data-yes + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in $(DISTFILES.common) Makevars.template; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +uninstall-data-no: +uninstall-data-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +check: all + +info dvi ps pdf html tags TAGS ctags CTAGS ID: + +mostlyclean: + rm -f remove-potcdate.sed + rm -f stamp-poT + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f stamp-po $(GMOFILES) + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: + $(MAKE) update-po + @$(MAKE) dist2 +# This is a separate target because 'update-po' must be executed before. +dist2: stamp-po $(DISTFILES) + dists="$(DISTFILES)"; \ + if test "$(PACKAGE)" = "gettext-tools"; then \ + dists="$$dists Makevars.template"; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + dists="$$dists $(DOMAIN).pot stamp-po"; \ + fi; \ + if test -f $(srcdir)/ChangeLog; then \ + dists="$$dists ChangeLog"; \ + fi; \ + for i in 0 1 2 3 4 5 6 7 8 9; do \ + if test -f $(srcdir)/ChangeLog.$$i; then \ + dists="$$dists ChangeLog.$$i"; \ + fi; \ + done; \ + if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ + for file in $$dists; do \ + if test -f $$file; then \ + cp -p $$file $(distdir) || exit 1; \ + else \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + fi; \ + done + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + esac; \ + }; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: + +# Recreate Makefile by invoking config.status. Explicitly invoke the shell, +# because execution permission bits may not work on the current file system. +# Use /bin/bash, which is the shell determined by autoconf for the use by its +# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. +Makefile: Makefile.in.in Makevars $(top_builddir)/config.status POTFILES.in LINGUAS + cd $(top_builddir) \ + && /bin/bash ./config.status $(subdir)/$@.in po-directories + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: +# Special Makefile rules for English message catalogs with quotation marks. + +DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot + +.SUFFIXES: .insert-header .po-update-en + +en@quot.po-create: + $(MAKE) en@quot.po-update +en@boldquot.po-create: + $(MAKE) en@boldquot.po-update + +en@quot.po-update: en@quot.po-update-en +en@boldquot.po-update: en@boldquot.po-update-en + +.insert-header.po-update-en: + @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ + if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + ll=`echo $$lang | sed -e 's/@.*//'`; \ + LC_ALL=C; export LC_ALL; \ + cd $(srcdir); \ + if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "creation of $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +en@quot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header + +en@boldquot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header + +mostlyclean: mostlyclean-quot +mostlyclean-quot: + rm -f *.insert-header diff --git a/goaccess++/po/Makefile.in b/goaccess++/po/Makefile.in new file mode 100644 index 0000000..a2ce276 --- /dev/null +++ b/goaccess++/po/Makefile.in @@ -0,0 +1,444 @@ +# Makefile for PO directory in any package using GNU gettext. +# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu> +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU General Public +# License but which still want to provide support for the GNU gettext +# functionality. +# Please note that the actual code of GNU gettext is covered by the GNU +# General Public License and is *not* in the public domain. +# +# Origin: gettext-0.18 +GETTEXT_MACRO_VERSION = 0.18 + +PACKAGE = goaccess +VERSION = 1.3 +PACKAGE_BUGREPORT = goaccess@prosoftcorp.com + +SHELL = /bin/sh + + +srcdir = . +top_srcdir = .. + + +prefix = /usr/local +exec_prefix = ${prefix} +datarootdir = ${prefix}/share +datadir = ${datarootdir} +localedir = ${datarootdir}/locale +gettextsrcdir = $(datadir)/gettext/po + +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 + +# We use $(mkdir_p). +# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as +# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, +# ${SHELL} /home/djq/goaccess-1.3/install-sh does not start with $(SHELL), so we add it. +# In automake >= 1.10, /usr/bin/mkdir -p is derived from ${MKDIR_P}, which is defined +# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake +# versions, $(mkinstalldirs) and $(install_sh) are unused. +mkinstalldirs = $(SHELL) ${SHELL} /home/djq/goaccess-1.3/install-sh -d +install_sh = $(SHELL) ${SHELL} /home/djq/goaccess-1.3/install-sh +MKDIR_P = /usr/bin/mkdir -p +mkdir_p = /usr/bin/mkdir -p + +GMSGFMT_ = : +GMSGFMT_no = : +GMSGFMT_yes = : +GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) +MSGFMT_ = : +MSGFMT_no = : +MSGFMT_yes = : +MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) +XGETTEXT_ = : +XGETTEXT_no = : +XGETTEXT_yes = : +XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +MSGMERGE = msgmerge +MSGMERGE_UPDATE = : --update +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +UPDATEPOFILES = @UPDATEPOFILES@ +DUMMYPOFILES = @DUMMYPOFILES@ +DISTFILES.common = Makefile.in.in remove-potcdate.sin \ +$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) +DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ +$(POFILES) $(GMOFILES) \ +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) + +POTFILES = \ + +CATALOGS = @CATALOGS@ + +# Makevars gets inserted here. (Don't remove this line!) + +.SUFFIXES: +.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update + +.po.mo: + @echo "$(MSGFMT) -c -o $@ $<"; \ + $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ + +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ + cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + +.sin.sed: + sed -e '/^#/d' $< > t-$@ + mv t-$@ $@ + + +all: check-macro-version all-yes + +all-yes: stamp-po +all-no: + +# Ensure that the gettext macros and this Makefile.in.in are in sync. +check-macro-version: + @test "$(GETTEXT_MACRO_VERSION)" = "0.18" \ + || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version 0.18" 1>&2; \ + exit 1; \ + } + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, stamp-po is a nop (i.e. a phony target). + +# stamp-po is a timestamp denoting the last time at which the CATALOGS have +# been loosely updated. Its purpose is that when a developer or translator +# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, +# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent +# invocations of "make" will do nothing. This timestamp would not be necessary +# if updating the $(CATALOGS) would always touch them; however, the rule for +# $(POFILES) has been designed to not touch files that don't need to be +# changed. +stamp-po: $(srcdir)/$(DOMAIN).pot + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch stamp-po" && \ + echo timestamp > stamp-poT && \ + mv stamp-poT stamp-po; \ + } + +# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', +# otherwise packages like GCC can not be built if only parts of the source +# have been downloaded. + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed + if LC_ALL=C grep 'GNU goaccess' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \ + package_gnu='GNU '; \ + else \ + package_gnu=''; \ + fi; \ + if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_gnu}goaccess" \ + --package-version='1.3' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + esac + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) \ + && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ + esac; \ + }; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-yes + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + for file in $(DISTFILES.common) Makevars.template; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + for file in Makevars; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +install-data-no: all +install-data-yes: all + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +install-strip: install + +installdirs: installdirs-exec installdirs-data +installdirs-exec: +installdirs-data: installdirs-data-yes + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi +installdirs-data-no: +installdirs-data-yes: + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: uninstall-exec uninstall-data +uninstall-exec: +uninstall-data: uninstall-data-yes + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in $(DISTFILES.common) Makevars.template; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +uninstall-data-no: +uninstall-data-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +check: all + +info dvi ps pdf html tags TAGS ctags CTAGS ID: + +mostlyclean: + rm -f remove-potcdate.sed + rm -f stamp-poT + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f stamp-po $(GMOFILES) + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: + $(MAKE) update-po + @$(MAKE) dist2 +# This is a separate target because 'update-po' must be executed before. +dist2: stamp-po $(DISTFILES) + dists="$(DISTFILES)"; \ + if test "$(PACKAGE)" = "gettext-tools"; then \ + dists="$$dists Makevars.template"; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + dists="$$dists $(DOMAIN).pot stamp-po"; \ + fi; \ + if test -f $(srcdir)/ChangeLog; then \ + dists="$$dists ChangeLog"; \ + fi; \ + for i in 0 1 2 3 4 5 6 7 8 9; do \ + if test -f $(srcdir)/ChangeLog.$$i; then \ + dists="$$dists ChangeLog.$$i"; \ + fi; \ + done; \ + if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ + for file in $$dists; do \ + if test -f $$file; then \ + cp -p $$file $(distdir) || exit 1; \ + else \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + fi; \ + done + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + esac; \ + }; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: + +# Recreate Makefile by invoking config.status. Explicitly invoke the shell, +# because execution permission bits may not work on the current file system. +# Use /bin/bash, which is the shell determined by autoconf for the use by its +# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. +Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ + cd $(top_builddir) \ + && /bin/bash ./config.status $(subdir)/$@.in po-directories + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/goaccess++/po/Makefile.in.in b/goaccess++/po/Makefile.in.in new file mode 100644 index 0000000..83d8838 --- /dev/null +++ b/goaccess++/po/Makefile.in.in @@ -0,0 +1,444 @@ +# Makefile for PO directory in any package using GNU gettext. +# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper <drepper@gnu.ai.mit.edu> +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU General Public +# License but which still want to provide support for the GNU gettext +# functionality. +# Please note that the actual code of GNU gettext is covered by the GNU +# General Public License and is *not* in the public domain. +# +# Origin: gettext-0.18 +GETTEXT_MACRO_VERSION = 0.18 + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datarootdir = @datarootdir@ +datadir = @datadir@ +localedir = @localedir@ +gettextsrcdir = $(datadir)/gettext/po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ + +# We use $(mkdir_p). +# In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as +# "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, +# @install_sh@ does not start with $(SHELL), so we add it. +# In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined +# either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake +# versions, $(mkinstalldirs) and $(install_sh) are unused. +mkinstalldirs = $(SHELL) @install_sh@ -d +install_sh = $(SHELL) @install_sh@ +MKDIR_P = @MKDIR_P@ +mkdir_p = @mkdir_p@ + +GMSGFMT_ = @GMSGFMT@ +GMSGFMT_no = @GMSGFMT@ +GMSGFMT_yes = @GMSGFMT_015@ +GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) +MSGFMT_ = @MSGFMT@ +MSGFMT_no = @MSGFMT@ +MSGFMT_yes = @MSGFMT_015@ +MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) +XGETTEXT_ = @XGETTEXT@ +XGETTEXT_no = @XGETTEXT@ +XGETTEXT_yes = @XGETTEXT_015@ +XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) +MSGMERGE = msgmerge +MSGMERGE_UPDATE = @MSGMERGE@ --update +MSGINIT = msginit +MSGCONV = msgconv +MSGFILTER = msgfilter + +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +UPDATEPOFILES = @UPDATEPOFILES@ +DUMMYPOFILES = @DUMMYPOFILES@ +DISTFILES.common = Makefile.in.in remove-potcdate.sin \ +$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) +DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ +$(POFILES) $(GMOFILES) \ +$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) + +POTFILES = \ + +CATALOGS = @CATALOGS@ + +# Makevars gets inserted here. (Don't remove this line!) + +.SUFFIXES: +.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update + +.po.mo: + @echo "$(MSGFMT) -c -o $@ $<"; \ + $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ + +.po.gmo: + @lang=`echo $* | sed -e 's,.*/,,'`; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ + cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo + +.sin.sed: + sed -e '/^#/d' $< > t-$@ + mv t-$@ $@ + + +all: check-macro-version all-@USE_NLS@ + +all-yes: stamp-po +all-no: + +# Ensure that the gettext macros and this Makefile.in.in are in sync. +check-macro-version: + @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ + || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ + exit 1; \ + } + +# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no +# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because +# we don't want to bother translators with empty POT files). We assume that +# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. +# In this case, stamp-po is a nop (i.e. a phony target). + +# stamp-po is a timestamp denoting the last time at which the CATALOGS have +# been loosely updated. Its purpose is that when a developer or translator +# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, +# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent +# invocations of "make" will do nothing. This timestamp would not be necessary +# if updating the $(CATALOGS) would always touch them; however, the rule for +# $(POFILES) has been designed to not touch files that don't need to be +# changed. +stamp-po: $(srcdir)/$(DOMAIN).pot + test ! -f $(srcdir)/$(DOMAIN).pot || \ + test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) + @test ! -f $(srcdir)/$(DOMAIN).pot || { \ + echo "touch stamp-po" && \ + echo timestamp > stamp-poT && \ + mv stamp-poT stamp-po; \ + } + +# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', +# otherwise packages like GCC can not be built if only parts of the source +# have been downloaded. + +# This target rebuilds $(DOMAIN).pot; it is an expensive operation. +# Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. +$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed + if LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null | grep -v 'libtool:' >/dev/null; then \ + package_gnu='GNU '; \ + else \ + package_gnu=''; \ + fi; \ + if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ + msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ + else \ + msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ + fi; \ + case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + *) \ + $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ + --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ + --files-from=$(srcdir)/POTFILES.in \ + --copyright-holder='$(COPYRIGHT_HOLDER)' \ + --package-name="$${package_gnu}@PACKAGE@" \ + --package-version='@VERSION@' \ + --msgid-bugs-address="$$msgid_bugs_address" \ + ;; \ + esac + test ! -f $(DOMAIN).po || { \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ + sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ + if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ + else \ + rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + else \ + mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ + fi; \ + } + +# This rule has no dependencies: we don't need to update $(DOMAIN).pot at +# every "make" invocation, only create it when it is missing. +# Only "make $(DOMAIN).pot-update" or "make dist" will force an update. +$(srcdir)/$(DOMAIN).pot: + $(MAKE) $(DOMAIN).pot-update + +# This target rebuilds a PO file if $(DOMAIN).pot has changed. +# Note that a PO file is not touched if it doesn't need to be changed. +$(POFILES): $(srcdir)/$(DOMAIN).pot + @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ + if test -f "$(srcdir)/$${lang}.po"; then \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ + cd $(srcdir) \ + && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ + esac; \ + }; \ + else \ + $(MAKE) $${lang}.po-create; \ + fi + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + for file in $(DISTFILES.common) Makevars.template; do \ + $(INSTALL_DATA) $(srcdir)/$$file \ + $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + for file in Makevars; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +install-data-no: all +install-data-yes: all + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ + $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ + echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ + cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ + fi; \ + done; \ + done + +install-strip: install + +installdirs: installdirs-exec installdirs-data +installdirs-exec: +installdirs-data: installdirs-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ + else \ + : ; \ + fi +installdirs-data-no: +installdirs-data-yes: + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + dir=$(localedir)/$$lang/LC_MESSAGES; \ + $(mkdir_p) $(DESTDIR)$$dir; \ + for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ + if test -n "$$lc"; then \ + if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ + link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ + mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ + for file in *; do \ + if test -f $$file; then \ + ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ + fi; \ + done); \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ + else \ + if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ + :; \ + else \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ + mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ + fi; \ + fi; \ + fi; \ + done; \ + done + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: uninstall-exec uninstall-data +uninstall-exec: +uninstall-data: uninstall-data-@USE_NLS@ + if test "$(PACKAGE)" = "gettext-tools"; then \ + for file in $(DISTFILES.common) Makevars.template; do \ + rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi +uninstall-data-no: +uninstall-data-yes: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ + for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ + rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ + done; \ + done + +check: all + +info dvi ps pdf html tags TAGS ctags CTAGS ID: + +mostlyclean: + rm -f remove-potcdate.sed + rm -f stamp-poT + rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f stamp-po $(GMOFILES) + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: + $(MAKE) update-po + @$(MAKE) dist2 +# This is a separate target because 'update-po' must be executed before. +dist2: stamp-po $(DISTFILES) + dists="$(DISTFILES)"; \ + if test "$(PACKAGE)" = "gettext-tools"; then \ + dists="$$dists Makevars.template"; \ + fi; \ + if test -f $(srcdir)/$(DOMAIN).pot; then \ + dists="$$dists $(DOMAIN).pot stamp-po"; \ + fi; \ + if test -f $(srcdir)/ChangeLog; then \ + dists="$$dists ChangeLog"; \ + fi; \ + for i in 0 1 2 3 4 5 6 7 8 9; do \ + if test -f $(srcdir)/ChangeLog.$$i; then \ + dists="$$dists ChangeLog.$$i"; \ + fi; \ + done; \ + if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ + for file in $$dists; do \ + if test -f $$file; then \ + cp -p $$file $(distdir) || exit 1; \ + else \ + cp -p $(srcdir)/$$file $(distdir) || exit 1; \ + fi; \ + done + +update-po: Makefile + $(MAKE) $(DOMAIN).pot-update + test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) + $(MAKE) update-gmo + +# General rule for creating PO files. + +.nop.po-create: + @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ + echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ + exit 1 + +# General rule for updating PO files. + +.nop.po-update: + @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ + if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ + echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ + cd $(srcdir); \ + if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ + '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + *) \ + $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ + esac; \ + }; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "msgmerge for $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +$(DUMMYPOFILES): + +update-gmo: Makefile $(GMOFILES) + @: + +# Recreate Makefile by invoking config.status. Explicitly invoke the shell, +# because execution permission bits may not work on the current file system. +# Use @SHELL@, which is the shell determined by autoconf for the use by its +# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. +Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ + cd $(top_builddir) \ + && @SHELL@ ./config.status $(subdir)/$@.in po-directories + +force: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/goaccess++/po/Makevars b/goaccess++/po/Makevars new file mode 100644 index 0000000..facec21 --- /dev/null +++ b/goaccess++/po/Makevars @@ -0,0 +1,79 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. +AM_CPPFLAGS = -I. -I$(srcdir) + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --from-code=UTF-8 --keyword=_ --keyword=N_ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Free Software Foundation, Inc. + +# This tells whether or not to prepend "GNU " prefix to the package +# name that gets inserted into the header of the $(DOMAIN).pot file. +# Possible values are "yes", "no", or empty. If it is empty, try to +# detect it automatically by scanning the files in $(top_srcdir) for +# "GNU packagename" string. +PACKAGE_GNU = + +# This is the email address or URL to which the translators shall report +# bugs in the untranslated strings: +# - Strings which are not entire sentences, see the maintainer guidelines +# in the GNU gettext documentation, section 'Preparing Strings'. +# - Strings which use unclear terms or require additional context to be +# understood. +# - Strings which make invalid assumptions about notation of date, time or +# money. +# - Pluralisation problems. +# - Incorrect English spelling. +# - Incorrect formatting. +# It can be your email address, or a mailing list address where translators +# can write to without being subscribed, or the URL of a web page through +# which the translators can contact you. +MSGID_BUGS_ADDRESS = hello@goaccess.io + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = + +# This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' +# context. Possible values are "yes" and "no". Set this to yes if the +# package uses functions taking also a message context, like pgettext(), or +# if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. +USE_MSGCTXT = no + +# These options get passed to msgmerge. +# Useful options are in particular: +# --previous to keep previous msgids of translated messages, +# --quiet to reduce the verbosity. +MSGMERGE_OPTIONS = + +# These options get passed to msginit. +# If you want to disable line wrapping when writing PO files, add +# --no-wrap to MSGMERGE_OPTIONS, XGETTEXT_OPTIONS, and +# MSGINIT_OPTIONS. +MSGINIT_OPTIONS = + +# This tells whether or not to regenerate a PO file when $(DOMAIN).pot +# has changed. Possible values are "yes" and "no". Set this to no if +# the POT file is checked in the repository and the version control +# program ignores timestamps. +PO_DEPENDS_ON_POT = yes + +# This tells whether or not to forcibly update $(DOMAIN).pot and +# regenerate PO files on "make dist". Possible values are "yes" and +# "no". Set this to no if the POT file and PO files are maintained +# externally. +DIST_DEPENDS_ON_UPDATE_PO = yes diff --git a/goaccess++/po/POTFILES b/goaccess++/po/POTFILES new file mode 100644 index 0000000..3a8dac9 --- /dev/null +++ b/goaccess++/po/POTFILES @@ -0,0 +1 @@ + ../src/labels.h diff --git a/goaccess++/po/POTFILES.in b/goaccess++/po/POTFILES.in new file mode 100644 index 0000000..99bde5c --- /dev/null +++ b/goaccess++/po/POTFILES.in @@ -0,0 +1,2 @@ +# List of source files which contain translatable strings. +src/labels.h diff --git a/goaccess++/po/Rules-quot b/goaccess++/po/Rules-quot new file mode 100644 index 0000000..af52487 --- /dev/null +++ b/goaccess++/po/Rules-quot @@ -0,0 +1,47 @@ +# Special Makefile rules for English message catalogs with quotation marks. + +DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot + +.SUFFIXES: .insert-header .po-update-en + +en@quot.po-create: + $(MAKE) en@quot.po-update +en@boldquot.po-create: + $(MAKE) en@boldquot.po-update + +en@quot.po-update: en@quot.po-update-en +en@boldquot.po-update: en@boldquot.po-update-en + +.insert-header.po-update-en: + @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ + if test "$(PACKAGE)" = "gettext"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ + tmpdir=`pwd`; \ + echo "$$lang:"; \ + ll=`echo $$lang | sed -e 's/@.*//'`; \ + LC_ALL=C; export LC_ALL; \ + cd $(srcdir); \ + if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) sed -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ + if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ + rm -f $$tmpdir/$$lang.new.po; \ + else \ + if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ + :; \ + else \ + echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ + exit 1; \ + fi; \ + fi; \ + else \ + echo "creation of $$lang.po failed!" 1>&2; \ + rm -f $$tmpdir/$$lang.new.po; \ + fi + +en@quot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header + +en@boldquot.insert-header: insert-header.sin + sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header + +mostlyclean: mostlyclean-quot +mostlyclean-quot: + rm -f *.insert-header diff --git a/goaccess++/po/boldquot.sed b/goaccess++/po/boldquot.sed new file mode 100644 index 0000000..4b937aa --- /dev/null +++ b/goaccess++/po/boldquot.sed @@ -0,0 +1,10 @@ +s/"\([^"]*\)"/“\1”/g +s/`\([^`']*\)'/‘\1’/g +s/ '\([^`']*\)' / ‘\1’ /g +s/ '\([^`']*\)'$/ ‘\1’/g +s/^'\([^`']*\)' /‘\1’ /g +s/“”/""/g +s/“/“/g +s/”/”/g +s/‘/‘/g +s/’/’/g diff --git a/goaccess++/po/en@boldquot.header b/goaccess++/po/en@boldquot.header new file mode 100644 index 0000000..fedb6a0 --- /dev/null +++ b/goaccess++/po/en@boldquot.header @@ -0,0 +1,25 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# +# This catalog furthermore displays the text between the quotation marks in +# bold face, assuming the VT100/XTerm escape sequences. +# diff --git a/goaccess++/po/en@quot.header b/goaccess++/po/en@quot.header new file mode 100644 index 0000000..a9647fc --- /dev/null +++ b/goaccess++/po/en@quot.header @@ -0,0 +1,22 @@ +# All this catalog "translates" are quotation characters. +# The msgids must be ASCII and therefore cannot contain real quotation +# characters, only substitutes like grave accent (0x60), apostrophe (0x27) +# and double quote (0x22). These substitutes look strange; see +# http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html +# +# This catalog translates grave accent (0x60) and apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019). +# It also translates pairs of apostrophe (0x27) to +# left single quotation mark (U+2018) and right single quotation mark (U+2019) +# and pairs of quotation mark (0x22) to +# left double quotation mark (U+201C) and right double quotation mark (U+201D). +# +# When output to an UTF-8 terminal, the quotation characters appear perfectly. +# When output to an ISO-8859-1 terminal, the single quotation marks are +# transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to +# grave/acute accent (by libiconv), and the double quotation marks are +# transliterated to 0x22. +# When output to an ASCII terminal, the single quotation marks are +# transliterated to apostrophes, and the double quotation marks are +# transliterated to 0x22. +# diff --git a/goaccess++/po/es.gmo b/goaccess++/po/es.gmo new file mode 100644 index 0000000..7b16262 Binary files /dev/null and b/goaccess++/po/es.gmo differ diff --git a/goaccess++/po/es.po b/goaccess++/po/es.po new file mode 100644 index 0000000..2b5261a --- /dev/null +++ b/goaccess++/po/es.po @@ -0,0 +1,902 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Goaccess\n" +"Report-Msgid-Bugs-To: hello@goaccess.io\n" +"POT-Creation-Date: 2018-11-22 23:38-0600\n" +"PO-Revision-Date: 2017-08-04 13:00-0300\n" +"Last-Translator: Enrique Becerra <kabeza@gmail.com>\n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.4\n" + +#: src/labels.h:40 +msgid "en" +msgstr "es" + +#: src/labels.h:43 +msgid "Exp. Panel" +msgstr "Exp. Panel" + +#: src/labels.h:44 +msgid "Help" +msgstr "Ayuda" + +#: src/labels.h:45 +msgid "Quit" +msgstr "Salir" + +#: src/labels.h:46 +msgid "Total" +msgstr "Total" + +#: src/labels.h:49 +msgid "[x] ASC [ ] DESC" +msgstr "[x] ASC [ ] DESC" + +#: src/labels.h:50 +msgid "[ ] ASC [x] DESC" +msgstr "[ ] ASC [x] DESC" + +#: src/labels.h:53 +#, c-format +msgid "[Active Panel: %1$s]" +msgstr "[Panel Activo: %1$s]" + +#: src/labels.h:54 +msgid "[q]uit GoAccess" +msgstr "[q]Salir GoAccess" + +#: src/labels.h:55 +msgid "[?] Help [Enter] Exp. Panel" +msgstr "[?] Ayuda [Enter] Exp. Panel" + +#: src/labels.h:56 +msgid "Dashboard" +msgstr "Panel de Control" + +#: src/labels.h:57 +msgid "Dashboard - Overall Analyzed Requests" +msgstr "Panel de Control - Peticiones Analizadas En General" + +#: src/labels.h:58 +msgid "Overall Analyzed Requests" +msgstr "Peticiones Analizadas en General" + +#: src/labels.h:60 src/labels.h:81 +msgid "Tx. Amount" +msgstr "" + +#: src/labels.h:61 +msgid "Date/Time" +msgstr "Fecha/Hora" + +#: src/labels.h:62 +msgid "Excl. IP Hits" +msgstr "Accesos IP Excl." + +#: src/labels.h:63 +msgid "Failed Requests" +msgstr "Peticiones Fallidas" + +#: src/labels.h:64 +msgid "Init. Proc. Time" +msgstr "Hora Inicio Proc." + +#: src/labels.h:65 +msgid "Log Size" +msgstr "Tamaño Log" + +#: src/labels.h:66 +msgid "Log Source" +msgstr "Origen de Log" + +#: src/labels.h:67 src/labels.h:174 +msgid "Referrers" +msgstr "Referidos" + +#: src/labels.h:68 +msgid "Total Requests" +msgstr "Peticiones Totales" + +#: src/labels.h:69 +msgid "Static Files" +msgstr "Archivos Estaticos" + +#: src/labels.h:70 src/labels.h:146 +msgid "Not Found" +msgstr "No Encontrado" + +#: src/labels.h:71 +#, fuzzy +msgid "Requested Files" +msgstr "Archivos Requeridos (URLs)" + +#: src/labels.h:72 +msgid "Unique Visitors" +msgstr "Visitantes Unicos" + +#: src/labels.h:73 +msgid "Valid Requests" +msgstr "Peticiones Validas" + +#: src/labels.h:76 +msgid "Hits" +msgstr "Hits" + +#: src/labels.h:77 +msgid "h%" +msgstr "h%" + +#: src/labels.h:78 src/labels.h:104 +msgid "Visitors" +msgstr "Visitantes" + +#: src/labels.h:79 +msgid "Vis." +msgstr "Vis." + +#: src/labels.h:80 +msgid "v%" +msgstr "v%" + +#: src/labels.h:82 +msgid "Avg. T.S." +msgstr "Prom. T.S." + +#: src/labels.h:83 +msgid "Cum. T.S." +msgstr "Cum. T.S." + +#: src/labels.h:84 +msgid "Max. T.S." +msgstr "Max. T.S." + +#: src/labels.h:85 +msgid "Method" +msgstr "Metodo" + +#: src/labels.h:86 +msgid "Mtd" +msgstr "Mtd" + +#: src/labels.h:87 +msgid "Protocol" +msgstr "Protocolo" + +#: src/labels.h:88 +msgid "Proto" +msgstr "Proto" + +#: src/labels.h:89 +msgid "City" +msgstr "Ciudad" + +#: src/labels.h:90 +msgid "Country" +msgstr "Pais" + +#: src/labels.h:91 +msgid "Hostname" +msgstr "Hostname" + +#: src/labels.h:92 +msgid "Data" +msgstr "Datos" + +#: src/labels.h:94 +msgid "Hits/Visitors" +msgstr "Hits/Visitas" + +#: src/labels.h:98 +msgid "Unique visitors per day" +msgstr "Visitantes unicos por dia" + +#: src/labels.h:100 +msgid "Unique visitors per day - Including spiders" +msgstr "Visitantes unicos por dia - Incluyendo M.Busqueda" + +#: src/labels.h:102 +msgid "Hits having the same IP, date and agent are a unique visit." +msgstr "Hits con el mismo IP, fecha y agente son unica visita" + +#: src/labels.h:107 +msgid "Requested Files (URLs)" +msgstr "Archivos Requeridos (URLs)" + +#: src/labels.h:109 +msgid "Top requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "Peticiones Top ordenadas por hits [, avgts, cumts, maxts, mthd, proto]" + +#: src/labels.h:111 +msgid "Requests" +msgstr "Peticiones" + +#: src/labels.h:114 src/labels.h:118 +msgid "Static Requests" +msgstr "Peticiones Estaticas" + +#: src/labels.h:116 +msgid "Top static requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" +"Peticiones estaticas top ordenadas por hits [, avgts, cumts, maxts, mthd, " +"proto]" + +#: src/labels.h:121 +msgid "Time Distribution" +msgstr "Distribucion Horaria" + +#: src/labels.h:123 +msgid "Data sorted by hour [, avgts, cumts, maxts]" +msgstr "Datos ordenados por hora [, avgts, cumts, maxts]" + +#: src/labels.h:125 +msgid "Time" +msgstr "Hora" + +#: src/labels.h:128 src/labels.h:132 +msgid "Virtual Hosts" +msgstr "Hosts Virtuales" + +#: src/labels.h:130 src/labels.h:137 +msgid "Data sorted by hits [, avgts, cumts, maxts]" +msgstr "Datos ordenados por hits [, avgts, cumts, maxts]" + +#: src/labels.h:135 +msgid "Remote User (HTTP authentication)" +msgstr "Usuario Remoto (Autenticacion HTTP)" + +#: src/labels.h:139 +msgid "Remote User" +msgstr "Usuario Remoto" + +#: src/labels.h:142 +msgid "Not Found URLs (404s)" +msgstr "URLs no encontradas (404)" + +#: src/labels.h:144 +msgid "Top not found URLs sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" +"URLs no encontradas top ordenadas por hits [, avgts, cumts, maxts, mthd, " +"proto]" + +#: src/labels.h:149 +msgid "Visitor Hostnames and IPs" +msgstr "Hosts e IPs de los Visitantes" + +#: src/labels.h:151 +msgid "Top visitor hosts sorted by hits [, avgts, cumts, maxts]" +msgstr "Hosts de visitante top ordenado por hits [, avgts, cumts, maxts]" + +#: src/labels.h:153 +msgid "Hosts" +msgstr "Hosts" + +#: src/labels.h:156 +msgid "Operating Systems" +msgstr "Sistemas Operativos" + +#: src/labels.h:158 +msgid "Top Operating Systems sorted by hits [, avgts, cumts, maxts]" +msgstr "Sistemas Operativos top ordenados por hits [, avgts, cumts, maxts]" + +#: src/labels.h:160 +msgid "OS" +msgstr "SO" + +#: src/labels.h:163 src/labels.h:167 +msgid "Browsers" +msgstr "Navegadores" + +#: src/labels.h:165 +msgid "Top Browsers sorted by hits [, avgts, cumts, maxts]" +msgstr "Navegadores top ordenados por hits [, avgts, cumts, maxts]" + +#: src/labels.h:170 +msgid "Referrers URLs" +msgstr "URLs Referidos" + +#: src/labels.h:172 +msgid "Top Requested Referrers sorted by hits [, avgts, cumts, maxts]" +msgstr "Peticiones top de referidos ordenadas por hits [, avgts, cumts, maxts]" + +#: src/labels.h:177 src/labels.h:181 +msgid "Referring Sites" +msgstr "Sitios Referidos" + +#: src/labels.h:179 +msgid "Top Referring Sites sorted by hits [, avgts, cumts, maxts]" +msgstr "Sitios Referidos top ordenados por hits [, avgts, cumts, maxts]" + +#: src/labels.h:184 +msgid "Keyphrases from Google's search engine" +msgstr "Frases de busqueda de motor de busqueda Google" + +#: src/labels.h:186 +msgid "Top Keyphrases sorted by hits [, avgts, cumts, maxts]" +msgstr "Frases de busqueda top ordenadas por hits [, avgts, cumts, maxts]" + +#: src/labels.h:188 +msgid "Keyphrases" +msgstr "Frases Clave" + +#: src/labels.h:191 src/labels.h:195 +msgid "Geo Location" +msgstr "Geo Localizacion" + +#: src/labels.h:193 +msgid "Continent > Country sorted by unique hits [, avgts, cumts, maxts]" +msgstr "Continente > Pais ordenado por hits unicos [, avgts, cumts, maxts]" + +#: src/labels.h:198 +msgid "HTTP Status Codes" +msgstr "Codigos de Estado HTTP" + +#: src/labels.h:200 +msgid "Top HTTP Status Codes sorted by hits [, avgts, cumts, maxts]" +msgstr "Codigos de Estado HTTP top ordenados por hits [, avgts, cumts, maxts]" + +#: src/labels.h:202 +msgid "Status Codes" +msgstr "Codigos de Estado" + +#: src/labels.h:206 +msgid "[ ] case sensitive" +msgstr "[ ] distinguir mayusculas" + +#: src/labels.h:208 +msgid "[x] case sensitive" +msgstr "[x] distinguir mayusculas" + +#: src/labels.h:210 +msgid "Regex allowed - ^g to cancel - TAB switch case" +msgstr "Permitido Regex - ^g para cancelar - TAB cambiar case" + +#: src/labels.h:212 +msgid "Find pattern in all views" +msgstr "Encontrar patron en todas las vistas" + +#: src/labels.h:216 +msgid "Log Format Configuration" +msgstr "Configuracion de Formato de Log" + +#: src/labels.h:218 +msgid "[SPACE] to toggle - [ENTER] to proceed - [q] to quit" +msgstr "[ESPACIO] para alternar - [ENTER] para proceder - [q] para salir" + +#: src/labels.h:220 +msgid "Log Format - [c] to add/edit format" +msgstr "Formato de Log - [c] para agregar/editar formato" + +#: src/labels.h:222 +msgid "Date Format - [d] to add/edit format" +msgstr "Formato de Fecha - [d] para agregar/editar formato" + +#: src/labels.h:224 +msgid "Time Format - [t] to add/edit format" +msgstr "Formato de Hora - [t] para agregar/editar formato" + +#: src/labels.h:226 src/labels.h:230 +msgid "[UP/DOWN] to scroll - [q] to close window" +msgstr "[ARRIBA/ABAJO] para scrollear - [q] para cerrar ventana" + +#: src/labels.h:232 +#, c-format +msgid "User Agents for %1$s" +msgstr "Agentes de Usuario para %1$s" + +#: src/labels.h:236 +msgid "Scheme Configuration" +msgstr "Configuracion de Esquema" + +#: src/labels.h:238 +msgid "[ENTER] to use scheme - [q]uit" +msgstr "[ENTER] para usar esquema - [q]Salir" + +#: src/labels.h:242 +msgid "Sort active module by" +msgstr "Ordenar modulo activo por" + +#: src/labels.h:244 +msgid "[ENTER] select - [TAB] sort - [q]uit" +msgstr "[ENTER] seleccionar - [TAB] ordenar - [q]Salir" + +#: src/labels.h:248 +msgid "GoAccess Quick Help" +msgstr "Ayuda Rapida de GoAccess" + +#: src/labels.h:250 +msgid "[UP/DOWN] to scroll - [q] to quit" +msgstr "[ARRIBA/ABAJO] para scrollear - [q] para salir" + +#: src/labels.h:254 +msgid "Built using Tokyo Cabinet on-disk B+ Tree." +msgstr "Construido usando Tokyo Cabinet on-disk B+ Tree." + +#: src/labels.h:256 +msgid "Built using Tokyo Cabinet in-memory hash database." +msgstr "Construido usando Tokyo Cabinet in-memory hash database." + +#: src/labels.h:258 +msgid "Built using the default in-memory hash database." +msgstr "Construido usando base de datos hash por defecto en-memoria" + +#: src/labels.h:262 +msgid "Format Errors - Verify your log/date/time format" +msgstr "Errores de Formato - Verifique su formato de log/fecha/hora" + +#: src/labels.h:264 +msgid "No date format was found on your conf file." +msgstr "No se encontro formato de fecha en su archivo de configuracion" + +#: src/labels.h:266 +msgid "No log format was found on your conf file." +msgstr "No se encontro formato de log en su archivo de configuracion" + +#: src/labels.h:268 +msgid "No time format was found on your conf file." +msgstr "No se encontro formato de hora en su archivo de configuracion" + +#: src/labels.h:270 +msgid "No default config file found." +msgstr "No se encontro archivo de configuracion por defecto." + +#: src/labels.h:272 +msgid "You may specify one with" +msgstr "Ud. puede especificar un ancho" + +#: src/labels.h:274 +msgid "producing the following errors" +msgstr "produciendo los siguientes errores" + +#: src/labels.h:276 +#, c-format +msgid "Parsed %1$d lines" +msgstr "Analizadas %1$d lineas" + +#: src/labels.h:278 +msgid "Please report it by opening an issue on GitHub" +msgstr "Por favor avise abriendo un issue en GitHub" + +#: src/labels.h:280 +msgid "Select a time format." +msgstr "Elija un formato de hora." + +#: src/labels.h:282 +msgid "Select a date format." +msgstr "Elija un formato de fecha." + +#: src/labels.h:284 +msgid "Select a log format." +msgstr "Elija un formato de log." + +#: src/labels.h:286 +#, c-format +msgid "'%1$s' panel is disabled" +msgstr "'%1$s' panel esta desactivado" + +#: src/labels.h:290 +msgid "For more details visit" +msgstr "Para mas detalles visite" + +#: src/labels.h:292 +msgid "Last Updated" +msgstr "Ultima actualizacion" + +#: src/labels.h:294 +msgid "WebSocket server ready to accept new client connections" +msgstr "Servidor WebSocket listo para aceptar nuevas conexiones de clientes" + +#: src/labels.h:297 +msgid "The following options can also be supplied to the command" +msgstr "Las siguientes opciones pueden ser ademas suplirse en el comando" + +#: src/labels.h:299 +msgid "Examples can be found by running" +msgstr "Ejemplos pueden encontrarse ejecutando" + +#: src/labels.h:302 +msgid "Server Statistics" +msgstr "Estadisticas de Servidor" + +#: src/labels.h:304 +msgid "Theme" +msgstr "Skin" + +#: src/labels.h:306 +msgid "Dark Gray" +msgstr "Gris Oscuro" + +#: src/labels.h:308 +msgid "Bright" +msgstr "Clara" + +#: src/labels.h:310 +msgid "Dark Blue" +msgstr "Azul Oscuro" + +#: src/labels.h:312 +#, fuzzy +msgid "Dark Purple" +msgstr "Azul Oscuro" + +#: src/labels.h:314 +msgid "Panels" +msgstr "Paneles" + +#: src/labels.h:316 +msgid "Items per Page" +msgstr "Items por pagina" + +#: src/labels.h:318 +msgid "Tables" +msgstr "Tablas" + +#: src/labels.h:320 +msgid "Display Tables" +msgstr "Mostrar Tablas" + +#: src/labels.h:322 +msgid "Auto-Hide on Small Devices" +msgstr "Auto-ocultar en Pequeños Dispositivos" + +#: src/labels.h:324 +msgid "Automatically hide tables on small screen devices" +msgstr "Automaticamente ocultar tablas en pequeños dispositivos" + +#: src/labels.h:326 +msgid "Layout" +msgstr "Diseño" + +#: src/labels.h:328 +msgid "Horizontal" +msgstr "Horizontal" + +#: src/labels.h:330 +msgid "Vertical" +msgstr "Vertical" + +#: src/labels.h:332 +msgid "File Options" +msgstr "Opciones de Archivo" + +#: src/labels.h:334 +msgid "Export as JSON" +msgstr "Exportar como JSON" + +#: src/labels.h:336 +msgid "Panel Options" +msgstr "Opciones de Panel" + +#: src/labels.h:338 +msgid "Previous" +msgstr "Anterior" + +#: src/labels.h:340 +msgid "Next" +msgstr "Siguiente" + +#: src/labels.h:342 +msgid "First" +msgstr "" + +#: src/labels.h:344 +msgid "Last" +msgstr "" + +#: src/labels.h:346 +msgid "Chart Options" +msgstr "Opciones de Grafico" + +#: src/labels.h:348 +msgid "Chart" +msgstr "Grafico" + +#: src/labels.h:350 +msgid "Type" +msgstr "Tipo" + +#: src/labels.h:352 +msgid "Area Spline" +msgstr "Area Ranura" + +#: src/labels.h:354 +msgid "Bar" +msgstr "Bar" + +#: src/labels.h:356 +msgid "Plot Metric" +msgstr "Trazado" + +#: src/labels.h:358 +msgid "Table Columns" +msgstr "Columnas de Tabla" + +#: src/labels.h:362 +msgid "1xx Informational" +msgstr "1xx Informativo" + +#: src/labels.h:364 +msgid "2xx Success" +msgstr "2xx Exito" + +#: src/labels.h:366 +msgid "3xx Redirection" +msgstr "3xx Redireccion" + +#: src/labels.h:368 +msgid "4xx Client Errors" +msgstr "4xx Errores de Cliente" + +#: src/labels.h:370 +msgid "5xx Server Errors" +msgstr "5xx Errores de Servidor" + +#: src/labels.h:373 +msgid "100 - Continue: Server received the initial part of the request" +msgstr "100 - Continuar: Servidor recibio la parte inicial de la peticion" + +#: src/labels.h:375 +msgid "101 - Switching Protocols: Client asked to switch protocols" +msgstr "101 - Cambiando Protocolos: Cliente pidio cambiar protocolos" + +#: src/labels.h:377 +msgid "200 - OK: The request sent by the client was successful" +msgstr "200 - OK: La peticion enviada por el cliente fue exitosa" + +#: src/labels.h:379 +msgid "201 - Created: The request has been fulfilled and created" +msgstr "201 - Creada: La peticion ha sido completada y creada" + +#: src/labels.h:381 +msgid "202 - Accepted: The request has been accepted for processing" +msgstr "202 - Aceptada: La peticion fue aceptada para procesar" + +#: src/labels.h:383 +msgid "203 - Non-authoritative Information: Response from a third party" +msgstr "203 - No-autoritario Informativo: Respuesta de una 3er. parte" + +#: src/labels.h:385 +msgid "204 - No Content: Request did not return any content" +msgstr "204 - Sin Contenido: Peticion no retorno ningun contenido" + +#: src/labels.h:387 +msgid "205 - Reset Content: Server asked the client to reset the document" +msgstr "" +"205 - Resetear Contenido: Servidor pidio al cliente resetear el documento" + +#: src/labels.h:389 +msgid "206 - Partial Content: The partial GET has been successful" +msgstr "206 - Contenido Parcial: el GET parcial fue exitoso" + +#: src/labels.h:391 +msgid "207 - Multi-Status: WebDAV; RFC 4918" +msgstr "207 - Multi-Estado: WebDAV; RFC 4918" + +#: src/labels.h:393 +msgid "208 - Already Reported: WebDAV; RFC 5842" +msgstr "208 - Ya Reportado: WebDAV; RFC 5842" + +#: src/labels.h:395 +msgid "300 - Multiple Choices: Multiple options for the resource" +msgstr "300 - Multiples Opciones: Multiples opciones para el recurso" + +#: src/labels.h:397 +msgid "301 - Moved Permanently: Resource has permanently moved" +msgstr "301 - Movido Permanente: Recurso ha sido permanentemente movido" + +#: src/labels.h:399 +msgid "302 - Moved Temporarily (redirect)" +msgstr "302 - Movido Temporalmente (redireccion)" + +#: src/labels.h:401 +msgid "303 - See Other Document: The response is at a different URI" +msgstr "303 - Ver Otro Documento: La respuesta es en una URI diferente" + +#: src/labels.h:403 +msgid "304 - Not Modified: Resource has not been modified" +msgstr "304 - No Modificado: Recurso no ha sido modificado" + +#: src/labels.h:405 +msgid "305 - Use Proxy: Can only be accessed through the proxy" +msgstr "305 - Usar Proxy: Puede ser accedido solo a traves de proxy" + +#: src/labels.h:407 +msgid "307 - Temporary Redirect: Resource temporarily moved" +msgstr "307 - Redireccion Temporal: Recurso movido temporalmente" + +#: src/labels.h:409 +msgid "400 - Bad Request: The syntax of the request is invalid" +msgstr "400 - Peticion Mala: La sintaxis de la peticion es invalida" + +#: src/labels.h:411 +msgid "401 - Unauthorized: Request needs user authentication" +msgstr "401 - Sin Autorizacion: Peticion necesita autenticacion de usuario" + +#: src/labels.h:413 +msgid "402 - Payment Required" +msgstr "402 - Pago Requerido" + +#: src/labels.h:415 +msgid "403 - Forbidden: Server is refusing to respond to it" +msgstr "403 - Prohibido: Servidor esta rechazando respuesta" + +#: src/labels.h:417 +msgid "404 - Not Found: Requested resource could not be found" +msgstr "404 - No Encontrado: Peticion de recurso no pudo encontrarse" + +#: src/labels.h:419 +msgid "405 - Method Not Allowed: Request method not supported" +msgstr "405 - Metodo No Permitido: Metodo de Peticion no soportado" + +#: src/labels.h:421 +msgid "406 - Not Acceptable" +msgstr "406 - No Aceptable" + +#: src/labels.h:423 +msgid "407 - Proxy Authentication Required" +msgstr "407 - Autenticacion de Proxy Requerida" + +#: src/labels.h:425 +msgid "408 - Request Timeout: Server timed out waiting for the request" +msgstr "408 - Timeout de Peticion: Tiempo agotado de espera para la solicitud" + +#: src/labels.h:427 +msgid "409 - Conflict: Conflict in the request" +msgstr "409 - Conflicto: Conflicto en la peticion" + +#: src/labels.h:429 +msgid "410 - Gone: Resource requested is no longer available" +msgstr "410 - Fue: Recurso requerido no esta mas disponible" + +#: src/labels.h:431 +msgid "411 - Length Required: Invalid Content-Length" +msgstr "411 - Longitud Requerida: Content-Length Invalido" + +#: src/labels.h:433 +msgid "412 - Precondition Failed: Server does not meet preconditions" +msgstr "412 - Precondicion Fallida: Servidor no cumple precondiciones" + +#: src/labels.h:435 +msgid "413 - Payload Too Large" +msgstr "413 - Carga Util Demasiado larga" + +#: src/labels.h:437 +msgid "414 - Request-URI Too Long" +msgstr "414 - Request-URI demasiado larga" + +#: src/labels.h:439 +msgid "415 - Unsupported Media Type: Media type is not supported" +msgstr "415 - Tipo de medios no soportado: El tipo de medios no es soportado" + +#: src/labels.h:441 +msgid "416 - Requested Range Not Satisfiable: Cannot supply that portion" +msgstr "416 - Rango requerido no satisfacible: No puede proveer esa porcion" + +#: src/labels.h:443 +msgid "417 - Expectation Failed" +msgstr "417 - Expectativa Fallida" + +#: src/labels.h:445 +msgid "421 - Misdirected Request" +msgstr "" + +#: src/labels.h:447 +msgid "422 - Unprocessable Entity due to semantic errors: WebDAV" +msgstr "" + +#: src/labels.h:449 +msgid "423 - The resource that is being accessed is locked" +msgstr "" + +#: src/labels.h:451 +msgid "424 - Failed Dependency: WebDAV" +msgstr "" + +#: src/labels.h:453 +msgid "426 - Upgrade Required: Client should switch to a different protocol" +msgstr "" + +#: src/labels.h:455 +#, fuzzy +msgid "428 - Precondition Required" +msgstr "402 - Pago Requerido" + +#: src/labels.h:457 +msgid "429 - Too Many Requests: The user has sent too many requests" +msgstr "" + +#: src/labels.h:459 +#, fuzzy +msgid "431 - Request Header Fields Too Large" +msgstr "494 - (Nginx) Cabecera de Peticion demasiada larga" + +#: src/labels.h:461 +msgid "451 - Unavailable For Legal Reasons" +msgstr "" + +#: src/labels.h:463 +msgid "444 - (Nginx) Connection closed without sending any headers" +msgstr "444 - (Nginx) Conexion cerrada sin enviar cabeceras" + +#: src/labels.h:465 +msgid "494 - (Nginx) Request Header Too Large" +msgstr "494 - (Nginx) Cabecera de Peticion demasiada larga" + +#: src/labels.h:467 +msgid "495 - (Nginx) SSL client certificate error" +msgstr "495 - (Nginx) Cliente SSL certificado erroneo" + +#: src/labels.h:469 +msgid "496 - (Nginx) Client didn't provide certificate" +msgstr "496 - (Nginx) Client no proveyo certificado" + +#: src/labels.h:471 +msgid "497 - (Nginx) HTTP request sent to HTTPS port" +msgstr "497 - (Nginx) Peticion HTTP enviada a puerto HTTPS" + +#: src/labels.h:473 +msgid "499 - (Nginx) Connection closed by client while processing request" +msgstr "499 - (Nginx) Conexion cerrada por cliente mientras procesaba peticion" + +#: src/labels.h:475 +msgid "500 - Internal Server Error" +msgstr "500 - Error Interno de Servidor" + +#: src/labels.h:477 +msgid "501 - Not Implemented" +msgstr "501 - No Implementado" + +#: src/labels.h:479 +msgid "502 - Bad Gateway: Received an invalid response from the upstream" +msgstr "502 - Entrada Erronea: Recibio respuesta invalida" + +#: src/labels.h:481 +msgid "503 - Service Unavailable: The server is currently unavailable" +msgstr "" +"503 - Servicio no disponible: El servidor actualmente no esta disponible" + +#: src/labels.h:483 +msgid "504 - Gateway Timeout: The upstream server failed to send request" +msgstr "" +"504 - Timeout de Gateway: El servidor upstream fallo al enviar peticion" + +#: src/labels.h:485 +msgid "505 - HTTP Version Not Supported" +msgstr "505 - Version HTTP no soportada" + +#: src/labels.h:487 +msgid "520 - CloudFlare - Web server is returning an unknown error" +msgstr "520 - CloudFlare - El servidor esta retornando un error desconocido" + +#: src/labels.h:489 +msgid "521 - CloudFlare - Web server is down" +msgstr "521 - CloudFlare - Servidor Web caido" + +#: src/labels.h:491 +msgid "522 - CloudFlare - Connection timed out" +msgstr "522 - CloudFlare - Tiempo de espera de conexion agotado " + +#: src/labels.h:493 +msgid "523 - CloudFlare - Origin is unreachable" +msgstr "523 - CloudFlare - Origen es inaccesible" + +#: src/labels.h:495 +msgid "524 - CloudFlare - A timeout occurred" +msgstr "524 - CloudFlare - Ocurrio cese de tiempo" + +#~ msgid "Bandwidth" +#~ msgstr "Ancho de Banda" + +#~ msgid "Unique Files" +#~ msgstr "Archivos Unicos" + +#~ msgid "Unique 404" +#~ msgstr "404 Unico" diff --git a/goaccess++/po/fr.gmo b/goaccess++/po/fr.gmo new file mode 100644 index 0000000..c90f9b9 Binary files /dev/null and b/goaccess++/po/fr.gmo differ diff --git a/goaccess++/po/fr.po b/goaccess++/po/fr.po new file mode 100644 index 0000000..e89e090 --- /dev/null +++ b/goaccess++/po/fr.po @@ -0,0 +1,904 @@ +# This file is distributed under the same license as the goaccess package. +# Nicolas P <np>, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: goaccess 1.2\n" +"Report-Msgid-Bugs-To: hello@goaccess.io\n" +"POT-Creation-Date: 2018-11-22 23:38-0600\n" +"PO-Revision-Date: 2017-04-03 09:43+0200\n" +"Last-Translator: Nicolas P <np.pascal@gmail.com>\n" +"Language-Team: français\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Gtranslator 2.91.7\n" + +#: src/labels.h:40 +msgid "en" +msgstr "fr" + +#: src/labels.h:43 +msgid "Exp. Panel" +msgstr "Dev. Panneau" + +#: src/labels.h:44 +msgid "Help" +msgstr "Aide" + +#: src/labels.h:45 +msgid "Quit" +msgstr "Quitter" + +#: src/labels.h:46 +msgid "Total" +msgstr "Total" + +#: src/labels.h:49 +msgid "[x] ASC [ ] DESC" +msgstr "[x] ASC [ ] DESC" + +#: src/labels.h:50 +msgid "[ ] ASC [x] DESC" +msgstr "[ ] ASC [x] DESC" + +#: src/labels.h:53 +#, c-format +msgid "[Active Panel: %1$s]" +msgstr "" + +#: src/labels.h:54 +msgid "[q]uit GoAccess" +msgstr "" + +#: src/labels.h:55 +msgid "[?] Help [Enter] Exp. Panel" +msgstr "" + +#: src/labels.h:56 +msgid "Dashboard" +msgstr "Tableau de bord" + +#: src/labels.h:57 +msgid "Dashboard - Overall Analyzed Requests" +msgstr "Tableau de bord - Requêtes analysées, vue d'ensemble" + +#: src/labels.h:58 +msgid "Overall Analyzed Requests" +msgstr "Requêtes analysées, vue d'ensemble" + +#: src/labels.h:60 src/labels.h:81 +msgid "Tx. Amount" +msgstr "" + +#: src/labels.h:61 +msgid "Date/Time" +msgstr "Date/Heure" + +#: src/labels.h:62 +msgid "Excl. IP Hits" +msgstr "Excl. IP Hits" + +#: src/labels.h:63 +msgid "Failed Requests" +msgstr "Requêtes échouées" + +#: src/labels.h:64 +msgid "Init. Proc. Time" +msgstr "Init. Proc. Time" + +#: src/labels.h:65 +msgid "Log Size" +msgstr "Taille du log" + +#: src/labels.h:66 +msgid "Log Source" +msgstr "Fichier de log" + +#: src/labels.h:67 src/labels.h:174 +msgid "Referrers" +msgstr "Origine" + +#: src/labels.h:68 +msgid "Total Requests" +msgstr "Requêtes totales" + +#: src/labels.h:69 +msgid "Static Files" +msgstr "Fichiers statiques" + +#: src/labels.h:70 src/labels.h:146 +msgid "Not Found" +msgstr "Non Trouvé" + +#: src/labels.h:71 +#, fuzzy +msgid "Requested Files" +msgstr "Fichiers demandés (URLs)" + +#: src/labels.h:72 +msgid "Unique Visitors" +msgstr "Visiteurs uniques" + +#: src/labels.h:73 +msgid "Valid Requests" +msgstr "Requêtes valides" + +#: src/labels.h:76 +msgid "Hits" +msgstr "Hits" + +#: src/labels.h:77 +msgid "h%" +msgstr "" + +#: src/labels.h:78 src/labels.h:104 +msgid "Visitors" +msgstr "Visiteurs" + +#: src/labels.h:79 +msgid "Vis." +msgstr "Vis." + +#: src/labels.h:80 +msgid "v%" +msgstr "" + +#: src/labels.h:82 +msgid "Avg. T.S." +msgstr "Avg. T.S." + +#: src/labels.h:83 +msgid "Cum. T.S." +msgstr "Cum. T.S." + +#: src/labels.h:84 +msgid "Max. T.S." +msgstr "Max. T.S." + +#: src/labels.h:85 +msgid "Method" +msgstr "Méthode" + +#: src/labels.h:86 +msgid "Mtd" +msgstr "Mtd" + +#: src/labels.h:87 +msgid "Protocol" +msgstr "Protocole" + +#: src/labels.h:88 +msgid "Proto" +msgstr "Proto" + +#: src/labels.h:89 +msgid "City" +msgstr "Ville" + +#: src/labels.h:90 +msgid "Country" +msgstr "Pays" + +#: src/labels.h:91 +msgid "Hostname" +msgstr "Nom d'hôte" + +#: src/labels.h:92 +msgid "Data" +msgstr "Données" + +#: src/labels.h:94 +#, fuzzy +msgid "Hits/Visitors" +msgstr "Visiteurs" + +#: src/labels.h:98 +msgid "Unique visitors per day" +msgstr "Visiteurs uniques par jour" + +#: src/labels.h:100 +msgid "Unique visitors per day - Including spiders" +msgstr "Visiteurs uniques/jour - Y compris bots" + +#: src/labels.h:102 +msgid "Hits having the same IP, date and agent are a unique visit." +msgstr "" +"Les hits depuis la même IP, date et user-agent comptent comme visite unique" + +#: src/labels.h:107 +msgid "Requested Files (URLs)" +msgstr "Fichiers demandés (URLs)" + +#: src/labels.h:109 +msgid "Top requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "Top des requêtes trié par hits [, avgts, cumts, maxts, mthd, proto]" + +#: src/labels.h:111 +msgid "Requests" +msgstr "Requêtes" + +#: src/labels.h:114 src/labels.h:118 +msgid "Static Requests" +msgstr "Requêtes statiques" + +#: src/labels.h:116 +msgid "Top static requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" +"Top des requêtes statiques trié par hits [, avgts, cumts, maxts, mthd, proto]" + +#: src/labels.h:121 +msgid "Time Distribution" +msgstr "Distribution temporelle" + +#: src/labels.h:123 +msgid "Data sorted by hour [, avgts, cumts, maxts]" +msgstr "Données triées par heure [, avgts, cumts, maxts]" + +#: src/labels.h:125 +msgid "Time" +msgstr "Temps" + +#: src/labels.h:128 src/labels.h:132 +msgid "Virtual Hosts" +msgstr "Hôtes virtuels" + +#: src/labels.h:130 src/labels.h:137 +msgid "Data sorted by hits [, avgts, cumts, maxts]" +msgstr "Données triées par hits [, avgts, cumts, maxts]" + +#: src/labels.h:135 +msgid "Remote User (HTTP authentication)" +msgstr "Utilisateur distant (authentification HTTP)" + +#: src/labels.h:139 +msgid "Remote User" +msgstr "Remote Utilisateur" + +#: src/labels.h:142 +msgid "Not Found URLs (404s)" +msgstr "URLs Non trouvées (404s)" + +#: src/labels.h:144 +msgid "Top not found URLs sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" +"Top des URLs non trouvées trié par hits [, avgts, cumts, maxts, mthd, proto]" + +#: src/labels.h:149 +msgid "Visitor Hostnames and IPs" +msgstr "Nom de machine et IPs des visiteurs" + +#: src/labels.h:151 +msgid "Top visitor hosts sorted by hits [, avgts, cumts, maxts]" +msgstr "Top des visiteurs trié par hits [, avgts, cumts, maxts]" + +#: src/labels.h:153 +msgid "Hosts" +msgstr "Hôtes" + +#: src/labels.h:156 +msgid "Operating Systems" +msgstr "Systèmes d'exploitation" + +#: src/labels.h:158 +msgid "Top Operating Systems sorted by hits [, avgts, cumts, maxts]" +msgstr "Top des SE trié par hits [, avgts, cumts, maxts]" + +#: src/labels.h:160 +msgid "OS" +msgstr "SE" + +#: src/labels.h:163 src/labels.h:167 +msgid "Browsers" +msgstr "Navigateurs" + +#: src/labels.h:165 +msgid "Top Browsers sorted by hits [, avgts, cumts, maxts]" +msgstr "Top des Navigateurs trié par hits [, avgts, cumts, maxts]" + +#: src/labels.h:170 +msgid "Referrers URLs" +msgstr "URLs d'origine" + +#: src/labels.h:172 +msgid "Top Requested Referrers sorted by hits [, avgts, cumts, maxts]" +msgstr "Top des URLs d'origine trié par hits [, avgts, cumts, maxts]" + +#: src/labels.h:177 src/labels.h:181 +msgid "Referring Sites" +msgstr "Sites d'origine" + +#: src/labels.h:179 +msgid "Top Referring Sites sorted by hits [, avgts, cumts, maxts]" +msgstr "Top des sites d'origine trié par hits [, avgts, cumts, maxts]" + +#: src/labels.h:184 +msgid "Keyphrases from Google's search engine" +msgstr "Mot-clés Google" + +#: src/labels.h:186 +msgid "Top Keyphrases sorted by hits [, avgts, cumts, maxts]" +msgstr "Top des Mot-clés trié par hits [, avgts, cumts, maxts]" + +#: src/labels.h:188 +msgid "Keyphrases" +msgstr "Mot-clés" + +#: src/labels.h:191 src/labels.h:195 +msgid "Geo Location" +msgstr "Géo Localisation" + +#: src/labels.h:193 +msgid "Continent > Country sorted by unique hits [, avgts, cumts, maxts]" +msgstr "Continent > Pays trié par hits unique [, avgts, cumts, maxts]" + +#: src/labels.h:198 +msgid "HTTP Status Codes" +msgstr "Status HTTP" + +#: src/labels.h:200 +msgid "Top HTTP Status Codes sorted by hits [, avgts, cumts, maxts]" +msgstr "Top des status HTTP trié par hits [, avgts, cumts, maxts]" + +#: src/labels.h:202 +msgid "Status Codes" +msgstr "Status HTTP" + +#: src/labels.h:206 +msgid "[ ] case sensitive" +msgstr "[ ] sensible à la casse" + +#: src/labels.h:208 +msgid "[x] case sensitive" +msgstr "[x] sensible à la casse" + +#: src/labels.h:210 +msgid "Regex allowed - ^g to cancel - TAB switch case" +msgstr "Regex OK - ^g pour annuler - TAB pour changer la casse" + +#: src/labels.h:212 +msgid "Find pattern in all views" +msgstr "Trouver tous les motifs dans toutes les vues" + +#: src/labels.h:216 +msgid "Log Format Configuration" +msgstr "" + +#: src/labels.h:218 +msgid "[SPACE] to toggle - [ENTER] to proceed - [q] to quit" +msgstr "" + +#: src/labels.h:220 +msgid "Log Format - [c] to add/edit format" +msgstr "" + +#: src/labels.h:222 +msgid "Date Format - [d] to add/edit format" +msgstr "" + +#: src/labels.h:224 +msgid "Time Format - [t] to add/edit format" +msgstr "" + +#: src/labels.h:226 src/labels.h:230 +msgid "[UP/DOWN] to scroll - [q] to close window" +msgstr "" + +#: src/labels.h:232 +#, c-format +msgid "User Agents for %1$s" +msgstr "" + +#: src/labels.h:236 +msgid "Scheme Configuration" +msgstr "" + +#: src/labels.h:238 +msgid "[ENTER] to use scheme - [q]uit" +msgstr "" + +#: src/labels.h:242 +msgid "Sort active module by" +msgstr "" + +#: src/labels.h:244 +msgid "[ENTER] select - [TAB] sort - [q]uit" +msgstr "" + +#: src/labels.h:248 +msgid "GoAccess Quick Help" +msgstr "" + +#: src/labels.h:250 +msgid "[UP/DOWN] to scroll - [q] to quit" +msgstr "" + +#: src/labels.h:254 +msgid "Built using Tokyo Cabinet on-disk B+ Tree." +msgstr "Construit sur le disque en arbre B+ en utilisant Tokyo Cabinet." + +#: src/labels.h:256 +msgid "Built using Tokyo Cabinet in-memory hash database." +msgstr "" +"Construit en mémoire avec une base de données de la table de hachage en " +"utilisant Tokyo Cabinet" + +#: src/labels.h:258 +msgid "Built using the default in-memory hash database." +msgstr "" +"Construit par défaut en mémoire avec une base de données de la table de " +"hachage" + +#: src/labels.h:262 +msgid "Format Errors - Verify your log/date/time format" +msgstr "Erreurs de format - Vérifiez votre format de journal / date / heure" + +#: src/labels.h:264 +msgid "No date format was found on your conf file." +msgstr "Aucun format de date n'a été trouvé sur votre fichier conf." + +#: src/labels.h:266 +msgid "No log format was found on your conf file." +msgstr "Aucun format de journal n'a été trouvé sur votre fichier conf." + +#: src/labels.h:268 +msgid "No time format was found on your conf file." +msgstr "Aucun format de journal n'a été trouvé sur votre fichier conf." + +#: src/labels.h:270 +msgid "No default config file found." +msgstr "Aucun fichier de configuration par défaut trouvé." + +#: src/labels.h:272 +msgid "You may specify one with" +msgstr "Vous pouvez en préciser un avec" + +#: src/labels.h:274 +msgid "producing the following errors" +msgstr "produisant les erreurs suivantes" + +#: src/labels.h:276 +#, c-format +msgid "Parsed %1$d lines" +msgstr "Analysé %1$d lignes" + +#: src/labels.h:278 +msgid "Please report it by opening an issue on GitHub" +msgstr "Si vous plaît, rapporter cela en ouvrant un probleme sur GitHub" + +#: src/labels.h:280 +msgid "Select a time format." +msgstr "" + +#: src/labels.h:282 +msgid "Select a date format." +msgstr "" + +#: src/labels.h:284 +msgid "Select a log format." +msgstr "" + +#: src/labels.h:286 +#, c-format +msgid "'%1$s' panel is disabled" +msgstr "" + +#: src/labels.h:290 +msgid "For more details visit" +msgstr "Pour plus de détails, visitez" + +#: src/labels.h:292 +msgid "Last Updated" +msgstr "Dernière mise à jour" + +#: src/labels.h:294 +msgid "WebSocket server ready to accept new client connections" +msgstr "WebSocket serveur prêt à accepter les nouvelles connexions client" + +#: src/labels.h:297 +msgid "The following options can also be supplied to the command" +msgstr "Les options suivantes peuvent également être fournies à la commande" + +#: src/labels.h:299 +msgid "Examples can be found by running" +msgstr "Des exemples peuvent être trouvés en cours d'exécution" + +#: src/labels.h:302 +msgid "Server Statistics" +msgstr "Statistiques du serveur" + +#: src/labels.h:304 +msgid "Theme" +msgstr "Thème" + +#: src/labels.h:306 +msgid "Dark Gray" +msgstr "Gris foncé" + +#: src/labels.h:308 +msgid "Bright" +msgstr "Brillant" + +#: src/labels.h:310 +msgid "Dark Blue" +msgstr "Bleu foncé" + +#: src/labels.h:312 +#, fuzzy +msgid "Dark Purple" +msgstr "Bleu foncé" + +#: src/labels.h:314 +msgid "Panels" +msgstr "Panneaux" + +#: src/labels.h:316 +msgid "Items per Page" +msgstr "Objets par page" + +#: src/labels.h:318 +msgid "Tables" +msgstr "Tableaux" + +#: src/labels.h:320 +msgid "Display Tables" +msgstr "Afficher les tableaux" + +#: src/labels.h:322 +msgid "Auto-Hide on Small Devices" +msgstr "Masquage-auto/Petits appareils" + +#: src/labels.h:324 +msgid "Automatically hide tables on small screen devices" +msgstr "" +"Masquer automatiquement les tableaux sur les appareils avec un petit écran" + +#: src/labels.h:326 +msgid "Layout" +msgstr "Disposition" + +#: src/labels.h:328 +msgid "Horizontal" +msgstr "Horizontal" + +#: src/labels.h:330 +msgid "Vertical" +msgstr "Verticale" + +#: src/labels.h:332 +msgid "File Options" +msgstr "Options de fichier" + +#: src/labels.h:334 +msgid "Export as JSON" +msgstr "Exporter en tant que JSON" + +#: src/labels.h:336 +msgid "Panel Options" +msgstr "Options du panneau" + +#: src/labels.h:338 +msgid "Previous" +msgstr "Précédent" + +#: src/labels.h:340 +msgid "Next" +msgstr "Suivant" + +#: src/labels.h:342 +msgid "First" +msgstr "" + +#: src/labels.h:344 +msgid "Last" +msgstr "" + +#: src/labels.h:346 +msgid "Chart Options" +msgstr "Options du graphique" + +#: src/labels.h:348 +msgid "Chart" +msgstr "Graphique" + +#: src/labels.h:350 +msgid "Type" +msgstr "Type" + +#: src/labels.h:352 +msgid "Area Spline" +msgstr "Courbe vectorielle" + +#: src/labels.h:354 +msgid "Bar" +msgstr "Barre" + +#: src/labels.h:356 +msgid "Plot Metric" +msgstr "Tracé métrique" + +#: src/labels.h:358 +msgid "Table Columns" +msgstr "Colonnes de tableau" + +#: src/labels.h:362 +msgid "1xx Informational" +msgstr "" + +#: src/labels.h:364 +msgid "2xx Success" +msgstr "" + +#: src/labels.h:366 +msgid "3xx Redirection" +msgstr "" + +#: src/labels.h:368 +msgid "4xx Client Errors" +msgstr "" + +#: src/labels.h:370 +msgid "5xx Server Errors" +msgstr "" + +#: src/labels.h:373 +msgid "100 - Continue: Server received the initial part of the request" +msgstr "" + +#: src/labels.h:375 +msgid "101 - Switching Protocols: Client asked to switch protocols" +msgstr "" + +#: src/labels.h:377 +msgid "200 - OK: The request sent by the client was successful" +msgstr "" + +#: src/labels.h:379 +msgid "201 - Created: The request has been fulfilled and created" +msgstr "" + +#: src/labels.h:381 +msgid "202 - Accepted: The request has been accepted for processing" +msgstr "" + +#: src/labels.h:383 +msgid "203 - Non-authoritative Information: Response from a third party" +msgstr "" + +#: src/labels.h:385 +msgid "204 - No Content: Request did not return any content" +msgstr "" + +#: src/labels.h:387 +msgid "205 - Reset Content: Server asked the client to reset the document" +msgstr "" + +#: src/labels.h:389 +msgid "206 - Partial Content: The partial GET has been successful" +msgstr "" + +#: src/labels.h:391 +msgid "207 - Multi-Status: WebDAV; RFC 4918" +msgstr "" + +#: src/labels.h:393 +msgid "208 - Already Reported: WebDAV; RFC 5842" +msgstr "" + +#: src/labels.h:395 +msgid "300 - Multiple Choices: Multiple options for the resource" +msgstr "" + +#: src/labels.h:397 +msgid "301 - Moved Permanently: Resource has permanently moved" +msgstr "" + +#: src/labels.h:399 +msgid "302 - Moved Temporarily (redirect)" +msgstr "" + +#: src/labels.h:401 +msgid "303 - See Other Document: The response is at a different URI" +msgstr "" + +#: src/labels.h:403 +msgid "304 - Not Modified: Resource has not been modified" +msgstr "" + +#: src/labels.h:405 +msgid "305 - Use Proxy: Can only be accessed through the proxy" +msgstr "" + +#: src/labels.h:407 +msgid "307 - Temporary Redirect: Resource temporarily moved" +msgstr "" + +#: src/labels.h:409 +msgid "400 - Bad Request: The syntax of the request is invalid" +msgstr "" + +#: src/labels.h:411 +msgid "401 - Unauthorized: Request needs user authentication" +msgstr "" + +#: src/labels.h:413 +msgid "402 - Payment Required" +msgstr "" + +#: src/labels.h:415 +msgid "403 - Forbidden: Server is refusing to respond to it" +msgstr "" + +#: src/labels.h:417 +msgid "404 - Not Found: Requested resource could not be found" +msgstr "" + +#: src/labels.h:419 +msgid "405 - Method Not Allowed: Request method not supported" +msgstr "" + +#: src/labels.h:421 +msgid "406 - Not Acceptable" +msgstr "" + +#: src/labels.h:423 +msgid "407 - Proxy Authentication Required" +msgstr "" + +#: src/labels.h:425 +msgid "408 - Request Timeout: Server timed out waiting for the request" +msgstr "" + +#: src/labels.h:427 +msgid "409 - Conflict: Conflict in the request" +msgstr "" + +#: src/labels.h:429 +msgid "410 - Gone: Resource requested is no longer available" +msgstr "" + +#: src/labels.h:431 +msgid "411 - Length Required: Invalid Content-Length" +msgstr "" + +#: src/labels.h:433 +msgid "412 - Precondition Failed: Server does not meet preconditions" +msgstr "" + +#: src/labels.h:435 +msgid "413 - Payload Too Large" +msgstr "" + +#: src/labels.h:437 +msgid "414 - Request-URI Too Long" +msgstr "" + +#: src/labels.h:439 +msgid "415 - Unsupported Media Type: Media type is not supported" +msgstr "" + +#: src/labels.h:441 +msgid "416 - Requested Range Not Satisfiable: Cannot supply that portion" +msgstr "" + +#: src/labels.h:443 +msgid "417 - Expectation Failed" +msgstr "" + +#: src/labels.h:445 +msgid "421 - Misdirected Request" +msgstr "" + +#: src/labels.h:447 +msgid "422 - Unprocessable Entity due to semantic errors: WebDAV" +msgstr "" + +#: src/labels.h:449 +msgid "423 - The resource that is being accessed is locked" +msgstr "" + +#: src/labels.h:451 +msgid "424 - Failed Dependency: WebDAV" +msgstr "" + +#: src/labels.h:453 +msgid "426 - Upgrade Required: Client should switch to a different protocol" +msgstr "" + +#: src/labels.h:455 +msgid "428 - Precondition Required" +msgstr "" + +#: src/labels.h:457 +msgid "429 - Too Many Requests: The user has sent too many requests" +msgstr "" + +#: src/labels.h:459 +msgid "431 - Request Header Fields Too Large" +msgstr "" + +#: src/labels.h:461 +msgid "451 - Unavailable For Legal Reasons" +msgstr "" + +#: src/labels.h:463 +msgid "444 - (Nginx) Connection closed without sending any headers" +msgstr "" + +#: src/labels.h:465 +msgid "494 - (Nginx) Request Header Too Large" +msgstr "" + +#: src/labels.h:467 +msgid "495 - (Nginx) SSL client certificate error" +msgstr "" + +#: src/labels.h:469 +msgid "496 - (Nginx) Client didn't provide certificate" +msgstr "" + +#: src/labels.h:471 +msgid "497 - (Nginx) HTTP request sent to HTTPS port" +msgstr "" + +#: src/labels.h:473 +msgid "499 - (Nginx) Connection closed by client while processing request" +msgstr "" + +#: src/labels.h:475 +msgid "500 - Internal Server Error" +msgstr "" + +#: src/labels.h:477 +msgid "501 - Not Implemented" +msgstr "" + +#: src/labels.h:479 +msgid "502 - Bad Gateway: Received an invalid response from the upstream" +msgstr "" + +#: src/labels.h:481 +msgid "503 - Service Unavailable: The server is currently unavailable" +msgstr "" + +#: src/labels.h:483 +msgid "504 - Gateway Timeout: The upstream server failed to send request" +msgstr "" + +#: src/labels.h:485 +msgid "505 - HTTP Version Not Supported" +msgstr "" + +#: src/labels.h:487 +msgid "520 - CloudFlare - Web server is returning an unknown error" +msgstr "" + +#: src/labels.h:489 +msgid "521 - CloudFlare - Web server is down" +msgstr "" + +#: src/labels.h:491 +msgid "522 - CloudFlare - Connection timed out" +msgstr "" + +#: src/labels.h:493 +msgid "523 - CloudFlare - Origin is unreachable" +msgstr "" + +#: src/labels.h:495 +msgid "524 - CloudFlare - A timeout occurred" +msgstr "" + +#~ msgid "Bandwidth" +#~ msgstr "Bande passante" + +#~ msgid "Unique Files" +#~ msgstr "Fichiers uniques" + +#~ msgid "Unique 404" +#~ msgstr "Unique 404" + +#~ msgid " - Including spiders" +#~ msgstr "- Inclus robots d'indexation" diff --git a/goaccess++/po/goaccess.pot b/goaccess++/po/goaccess.pot new file mode 100644 index 0000000..f107298 --- /dev/null +++ b/goaccess++/po/goaccess.pot @@ -0,0 +1,882 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: goaccess 1.3\n" +"Report-Msgid-Bugs-To: hello@goaccess.io\n" +"POT-Creation-Date: 2018-11-22 23:38-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL@li.org>\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: src/labels.h:40 +msgid "en" +msgstr "" + +#: src/labels.h:43 +msgid "Exp. Panel" +msgstr "" + +#: src/labels.h:44 +msgid "Help" +msgstr "" + +#: src/labels.h:45 +msgid "Quit" +msgstr "" + +#: src/labels.h:46 +msgid "Total" +msgstr "" + +#: src/labels.h:49 +msgid "[x] ASC [ ] DESC" +msgstr "" + +#: src/labels.h:50 +msgid "[ ] ASC [x] DESC" +msgstr "" + +#: src/labels.h:53 +#, c-format +msgid "[Active Panel: %1$s]" +msgstr "" + +#: src/labels.h:54 +msgid "[q]uit GoAccess" +msgstr "" + +#: src/labels.h:55 +msgid "[?] Help [Enter] Exp. Panel" +msgstr "" + +#: src/labels.h:56 +msgid "Dashboard" +msgstr "" + +#: src/labels.h:57 +msgid "Dashboard - Overall Analyzed Requests" +msgstr "" + +#: src/labels.h:58 +msgid "Overall Analyzed Requests" +msgstr "" + +#: src/labels.h:60 src/labels.h:81 +msgid "Tx. Amount" +msgstr "" + +#: src/labels.h:61 +msgid "Date/Time" +msgstr "" + +#: src/labels.h:62 +msgid "Excl. IP Hits" +msgstr "" + +#: src/labels.h:63 +msgid "Failed Requests" +msgstr "" + +#: src/labels.h:64 +msgid "Init. Proc. Time" +msgstr "" + +#: src/labels.h:65 +msgid "Log Size" +msgstr "" + +#: src/labels.h:66 +msgid "Log Source" +msgstr "" + +#: src/labels.h:67 src/labels.h:174 +msgid "Referrers" +msgstr "" + +#: src/labels.h:68 +msgid "Total Requests" +msgstr "" + +#: src/labels.h:69 +msgid "Static Files" +msgstr "" + +#: src/labels.h:70 src/labels.h:146 +msgid "Not Found" +msgstr "" + +#: src/labels.h:71 +msgid "Requested Files" +msgstr "" + +#: src/labels.h:72 +msgid "Unique Visitors" +msgstr "" + +#: src/labels.h:73 +msgid "Valid Requests" +msgstr "" + +#: src/labels.h:76 +msgid "Hits" +msgstr "" + +#: src/labels.h:77 +msgid "h%" +msgstr "" + +#: src/labels.h:78 src/labels.h:104 +msgid "Visitors" +msgstr "" + +#: src/labels.h:79 +msgid "Vis." +msgstr "" + +#: src/labels.h:80 +msgid "v%" +msgstr "" + +#: src/labels.h:82 +msgid "Avg. T.S." +msgstr "" + +#: src/labels.h:83 +msgid "Cum. T.S." +msgstr "" + +#: src/labels.h:84 +msgid "Max. T.S." +msgstr "" + +#: src/labels.h:85 +msgid "Method" +msgstr "" + +#: src/labels.h:86 +msgid "Mtd" +msgstr "" + +#: src/labels.h:87 +msgid "Protocol" +msgstr "" + +#: src/labels.h:88 +msgid "Proto" +msgstr "" + +#: src/labels.h:89 +msgid "City" +msgstr "" + +#: src/labels.h:90 +msgid "Country" +msgstr "" + +#: src/labels.h:91 +msgid "Hostname" +msgstr "" + +#: src/labels.h:92 +msgid "Data" +msgstr "" + +#: src/labels.h:94 +msgid "Hits/Visitors" +msgstr "" + +#: src/labels.h:98 +msgid "Unique visitors per day" +msgstr "" + +#: src/labels.h:100 +msgid "Unique visitors per day - Including spiders" +msgstr "" + +#: src/labels.h:102 +msgid "Hits having the same IP, date and agent are a unique visit." +msgstr "" + +#: src/labels.h:107 +msgid "Requested Files (URLs)" +msgstr "" + +#: src/labels.h:109 +msgid "Top requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" + +#: src/labels.h:111 +msgid "Requests" +msgstr "" + +#: src/labels.h:114 src/labels.h:118 +msgid "Static Requests" +msgstr "" + +#: src/labels.h:116 +msgid "Top static requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" + +#: src/labels.h:121 +msgid "Time Distribution" +msgstr "" + +#: src/labels.h:123 +msgid "Data sorted by hour [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:125 +msgid "Time" +msgstr "" + +#: src/labels.h:128 src/labels.h:132 +msgid "Virtual Hosts" +msgstr "" + +#: src/labels.h:130 src/labels.h:137 +msgid "Data sorted by hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:135 +msgid "Remote User (HTTP authentication)" +msgstr "" + +#: src/labels.h:139 +msgid "Remote User" +msgstr "" + +#: src/labels.h:142 +msgid "Not Found URLs (404s)" +msgstr "" + +#: src/labels.h:144 +msgid "Top not found URLs sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" + +#: src/labels.h:149 +msgid "Visitor Hostnames and IPs" +msgstr "" + +#: src/labels.h:151 +msgid "Top visitor hosts sorted by hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:153 +msgid "Hosts" +msgstr "" + +#: src/labels.h:156 +msgid "Operating Systems" +msgstr "" + +#: src/labels.h:158 +msgid "Top Operating Systems sorted by hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:160 +msgid "OS" +msgstr "" + +#: src/labels.h:163 src/labels.h:167 +msgid "Browsers" +msgstr "" + +#: src/labels.h:165 +msgid "Top Browsers sorted by hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:170 +msgid "Referrers URLs" +msgstr "" + +#: src/labels.h:172 +msgid "Top Requested Referrers sorted by hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:177 src/labels.h:181 +msgid "Referring Sites" +msgstr "" + +#: src/labels.h:179 +msgid "Top Referring Sites sorted by hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:184 +msgid "Keyphrases from Google's search engine" +msgstr "" + +#: src/labels.h:186 +msgid "Top Keyphrases sorted by hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:188 +msgid "Keyphrases" +msgstr "" + +#: src/labels.h:191 src/labels.h:195 +msgid "Geo Location" +msgstr "" + +#: src/labels.h:193 +msgid "Continent > Country sorted by unique hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:198 +msgid "HTTP Status Codes" +msgstr "" + +#: src/labels.h:200 +msgid "Top HTTP Status Codes sorted by hits [, avgts, cumts, maxts]" +msgstr "" + +#: src/labels.h:202 +msgid "Status Codes" +msgstr "" + +#: src/labels.h:206 +msgid "[ ] case sensitive" +msgstr "" + +#: src/labels.h:208 +msgid "[x] case sensitive" +msgstr "" + +#: src/labels.h:210 +msgid "Regex allowed - ^g to cancel - TAB switch case" +msgstr "" + +#: src/labels.h:212 +msgid "Find pattern in all views" +msgstr "" + +#: src/labels.h:216 +msgid "Log Format Configuration" +msgstr "" + +#: src/labels.h:218 +msgid "[SPACE] to toggle - [ENTER] to proceed - [q] to quit" +msgstr "" + +#: src/labels.h:220 +msgid "Log Format - [c] to add/edit format" +msgstr "" + +#: src/labels.h:222 +msgid "Date Format - [d] to add/edit format" +msgstr "" + +#: src/labels.h:224 +msgid "Time Format - [t] to add/edit format" +msgstr "" + +#: src/labels.h:226 src/labels.h:230 +msgid "[UP/DOWN] to scroll - [q] to close window" +msgstr "" + +#: src/labels.h:232 +#, c-format +msgid "User Agents for %1$s" +msgstr "" + +#: src/labels.h:236 +msgid "Scheme Configuration" +msgstr "" + +#: src/labels.h:238 +msgid "[ENTER] to use scheme - [q]uit" +msgstr "" + +#: src/labels.h:242 +msgid "Sort active module by" +msgstr "" + +#: src/labels.h:244 +msgid "[ENTER] select - [TAB] sort - [q]uit" +msgstr "" + +#: src/labels.h:248 +msgid "GoAccess Quick Help" +msgstr "" + +#: src/labels.h:250 +msgid "[UP/DOWN] to scroll - [q] to quit" +msgstr "" + +#: src/labels.h:254 +msgid "Built using Tokyo Cabinet on-disk B+ Tree." +msgstr "" + +#: src/labels.h:256 +msgid "Built using Tokyo Cabinet in-memory hash database." +msgstr "" + +#: src/labels.h:258 +msgid "Built using the default in-memory hash database." +msgstr "" + +#: src/labels.h:262 +msgid "Format Errors - Verify your log/date/time format" +msgstr "" + +#: src/labels.h:264 +msgid "No date format was found on your conf file." +msgstr "" + +#: src/labels.h:266 +msgid "No log format was found on your conf file." +msgstr "" + +#: src/labels.h:268 +msgid "No time format was found on your conf file." +msgstr "" + +#: src/labels.h:270 +msgid "No default config file found." +msgstr "" + +#: src/labels.h:272 +msgid "You may specify one with" +msgstr "" + +#: src/labels.h:274 +msgid "producing the following errors" +msgstr "" + +#: src/labels.h:276 +#, c-format +msgid "Parsed %1$d lines" +msgstr "" + +#: src/labels.h:278 +msgid "Please report it by opening an issue on GitHub" +msgstr "" + +#: src/labels.h:280 +msgid "Select a time format." +msgstr "" + +#: src/labels.h:282 +msgid "Select a date format." +msgstr "" + +#: src/labels.h:284 +msgid "Select a log format." +msgstr "" + +#: src/labels.h:286 +#, c-format +msgid "'%1$s' panel is disabled" +msgstr "" + +#: src/labels.h:290 +msgid "For more details visit" +msgstr "" + +#: src/labels.h:292 +msgid "Last Updated" +msgstr "" + +#: src/labels.h:294 +msgid "WebSocket server ready to accept new client connections" +msgstr "" + +#: src/labels.h:297 +msgid "The following options can also be supplied to the command" +msgstr "" + +#: src/labels.h:299 +msgid "Examples can be found by running" +msgstr "" + +#: src/labels.h:302 +msgid "Server Statistics" +msgstr "" + +#: src/labels.h:304 +msgid "Theme" +msgstr "" + +#: src/labels.h:306 +msgid "Dark Gray" +msgstr "" + +#: src/labels.h:308 +msgid "Bright" +msgstr "" + +#: src/labels.h:310 +msgid "Dark Blue" +msgstr "" + +#: src/labels.h:312 +msgid "Dark Purple" +msgstr "" + +#: src/labels.h:314 +msgid "Panels" +msgstr "" + +#: src/labels.h:316 +msgid "Items per Page" +msgstr "" + +#: src/labels.h:318 +msgid "Tables" +msgstr "" + +#: src/labels.h:320 +msgid "Display Tables" +msgstr "" + +#: src/labels.h:322 +msgid "Auto-Hide on Small Devices" +msgstr "" + +#: src/labels.h:324 +msgid "Automatically hide tables on small screen devices" +msgstr "" + +#: src/labels.h:326 +msgid "Layout" +msgstr "" + +#: src/labels.h:328 +msgid "Horizontal" +msgstr "" + +#: src/labels.h:330 +msgid "Vertical" +msgstr "" + +#: src/labels.h:332 +msgid "File Options" +msgstr "" + +#: src/labels.h:334 +msgid "Export as JSON" +msgstr "" + +#: src/labels.h:336 +msgid "Panel Options" +msgstr "" + +#: src/labels.h:338 +msgid "Previous" +msgstr "" + +#: src/labels.h:340 +msgid "Next" +msgstr "" + +#: src/labels.h:342 +msgid "First" +msgstr "" + +#: src/labels.h:344 +msgid "Last" +msgstr "" + +#: src/labels.h:346 +msgid "Chart Options" +msgstr "" + +#: src/labels.h:348 +msgid "Chart" +msgstr "" + +#: src/labels.h:350 +msgid "Type" +msgstr "" + +#: src/labels.h:352 +msgid "Area Spline" +msgstr "" + +#: src/labels.h:354 +msgid "Bar" +msgstr "" + +#: src/labels.h:356 +msgid "Plot Metric" +msgstr "" + +#: src/labels.h:358 +msgid "Table Columns" +msgstr "" + +#: src/labels.h:362 +msgid "1xx Informational" +msgstr "" + +#: src/labels.h:364 +msgid "2xx Success" +msgstr "" + +#: src/labels.h:366 +msgid "3xx Redirection" +msgstr "" + +#: src/labels.h:368 +msgid "4xx Client Errors" +msgstr "" + +#: src/labels.h:370 +msgid "5xx Server Errors" +msgstr "" + +#: src/labels.h:373 +msgid "100 - Continue: Server received the initial part of the request" +msgstr "" + +#: src/labels.h:375 +msgid "101 - Switching Protocols: Client asked to switch protocols" +msgstr "" + +#: src/labels.h:377 +msgid "200 - OK: The request sent by the client was successful" +msgstr "" + +#: src/labels.h:379 +msgid "201 - Created: The request has been fulfilled and created" +msgstr "" + +#: src/labels.h:381 +msgid "202 - Accepted: The request has been accepted for processing" +msgstr "" + +#: src/labels.h:383 +msgid "203 - Non-authoritative Information: Response from a third party" +msgstr "" + +#: src/labels.h:385 +msgid "204 - No Content: Request did not return any content" +msgstr "" + +#: src/labels.h:387 +msgid "205 - Reset Content: Server asked the client to reset the document" +msgstr "" + +#: src/labels.h:389 +msgid "206 - Partial Content: The partial GET has been successful" +msgstr "" + +#: src/labels.h:391 +msgid "207 - Multi-Status: WebDAV; RFC 4918" +msgstr "" + +#: src/labels.h:393 +msgid "208 - Already Reported: WebDAV; RFC 5842" +msgstr "" + +#: src/labels.h:395 +msgid "300 - Multiple Choices: Multiple options for the resource" +msgstr "" + +#: src/labels.h:397 +msgid "301 - Moved Permanently: Resource has permanently moved" +msgstr "" + +#: src/labels.h:399 +msgid "302 - Moved Temporarily (redirect)" +msgstr "" + +#: src/labels.h:401 +msgid "303 - See Other Document: The response is at a different URI" +msgstr "" + +#: src/labels.h:403 +msgid "304 - Not Modified: Resource has not been modified" +msgstr "" + +#: src/labels.h:405 +msgid "305 - Use Proxy: Can only be accessed through the proxy" +msgstr "" + +#: src/labels.h:407 +msgid "307 - Temporary Redirect: Resource temporarily moved" +msgstr "" + +#: src/labels.h:409 +msgid "400 - Bad Request: The syntax of the request is invalid" +msgstr "" + +#: src/labels.h:411 +msgid "401 - Unauthorized: Request needs user authentication" +msgstr "" + +#: src/labels.h:413 +msgid "402 - Payment Required" +msgstr "" + +#: src/labels.h:415 +msgid "403 - Forbidden: Server is refusing to respond to it" +msgstr "" + +#: src/labels.h:417 +msgid "404 - Not Found: Requested resource could not be found" +msgstr "" + +#: src/labels.h:419 +msgid "405 - Method Not Allowed: Request method not supported" +msgstr "" + +#: src/labels.h:421 +msgid "406 - Not Acceptable" +msgstr "" + +#: src/labels.h:423 +msgid "407 - Proxy Authentication Required" +msgstr "" + +#: src/labels.h:425 +msgid "408 - Request Timeout: Server timed out waiting for the request" +msgstr "" + +#: src/labels.h:427 +msgid "409 - Conflict: Conflict in the request" +msgstr "" + +#: src/labels.h:429 +msgid "410 - Gone: Resource requested is no longer available" +msgstr "" + +#: src/labels.h:431 +msgid "411 - Length Required: Invalid Content-Length" +msgstr "" + +#: src/labels.h:433 +msgid "412 - Precondition Failed: Server does not meet preconditions" +msgstr "" + +#: src/labels.h:435 +msgid "413 - Payload Too Large" +msgstr "" + +#: src/labels.h:437 +msgid "414 - Request-URI Too Long" +msgstr "" + +#: src/labels.h:439 +msgid "415 - Unsupported Media Type: Media type is not supported" +msgstr "" + +#: src/labels.h:441 +msgid "416 - Requested Range Not Satisfiable: Cannot supply that portion" +msgstr "" + +#: src/labels.h:443 +msgid "417 - Expectation Failed" +msgstr "" + +#: src/labels.h:445 +msgid "421 - Misdirected Request" +msgstr "" + +#: src/labels.h:447 +msgid "422 - Unprocessable Entity due to semantic errors: WebDAV" +msgstr "" + +#: src/labels.h:449 +msgid "423 - The resource that is being accessed is locked" +msgstr "" + +#: src/labels.h:451 +msgid "424 - Failed Dependency: WebDAV" +msgstr "" + +#: src/labels.h:453 +msgid "426 - Upgrade Required: Client should switch to a different protocol" +msgstr "" + +#: src/labels.h:455 +msgid "428 - Precondition Required" +msgstr "" + +#: src/labels.h:457 +msgid "429 - Too Many Requests: The user has sent too many requests" +msgstr "" + +#: src/labels.h:459 +msgid "431 - Request Header Fields Too Large" +msgstr "" + +#: src/labels.h:461 +msgid "451 - Unavailable For Legal Reasons" +msgstr "" + +#: src/labels.h:463 +msgid "444 - (Nginx) Connection closed without sending any headers" +msgstr "" + +#: src/labels.h:465 +msgid "494 - (Nginx) Request Header Too Large" +msgstr "" + +#: src/labels.h:467 +msgid "495 - (Nginx) SSL client certificate error" +msgstr "" + +#: src/labels.h:469 +msgid "496 - (Nginx) Client didn't provide certificate" +msgstr "" + +#: src/labels.h:471 +msgid "497 - (Nginx) HTTP request sent to HTTPS port" +msgstr "" + +#: src/labels.h:473 +msgid "499 - (Nginx) Connection closed by client while processing request" +msgstr "" + +#: src/labels.h:475 +msgid "500 - Internal Server Error" +msgstr "" + +#: src/labels.h:477 +msgid "501 - Not Implemented" +msgstr "" + +#: src/labels.h:479 +msgid "502 - Bad Gateway: Received an invalid response from the upstream" +msgstr "" + +#: src/labels.h:481 +msgid "503 - Service Unavailable: The server is currently unavailable" +msgstr "" + +#: src/labels.h:483 +msgid "504 - Gateway Timeout: The upstream server failed to send request" +msgstr "" + +#: src/labels.h:485 +msgid "505 - HTTP Version Not Supported" +msgstr "" + +#: src/labels.h:487 +msgid "520 - CloudFlare - Web server is returning an unknown error" +msgstr "" + +#: src/labels.h:489 +msgid "521 - CloudFlare - Web server is down" +msgstr "" + +#: src/labels.h:491 +msgid "522 - CloudFlare - Connection timed out" +msgstr "" + +#: src/labels.h:493 +msgid "523 - CloudFlare - Origin is unreachable" +msgstr "" + +#: src/labels.h:495 +msgid "524 - CloudFlare - A timeout occurred" +msgstr "" diff --git a/goaccess++/po/insert-header.sin b/goaccess++/po/insert-header.sin new file mode 100644 index 0000000..b26de01 --- /dev/null +++ b/goaccess++/po/insert-header.sin @@ -0,0 +1,23 @@ +# Sed script that inserts the file called HEADER before the header entry. +# +# At each occurrence of a line starting with "msgid ", we execute the following +# commands. At the first occurrence, insert the file. At the following +# occurrences, do nothing. The distinction between the first and the following +# occurrences is achieved by looking at the hold space. +/^msgid /{ +x +# Test if the hold space is empty. +s/m/m/ +ta +# Yes it was empty. First occurrence. Read the file. +r HEADER +# Output the file's contents by reading the next line. But don't lose the +# current line while doing this. +g +N +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/goaccess++/po/ja.gmo b/goaccess++/po/ja.gmo new file mode 100644 index 0000000..1c4576c Binary files /dev/null and b/goaccess++/po/ja.gmo differ diff --git a/goaccess++/po/ja.po b/goaccess++/po/ja.po new file mode 100644 index 0000000..9f7dc5a --- /dev/null +++ b/goaccess++/po/ja.po @@ -0,0 +1,914 @@ +# This file is distributed under the same license as the goaccess package. +# Kamino Hiroki, 2019. +# +msgid "" +msgstr "" +"Project-Id-Version: goaccess 1.2\n" +"Report-Msgid-Bugs-To: hello@goaccess.io\n" +"POT-Creation-Date: 2018-11-22 23:38-0600\n" +"PO-Revision-Date: 2018-10-26 22:00+0900\n" +"Last-Translator: Kamino Hiroki <37243867+4f8p@users.noreply.github.com>\n" +"Language-Team: Japanese\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/labels.h:40 +msgid "en" +msgstr "ja" + +#: src/labels.h:43 +msgid "Exp. Panel" +msgstr "詳細表示" + +#: src/labels.h:44 +msgid "Help" +msgstr "ヘルプ" + +#: src/labels.h:45 +msgid "Quit" +msgstr "終了" + +#: src/labels.h:46 +msgid "Total" +msgstr "合計" + +#: src/labels.h:49 +msgid "[x] ASC [ ] DESC" +msgstr "[x] 昇順 [ ] 降順" + +#: src/labels.h:50 +msgid "[ ] ASC [x] DESC" +msgstr "[ ] 昇順 [x] 降順" + +#: src/labels.h:53 +#, c-format +msgid "[Active Panel: %1$s]" +msgstr "[表示中のパネル: %1$s]" + +#: src/labels.h:54 +msgid "[q]uit GoAccess" +msgstr "[q] GoAccessを閉じる" + +#: src/labels.h:55 +msgid "[?] Help [Enter] Exp. Panel" +msgstr "[?] ヘルプ [Enter] 詳細表示" + +#: src/labels.h:56 +msgid "Dashboard" +msgstr "ダッシュボード" + +#: src/labels.h:57 +msgid "Dashboard - Overall Analyzed Requests" +msgstr "ダッシュボード - 解析済みリクエスト全体" + +#: src/labels.h:58 +msgid "Overall Analyzed Requests" +msgstr "解析済みリクエスト全体" + +#: src/labels.h:60 src/labels.h:81 +msgid "Tx. Amount" +msgstr "データ転送量" + +#: src/labels.h:61 +msgid "Date/Time" +msgstr "日付/時刻" + +#: src/labels.h:62 +msgid "Excl. IP Hits" +msgstr "除外対象数" + +#: src/labels.h:63 +msgid "Failed Requests" +msgstr "無効リクエスト数" + +#: src/labels.h:64 +msgid "Init. Proc. Time" +msgstr "解析にかかった時間" + +#: src/labels.h:65 +msgid "Log Size" +msgstr "ログファイルサイズ" + +#: src/labels.h:66 +msgid "Log Source" +msgstr "ログ取得元" + +#: src/labels.h:67 src/labels.h:174 +msgid "Referrers" +msgstr "リファラー数" + +#: src/labels.h:68 +msgid "Total Requests" +msgstr "合計リクエスト数" + +#: src/labels.h:69 +msgid "Static Files" +msgstr "静的ファイル数" + +#: src/labels.h:70 src/labels.h:146 +msgid "Not Found" +msgstr "404エラー数" + +#: src/labels.h:71 +msgid "Requested Files" +msgstr "要求されたファイル数" + +#: src/labels.h:72 +msgid "Unique Visitors" +msgstr "ユニークユーザー数" + +#: src/labels.h:73 +msgid "Valid Requests" +msgstr "有効リクエスト数" + +#: src/labels.h:76 +msgid "Hits" +msgstr "ヒット数" + +#: src/labels.h:77 +msgid "h%" +msgstr "h%" + +#: src/labels.h:78 src/labels.h:104 +msgid "Visitors" +msgstr "ユーザー数" + +#: src/labels.h:79 +msgid "Vis." +msgstr "ユーザー数" + +#: src/labels.h:80 +msgid "v%" +msgstr "v%" + +#: src/labels.h:82 +msgid "Avg. T.S." +msgstr "平均処理時間" + +#: src/labels.h:83 +msgid "Cum. T.S." +msgstr "合計処理時間" + +#: src/labels.h:84 +msgid "Max. T.S." +msgstr "最大処理時間" + +#: src/labels.h:85 +msgid "Method" +msgstr "要求" + +#: src/labels.h:86 +msgid "Mtd" +msgstr "要求" + +#: src/labels.h:87 +msgid "Protocol" +msgstr "プロトコル" + +#: src/labels.h:88 +msgid "Proto" +msgstr "プロトコル" + +#: src/labels.h:89 +msgid "City" +msgstr "地域" + +#: src/labels.h:90 +msgid "Country" +msgstr "国名" + +#: src/labels.h:91 +msgid "Hostname" +msgstr "ホスト名" + +#: src/labels.h:92 +msgid "Data" +msgstr "データ" + +#: src/labels.h:94 +msgid "Hits/Visitors" +msgstr "ヒット数/ユーザー数" + +#: src/labels.h:98 +msgid "Unique visitors per day" +msgstr "一日あたりのユニークユーザー数" + +#: src/labels.h:100 +msgid "Unique visitors per day - Including spiders" +msgstr "一日あたりのユニークユーザー数(クローラも含める)" + +#: src/labels.h:102 +msgid "Hits having the same IP, date and agent are a unique visit." +msgstr "" +"IPアドレス、日付、ユーザーエージェントが全て同一だった場合、ユニークユーザー" +"として扱われます。" + +#: src/labels.h:107 +msgid "Requested Files (URLs)" +msgstr "リクエストされたファイル(URL)" + +#: src/labels.h:109 +msgid "Top requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "リクエスト順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:111 +msgid "Requests" +msgstr "リクエスト数" + +#: src/labels.h:114 src/labels.h:118 +msgid "Static Requests" +msgstr "静的ファイルリクエスト数" + +#: src/labels.h:116 +msgid "Top static requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" +"静的ファイルリクエスト順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:121 +msgid "Time Distribution" +msgstr "時間分布" + +#: src/labels.h:123 +msgid "Data sorted by hour [, avgts, cumts, maxts]" +msgstr "" +"リクエストされた時刻順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:125 +msgid "Time" +msgstr "時刻" + +#: src/labels.h:128 src/labels.h:132 +msgid "Virtual Hosts" +msgstr "バーチャルホスト" + +#: src/labels.h:130 src/labels.h:137 +msgid "Data sorted by hits [, avgts, cumts, maxts]" +msgstr "リクエスト順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:135 +msgid "Remote User (HTTP authentication)" +msgstr "認証されたユーザー(HTTP認証)" + +#: src/labels.h:139 +msgid "Remote User" +msgstr "認証されたユーザー" + +#: src/labels.h:142 +msgid "Not Found URLs (404s)" +msgstr "404エラーが返されたURL" + +#: src/labels.h:144 +msgid "Top not found URLs sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "エラーとなったURL順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:149 +msgid "Visitor Hostnames and IPs" +msgstr "ユーザーのホスト名とIPアドレス" + +#: src/labels.h:151 +msgid "Top visitor hosts sorted by hits [, avgts, cumts, maxts]" +msgstr "ホスト名順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:153 +msgid "Hosts" +msgstr "ホスト名" + +#: src/labels.h:156 +msgid "Operating Systems" +msgstr "オペレーティングシステム" + +#: src/labels.h:158 +msgid "Top Operating Systems sorted by hits [, avgts, cumts, maxts]" +msgstr "OS順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:160 +msgid "OS" +msgstr "OS" + +#: src/labels.h:163 src/labels.h:167 +msgid "Browsers" +msgstr "ブラウザ" + +#: src/labels.h:165 +msgid "Top Browsers sorted by hits [, avgts, cumts, maxts]" +msgstr "ブラウザ順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:170 +msgid "Referrers URLs" +msgstr "参照元(URL)" + +#: src/labels.h:172 +msgid "Top Requested Referrers sorted by hits [, avgts, cumts, maxts]" +msgstr "送信元アドレス順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:177 src/labels.h:181 +msgid "Referring Sites" +msgstr "参照元サイト" + +#: src/labels.h:179 +msgid "Top Referring Sites sorted by hits [, avgts, cumts, maxts]" +msgstr "参照元サイト順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:184 +msgid "Keyphrases from Google's search engine" +msgstr "キーフレーズ(Google検索から)" + +#: src/labels.h:186 +msgid "Top Keyphrases sorted by hits [, avgts, cumts, maxts]" +msgstr "キーフレーズ順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:188 +msgid "Keyphrases" +msgstr "キーフレーズ" + +#: src/labels.h:191 src/labels.h:195 +msgid "Geo Location" +msgstr "位置情報" + +#: src/labels.h:193 +msgid "Continent > Country sorted by unique hits [, avgts, cumts, maxts]" +msgstr "地理区分 > 国別にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:198 +msgid "HTTP Status Codes" +msgstr "HTTPステータスコード" + +#: src/labels.h:200 +msgid "Top HTTP Status Codes sorted by hits [, avgts, cumts, maxts]" +msgstr "" +"HTTPステータスコード順にソート [平均処理時間、合計処理時間、最大処理時間]" + +#: src/labels.h:202 +msgid "Status Codes" +msgstr "ステータスコード" + +#: src/labels.h:206 +msgid "[ ] case sensitive" +msgstr "[ ] 大文字と小文字を区別する" + +#: src/labels.h:208 +msgid "[x] case sensitive" +msgstr "[x] 大文字と小文字を区別する" + +#: src/labels.h:210 +msgid "Regex allowed - ^g to cancel - TAB switch case" +msgstr "正規表現を許可する - [^g] キャンセル - [TAB] 切り替え" + +#: src/labels.h:212 +msgid "Find pattern in all views" +msgstr "すべてのビューでパターン検索を行う" + +#: src/labels.h:216 +msgid "Log Format Configuration" +msgstr "ログ形式設定" + +#: src/labels.h:218 +msgid "[SPACE] to toggle - [ENTER] to proceed - [q] to quit" +msgstr "[SPACE] 切り替え - [ENTER] 決定 - [q] 終了" + +#: src/labels.h:220 +msgid "Log Format - [c] to add/edit format" +msgstr "ログ形式 - [c] 追加/編集" + +#: src/labels.h:222 +msgid "Date Format - [d] to add/edit format" +msgstr "日付形式 - [d] 追加/編集" + +#: src/labels.h:224 +msgid "Time Format - [t] to add/edit format" +msgstr "時刻形式 - [t] 追加/編集" + +#: src/labels.h:226 src/labels.h:230 +msgid "[UP/DOWN] to scroll - [q] to close window" +msgstr "[↑/↓] スクロール - [q] ウィンドウを閉じる" + +#: src/labels.h:232 +#, c-format +msgid "User Agents for %1$s" +msgstr "%1$s のユーザーエージェント" + +#: src/labels.h:236 +msgid "Scheme Configuration" +msgstr "スキーム設定" + +#: src/labels.h:238 +msgid "[ENTER] to use scheme - [q]uit" +msgstr "[ENTER] スキーム選択 - [q] 終了" + +#: src/labels.h:242 +msgid "Sort active module by" +msgstr "選択したカラムで並び替え" + +#: src/labels.h:244 +msgid "[ENTER] select - [TAB] sort - [q]uit" +msgstr "[ENTER] 選択 - [TAB] ソート - [q] 終了" + +#: src/labels.h:248 +msgid "GoAccess Quick Help" +msgstr "GoAccessクイックヘルプ" + +#: src/labels.h:250 +msgid "[UP/DOWN] to scroll - [q] to quit" +msgstr "[↑/↓] スクロール - [q] 終了" + +#: src/labels.h:254 +msgid "Built using Tokyo Cabinet on-disk B+ Tree." +msgstr "Tokyo CabinetのB+木データベースを使用する。" + +#: src/labels.h:256 +msgid "Built using Tokyo Cabinet in-memory hash database." +msgstr "Tokyo Cabinetのインメモリハッシュデータベースを使用する。" + +#: src/labels.h:258 +msgid "Built using the default in-memory hash database." +msgstr "デフォルトのインメモリハッシュデータベースを使用する。" + +#: src/labels.h:262 +msgid "Format Errors - Verify your log/date/time format" +msgstr "" +"解析に失敗しました - ログ/日付/時刻のフォーマット設定を確認してください" + +#: src/labels.h:264 +msgid "No date format was found on your conf file." +msgstr "設定ファイル内で日付形式がセットされていません。" + +#: src/labels.h:266 +msgid "No log format was found on your conf file." +msgstr "設定ファイル内でログ形式がセットされていません。" + +#: src/labels.h:268 +msgid "No time format was found on your conf file." +msgstr "設定ファイル内で時刻形式がセットされていません。" + +#: src/labels.h:270 +msgid "No default config file found." +msgstr "デフォルトの設定ファイルが見つかりません。" + +#: src/labels.h:272 +msgid "You may specify one with" +msgstr "いずれか指定してください" + +#: src/labels.h:274 +msgid "producing the following errors" +msgstr "エラーが発生しました" + +#: src/labels.h:276 +#, c-format +msgid "Parsed %1$d lines" +msgstr "解析済み: %1$d 行" + +#: src/labels.h:278 +msgid "Please report it by opening an issue on GitHub" +msgstr "GitHub上のIssueから問題を報告してください" + +#: src/labels.h:280 +msgid "Select a time format." +msgstr "時刻形式を選択します。" + +#: src/labels.h:282 +msgid "Select a date format." +msgstr "日付形式を選択します。" + +#: src/labels.h:284 +msgid "Select a log format." +msgstr "ログ形式を選択します。" + +#: src/labels.h:286 +#, c-format +msgid "'%1$s' panel is disabled" +msgstr "'%1$s' パネルは無効化されています" + +#: src/labels.h:290 +msgid "For more details visit" +msgstr "詳細はこちら" + +#: src/labels.h:292 +msgid "Last Updated" +msgstr "最終更新日時" + +#: src/labels.h:294 +msgid "WebSocket server ready to accept new client connections" +msgstr "WebSocket接続の準備ができました" + +#: src/labels.h:297 +msgid "The following options can also be supplied to the command" +msgstr "次のオプションはコマンドで指定することもできます" + +#: src/labels.h:299 +msgid "Examples can be found by running" +msgstr "実行例" + +#: src/labels.h:302 +msgid "Server Statistics" +msgstr "サーバーの統計情報" + +#: src/labels.h:304 +msgid "Theme" +msgstr "テーマ" + +#: src/labels.h:306 +msgid "Dark Gray" +msgstr "ダークグレー" + +#: src/labels.h:308 +msgid "Bright" +msgstr "ライト" + +#: src/labels.h:310 +msgid "Dark Blue" +msgstr "ダークブルー" + +#: src/labels.h:312 +#, fuzzy +msgid "Dark Purple" +msgstr "ダークブルー" + +#: src/labels.h:314 +msgid "Panels" +msgstr "パネル" + +#: src/labels.h:316 +msgid "Items per Page" +msgstr "ページあたりの表示数" + +#: src/labels.h:318 +msgid "Tables" +msgstr "テーブル" + +#: src/labels.h:320 +msgid "Display Tables" +msgstr "テーブル表示" + +#: src/labels.h:322 +msgid "Auto-Hide on Small Devices" +msgstr "自動非表示設定(小型端末用)" + +#: src/labels.h:324 +msgid "Automatically hide tables on small screen devices" +msgstr "画面が小さい場合に自動でテーブルを非表示にする" + +#: src/labels.h:326 +msgid "Layout" +msgstr "レイアウト" + +#: src/labels.h:328 +msgid "Horizontal" +msgstr "水平" + +#: src/labels.h:330 +msgid "Vertical" +msgstr "垂直" + +#: src/labels.h:332 +msgid "File Options" +msgstr "ファイルオプション" + +#: src/labels.h:334 +msgid "Export as JSON" +msgstr "JSON形式でエクスポート" + +#: src/labels.h:336 +msgid "Panel Options" +msgstr "パネルオプション" + +#: src/labels.h:338 +msgid "Previous" +msgstr "前へ" + +#: src/labels.h:340 +msgid "Next" +msgstr "次へ" + +#: src/labels.h:342 +msgid "First" +msgstr "" + +#: src/labels.h:344 +msgid "Last" +msgstr "" + +#: src/labels.h:346 +msgid "Chart Options" +msgstr "グラフ設定" + +#: src/labels.h:348 +msgid "Chart" +msgstr "グラフ" + +#: src/labels.h:350 +msgid "Type" +msgstr "タイプ" + +#: src/labels.h:352 +msgid "Area Spline" +msgstr "平滑面グラフ" + +#: src/labels.h:354 +msgid "Bar" +msgstr "棒グラフ" + +#: src/labels.h:356 +msgid "Plot Metric" +msgstr "表示するデータ" + +#: src/labels.h:358 +msgid "Table Columns" +msgstr "テーブルカラム" + +#: src/labels.h:362 +msgid "1xx Informational" +msgstr "1xx 情報" + +#: src/labels.h:364 +msgid "2xx Success" +msgstr "2xx 成功" + +#: src/labels.h:366 +msgid "3xx Redirection" +msgstr "3xx リダイレクション" + +#: src/labels.h:368 +msgid "4xx Client Errors" +msgstr "4xx クライアントエラー" + +#: src/labels.h:370 +msgid "5xx Server Errors" +msgstr "5xx サーバーエラー" + +#: src/labels.h:373 +msgid "100 - Continue: Server received the initial part of the request" +msgstr "100 - 継続: リクエストヘッダーを受理しました" + +#: src/labels.h:375 +msgid "101 - Switching Protocols: Client asked to switch protocols" +msgstr "" +"101 - プロトコル変更: HTTPヘッダーでリクエストされたプロトコルに切り替えます" + +#: src/labels.h:377 +msgid "200 - OK: The request sent by the client was successful" +msgstr "200 - 成功: リクエストに成功しました" + +#: src/labels.h:379 +msgid "201 - Created: The request has been fulfilled and created" +msgstr "201 - 作成: リクエストが成功して新たなリソースの作成が完了しました" + +#: src/labels.h:381 +msgid "202 - Accepted: The request has been accepted for processing" +msgstr "202 - 受理: リクエストを受け取ったが処理されていません" + +#: src/labels.h:383 +msgid "203 - Non-authoritative Information: Response from a third party" +msgstr "" +"203 - 認証されていない情報: リクエストを正常に処理しましたが、返される情報は" +"別の送信元から来る可能性があります" + +#: src/labels.h:385 +msgid "204 - No Content: Request did not return any content" +msgstr "" +"204 - コンテンツ無し: リクエストを正常に処理しましたが、返すべき情報がありま" +"せん" + +#: src/labels.h:387 +msgid "205 - Reset Content: Server asked the client to reset the document" +msgstr "" +"205 - リセット要求: リクエストを行ったクライアントに対してドキュメントビュー" +"のリセットを行うよう指示します" + +#: src/labels.h:389 +msgid "206 - Partial Content: The partial GET has been successful" +msgstr "" +"206 - 部分的なリクエスト: GETリクエストを正常に処理しました(リソースが分割さ" +"れている可能性があります)" + +#: src/labels.h:391 +msgid "207 - Multi-Status: WebDAV; RFC 4918" +msgstr "207 - 複数ステータス: (WebDAV拡張) RFC 4918" + +#: src/labels.h:393 +msgid "208 - Already Reported: WebDAV; RFC 5842" +msgstr "208 - 報告済み: (WebDAV拡張) RFC 5842" + +#: src/labels.h:395 +msgid "300 - Multiple Choices: Multiple options for the resource" +msgstr "" +"300 - 選択が必要: 複数のリダイレクト先があり、クライアント側が選択する必要が" +"あります" + +#: src/labels.h:397 +msgid "301 - Moved Permanently: Resource has permanently moved" +msgstr "301 - 恒久的な移動: リクエストされたリソースは完全に移動されました" + +#: src/labels.h:399 +msgid "302 - Moved Temporarily (redirect)" +msgstr "302 - 一時的な移動: リクエストされたリソースは一時的に移動されました" + +#: src/labels.h:401 +msgid "303 - See Other Document: The response is at a different URI" +msgstr "" +"303 - 別コンテンツ: リクエストされたリソースは別のURLで提供されています" + +#: src/labels.h:403 +msgid "304 - Not Modified: Resource has not been modified" +msgstr "304 - 更新無し: リクエストされたリソースは更新されていません" + +#: src/labels.h:405 +msgid "305 - Use Proxy: Can only be accessed through the proxy" +msgstr "" +"305 - プロキシ使用: リクエストされたリソースはプロキシを使用して取得できます" + +#: src/labels.h:407 +msgid "307 - Temporary Redirect: Resource temporarily moved" +msgstr "307 - 一時的な移動: リクエストされたリソースは一時的に移動されました" + +#: src/labels.h:409 +msgid "400 - Bad Request: The syntax of the request is invalid" +msgstr "400 - 不正なリクエスト: リクエストを処理できません" + +#: src/labels.h:411 +msgid "401 - Unauthorized: Request needs user authentication" +msgstr "401 - 認証が必要: このリクエストを処理するには認証が必要です" + +#: src/labels.h:413 +msgid "402 - Payment Required" +msgstr "402 - このリクエストを処理するには料金を支払う必要があります" + +#: src/labels.h:415 +msgid "403 - Forbidden: Server is refusing to respond to it" +msgstr "403 - アクセス禁止: このリクエストへのアクセスは禁止されています" + +#: src/labels.h:417 +msgid "404 - Not Found: Requested resource could not be found" +msgstr "404 - リソース不明: リクエストされたリソースは存在しません" + +#: src/labels.h:419 +msgid "405 - Method Not Allowed: Request method not supported" +msgstr "" +"405 - 許可されていない: リクエストされたメソッドでのアクセスは禁止されていま" +"す" + +#: src/labels.h:421 +msgid "406 - Not Acceptable" +msgstr "406 - リクエストを受理できません" + +#: src/labels.h:423 +msgid "407 - Proxy Authentication Required" +msgstr "407 - プロキシ認証が必要です" + +#: src/labels.h:425 +msgid "408 - Request Timeout: Server timed out waiting for the request" +msgstr "408 - タイムアウト: リクエストがタイムアウトしました" + +#: src/labels.h:427 +msgid "409 - Conflict: Conflict in the request" +msgstr "409 - 衝突: リクエストが衝突しました" + +#: src/labels.h:429 +msgid "410 - Gone: Resource requested is no longer available" +msgstr "410 - 消滅: リクエストされたリソースは完全に削除されました" + +#: src/labels.h:431 +msgid "411 - Length Required: Invalid Content-Length" +msgstr "411 - Content-Lengthヘッダーが必要です" + +#: src/labels.h:433 +msgid "412 - Precondition Failed: Server does not meet preconditions" +msgstr "" +"412 - 前提条件が満たされていない: このリクエストはサーバー側の前提条件を満た" +"していません" + +#: src/labels.h:435 +msgid "413 - Payload Too Large" +msgstr "413 - ペイロードが長すぎます" + +#: src/labels.h:437 +msgid "414 - Request-URI Too Long" +msgstr "414 - URLが長すぎます" + +#: src/labels.h:439 +msgid "415 - Unsupported Media Type: Media type is not supported" +msgstr "415 - サポートされていないメディアタイプ" + +#: src/labels.h:441 +msgid "416 - Requested Range Not Satisfiable: Cannot supply that portion" +msgstr "" +"416 - リクエストされたContent-Lengthヘッダーの範囲がリソースより超過していま" +"す" + +#: src/labels.h:443 +msgid "417 - Expectation Failed" +msgstr "417 - 拡張ステータスコードが使えません" + +#: src/labels.h:445 +msgid "421 - Misdirected Request" +msgstr "421 - 不明なリクエスト" + +#: src/labels.h:447 +msgid "422 - Unprocessable Entity due to semantic errors: WebDAV" +msgstr "422 - リクエストを受理したが、処理を継続できません" + +#: src/labels.h:449 +msgid "423 - The resource that is being accessed is locked" +msgstr "423 - このリソースはロックされています" + +#: src/labels.h:451 +msgid "424 - Failed Dependency: WebDAV" +msgstr "424 - 依存する他の処理が失敗したため処理できません" + +#: src/labels.h:453 +msgid "426 - Upgrade Required: Client should switch to a different protocol" +msgstr "" +"426 - アップグレードが必要: プロトコルが古すぎてリクエストを処理できません" + +#: src/labels.h:455 +msgid "428 - Precondition Required" +msgstr "428 - リクエストを条件付きにする必要があります" + +#: src/labels.h:457 +msgid "429 - Too Many Requests: The user has sent too many requests" +msgstr "429 - 過重リクエスト: 制限されたリクエスト数を超えたので処理できません" + +#: src/labels.h:459 +msgid "431 - Request Header Fields Too Large" +msgstr "431 - HTTPヘッダーが長すぎます" + +#: src/labels.h:461 +msgid "451 - Unavailable For Legal Reasons" +msgstr "451 - 法律上の理由でリクエストを処理できません" + +#: src/labels.h:463 +msgid "444 - (Nginx) Connection closed without sending any headers" +msgstr "444 - (nginx) ヘッダーを返さずコネクションを切断しました" + +#: src/labels.h:465 +msgid "494 - (Nginx) Request Header Too Large" +msgstr "494 - (nginx) HTTPヘッダーが長すぎます" + +#: src/labels.h:467 +msgid "495 - (Nginx) SSL client certificate error" +msgstr "495 - (nginx) SSLクライアント証明書エラー" + +#: src/labels.h:469 +msgid "496 - (Nginx) Client didn't provide certificate" +msgstr "496 - (nginx) クライアントが証明書を提供しませんでした" + +#: src/labels.h:471 +msgid "497 - (Nginx) HTTP request sent to HTTPS port" +msgstr "497 - (nginx) HTTPリクエストをHTTPSポートに送信しました" + +#: src/labels.h:473 +msgid "499 - (Nginx) Connection closed by client while processing request" +msgstr "" +"499 - (nginx) リクエストを処理中にクライアントによって接続を閉じられました" + +#: src/labels.h:475 +msgid "500 - Internal Server Error" +msgstr "500 - 内部サーバーエラー" + +#: src/labels.h:477 +msgid "501 - Not Implemented" +msgstr "501 - サーバーでメソッドが実装されていません" + +#: src/labels.h:479 +msgid "502 - Bad Gateway: Received an invalid response from the upstream" +msgstr "" +"502 - 不正なゲートウェイ: 上流にあるゲートウェイまたはプロキシサーバーから不" +"正なリクエストを受け取りました" + +#: src/labels.h:481 +msgid "503 - Service Unavailable: The server is currently unavailable" +msgstr "503 - サービス利用不可: サーバーがダウンしました" + +#: src/labels.h:483 +msgid "504 - Gateway Timeout: The upstream server failed to send request" +msgstr "" +"504 - ゲートウェイタイムアウト: 上流にあるゲートウェイまたはプロキシサーバー" +"がタイムアウトを起こしました" + +#: src/labels.h:485 +msgid "505 - HTTP Version Not Supported" +msgstr "" +"505 - リクエストで使用されているHTTPバージョンがサーバーでサポートされていま" +"せん" + +#: src/labels.h:487 +msgid "520 - CloudFlare - Web server is returning an unknown error" +msgstr "520 - CloudFlare - Originサーバーからエラーが返されました" + +#: src/labels.h:489 +msgid "521 - CloudFlare - Web server is down" +msgstr "521 - CloudFlare - Originサーバーがダウンしています" + +#: src/labels.h:491 +msgid "522 - CloudFlare - Connection timed out" +msgstr "522 - CloudFlare - Originサーバーへの接続がタイムアウトしました" + +#: src/labels.h:493 +msgid "523 - CloudFlare - Origin is unreachable" +msgstr "523 - CloudFlare - Originサーバーにアクセスできません(到達不能)" + +#: src/labels.h:495 +msgid "524 - CloudFlare - A timeout occurred" +msgstr "524 - CloudFlare - Originサーバーにアクセスできません(タイムアウト)" diff --git a/goaccess++/po/quot.sed b/goaccess++/po/quot.sed new file mode 100644 index 0000000..0122c46 --- /dev/null +++ b/goaccess++/po/quot.sed @@ -0,0 +1,6 @@ +s/"\([^"]*\)"/“\1”/g +s/`\([^`']*\)'/‘\1’/g +s/ '\([^`']*\)' / ‘\1’ /g +s/ '\([^`']*\)'$/ ‘\1’/g +s/^'\([^`']*\)' /‘\1’ /g +s/“”/""/g diff --git a/goaccess++/po/remove-potcdate.sin b/goaccess++/po/remove-potcdate.sin new file mode 100644 index 0000000..2436c49 --- /dev/null +++ b/goaccess++/po/remove-potcdate.sin @@ -0,0 +1,19 @@ +# Sed script that remove the POT-Creation-Date line in the header entry +# from a POT file. +# +# The distinction between the first and the following occurrences of the +# pattern is achieved by looking at the hold space. +/^"POT-Creation-Date: .*"$/{ +x +# Test if the hold space is empty. +s/P/P/ +ta +# Yes it was empty. First occurrence. Remove the line. +g +d +bb +:a +# The hold space was nonempty. Following occurrences. Do nothing. +x +:b +} diff --git a/goaccess++/po/stamp-po b/goaccess++/po/stamp-po new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/goaccess++/po/stamp-po @@ -0,0 +1 @@ +timestamp diff --git a/goaccess++/po/zh_CN.gmo b/goaccess++/po/zh_CN.gmo new file mode 100644 index 0000000..bb4db2e Binary files /dev/null and b/goaccess++/po/zh_CN.gmo differ diff --git a/goaccess++/po/zh_CN.po b/goaccess++/po/zh_CN.po new file mode 100644 index 0000000..5f73e35 --- /dev/null +++ b/goaccess++/po/zh_CN.po @@ -0,0 +1,899 @@ +# This file is distributed under the same license as the goaccess package. +# Ai, 2018. +# +msgid "" +msgstr "" +"Project-Id-Version: goaccess 1.2\n" +"Report-Msgid-Bugs-To: hello@goaccess.io\n" +"POT-Creation-Date: 2018-11-22 23:38-0600\n" +"PO-Revision-Date: 2017-04-03 09:43+0200\n" +"Last-Translator: Ai<hello@goaccess.io>\n" +"Language-Team: Ai\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Gtranslator 2.91.7\n" + +#: src/labels.h:40 +msgid "en" +msgstr "zh-CN" + +#: src/labels.h:43 +msgid "Exp. Panel" +msgstr "展开面板" + +#: src/labels.h:44 +msgid "Help" +msgstr "帮助" + +#: src/labels.h:45 +msgid "Quit" +msgstr "退出" + +#: src/labels.h:46 +msgid "Total" +msgstr "总共" + +#: src/labels.h:49 +msgid "[x] ASC [ ] DESC" +msgstr "[x] 递增 [ ] 递减" + +#: src/labels.h:50 +msgid "[ ] ASC [x] DESC" +msgstr "[ ] 递增 [x] 递减" + +#: src/labels.h:53 +#, c-format +msgid "[Active Panel: %1$s]" +msgstr "[当前面板: %1$s]" + +#: src/labels.h:54 +msgid "[q]uit GoAccess" +msgstr "[q]退出GoAccess" + +#: src/labels.h:55 +msgid "[?] Help [Enter] Exp. Panel" +msgstr "[?]帮助 [回车]展开面板" + +#: src/labels.h:56 +msgid "Dashboard" +msgstr "概览" + +#: src/labels.h:57 +msgid "Dashboard - Overall Analyzed Requests" +msgstr "概览-所有已分析的请求" + +#: src/labels.h:58 +msgid "Overall Analyzed Requests" +msgstr "所有已分析的请求" + +#: src/labels.h:60 src/labels.h:81 +msgid "Tx. Amount" +msgstr "" + +#: src/labels.h:61 +msgid "Date/Time" +msgstr "时期/时间" + +#: src/labels.h:62 +msgid "Excl. IP Hits" +msgstr "过滤来自此IP的请求" + +#: src/labels.h:63 +msgid "Failed Requests" +msgstr "失败的请求" + +#: src/labels.h:64 +msgid "Init. Proc. Time" +msgstr "第一次处理耗时" + +#: src/labels.h:65 +msgid "Log Size" +msgstr "日志大小" + +#: src/labels.h:66 +msgid "Log Source" +msgstr "日志文件夹地址" + +#: src/labels.h:67 src/labels.h:174 +msgid "Referrers" +msgstr "来源地址" + +#: src/labels.h:68 +msgid "Total Requests" +msgstr "所有请求" + +#: src/labels.h:69 +msgid "Static Files" +msgstr "静态文件" + +#: src/labels.h:70 src/labels.h:146 +msgid "Not Found" +msgstr "未找到(404)" + +#: src/labels.h:71 +msgid "Requested Files" +msgstr "请求的文件" + +#: src/labels.h:72 +msgid "Unique Visitors" +msgstr "独立访客" + +#: src/labels.h:73 +msgid "Valid Requests" +msgstr "有效的请求" + +#: src/labels.h:76 +msgid "Hits" +msgstr "点击量" + +#: src/labels.h:77 +msgid "h%" +msgstr "" + +#: src/labels.h:78 src/labels.h:104 +msgid "Visitors" +msgstr "访客" + +#: src/labels.h:79 +msgid "Vis." +msgstr "访客" + +#: src/labels.h:80 +msgid "v%" +msgstr "" + +#: src/labels.h:82 +msgid "Avg. T.S." +msgstr "平均响应时" + +#: src/labels.h:83 +msgid "Cum. T.S." +msgstr "总共响应时" + +#: src/labels.h:84 +msgid "Max. T.S." +msgstr "最高响应时" + +#: src/labels.h:85 +msgid "Method" +msgstr "请求方法" + +#: src/labels.h:86 +msgid "Mtd" +msgstr "请求方法" + +#: src/labels.h:87 +msgid "Protocol" +msgstr "协议" + +#: src/labels.h:88 +msgid "Proto" +msgstr "协议" + +#: src/labels.h:89 +msgid "City" +msgstr "城市" + +#: src/labels.h:90 +msgid "Country" +msgstr "国家" + +#: src/labels.h:91 +msgid "Hostname" +msgstr "主机名" + +#: src/labels.h:92 +msgid "Data" +msgstr "数据" + +#: src/labels.h:94 +msgid "Hits/Visitors" +msgstr "点击量/访客" + +#: src/labels.h:98 +msgid "Unique visitors per day" +msgstr "每日独立访客" + +#: src/labels.h:100 +msgid "Unique visitors per day - Including spiders" +msgstr "每日独立访客 - 包括网络机器人" + +#: src/labels.h:102 +msgid "Hits having the same IP, date and agent are a unique visit." +msgstr "来自同一IP、时间和Http用户代理的多次点击被视作一次访问" + +#: src/labels.h:107 +msgid "Requested Files (URLs)" +msgstr "请求的文件" + +#: src/labels.h:109 +msgid "Top requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" +"请求排序按 [点击量, 平均响应时, 总共响应时, 最高响应时, 请求方法, 协议]" + +#: src/labels.h:111 +msgid "Requests" +msgstr "请求" + +#: src/labels.h:114 src/labels.h:118 +msgid "Static Requests" +msgstr "静态请求" + +#: src/labels.h:116 +msgid "Top static requests sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" +"静态请求排序按 [点击量, 平均响应时, 总共响应时, 最高响应时, 请求方法, 协议]" + +#: src/labels.h:121 +msgid "Time Distribution" +msgstr "时间分配" + +#: src/labels.h:123 +msgid "Data sorted by hour [, avgts, cumts, maxts]" +msgstr "数据列排序按 [小时, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:125 +msgid "Time" +msgstr "时间" + +#: src/labels.h:128 src/labels.h:132 +msgid "Virtual Hosts" +msgstr "虚拟主机" + +#: src/labels.h:130 src/labels.h:137 +msgid "Data sorted by hits [, avgts, cumts, maxts]" +msgstr "数据列排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:135 +msgid "Remote User (HTTP authentication)" +msgstr "已认证用户(HTTP authentication)" + +#: src/labels.h:139 +msgid "Remote User" +msgstr "已认证用户" + +#: src/labels.h:142 +msgid "Not Found URLs (404s)" +msgstr "未找到的URLs" + +#: src/labels.h:144 +msgid "Top not found URLs sorted by hits [, avgts, cumts, maxts, mthd, proto]" +msgstr "" +"未找到的URLs排序按 [点击量, 平均响应时, 总共响应时, 最高响应时, 请求方法, 协" +"议]" + +#: src/labels.h:149 +msgid "Visitor Hostnames and IPs" +msgstr "访客主机名和IP地址" + +#: src/labels.h:151 +msgid "Top visitor hosts sorted by hits [, avgts, cumts, maxts]" +msgstr "访客主机排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:153 +msgid "Hosts" +msgstr "主机" + +#: src/labels.h:156 +msgid "Operating Systems" +msgstr "操作系统" + +#: src/labels.h:158 +msgid "Top Operating Systems sorted by hits [, avgts, cumts, maxts]" +msgstr "操作系统排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:160 +msgid "OS" +msgstr "操作系统" + +#: src/labels.h:163 src/labels.h:167 +msgid "Browsers" +msgstr "浏览器" + +#: src/labels.h:165 +msgid "Top Browsers sorted by hits [, avgts, cumts, maxts]" +msgstr "浏览器排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:170 +msgid "Referrers URLs" +msgstr "来源地址URLs" + +#: src/labels.h:172 +msgid "Top Requested Referrers sorted by hits [, avgts, cumts, maxts]" +msgstr "来源地址排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:177 src/labels.h:181 +msgid "Referring Sites" +msgstr "推荐网站" + +#: src/labels.h:179 +msgid "Top Referring Sites sorted by hits [, avgts, cumts, maxts]" +msgstr "推荐网站排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:184 +msgid "Keyphrases from Google's search engine" +msgstr "谷歌搜索关键字" + +#: src/labels.h:186 +msgid "Top Keyphrases sorted by hits [, avgts, cumts, maxts]" +msgstr "关键字排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:188 +msgid "Keyphrases" +msgstr "关键字" + +#: src/labels.h:191 src/labels.h:195 +msgid "Geo Location" +msgstr "地理位置" + +#: src/labels.h:193 +msgid "Continent > Country sorted by unique hits [, avgts, cumts, maxts]" +msgstr "大陆 > 国家排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:198 +msgid "HTTP Status Codes" +msgstr "HTTP状态码" + +#: src/labels.h:200 +msgid "Top HTTP Status Codes sorted by hits [, avgts, cumts, maxts]" +msgstr "HTTP状态码排序按 [点击量, 平均响应时, 总共响应时, 最高响应时]" + +#: src/labels.h:202 +msgid "Status Codes" +msgstr "状态码" + +#: src/labels.h:206 +msgid "[ ] case sensitive" +msgstr "[ ] 区分大小写" + +#: src/labels.h:208 +msgid "[x] case sensitive" +msgstr "[x] 区分大小写" + +#: src/labels.h:210 +msgid "Regex allowed - ^g to cancel - TAB switch case" +msgstr "允许正则表达式 - ^g退出 - TAB改变大小写" + +#: src/labels.h:212 +msgid "Find pattern in all views" +msgstr "在所有界面中查找匹配模式" + +#: src/labels.h:216 +msgid "Log Format Configuration" +msgstr "日志格式设置" + +#: src/labels.h:218 +msgid "[SPACE] to toggle - [ENTER] to proceed - [q] to quit" +msgstr "[空格]切换 - [回车]继续 - [q]退出" + +#: src/labels.h:220 +msgid "Log Format - [c] to add/edit format" +msgstr "日志格式 - [c]新建/修改格式" + +#: src/labels.h:222 +msgid "Date Format - [d] to add/edit format" +msgstr "日期格式 - [d]新建/修改格式" + +#: src/labels.h:224 +msgid "Time Format - [t] to add/edit format" +msgstr "时间格式 - [t]新建/修改格式" + +#: src/labels.h:226 src/labels.h:230 +msgid "[UP/DOWN] to scroll - [q] to close window" +msgstr "[UP/DOWN]上下滚动 - [q]退出" + +#: src/labels.h:232 +#, c-format +msgid "User Agents for %1$s" +msgstr "用户代理 %1$s" + +#: src/labels.h:236 +msgid "Scheme Configuration" +msgstr "颜色方案设置" + +#: src/labels.h:238 +msgid "[ENTER] to use scheme - [q]uit" +msgstr "[回车]选取方案 - [q]退出" + +#: src/labels.h:242 +msgid "Sort active module by" +msgstr "当前选择栏目排序" + +#: src/labels.h:244 +msgid "[ENTER] select - [TAB] sort - [q]uit" +msgstr "[回车]选择 - [TAB]排序 - [q]退出" + +#: src/labels.h:248 +msgid "GoAccess Quick Help" +msgstr "GoAccess快速帮助" + +#: src/labels.h:250 +msgid "[UP/DOWN] to scroll - [q] to quit" +msgstr "[UP/DOWN]上下滚动 - [q]退出" + +#: src/labels.h:254 +msgid "Built using Tokyo Cabinet on-disk B+ Tree." +msgstr "使用Tokyo Cabinet在磁盘中的B+树来构建" + +#: src/labels.h:256 +msgid "Built using Tokyo Cabinet in-memory hash database." +msgstr "使用Tokyo Cabinet的内存中的哈希表来构建" + +#: src/labels.h:258 +msgid "Built using the default in-memory hash database." +msgstr "使用默认的在内存中的哈希表来构建" + +#: src/labels.h:262 +msgid "Format Errors - Verify your log/date/time format" +msgstr "格式错误 - 请检查你的日志/日期/时间格式" + +#: src/labels.h:264 +msgid "No date format was found on your conf file." +msgstr "未在配置文件中设置日期格式" + +#: src/labels.h:266 +msgid "No log format was found on your conf file." +msgstr "未在配置文件中设置日志格式" + +#: src/labels.h:268 +msgid "No time format was found on your conf file." +msgstr "未在配置文件中设置时间格式" + +#: src/labels.h:270 +msgid "No default config file found." +msgstr "未找到默认的配置文件" + +#: src/labels.h:272 +msgid "You may specify one with" +msgstr "你可以指定配置文件" + +#: src/labels.h:274 +msgid "producing the following errors" +msgstr "出现以下错误" + +#: src/labels.h:276 +#, c-format +msgid "Parsed %1$d lines" +msgstr "已解析 %1$d 行" + +#: src/labels.h:278 +msgid "Please report it by opening an issue on GitHub" +msgstr "请在GitHub中添加一个issue来给我们反馈信息" + +#: src/labels.h:280 +msgid "Select a time format." +msgstr "选择时间格式" + +#: src/labels.h:282 +msgid "Select a date format." +msgstr "选择日期格式" + +#: src/labels.h:284 +msgid "Select a log format." +msgstr "选择日志格式" + +#: src/labels.h:286 +#, c-format +msgid "'%1$s' panel is disabled" +msgstr "'%1$s' 面板已禁用" + +#: src/labels.h:290 +msgid "For more details visit" +msgstr "更多信息请访问" + +#: src/labels.h:292 +msgid "Last Updated" +msgstr "最近更新" + +#: src/labels.h:294 +msgid "WebSocket server ready to accept new client connections" +msgstr "WebSocket服务器已准备接收来自客户的连接" + +#: src/labels.h:297 +msgid "The following options can also be supplied to the command" +msgstr "你也可以在command中选择以下选项" + +#: src/labels.h:299 +msgid "Examples can be found by running" +msgstr "运行一下指令查看更多示例" + +#: src/labels.h:302 +msgid "Server Statistics" +msgstr "服务器统计信息" + +#: src/labels.h:304 +msgid "Theme" +msgstr "主题" + +#: src/labels.h:306 +msgid "Dark Gray" +msgstr "深黑" + +#: src/labels.h:308 +msgid "Bright" +msgstr "明亮" + +#: src/labels.h:310 +msgid "Dark Blue" +msgstr "深蓝" + +#: src/labels.h:312 +#, fuzzy +msgid "Dark Purple" +msgstr "深蓝" + +#: src/labels.h:314 +msgid "Panels" +msgstr "面板" + +#: src/labels.h:316 +msgid "Items per Page" +msgstr "每页项目" + +#: src/labels.h:318 +msgid "Tables" +msgstr "表格" + +#: src/labels.h:320 +msgid "Display Tables" +msgstr "显示表格" + +#: src/labels.h:322 +msgid "Auto-Hide on Small Devices" +msgstr "屏幕过小时自动隐藏" + +#: src/labels.h:324 +msgid "Automatically hide tables on small screen devices" +msgstr "屏幕过小时自动隐藏表格" + +#: src/labels.h:326 +msgid "Layout" +msgstr "布局" + +#: src/labels.h:328 +msgid "Horizontal" +msgstr "横向" + +#: src/labels.h:330 +msgid "Vertical" +msgstr "纵向" + +#: src/labels.h:332 +msgid "File Options" +msgstr "文件选项" + +#: src/labels.h:334 +msgid "Export as JSON" +msgstr "导出为JSON文件" + +#: src/labels.h:336 +msgid "Panel Options" +msgstr "面板选项" + +#: src/labels.h:338 +msgid "Previous" +msgstr "后退" + +#: src/labels.h:340 +msgid "Next" +msgstr "前进" + +#: src/labels.h:342 +msgid "First" +msgstr "" + +#: src/labels.h:344 +msgid "Last" +msgstr "" + +#: src/labels.h:346 +msgid "Chart Options" +msgstr "图表选项" + +#: src/labels.h:348 +msgid "Chart" +msgstr "图表" + +#: src/labels.h:350 +msgid "Type" +msgstr "类型" + +#: src/labels.h:352 +msgid "Area Spline" +msgstr "AreaSpline图表" + +#: src/labels.h:354 +msgid "Bar" +msgstr "条形图" + +#: src/labels.h:356 +msgid "Plot Metric" +msgstr "绘制度量" + +# change +#: src/labels.h:358 +msgid "Table Columns" +msgstr "表格列" + +#: src/labels.h:362 +msgid "1xx Informational" +msgstr "1xx 消息" + +#: src/labels.h:364 +msgid "2xx Success" +msgstr "2xx 成功" + +#: src/labels.h:366 +msgid "3xx Redirection" +msgstr "3xx Url重定向" + +#: src/labels.h:368 +msgid "4xx Client Errors" +msgstr "4xx 客户端错" + +#: src/labels.h:370 +msgid "5xx Server Errors" +msgstr "5xx 服务器错" + +#: src/labels.h:373 +msgid "100 - Continue: Server received the initial part of the request" +msgstr "100 - 继续: 服务器已经接收到请求头" + +#: src/labels.h:375 +msgid "101 - Switching Protocols: Client asked to switch protocols" +msgstr "101 - 更改协议: 客户端被通知变更协议来完成请求" + +#: src/labels.h:377 +msgid "200 - OK: The request sent by the client was successful" +msgstr "200 - 成功: 请求成功" + +#: src/labels.h:379 +msgid "201 - Created: The request has been fulfilled and created" +msgstr "201 - 已创建: 请求成功并且服务器创建了新的资源" + +#: src/labels.h:381 +msgid "202 - Accepted: The request has been accepted for processing" +msgstr "202 - 已接收: 服务器已接受请求,但尚未处理" + +#: src/labels.h:383 +msgid "203 - Non-authoritative Information: Response from a third party" +msgstr "203 - 非授权信息: 服务器已成功处理请求 但返回的信息可能来自另一来源" + +#: src/labels.h:385 +msgid "204 - No Content: Request did not return any content" +msgstr "204 - 无内容: 没有返回任何内容" + +#: src/labels.h:387 +msgid "205 - Reset Content: Server asked the client to reset the document" +msgstr "205 - 重置内容: 服务器已成功处理请求 但没有返回任何内容" + +#: src/labels.h:389 +msgid "206 - Partial Content: The partial GET has been successful" +msgstr "206 - 部分内容: 服务器成功处理了部分GET请求" + +#: src/labels.h:391 +msgid "207 - Multi-Status: WebDAV; RFC 4918" +msgstr "207 - 多状态: WebDAV; RFC 4918" + +#: src/labels.h:393 +msgid "208 - Already Reported: WebDAV; RFC 5842" +msgstr "208 - 已报告: WebDAV; RFC 5842" + +#: src/labels.h:395 +msgid "300 - Multiple Choices: Multiple options for the resource" +msgstr "300 - 多重选择: 资源提供多种选项让客户端选择" + +#: src/labels.h:397 +msgid "301 - Moved Permanently: Resource has permanently moved" +msgstr "301 - 永久移除: 资源已被永久移动到新位置" + +#: src/labels.h:399 +msgid "302 - Moved Temporarily (redirect)" +msgstr "302 - 临时移动" + +#: src/labels.h:401 +msgid "303 - See Other Document: The response is at a different URI" +msgstr "303 - 查看其他位置: 当前请求的响应在另一个URI上被找到" + +#: src/labels.h:403 +msgid "304 - Not Modified: Resource has not been modified" +msgstr "304 - 未修改: 资源未被修改" + +#: src/labels.h:405 +msgid "305 - Use Proxy: Can only be accessed through the proxy" +msgstr "305 - 使用代理: 只能通过代理访问资源" + +#: src/labels.h:407 +msgid "307 - Temporary Redirect: Resource temporarily moved" +msgstr "307 - 临时重定向: 临时从另外的URI响应" + +#: src/labels.h:409 +msgid "400 - Bad Request: The syntax of the request is invalid" +msgstr "400 - 错误请求: 客户端语法错误" + +#: src/labels.h:411 +msgid "401 - Unauthorized: Request needs user authentication" +msgstr "401 - 未授权: 当前请求需要用户授权" + +#: src/labels.h:413 +msgid "402 - Payment Required" +msgstr "402 - 需要支付" + +#: src/labels.h:415 +msgid "403 - Forbidden: Server is refusing to respond to it" +msgstr "403 - 禁止: 服务器拒绝响应请求" + +#: src/labels.h:417 +msgid "404 - Not Found: Requested resource could not be found" +msgstr "404 - 未找到: 找不到请求的资源" + +#: src/labels.h:419 +msgid "405 - Method Not Allowed: Request method not supported" +msgstr "405 - 方法禁用: 不支持请求中指定的方法" + +#: src/labels.h:421 +msgid "406 - Not Acceptable" +msgstr "406 - 无法接收" + +#: src/labels.h:423 +msgid "407 - Proxy Authentication Required" +msgstr "407 - 需要代理授权" + +#: src/labels.h:425 +msgid "408 - Request Timeout: Server timed out waiting for the request" +msgstr "408 - 请求超时: 服务器在等候请求时超时" + +#: src/labels.h:427 +msgid "409 - Conflict: Conflict in the request" +msgstr "409 - 冲突: 服务器在完成请求时发生冲突" + +#: src/labels.h:429 +msgid "410 - Gone: Resource requested is no longer available" +msgstr "410 - 已删除: 请求的资源已永久删除" + +#: src/labels.h:431 +msgid "411 - Length Required: Invalid Content-Length" +msgstr "411 - 需要有效长度: Content-Length无效" + +#: src/labels.h:433 +msgid "412 - Precondition Failed: Server does not meet preconditions" +msgstr "412 - 未满足前提条件: 服务器未满足请求中的前提条件" + +#: src/labels.h:435 +msgid "413 - Payload Too Large" +msgstr "413 - 请求实体过大" + +#: src/labels.h:437 +msgid "414 - Request-URI Too Long" +msgstr "414 - 请求的URI过长" + +#: src/labels.h:439 +msgid "415 - Unsupported Media Type: Media type is not supported" +msgstr "415 - 不支持的媒体类型" + +#: src/labels.h:441 +msgid "416 - Requested Range Not Satisfiable: Cannot supply that portion" +msgstr "416 - 请求范围不符合要求" + +#: src/labels.h:443 +msgid "417 - Expectation Failed" +msgstr "417 - 未满足期望值" + +#: src/labels.h:445 +msgid "421 - Misdirected Request" +msgstr "421 - 被误导的请求" + +#: src/labels.h:447 +msgid "422 - Unprocessable Entity due to semantic errors: WebDAV" +msgstr "422 - 请求格式正确但因存在语法错而无法响应" + +#: src/labels.h:449 +msgid "423 - The resource that is being accessed is locked" +msgstr "423 - 当前资源被锁定" + +#: src/labels.h:451 +msgid "424 - Failed Dependency: WebDAV" +msgstr "424 - 失败的依赖" + +#: src/labels.h:453 +msgid "426 - Upgrade Required: Client should switch to a different protocol" +msgstr "426 - 需要升级: 客户端应该切换到其他的协议" + +#: src/labels.h:455 +msgid "428 - Precondition Required" +msgstr "428 - 需要前提条件" + +#: src/labels.h:457 +msgid "429 - Too Many Requests: The user has sent too many requests" +msgstr "429 - 请求过多: 客户端发送了太多请求" + +#: src/labels.h:459 +msgid "431 - Request Header Fields Too Large" +msgstr "431 - 请求头字段太长" + +#: src/labels.h:461 +msgid "451 - Unavailable For Legal Reasons" +msgstr "451 - 因法律原因不可用" + +#: src/labels.h:463 +msgid "444 - (Nginx) Connection closed without sending any headers" +msgstr "444 - (Nginx) 未发送响应头且连接已关闭" + +#: src/labels.h:465 +msgid "494 - (Nginx) Request Header Too Large" +msgstr "494 - (Nginx) 请求头太大" + +#: src/labels.h:467 +msgid "495 - (Nginx) SSL client certificate error" +msgstr "495 - (Nginx) SSL客户端证书错" + +#: src/labels.h:469 +msgid "496 - (Nginx) Client didn't provide certificate" +msgstr "496 - (Nginx) 客户端未提供证书" + +#: src/labels.h:471 +msgid "497 - (Nginx) HTTP request sent to HTTPS port" +msgstr "497 - (Nginx) HTTP请求被发送到了HTTPS端口" + +#: src/labels.h:473 +msgid "499 - (Nginx) Connection closed by client while processing request" +msgstr "499 - (Nginx) 处理请求时连接被客户端关闭" + +#: src/labels.h:475 +msgid "500 - Internal Server Error" +msgstr "500 - 服务器内部错" + +#: src/labels.h:477 +msgid "501 - Not Implemented" +msgstr "501 - 尚未实施" + +#: src/labels.h:479 +msgid "502 - Bad Gateway: Received an invalid response from the upstream" +msgstr "502 - 错误网关: 服务器作为网关或代理, 从上游服务器收到无效响应" + +#: src/labels.h:481 +msgid "503 - Service Unavailable: The server is currently unavailable" +msgstr "503 - 服务不可用: 服务器无法使用" + +#: src/labels.h:483 +msgid "504 - Gateway Timeout: The upstream server failed to send request" +msgstr "504 - 网关超时: 服务器作为网关或代理, 未从上游服务器收到请求" + +#: src/labels.h:485 +msgid "505 - HTTP Version Not Supported" +msgstr "505 - HTTP版本不受支持" + +#: src/labels.h:487 +msgid "520 - CloudFlare - Web server is returning an unknown error" +msgstr "520 - CloudFlare - 服务器返回一个未知错误" + +#: src/labels.h:489 +msgid "521 - CloudFlare - Web server is down" +msgstr "521 - CloudFlare - 服务器挂了" + +#: src/labels.h:491 +msgid "522 - CloudFlare - Connection timed out" +msgstr "522 - CloudFlare - 连接超时" + +#: src/labels.h:493 +msgid "523 - CloudFlare - Origin is unreachable" +msgstr "523 - CloudFlare - 服务器无法访问" + +#: src/labels.h:495 +msgid "524 - CloudFlare - A timeout occurred" +msgstr "524 - CloudFlare - 服务器响应超时" + +#~ msgid "Bandwidth" +#~ msgstr "带宽" + +#~ msgid "Unique Files" +#~ msgstr "唯一的文件" + +#~ msgid "Unique 404" +#~ msgstr "唯一的404" + +#~ msgid " - Including spiders" +#~ msgstr "- 包括网络机器人" diff --git a/goaccess++/resources/css/app.css b/goaccess++/resources/css/app.css new file mode 100644 index 0000000..a54201c --- /dev/null +++ b/goaccess++/resources/css/app.css @@ -0,0 +1,987 @@ +/* GLOBAL */ +html, +body { + background: #f0f0f0; + overflow-x: hidden; +} +h1 { + font-weight: bold; + letter-spacing: -3px; +} +h3 { + font-size: 21px; + letter-spacing: -1px; +} +.page-header { + border-bottom: 1px solid rgba(0, 0, 0, 0.15); + margin: 25px 0 20px; + position: relative; +} +.page-header h1 { + margin: 0; +} +.pagination { + margin: 5px 0; +} +.clickable, +.expandable>td { + cursor: pointer; +} +.spinner { + color: #999; + left: 50%; + position: absolute; + top: 50%; +} +.powered { + bottom: 190px; + color: #9E9E9E; + font-size: smaller; + position: absolute; + right: 20px; + transform-origin: 100% 0; + transform: rotate(-90deg); +} +.powered a { + color: #636363; +} +.powered span { + color: #007bc3; +} +.dropdown-header { + color: #007bc3; + padding: 3px 25px; + text-transform: uppercase; +} +.gheader { + letter-spacing: -1px; + text-transform: uppercase; +} +h5.gheader { + letter-spacing: 0; +} +.panel-header h4.gheader { + margin-top: 20px; +} +.panel-header .gheader small { + font-size: 69%; +} + +/* NAVIGATION */ +nav { + -webkit-transition: left .2s; + background: #1C1C1C; + border-right: 3px solid #5bc0de; + height: 100%; + left: -236px; + overflow: hidden; + position: fixed; + top: 0; + transition: left .2s; + width: 300px; + z-index: 2; +} +nav .nav-list { + height: 100%; + overflow-y: auto; + width: 350px; +} +nav header { + margin: 40px 20px 30px; +} +nav header a { + color: rgba(240,240,240,.7); + font-size: 2.7em; + font-weight: 300; + text-transform: uppercase; +} +nav header a:hover { + color: #eee; +} +nav.active { + display: block !important; + left: 0; + opacity: .97; +} +nav:hover ~ #content { + opacity: .3; +} +nav.active .nav-bars, +nav.active .nav-gears, +nav.active .nav-ws-status { + opacity: 0; +} +nav .nav-bars, +nav .nav-gears, +nav .nav-ws-status { + -webkit-transition: opacity .2s; + color: #9E9E9E; + cursor: pointer; + float: right; + font-size: 36px; + height: 32px; + left: 13px; + line-height: 32px; + position: fixed; + text-align: center; + top: 30px; + transition: opacity .2s; + width: 32px; +} +nav .nav-gears { + top: 100px; + opacity: 0.6; +} +nav .nav-ws-status, +.nav-ws-status.mini { + color: #6A6A6A; + cursor: help; + display: none; + font-size: 12px; +} +nav .nav-ws-status { + left: 25px; + top: 125px; +} +.nav-ws-status.mini { + top: 14px; + left: 50px; + position: absolute; +} +.nav-ws-status.connected { + color: #5DB56A; +} +nav li a { + border-left: 3px solid transparent; + color: rgba(200,200,200,.5); + display: block; + font-size: smaller; + max-width: 235px; + opacity: 0; + overflow: hidden; + padding: 9px 20px; + text-overflow: ellipsis; + text-transform: uppercase; + transition: opacity .2s; + white-space: nowrap; +} +nav.active li a { + max-width: 100%; + opacity: 1; +} +nav li a:hover, +nav li.active a { + background: rgba(0,0,0,.1); + border-color: #5BC0DE; + color: #eee; +} +nav ul { + padding-left: 0; + list-style: none; +} +/* Navigation -- Icon */ +nav a, +nav a:hover { + text-decoration: none; +} +nav h3 { + color: #FFF !important; + font-size: medium; + font-weight: bold; + margin: 20px 25px 10px; + text-transform: uppercase; +} + +/* CONTAINER */ +@media screen and (max-width: 767px) { + .row-offcanvas { + -webkit-transition: all .25s ease-out; + -o-transition: all .25s ease-out; + position: relative; + transition: all .25s ease-out; + } + + .row-offcanvas-right { + right: 0; + } + + .row-offcanvas-left { + left: 0; + } + + .row-offcanvas-right + .sidebar-offcanvas { + right: -50%; + } + + .row-offcanvas-left + .sidebar-offcanvas { + left: -50%; + } + + .row-offcanvas-right.active { + right: 50%; + } + + .row-offcanvas-left.active { + left: 50%; + } + + .sidebar-offcanvas { + position: absolute; + top: 0; + width: 50%; + }; +} +@media (min-width: 768px) { + .container { + width: 750px; + }; +} +@media (max-width: 480px) { + .wrap-general h5, + .wrap-panel h5 { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + .wrap-general h5 { + width: 100% + } + .wrap-panel h5 { + width: 70% + } +} +.container-fluid { + margin-left: 75px; +} +@media (min-width: 1120px) { + .container { + width: 970px; + }; +} +@media (min-width: 1320px) { + .container { + width: 1170px; + }; +} +@media (max-width: 992px) { + .container-fluid { + margin-left: auto; + }; +} +@media (max-width: 768px) { + .container-fluid { + padding-left: 5px; + padding-right: 5px; + } + .page-header { + padding: 0 10px; + } +} + +/* PANEL STYLES */ +.wrap-panel .panel-header { + position: relative; +} +div.wrap-panel > div { + background: #FFF; + margin-top: 10px; + padding: 0 10px; + border-top: 1px solid rgba(0, 0, 0, 0.15); +} + +/* PANEL TABLES */ +.wrap-panel table.table-borderless tbody tr td, +.wrap-panel table.table-borderless tbody tr th, +.wrap-panel table.table-borderless thead tr th { + border: none; +} +.wrap-panel table thead tr th { + text-align: right; + border-bottom-width: 1px; +} +.wrap-panel table .string, +.wrap-panel table .date { + text-align: left; +} +.wrap-panel table .percent { + color: #898989; +} +.wrap-panel table td, +.wrap-panel table th { + white-space: nowrap; + overflow: hidden; +} +.wrap-panel table th.sortable { + cursor: pointer; +} +/* thead meta */ +.wrap-panel table tbody.tbody-meta { + border-top: 1px solid #C7C7C7; + border-bottom: 1px solid #C7C7C7; +} +.wrap-panel table tbody.tbody-meta tr { + background-color: #F1F1F1; + color: #222; +} +.wrap-panel table tbody.tbody-meta small { + font-size: 65%; +} +/* thead data */ +.wrap-panel table tbody.tbody-data tr td { + border-right: 1px solid #F1F1F1; + font-size: smaller; +} +.wrap-panel table tbody.tbody-data td:last-child { + border-right: none; +} +.wrap-panel table tbody.tbody-data td.row-idx { + color: #898989; +} +.wrap-panel table>tbody+tbody { + border-top-width: 1px; +} +.wrap-panel table tbody.tbody-data tr.shaded { + background-color: #F7F7F7; +} +.wrap-panel table tbody.tbody-data tr. { + background-color: #F7F7F7; +} +.wrap-panel table tbody.tbody-data tr.child td:nth-child(1), +.wrap-panel table tbody.tbody-data tr.child td:nth-child(2) { + border-right: none; +} +.wrap-panel table.table-hover>tbody>tr:hover { + background-color: #EEE; +} + +/* GENERAL */ +.wrap-general { + position: relative; +} +.report-title { + background: #FFF; + border-radius: 4px; + bottom: -10px; + color: #9E9E9E; + font-size: small; + padding: 0 10px; + position: absolute; + right: 0; + z-index: 1; +} +.panel-plot-wrap { + position: absolute; + right: 0; + top: 18px; +} +.col-title { + font-size: 85%; + overflow: hidden; + text-overflow: ellipsis; + text-shadow: 1px 1px 0 #FFF; + white-space: nowrap; + width: 100%; +} +.grid-module { + background: #FFF; + color: rgb(36, 36, 36); + font-weight: normal; + margin-top: 5px; + padding: 7px; +} +.grid-module h3 { + font-size: 25px; + margin: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; +} +.grid-module.black { + border-top: 4px solid #0F1214; +} +.grid-module.gray { + border-top: 4px solid #9E9E9E; +} +.grid-module.red { + border-top: 4px solid #FF303E; +} +.grid-module.blue{ + border-top: 4px solid #00D4E1; +} +.grid-module.green { + border-top: 4px solid #5DB56A; +} +@media (max-width: 767px) { + .panel-plot-wrap { + top: 10px; + } + .powered { + bottom: 10px; + left: 25px; + transform: initial; + } +} + +/* CHARTS */ +.chart-wrap { + margin-bottom: 15px; + position: relative; +} +svg { + background-color: #fff; + display: block; +} +.axis path { + fill: transparent; + stroke: black; + shape-rendering: crispEdges; + stroke-width: 1; +} +.grid.y .tick line, +.grid.x .tick line { + shape-rendering: crispEdges; + stroke: #999; + stroke-dasharray: 3 3; + stroke-width: 1; +} +.axis.x .tick line, +.axis.y0 .tick line, +.axis.y1 .tick line, +.grid.y .tick:first-child line { + stroke: black; + stroke-width: 1; + shape-rendering: crispEdges; +} +.bars rect.bar { + shape-rendering: crispEdges; +} +.rects rect { + fill: transparent; +} +.area { + opacity: 0.2; +} +.points { + stroke: transparent; +} +line.indicator { + fill: transparent; + pointer-events: none; + shape-rendering: crispEdges; + stroke: #999; + stroke-width: 1; +} +.area0, +.bars.y0 .bar, +.points.y0, +rect.legend.y0 { + fill: #447FB3; +} +.area1, +.bars.y1 .bar, +.points.y1, +rect.legend.y1 { + fill: #FF6854; +} +.line0, +.line1 { + fill: transparent; + stroke-width: 1; +} +.line0 { + stroke: #007BC3; +} +.line1 { + stroke: #FF303E; +} +.axis text, +.axis-label, +text.legend { + font: 10px sans-serif; +} +.axis-label.y0, +.axis-label.y1 { + text-anchor: end; +} +rect.legend { + height: 10px; + width: 10px; +} +.legend { + cursor: pointer; +} +.wrap-text text { + text-anchor: start!important; +} + +/* CHART TOOLTIP */ +.chart-tooltip-wrap { + left: 0; + pointer-events: none; + position: absolute; + top: 10px; + z-index: 10; +} +.chart-tooltip { + -moz-box-shadow: 7px 7px 12px -9px #777777; + -webkit-box-shadow: 7px 7px 12px -9px #777777; + background-color: #fff; + border-collapse: collapse; + border-spacing: 0; + box-shadow: 7px 7px 12px -9px #777777; + empty-cells: show; + opacity: 0.9; +} +.chart-tooltip tr { + border: 1px solid #CCC; +} +.chart-tooltip th { + background-color: #aaa; + color: #FFF; + font-size: 14px; + max-width: 380px; + overflow: hidden; + padding: 2px 5px; + text-align: left; + text-overflow: ellipsis; + white-space: nowrap; +} +.chart-tooltip td { + border-left: 1px dotted #999; + font-size: 13px; + padding: 3px 6px; +} +.chart-tooltip td > span { + display: inline-block; + height: 10px; + margin-right: 6px; + width: 10px; +} +.chart-tooltip td.value { + text-align: right; +} +.chart-tooltip .blue { + background-color: #007BC3; +} +.chart-tooltip .red { + background-color: #FF303E; +} + +/* DARK THEME */ +.dark h1 { + color: rgba(255, 255, 255, 0.6); +} +.dark h3, +.dark h4, +.dark h5 { + color: rgba(255,255,255,0.4); +} +.dark .table-responsive { + border: none; +} +.dark .wrap-panel > div > table { + color: #D2D2D2; +} +.dark .wrap-panel table tbody.tbody-meta tr { + background-color: transparent; + color: #F7F7F7; +} +.dark .wrap-panel table tbody.tbody-data tr td { + border-right: none; +} +.dark .wrap-panel table.table-hover>tbody.tbody-data>tr:hover { + background-color: rgba(255, 255, 255, 0.08) !important; +} +.dark .col-title { + color: #9e9e9e; + text-shadow:none; +} +.dark .grid-module h3 { + color: #FFF; +} +.dark .dropdown-menu>li>a { + color: #FFF; +} +.dark div.wrap-panel > div { + color: #EEE; + margin-top: 10px; + padding: 0 10px; + border-top: 1px solid rgba(255, 255, 255, 0.15); +} + +/* DARK BLUE THEME */ +html.dark.blue, +.dark.blue body { + background: #252B30; +} +.dark.blue .container { + background: #252B30; +} +.dark.blue .page-header { + border-bottom: 1px solid #3B444C; +} +.dark.blue .label-info { + background-color: #252B30; +} +.dark.blue nav { + border-right: 1px solid #181B1F; + background: #1F2328; +} +.dark.blue div.wrap-panel > div { + background: #1F2328; +} +.dark.blue .wrap-panel table tbody.tbody-meta { + border-top: 1px solid #3B444C; + border-bottom: 1px solid #3B444C; +} +.dark.blue .wrap-panel table tbody.tbody-data tr.shaded { + background-color: #181B1F; +} +.dark.blue .gray { + border-top: 4px solid #3B444C; +} +.dark.blue .grid-module { + background: #1F2328; +} +.dark.blue .btn-default { + color: #9E9E9E; + background-color: #1F2328; + border-color: #3B444C; +} +.dark.blue .btn-default:active, +.dark.blue .btn-default:hover, +.dark.blue .btn-default.active, +.dark.blue .open>.dropdown-toggle.btn-default { + color: #3B444C; + background-color: #1F2328; + border-color: #0F1214; +} +.dark.blue .pagination>.disabled>a, +.dark.blue .pagination>.disabled>a:hover, +.dark.blue .pagination>.disabled>a:focus { + color: #777; +} +.dark.blue .pagination>li>a { + background-color: #1F2328; + border: 1px solid #3B444C; +} +.dark.blue .pagination>li>a:hover, +.dark.blue .pagination>li>a:active, +.dark.blue .pagination>li>a:focus { + color: #0370B0; + background-color: #1F2328; + border-color: #3B444C; +} +.dark.blue .dropdown-menu>li>a:hover, +.dark.blue .dropdown-menu>li>a:focus { + color: #FFF; + background-color: #3B444C; +} +.dark.blue .dropdown-menu { + background-color: #252B30; +} +.dark.blue::-webkit-scrollbar-track, +.dark.blue .table-responsive::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + background-color: #9E9E9E; +} +.dark.blue::-webkit-scrollbar, +.dark.blue .table-responsive::-webkit-scrollbar { + width: 10px; + height: 10px; + background-color: #9E9E9E; +} +.dark.blue::-webkit-scrollbar-thumb, +.dark.blue .table-responsive::-webkit-scrollbar-thumb { + background-color: #3B444C; +} +.dark.blue .chart-tooltip { + background-color: #252B30; +} +.dark.blue .report-title { + background: #1F2328; +} + +/* DARK GREY THEME */ +html.dark.gray, +.dark.gray body { + background: #212121; +} +.dark.gray .container { + background: #212121; +} +.dark.gray .page-header { + border-bottom: 1px solid #303030; +} +.dark.gray .label-info { + background-color: #303030; +} +.dark.gray nav { + border-right: 1px solid #363737; + background: #1C1C1C; +} +.dark.gray div.wrap-panel > div { + background: #1C1C1C; +} +.dark.gray .wrap-panel table tbody.tbody-meta { + border-top: 1px solid #363737; + border-bottom: 1px solid #363737; +} +.dark.gray .wrap-panel table tbody.tbody-data tr.shaded { + background-color: rgba(48, 48, 48, 0.48); +} +.dark.gray .gray { + border-top: 4px solid #303030; +} +.dark.gray .grid-module { + background: #1C1C1C; +} +.dark.gray .btn-default { + color: #9E9E9E; + background-color: #212121; + border-color: #303030; +} +.dark.gray .btn-default:active, +.dark.gray .btn-default:hover, +.dark.gray .btn-default.active, +.dark.gray .open>.dropdown-toggle.btn-default { + color: #363737; + background-color: #1C1C1C; + border-color: #0F1214; +} +.dark.gray .pagination>.disabled>a, +.dark.gray .pagination>.disabled>a:hover, +.dark.gray .pagination>.disabled>a:focus { + color: #777; +} +.dark.gray .pagination>li>a { + background-color: #212121; + border: 1px solid #303030; +} +.dark.gray .pagination>li>a:hover, +.dark.gray .pagination>li>a:active, +.dark.gray .pagination>li>a:focus { + color: #0370B0; + background-color: #212121; + border-color: #303030; +} +.dark.gray .dropdown-menu>li>a { + color: #FFF; +} +.dark.gray .dropdown-menu>li>a:hover, +.dark.gray .dropdown-menu>li>a:focus { + color: #FFF; + background-color: #303030; +} +.dark.gray .dropdown-menu { + background-color: #212121; +} +.dark.gray::-webkit-scrollbar-track, +.dark.gray .table-responsive::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + background-color: #9E9E9E; +} +.dark.gray::-webkit-scrollbar, +.dark.gray .table-responsive::-webkit-scrollbar { + width: 10px; + height: 10px; + background-color: #9E9E9E; +} +.dark.gray::-webkit-scrollbar-thumb, +.dark.gray .table-responsive::-webkit-scrollbar-thumb { + background-color: #303030; +} +.dark.gray .chart-tooltip { + background-color: #303030; +} +.dark.gray .report-title { + background: #303030; +} + +/* DARK CHARTS */ +.dark svg { + background-color: transparent; +} +.dark .area { + opacity: 0.1; +} +.dark .line0, +.dark .line1 { + stroke-width: 2; +} +.dark .area0, +.dark .bars.y0 .bar, +.dark rect.legend.y0 { + fill: #007BC3; +} +.dark .area1, +.dark .bars.y1 .bar, +.dark .points.y1, +.dark rect.legend.y1 { + fill: #FF303E; +} +.dark .points.y0 { + fill: #00D4E1; +} +.dark .line0 { + stroke: #007BC3; +} +.dark .line1 { + stroke: #FF303E; +} +.dark .grid.y .tick line, +.dark .grid.x .tick line { + stroke: #44474B; + stroke-dasharray: 1 1; +} +.dark .axis text, +.dark .axis-label, +.dark text.legend { + fill: #9E9E9E; +} +.dark .axis path { + stroke: #999999; +} +.dark .axis.x .tick line, +.dark .axis.y0 .tick line, +.dark .axis.y1 .tick line, +.dark .grid.y .tick:first-child line { + stroke: #3B444C; +} +.dark .chart-tooltip th { + background-color: #1c1c1c; +} +.dark .chart-tooltip tr { + border: 1px solid #363737; +} + +/* DARK PURPLE THEME */ +html.dark.purple, +.dark.purple body { + background: #1e1e2f; +} +.dark.purple .container { + background: #1e1e2f; +} +.dark.purple .page-header { + border-bottom: 1px solid #2b3553; +} +.dark.purple .label-info { + background-color: #181823; +} +.dark.purple nav { + border-right: 1px solid #e14eca; + background: #181823; +} +.dark.purple div.wrap-panel > div { + background: #27293d; + border-top: 1px solid #2b3553; +} +.dark.purple .wrap-panel table tbody.tbody-meta { + border-top: 1px solid #2b3553; + border-bottom: 1px solid #2b3553; +} +.dark.purple .wrap-panel table tbody.tbody-data tr.shaded { + background-color: #1e1e2f; +} +.dark.purple .gray { + border-top: 4px solid #2b3553; +} +.dark.purple .red { + border-top: 4px solid #fd5d93; +} +.dark.purple .green { + border-top: 4px solid #00f2c3; +} +.dark.purple .blue { + border-top: 4px solid #1f8ef1; +} +.dark.purple h3, .dark.purple h4, .dark.purple h5 { + color: #9a9a9a; +} +.dark.purple .grid-module { + background: #27293d; +} +.dark.purple .grid-module h3 { + color: #FFF; +} +.dark.purple .btn-default { + color: #9E9E9E; + background-color: #1e1e2f; + border-color: #2b3553; +} +.dark.purple .btn-default:active, +.dark.purple .btn-default:hover, +.dark.purple .btn-default.active, +.dark.purple .open>.dropdown-toggle.btn-default { + color: #59595f; + background-color: #1e1e2f; + border-color: #2b3553; +} +.dark.purple .pagination>.disabled>a, +.dark.purple .pagination>.disabled>a:hover, +.dark.purple .pagination>.disabled>a:focus { + color: #777; +} +.dark.purple .pagination>li>a { + background-color: #1e1e2f; + border: 1px solid #3B444C; +} +.dark.purple .pagination>li>a:hover, +.dark.purple .pagination>li>a:active, +.dark.purple .pagination>li>a:focus { + color: #0370B0; + background-color: #181823; +} +.dark.purple .dropdown-menu>li>a:hover, +.dark.purple .dropdown-menu>li>a:focus { + color: #FFF; + background-color: #181823; +} +.dark.purple .dropdown-menu { + background-color: #1e1e2f; +} +.dark.purple::-webkit-scrollbar-track, +.dark.purple .table-responsive::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); + background-color: #9E9E9E; +} +.dark.purple::-webkit-scrollbar, +.dark.purple .table-responsive::-webkit-scrollbar { + width: 10px; + height: 10px; + background-color: #9E9E9E; +} +.dark.purple::-webkit-scrollbar-thumb, +.dark.purple .table-responsive::-webkit-scrollbar-thumb { + background-color: #1e1e2f; +} +.dark.purple .chart-tooltip { + background-color: #181823; +} +.dark.purple .report-title { + background: #181823; +} +.dark.purple .area0, +.dark.purple .bars.y0 .bar, +.dark.purple rect.legend.y0 { + fill: #007BC3; +} +.dark.purple .area1, +.dark.purple .bars.y1 .bar, +.dark.purple .points.y1, +.dark.purple rect.legend.y1 { + fill: #d048b6; +} +.dark.purple .points.y0 { + fill: #00D4E1; +} +.dark.purple .line0 { + stroke: #007BC3; +} +.dark.purple .line1 { + stroke: #d048b6; +} diff --git a/goaccess++/resources/css/app.css.tmp b/goaccess++/resources/css/app.css.tmp new file mode 100644 index 0000000..e01e62b --- /dev/null +++ b/goaccess++/resources/css/app.css.tmp @@ -0,0 +1 @@ +/* GLOBAL */html,body {background: #f0f0f0;overflow-x: hidden;}h1 {font-weight: bold;letter-spacing: -3px;}h3 {font-size: 21px;letter-spacing: -1px;}.page-header {border-bottom: 1px solid rgba(0, 0, 0, 0.15);margin: 25px 0 20px;position: relative;}.page-header h1 {margin: 0;}.pagination {margin: 5px 0;}.clickable,.expandable>td {cursor: pointer;}.spinner {color: #999;left: 50%;position: absolute;top: 50%;}.powered {bottom: 190px;color: #9E9E9E;font-size: smaller;position: absolute;right: 20px;transform-origin: 100% 0;transform: rotate(-90deg);}.powered a {color: #636363;}.powered span {color: #007bc3;}.dropdown-header {color: #007bc3;padding: 3px 25px;text-transform: uppercase;}.gheader {letter-spacing: -1px;text-transform: uppercase;}h5.gheader {letter-spacing: 0;}.panel-header h4.gheader {margin-top: 20px;}.panel-header .gheader small {font-size: 69%;}/* NAVIGATION */nav {-webkit-transition: left .2s;background: #1C1C1C;border-right: 3px solid #5bc0de;height: 100%;left: -236px;overflow: hidden;position: fixed;top: 0;transition: left .2s;width: 300px;z-index: 2;}nav .nav-list {height: 100%;overflow-y: auto;width: 350px;}nav header {margin: 40px 20px 30px;}nav header a {color: rgba(240,240,240,.7);font-size: 2.7em;font-weight: 300;text-transform: uppercase;}nav header a:hover {color: #eee;}nav.active {display: block !important;left: 0;opacity: .97;}nav:hover ~ #content {opacity: .3;}nav.active .nav-bars,nav.active .nav-gears,nav.active .nav-ws-status {opacity: 0;}nav .nav-bars,nav .nav-gears,nav .nav-ws-status {-webkit-transition: opacity .2s;color: #9E9E9E;cursor: pointer;float: right;font-size: 36px;height: 32px;left: 13px;line-height: 32px;position: fixed;text-align: center;top: 30px;transition: opacity .2s;width: 32px;}nav .nav-gears {top: 100px;opacity: 0.6;}nav .nav-ws-status,.nav-ws-status.mini {color: #6A6A6A;cursor: help;display: none;font-size: 12px;}nav .nav-ws-status {left: 25px;top: 125px;}.nav-ws-status.mini {top: 14px;left: 50px;position: absolute;}.nav-ws-status.connected {color: #5DB56A;}nav li a {border-left: 3px solid transparent;color: rgba(200,200,200,.5);display: block;font-size: smaller;max-width: 235px;opacity: 0;overflow: hidden;padding: 9px 20px;text-overflow: ellipsis;text-transform: uppercase;transition: opacity .2s;white-space: nowrap;}nav.active li a {max-width: 100%;opacity: 1;}nav li a:hover,nav li.active a {background: rgba(0,0,0,.1);border-color: #5BC0DE;color: #eee;}nav ul {padding-left: 0;list-style: none;}/* Navigation -- Icon */nav a,nav a:hover {text-decoration: none;}nav h3 {color: #FFF !important;font-size: medium;font-weight: bold;margin: 20px 25px 10px;text-transform: uppercase;}/* CONTAINER */@media screen and (max-width: 767px) {.row-offcanvas {-webkit-transition: all .25s ease-out;-o-transition: all .25s ease-out;position: relative;transition: all .25s ease-out;}.row-offcanvas-right {right: 0;}.row-offcanvas-left {left: 0;}.row-offcanvas-right.sidebar-offcanvas {right: -50%;}.row-offcanvas-left.sidebar-offcanvas {left: -50%;}.row-offcanvas-right.active {right: 50%;}.row-offcanvas-left.active {left: 50%;}.sidebar-offcanvas {position: absolute;top: 0;width: 50%;};}@media (min-width: 768px) {.container {width: 750px;};}@media (max-width: 480px) {.wrap-general h5,.wrap-panel h5 {white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}.wrap-general h5 {width: 100%}.wrap-panel h5 {width: 70%}}.container-fluid {margin-left: 75px;}@media (min-width: 1120px) {.container {width: 970px;};}@media (min-width: 1320px) {.container {width: 1170px;};}@media (max-width: 992px) {.container-fluid {margin-left: auto;};}@media (max-width: 768px) {.container-fluid {padding-left: 5px;padding-right: 5px;}.page-header {padding: 0 10px;}}/* PANEL STYLES */.wrap-panel .panel-header {position: relative;}div.wrap-panel > div {background: #FFF;margin-top: 10px;padding: 0 10px;border-top: 1px solid rgba(0, 0, 0, 0.15);}/* PANEL TABLES */.wrap-panel table.table-borderless tbody tr td,.wrap-panel table.table-borderless tbody tr th,.wrap-panel table.table-borderless thead tr th {border: none;}.wrap-panel table thead tr th {text-align: right;border-bottom-width: 1px;}.wrap-panel table .string,.wrap-panel table .date {text-align: left;}.wrap-panel table .percent {color: #898989;}.wrap-panel table td,.wrap-panel table th {white-space: nowrap;overflow: hidden;}.wrap-panel table th.sortable {cursor: pointer;}/* thead meta */.wrap-panel table tbody.tbody-meta {border-top: 1px solid #C7C7C7;border-bottom: 1px solid #C7C7C7;}.wrap-panel table tbody.tbody-meta tr {background-color: #F1F1F1;color: #222;}.wrap-panel table tbody.tbody-meta small {font-size: 65%;}/* thead data */.wrap-panel table tbody.tbody-data tr td {border-right: 1px solid #F1F1F1;font-size: smaller;}.wrap-panel table tbody.tbody-data td:last-child {border-right: none;}.wrap-panel table tbody.tbody-data td.row-idx {color: #898989;}.wrap-panel table>tbody+tbody {border-top-width: 1px;}.wrap-panel table tbody.tbody-data tr.shaded {background-color: #F7F7F7;}.wrap-panel table tbody.tbody-data tr. {background-color: #F7F7F7;}.wrap-panel table tbody.tbody-data tr.child td:nth-child(1),.wrap-panel table tbody.tbody-data tr.child td:nth-child(2) {border-right: none;}.wrap-panel table.table-hover>tbody>tr:hover {background-color: #EEE;}/* GENERAL */.wrap-general {position: relative;}.report-title {background: #FFF;border-radius: 4px;bottom: -10px;color: #9E9E9E;font-size: small;padding: 0 10px;position: absolute;right: 0;z-index: 1;}.panel-plot-wrap {position: absolute;right: 0;top: 18px;}.col-title {font-size: 85%;overflow: hidden;text-overflow: ellipsis;text-shadow: 1px 1px 0 #FFF;white-space: nowrap;width: 100%;}.grid-module {background: #FFF;color: rgb(36, 36, 36);font-weight: normal;margin-top: 5px;padding: 7px;}.grid-module h3 {font-size: 25px;margin: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;width: 100%;}.grid-module.black {border-top: 4px solid #0F1214;}.grid-module.gray {border-top: 4px solid #9E9E9E;}.grid-module.red {border-top: 4px solid #FF303E;}.grid-module.blue{border-top: 4px solid #00D4E1;}.grid-module.green {border-top: 4px solid #5DB56A;}@media (max-width: 767px) {.panel-plot-wrap {top: 10px;}.powered {bottom: 10px;left: 25px;transform: initial;}}/* CHARTS */.chart-wrap {margin-bottom: 15px;position: relative;}svg {background-color: #fff;display: block;}.axis path {fill: transparent;stroke: black;shape-rendering: crispEdges;stroke-width: 1;}.grid.y .tick line,.grid.x .tick line {shape-rendering: crispEdges;stroke: #999;stroke-dasharray: 3 3;stroke-width: 1;}.axis.x .tick line,.axis.y0 .tick line,.axis.y1 .tick line,.grid.y .tick:first-child line {stroke: black;stroke-width: 1;shape-rendering: crispEdges;}.bars rect.bar {shape-rendering: crispEdges;}.rects rect {fill: transparent;}.area {opacity: 0.2;}.points {stroke: transparent;}line.indicator {fill: transparent;pointer-events: none;shape-rendering: crispEdges;stroke: #999;stroke-width: 1;}.area0,.bars.y0 .bar,.points.y0,rect.legend.y0 {fill: #447FB3;}.area1,.bars.y1 .bar,.points.y1,rect.legend.y1 {fill: #FF6854;}.line0,.line1 {fill: transparent;stroke-width: 1;}.line0 {stroke: #007BC3;}.line1 {stroke: #FF303E;}.axis text,.axis-label,text.legend {font: 10px sans-serif;}.axis-label.y0,.axis-label.y1 {text-anchor: end;}rect.legend {height: 10px;width: 10px;}.legend {cursor: pointer;}.wrap-text text {text-anchor: start!important;}/* CHART TOOLTIP */.chart-tooltip-wrap {left: 0;pointer-events: none;position: absolute;top: 10px;z-index: 10;}.chart-tooltip {-moz-box-shadow: 7px 7px 12px -9px #777777;-webkit-box-shadow: 7px 7px 12px -9px #777777;background-color: #fff;border-collapse: collapse;border-spacing: 0;box-shadow: 7px 7px 12px -9px #777777;empty-cells: show;opacity: 0.9;}.chart-tooltip tr {border: 1px solid #CCC;}.chart-tooltip th {background-color: #aaa;color: #FFF;font-size: 14px;max-width: 380px;overflow: hidden;padding: 2px 5px;text-align: left;text-overflow: ellipsis;white-space: nowrap;}.chart-tooltip td {border-left: 1px dotted #999;font-size: 13px;padding: 3px 6px;}.chart-tooltip td > span {display: inline-block;height: 10px;margin-right: 6px;width: 10px;}.chart-tooltip td.value {text-align: right;}.chart-tooltip .blue {background-color: #007BC3;}.chart-tooltip .red {background-color: #FF303E;}/* DARK THEME */.dark h1 {color: rgba(255, 255, 255, 0.6);}.dark h3,.dark h4,.dark h5 {color: rgba(255,255,255,0.4);}.dark .table-responsive {border: none;}.dark .wrap-panel > div > table {color: #D2D2D2;}.dark .wrap-panel table tbody.tbody-meta tr {background-color: transparent;color: #F7F7F7;}.dark .wrap-panel table tbody.tbody-data tr td {border-right: none;}.dark .wrap-panel table.table-hover>tbody.tbody-data>tr:hover {background-color: rgba(255, 255, 255, 0.08) !important;}.dark .col-title {color: #9e9e9e;text-shadow:none;}.dark .grid-module h3 {color: #FFF;}.dark .dropdown-menu>li>a {color: #FFF;}.dark div.wrap-panel > div {color: #EEE;margin-top: 10px;padding: 0 10px;border-top: 1px solid rgba(255, 255, 255, 0.15);}/* DARK BLUE THEME */html.dark.blue,.dark.blue body {background: #252B30;}.dark.blue .container {background: #252B30;}.dark.blue .page-header {border-bottom: 1px solid #3B444C;}.dark.blue .label-info {background-color: #252B30;}.dark.blue nav {border-right: 1px solid #181B1F;background: #1F2328;}.dark.blue div.wrap-panel > div {background: #1F2328;}.dark.blue .wrap-panel table tbody.tbody-meta {border-top: 1px solid #3B444C;border-bottom: 1px solid #3B444C;}.dark.blue .wrap-panel table tbody.tbody-data tr.shaded {background-color: #181B1F;}.dark.blue .gray {border-top: 4px solid #3B444C;}.dark.blue .grid-module {background: #1F2328;}.dark.blue .btn-default {color: #9E9E9E;background-color: #1F2328;border-color: #3B444C;}.dark.blue .btn-default:active,.dark.blue .btn-default:hover,.dark.blue .btn-default.active,.dark.blue .open>.dropdown-toggle.btn-default {color: #3B444C;background-color: #1F2328;border-color: #0F1214;}.dark.blue .pagination>.disabled>a,.dark.blue .pagination>.disabled>a:hover,.dark.blue .pagination>.disabled>a:focus {color: #777;}.dark.blue .pagination>li>a {background-color: #1F2328;border: 1px solid #3B444C;}.dark.blue .pagination>li>a:hover,.dark.blue .pagination>li>a:active,.dark.blue .pagination>li>a:focus {color: #0370B0;background-color: #1F2328;border-color: #3B444C;}.dark.blue .dropdown-menu>li>a:hover,.dark.blue .dropdown-menu>li>a:focus {color: #FFF;background-color: #3B444C;}.dark.blue .dropdown-menu {background-color: #252B30;}.dark.blue::-webkit-scrollbar-track,.dark.blue .table-responsive::-webkit-scrollbar-track {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);background-color: #9E9E9E;}.dark.blue::-webkit-scrollbar,.dark.blue .table-responsive::-webkit-scrollbar {width: 10px;height: 10px;background-color: #9E9E9E;}.dark.blue::-webkit-scrollbar-thumb,.dark.blue .table-responsive::-webkit-scrollbar-thumb {background-color: #3B444C;}.dark.blue .chart-tooltip {background-color: #252B30;}.dark.blue .report-title {background: #1F2328;}/* DARK GREY THEME */html.dark.gray,.dark.gray body {background: #212121;}.dark.gray .container {background: #212121;}.dark.gray .page-header {border-bottom: 1px solid #303030;}.dark.gray .label-info {background-color: #303030;}.dark.gray nav {border-right: 1px solid #363737;background: #1C1C1C;}.dark.gray div.wrap-panel > div {background: #1C1C1C;}.dark.gray .wrap-panel table tbody.tbody-meta {border-top: 1px solid #363737;border-bottom: 1px solid #363737;}.dark.gray .wrap-panel table tbody.tbody-data tr.shaded {background-color: rgba(48, 48, 48, 0.48);}.dark.gray .gray {border-top: 4px solid #303030;}.dark.gray .grid-module {background: #1C1C1C;}.dark.gray .btn-default {color: #9E9E9E;background-color: #212121;border-color: #303030;}.dark.gray .btn-default:active,.dark.gray .btn-default:hover,.dark.gray .btn-default.active,.dark.gray .open>.dropdown-toggle.btn-default {color: #363737;background-color: #1C1C1C;border-color: #0F1214;}.dark.gray .pagination>.disabled>a,.dark.gray .pagination>.disabled>a:hover,.dark.gray .pagination>.disabled>a:focus {color: #777;}.dark.gray .pagination>li>a {background-color: #212121;border: 1px solid #303030;}.dark.gray .pagination>li>a:hover,.dark.gray .pagination>li>a:active,.dark.gray .pagination>li>a:focus {color: #0370B0;background-color: #212121;border-color: #303030;}.dark.gray .dropdown-menu>li>a {color: #FFF;}.dark.gray .dropdown-menu>li>a:hover,.dark.gray .dropdown-menu>li>a:focus {color: #FFF;background-color: #303030;}.dark.gray .dropdown-menu {background-color: #212121;}.dark.gray::-webkit-scrollbar-track,.dark.gray .table-responsive::-webkit-scrollbar-track {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);background-color: #9E9E9E;}.dark.gray::-webkit-scrollbar,.dark.gray .table-responsive::-webkit-scrollbar {width: 10px;height: 10px;background-color: #9E9E9E;}.dark.gray::-webkit-scrollbar-thumb,.dark.gray .table-responsive::-webkit-scrollbar-thumb {background-color: #303030;}.dark.gray .chart-tooltip {background-color: #303030;}.dark.gray .report-title {background: #303030;}/* DARK CHARTS */.dark svg {background-color: transparent;}.dark .area {opacity: 0.1;}.dark .line0,.dark .line1 {stroke-width: 2;}.dark .area0,.dark .bars.y0 .bar,.dark rect.legend.y0 {fill: #007BC3;}.dark .area1,.dark .bars.y1 .bar,.dark .points.y1,.dark rect.legend.y1 {fill: #FF303E;}.dark .points.y0 {fill: #00D4E1;}.dark .line0 {stroke: #007BC3;}.dark .line1 {stroke: #FF303E;}.dark .grid.y .tick line,.dark .grid.x .tick line {stroke: #44474B;stroke-dasharray: 1 1;}.dark .axis text,.dark .axis-label,.dark text.legend {fill: #9E9E9E;}.dark .axis path {stroke: #999999;}.dark .axis.x .tick line,.dark .axis.y0 .tick line,.dark .axis.y1 .tick line,.dark .grid.y .tick:first-child line {stroke: #3B444C;}.dark .chart-tooltip th {background-color: #1c1c1c;}.dark .chart-tooltip tr {border: 1px solid #363737;}/* DARK PURPLE THEME */html.dark.purple,.dark.purple body {background: #1e1e2f;}.dark.purple .container {background: #1e1e2f;}.dark.purple .page-header {border-bottom: 1px solid #2b3553;}.dark.purple .label-info {background-color: #181823;}.dark.purple nav {border-right: 1px solid #e14eca;background: #181823;}.dark.purple div.wrap-panel > div {background: #27293d;border-top: 1px solid #2b3553;}.dark.purple .wrap-panel table tbody.tbody-meta {border-top: 1px solid #2b3553;border-bottom: 1px solid #2b3553;}.dark.purple .wrap-panel table tbody.tbody-data tr.shaded {background-color: #1e1e2f;}.dark.purple .gray {border-top: 4px solid #2b3553;}.dark.purple .red {border-top: 4px solid #fd5d93;}.dark.purple .green {border-top: 4px solid #00f2c3;}.dark.purple .blue {border-top: 4px solid #1f8ef1;}.dark.purple h3, .dark.purple h4, .dark.purple h5 {color: #9a9a9a;}.dark.purple .grid-module {background: #27293d;}.dark.purple .grid-module h3 {color: #FFF;}.dark.purple .btn-default {color: #9E9E9E;background-color: #1e1e2f;border-color: #2b3553;}.dark.purple .btn-default:active,.dark.purple .btn-default:hover,.dark.purple .btn-default.active,.dark.purple .open>.dropdown-toggle.btn-default {color: #59595f;background-color: #1e1e2f;border-color: #2b3553;}.dark.purple .pagination>.disabled>a,.dark.purple .pagination>.disabled>a:hover,.dark.purple .pagination>.disabled>a:focus {color: #777;}.dark.purple .pagination>li>a {background-color: #1e1e2f;border: 1px solid #3B444C;}.dark.purple .pagination>li>a:hover,.dark.purple .pagination>li>a:active,.dark.purple .pagination>li>a:focus {color: #0370B0;background-color: #181823;}.dark.purple .dropdown-menu>li>a:hover,.dark.purple .dropdown-menu>li>a:focus {color: #FFF;background-color: #181823;}.dark.purple .dropdown-menu {background-color: #1e1e2f;}.dark.purple::-webkit-scrollbar-track,.dark.purple .table-responsive::-webkit-scrollbar-track {-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);background-color: #9E9E9E;}.dark.purple::-webkit-scrollbar,.dark.purple .table-responsive::-webkit-scrollbar {width: 10px;height: 10px;background-color: #9E9E9E;}.dark.purple::-webkit-scrollbar-thumb,.dark.purple .table-responsive::-webkit-scrollbar-thumb {background-color: #1e1e2f;}.dark.purple .chart-tooltip {background-color: #181823;}.dark.purple .report-title {background: #181823;}.dark.purple .area0,.dark.purple .bars.y0 .bar,.dark.purple rect.legend.y0 {fill: #007BC3;}.dark.purple .area1,.dark.purple .bars.y1 .bar,.dark.purple .points.y1,.dark.purple rect.legend.y1 {fill: #d048b6;}.dark.purple .points.y0 {fill: #00D4E1;}.dark.purple .line0 {stroke: #007BC3;}.dark.purple .line1 {stroke: #d048b6;} \ No newline at end of file diff --git a/goaccess++/resources/css/bootstrap.min.css b/goaccess++/resources/css/bootstrap.min.css new file mode 100644 index 0000000..c9677e9 --- /dev/null +++ b/goaccess++/resources/css/bootstrap.min.css @@ -0,0 +1 @@ +/*! http://getbootstrap.com/customize/?id=f8abc08c888af89b2ed8cd64f48a1fe3 */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover,a.text-primary:focus{color:#286090}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover,a.bg-primary:focus{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:34px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#337ab7}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#337ab7;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#fff;background-color:#337ab7;border-color:#337ab7;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}} diff --git a/goaccess++/resources/css/bootstrap.min.css.tmp b/goaccess++/resources/css/bootstrap.min.css.tmp new file mode 100644 index 0000000..0312f0c --- /dev/null +++ b/goaccess++/resources/css/bootstrap.min.css.tmp @@ -0,0 +1 @@ +/*! http://getbootstrap.com/customize/?id=f8abc08c888af89b2ed8cd64f48a1fe3 */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover,a.text-primary:focus{color:#286090}.text-success{color:#3c763d}a.text-success:hover,a.text-success:focus{color:#2b542c}.text-info{color:#31708f}a.text-info:hover,a.text-info:focus{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover,a.text-warning:focus{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover,a.text-danger:focus{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover,a.bg-primary:focus{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:34px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:focus,.btn-default.focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:focus,.btn-primary.focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:focus,.btn-success.focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#fff;background-color:#398439;border-color:#255625}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:focus,.btn-warning.focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:focus,.btn-danger.focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#337ab7}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#337ab7;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#fff;background-color:#337ab7;border-color:#337ab7;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}} \ No newline at end of file diff --git a/goaccess++/resources/css/fa.min.css b/goaccess++/resources/css/fa.min.css new file mode 100644 index 0000000..179498e --- /dev/null +++ b/goaccess++/resources/css/fa.min.css @@ -0,0 +1,8 @@ +@font-face { + font-family: 'fa'; + src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAC2sAAsAAAAALWAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDxIPHGNtYXAAAAFoAAABbAAAAWzzYPN8Z2FzcAAAAtQAAAAIAAAACAAAABBnbHlmAAAC3AAAJ7QAACe0PqRPf2hlYWQAACqQAAAANgAAADYSBhrHaGhlYQAAKsgAAAAkAAAAJAhUBIZobXR4AAAq7AAAAMwAAADMpCoCC2xvY2EAACu4AAAAaAAAAGjyrvuebWF4cAAALCAAAAAgAAAAIAA+AVduYW1lAAAsQAAAAUoAAAFKIhWTsnBvc3QAAC2MAAAAIAAAACAAAwAAAAMDVgGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA8pwDwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEAVAAAABQAEAABQAQAAEAIPAH8AnwDfAT8BfwIvA68EHwRvBU8HHwgPCF8I7wlvCi8MDwyfDO8Nrw3PDk8QHxBfEI8QzxEfEh8VzxoPHO8ffx/vJo8pLynP/9//8AAAAAACDwB/AJ8AvwE/AW8CHwOvBB8EbwU/Bx8IDwhfCO8JbwovDA8MnwzvDX8Nzw5PEA8QTxCPEM8RHxIfFb8aDxzvH38f7yaPKS8pz//f//AAH/4w/9D/wP+w/2D/QP6w/UD84Pyg++D6IPlA+QD4gPgQ92D1kPUQ9ND0UPRA89DyIPIA8eDxsPFw8IDs8OjA5fDjcOMQ3IDZ8NlgADAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAIAAAAAAtsDbgAbADcAACUUBiMhIiY1NDc+ATc2Mx4BMzI2NzIXHgEXFhUDFAcOAQcGIyInLgEnJjU0Nz4BNzYzMhceARcWAttHMv4YMkgICColJDgjWzU0XCM4JCQqCAiSERE8KCgtLigoOxESEhE7KCguLSgoPBERlz5ZWT45OTpdHh0hKCghHR5dOjk5AfstKCg8ERERETwoKC0uKCg7ERISETsoKAAAAAAEAAAASQO3A24AEAAhADEAQQAAARUUBiMhIiY9ATQ2MyEyFhURFRQGIyEiJj0BNDYzITIWFQEVFAYjISImPQE0NjMhMhYRFRQGIyEiJj0BNDYzITIWAbcrHv7bHisrHgElHisrHv7bHisrHgElHisCACse/tseKyseASUeKyse/tseKyseASUeKwFu3B4rKx7cHisrHgG33B4rKx7cHisrHv5J3B4rKx7cHisrAZncHisrHtweKysABgAAAEkEAANuAA8AHwAvAD8ATwBfAAAlFRQGKwEiJj0BNDY7ATIWERUUBisBIiY9ATQ2OwEyFgEVFAYjISImPQE0NjMhMhYBFRQGKwEiJj0BNDY7ATIWARUUBiMhIiY9ATQ2MyEyFhEVFAYjISImPQE0NjMhMhYBJSEWtxcgIBe3FiEhFrcXICAXtxYhAtsgF/3cFyAgFwIkFyD9JSEWtxcgIBe3FiEC2yAX/dwXICAXAiQXICAX/dwXICAXAiQXIO5uFyAgF24WISEBDm0XICAXbRcgIP7FbhcgIBduFiEhAjNuFyAgF24XICD+xG0XICAXbRcgIAEObhcgIBduFyAgAAABAEUAUQO7AvgAJAAAARQGBwEOASMiJicBLgE1NDY/AT4BMzIWHwEBPgEzMhYfAR4BFQO7CAj+FAcVCgsVB/7jCAgICE4IFAsKFQioAXYIFQoLFAhOCAgCcwoVB/4UCAgICAEdBxULChUHTggICAioAXcICAgITgcVCwAAAQA/AD8C5gLmADwAACUUBg8BDgEjIiYvAQcOASMiJi8BLgE1NDY/AScuATU0Nj8BPgEzMhYfATc+ATMyFh8BHgEVFAYPARceARUC5gkHTggUCwsUCKioBxULChUHTggICAioqAgICAhOBxUKCxUHqKgIFAsLFAhOBwkJB6ioBwnDChUHTggICAioqAgICAhOBxUKCxUHqKgIFAsLFAhOBwkJB6ioBwkJB04IFAsLFAioqAcVCwAAAAIAAAAAA24DbgALAJIAAAE0JiMiBhUUFjMyNiUVFAYPAQ4BBx4BFx4BFRQGBw4BIyImLwEOAQcOAQcOASsBIiYvAS4BJwcOASMiJicuAScuATU0Njc+ATcuAS8BLgE9ATQ2PwE+ATcuAScuATU0Njc+ATMyFh8BPgE3PgE3PgE7ATIWHwEeARc3PgEzMhYXHgEXHgEVFAYHDgEHHgEfAR4BFQJJVjw9VVU9PFYBJQkHagUKBw4fEAIEAwMKVQ8EBwRPDBoOAwYHAgsIfwcMARANGg1QAwgDBAgDFjYSAgICAw4fDwgMBGgICQkGawQLBw8eEAMDAwILVQ8DCANPDRoNAwcHAgsHfwgMARANGgxRAwcEBAcDFzYSAgIDAg4fDwcMBWgHCgG3PFZWPD1VVXt/Bg0BEA4aDBUnEwMIAwQHAw1ZAwI+BgsFGjYaBwkKB2kFCgY9AgMDAxUzGAMHBAMHAxMnFA4cDw8BDAh+Bw0BEA4aDRQnEwMHBAQGAw5ZBAI9BgsEGzYaBwkKB2oECgc9AwMEAhUzGQMGBAQGAxQmFA4cDhACDAcAAAAAAwAA/7cDbgO3ABMAHAAmAAABHgEVERQGIyEiJjURNDYzITIWFwcVMy4BLwEuARMRIyImPQEhESEDRxAXIBf9ABcgIBcCABc3EEzXAwcDsgMO1e4XIP5JAtwC3hA3F/1uFyAgFwOSFyAXECfXCA0DswMH/JkCSSAX7vySAAMAAAAAA24DbgAVADEATQAAAREUBisBIiY9ATQ2OwE1NDY7ATIWFRc0Jy4BJyYjIgcOAQcGFRQXHgEXFjMyNz4BNzY3FAcOAQcGIyInLgEnJjU0Nz4BNzYzMhceARcWAgALB7cICgoIgAoIJQcL7hkYVTg5QEA5OVQZGBgZVDk5QEA5OFUYGYAjIndQUFtbUFB3IyIiI3dQUFtbUFB3IiMCgP8ACAoKCCUHC8kICgoIyUA5OFUYGRkYVTg5QEA5OVQZGBgZVDk5QFtQUHciIyMid1BQW1tQUHciIyMid1BQAAAAAAIAAAAAA24DbgA0AGcAAAEwFBUGBw4BBwYjIicuAScmJwcOASMiJjURNDYzITIWFRQGDwEeATMyNjc+ATc+ATsBMhYVExEUBiMhIiY1NDY/AS4BIyIGBw4BBw4BKwEiJj0BNjc+ATc2MzIXHgEXFhc3PgEzMhYVA18SKCdvRkVPKikpTCMkHkoFDQcPFhYPAQAPFQYFTihoN0yFKAoNBwIJBm4ICg8WD/8ADxUFBU8oaDdMhSgLDAgCCAdxCAsTJyhwRkZPKikpTSMkHkoGDQcPFgFbAwFLQD9bGRkICB8XFh1KBQUVDwEADxYWDwcNBk4mKUtBECESBgcLCAHK/wAPFhYPBw0FTyYoSkERIREGBwsHBExAP1oaGQgJHxYXHEkFBhUPAAAACAAAAEkEAANuABAAIAAwAEEAUgBjAHQAhAAAExUUBisBIiY9ATQ2OwEyFhU1FRQGKwEiJj0BNDY7ATIWNRUUBisBIiY9ATQ2OwEyFgEVFAYjISImPQE0NjMhMhYVNRUUBiMhIiY9ATQ2MyEyFhU1FRQGIyEiJj0BNDYzITIWFRMRNCYjISIGFREUFjMhMjY1ExEUBiMhIiY1ETQ2MyEyFtsLByQICwsIJAcLCwckCAsLCCQHCwsHJAgLCwgkBwsCkwsI/dwHCwsHAiQICwsI/dwHCwsHAiQICwsI/dwHCwsHAiQIC0kLB/y2BwsLBwNKBwtJNiX8tiU2NiUDSiU2ARIkCAsLCCQICwsIkyUHCwsHJQcLC4slBwsLByUHCwv+1CQICwsIJAgLCwiTJQcLCwclBwsLB5IlBwsLByUHCwsH/m4B2wcLCwf+JQgLCwgCbf2TJjY2JgJtJjY2AAAAAAgAAABJBAADbgAQACEAMQBCAFIAYwBzAIMAADcVFAYrASImPQE0NjsBMhYVNRUUBisBIiY9ATQ2OwEyFhU1FRQGKwEiJj0BNDY7ATIWARUUBiMhIiY9ATQ2MyEyFhUBFRQGKwEiJj0BNDY7ATIWARUUBiMhIiY9ATQ2MyEyFhU1FRQGIyEiJj0BNDYzITIWNRUUBiMhIiY9ATQ2MyEyFpILB24HCwsHbgcLCwduBwsLB24HCwsHbgcLCwduBwsDbgsH/QAICwsIAwAHC/ySCwduBwsLB24HCwNuCwf9AAgLCwgDAAcLCwf9AAgLCwgDAAcLCwf9AAgLCwgDAAcLyW4HCwsHbgcLCwfcbgcLCwduBwsLB9tuBwsLB24HCwv+Qm4HCwsHbgcLCwcCkm0ICwsIbQgLC/5CbgcLCwduBwsLB9tuBwsLB24HCwvUbQgLCwhtCAsLAAAAAgAAAAACSQNuAAsAKAAAATQmIyIGFRQWMzI2NxQGBwMOASMiJicDLgE1NDc+ATc2MzIXHgEXFhUBt1Y8PVZWPTxWkggL0AkkFBUkCdALCBcXTzY1PTw2NU8XFwJJPVVVPTxWVjwaNRf+RhMWFhMBuhc1Gj01NVAXFxcXUDU1PQACAAAASQOpA24AOgBQAAABFRQGIyEiJjURNDYzITIWFx4BFxYGDwEOASMiJiMuASMhIgYVERQWMyEyNj0BNDY/AT4BMzIWFx4BFRMBBiIvASY0PwE2Mh8BATYyHwEWFAcDJWFE/iVFYGBFAdsRIhAEBQEBAwMcAwcDAQMBBw0G/iUmNjYmAdsmNQMDJAMHAwIDAgUHhP4uDSYO9Q4OPg4mDpYBcg0mDj8NDQGjtURhYUQB20RhBwgBBwUECQMcAwMBAgI2Jv4lJjY2JpEDBwIlAwMBAQIJBgEY/i8ODvUOJg4+Dg6WAXIODj8OJQ4AAAABAGMAGgKdA50AFQAACQIWFA8BBiInASY0NwE2Mh8BFhQHAp3+0QEvCwtfCh4L/lgLCwGoCx4KXwsLAwv+0P7RCx4KXwsLAagKHgsBqAsLXwoeCwABAD4AGgJ5A50AFQAACQEGIi8BJjQ3CQEmND8BNjIXARYUBwJ5/lgLHgtfCgoBMP7QCgpfCx4LAagKCgHC/lgLC18KHgsBLwEwCx4KXwsL/lgLHgoAAAAAAwAJAAAD9wO3AA8AJgA8AAAlNTQmKwEiBh0BFBY7ATI2JxM0JicuASsBIgYHDgEVExQWOwEyNjUDARYUBw4BIyEiJicmNDcBPgEzMhYXAkkKCG4ICgoIbggKAQoCAwMHBH4EBwMDAgkMCGoHDAgBtwkKCiIT/JITIgoKCQG3CSMUFCMJpW0HDAwHbQgLC94BBgMGAgIEBAICBwP++wYHBwYCFvzbESYRERMTEREmEQMlERUVEQAAAAUAAAAABJIDbgADAAgADgATABgAAAERIxEBESMRMwEVIREzEQERIxEzNxEjETMBbpMBbpKSAkn7bkkC3JOT25KSAbf+2wElAST9twJJ/W5JA2782wIA/kkBt9z9bQKTAAYAAP+/BEkDrgALABcAIwCkAPwBVAAAATQmIyIGFRQWMzI2BTQmIyIGFRQWMzI2ETQmIyIGFRQWMzI2BxUUBg8BDgEHHgEXHgEVFAYHDgEjIiYvAQ4BBw4BBw4BKwEiJi8BLgEnBw4BIyImJy4BNTQ2Nz4BNy4BLwEuAT0BNDY/AT4BNy4BJy4BNTQ2Nz4BMzIWHwE+ATc+ATc+ATsBMhYfAR4BFzc+ATMyFhceARUUBgcOAQceAR8BHgEVARUUBiMOAQceARUUBgcOASMiJiciBiMiJiMOASMiJicuATU0NjcuASciJj0BNDY3PgE3LgE1MDY3PgEzMhYXPgEzMhYXPgE/ATIWFx4BMRQGBx4BFx4BFREVFAYHDgEHHgEVFAYHDgEjIiYnIgYjIiYjDgEjIiYnLgE1NDY3LgEnLgE9ATQ2Nz4BNy4BNTQ2Nz4BMzIWFzI2MzIWMz4BPwEyFhceARUUBgceARceARUCAFY8PVZWPTxWAbcrHh4rKx4eKyseHisrHh4r3AcGWAQJBgwaDgICAgIJRwwEBgJCCxUMAgUGAgkGagYLAQ0LFQtDAgYDBAYCDEcDAQ0ZDQYLA1cGCAgFWQMJBgwaDQICAQMIRw0DBgNBCxYLAgYFAgoGagYKAQ0LFgpDAwYDAwYDC0cCAgwaDAYKBFcGBwFuTAkDCQUEGQEBBUACBi4EBAkEBQgEBS4FAz8FAgEaBAYIBAhNTQgECAYEGgECBT8DBS4FBAgFBAkEDBoOBAJABQEBGQQFCQMJTEwJAwkFBBkBAQVAAgYuBAQJBAUIBAUuBQM/BQIBGgQGCAQITU0IBAgGBBoBAgU/AwUuBQQIBQQJBAwaDgQCQAUBARkEBQkDCUwBtzxWVjw9VVXoHisrHh4rKwJnHiwsHh4rK9JqBQsBDgsVCxEhEAIGAwMGAgxJAgIzBQkEFS4VBggIBlgDCQYzAgICAgtEDQMFAxAgEQsYDA0BCgZqBQsBDQwVCxEgEQIGAwMGAgxJAgIzBQkEFS4VBggJBlcECQUzAgICAwpFDAMFAxEfEQwXDA0BCgb+z1AGCwkOBwk+CAECAQMmPAYBAQY8JgMBAgEHPwkHDgkLBlAHCgEIDwcIPwgDAQImOwcBAQEBESEOAiUDAQMIPwgHDwgBCgcCSVAGCgEIDwcJPggBAgEDJTsGAQEGOyUDAQIBBz8JBw8IAQoGUAcKAQgPBwg/CAECAQImOwYBARAhDwElAwECAQg/CAcPCAEKBwAAAgAAAEkEAAO3ACgASwAAARUUBiMhIiY1ETQ2MyEyFh0BFAYjISIGFREUFjMhMjY9ATQ2OwEyFhUTERQGIyImLwEBDgEjIiYvAS4BNTQ2NwEnLgE1NDYzITIWFQMlYUT+JUVgYEUBkggKCgj+biY2NiYB2yY1CwgkCAvbFg8HDQVl/owDBwQDBwNBAgQEAgF1ZQUGFg8BJA8WAaW3RGFhRAHbRGELCCQICjYm/iUmNjYmtwcLCwcB7f7cDxYGBWX+iwMDAwNBAwcDBAcCAXVlBQ0HDxYWDwAAAgAAAEkDJQNuAA8AHwAAASEiBhURFBYzITI2NRE0JhcRFAYjISImNRE0NjMhMhYCgP4lJjY2JgHbJjU1f2FE/iVFYGBFAdtEYQMlNib+JSY2NiYB2yY2XP4lRGFhRAHbRGFhAAMAJf+3A9sDtwASADAAZwAABTQmIyImNTQmIyIGFRQWMzI2NSUhJicuAScmNTQnLgEnJiMiBw4BBwYVFAcOAQcGByEUBiMhFAYjIiY1ISImNTY3PgE3NjU0Nz4BNzY3LgE1NDYzMhYVFAYHFhceARcWFRQXHgEXFhcCCQUEIjAGAwQGOyoEBf6EAuYmHB0mCQoNDTYqKTg4KSo2DQ0KCSYdHCYDTise/wBWPDxW/wAeKx8hIDUREBERPi0tOQIDIBcXIAMCOS0tPhEREBE1ICEfEgQFMCIEBQUEKTsFBKQsMzN2RENNGyAgNxITExI3ICAbTUNEdjMzLB4rPFZWPCseGycncU1NaCkpKkUZGQkFCwYXICAXBgsFCRkZRSopKWhNTXEnJxsABgAA/7cESQO3ABoANgBCAF4AeACEAAABDgEHIyImNTQ3PgE3NjMyFjMyNjcOARUUFhcBFAYjISImNTQ3PgE3NjMyFjMyNjMyFx4BFxYVARQGIyImNTQ2MzIWARQHDgEHBiMiJy4BJyY1NDc+ATc2MzIXHgEXFgUUBisBLgEnPgE1NCYnHgEzMjYzMhceARcWAxQGIyImNTQ2MzIWAVMtTh1MK0QBAQ0ODxsJUjkUJhIBARgWAmRURf4NRVQIBysmJz8PaFZVaQ4/JyYrCAf9t1Y9PFZWPD1WAZIREjsoKC0uKCg7EhEREjsoKC4tKCg7EhEBSUQrTB1OLRcYAgESJhQ6UQkcDg4NAQFJVjw9VlY9PFYBtwEmIiswESIhQxkZMAYHChIKJ0sg/pRGTk5GMDo5YiEhT08hIWI5OjAC2j1WVj08Vlb+6C0oKDwRERERPCgoLS4oKDsREhIROygorjArIiYBIEsnChIKBwYwGRlDISIBSz1WVj08VlYAAAAAAwAAAEkDbgMlAA8AHwAvAAAlFRQGIyEiJj0BNDYzITIWERUUBiMhIiY9ATQ2MyEyFhEVFAYjISImPQE0NjMhMhYDbhYP/NwPFhYPAyQPFhYP/NwPFhYPAyQPFhYP/NwPFhYPAyQPFrdJDxYWD0kPFRUBFUkPFRUPSQ8WFgEWSQ8WFg9JDxYWAAoAAABJA7cDbgAQACAAMQBBAFEAYgByAIMAlACkAAAlNTQmKwEiBh0BFBY7ATI2NT0BNCYrASIGHQEUFjsBMjYFNTQmKwEiBh0BFBY7ATI2NQE1NCYrASIGHQEUFjsBMjYFNTQmKwEiBh0BFBY7ATI2BTU0JisBIgYdARQWOwEyNjUBNTQmKwEiBh0BFBY7ATI2BTU0JisBIgYdARQWOwEyNjU9ATQmKwEiBh0BFBY7ATI2NTcRFAYjISImNRE0NjMhMhYBJQsItwcLCwe3CAsLCLcHCwsHtwgLASQKCLcICgoItwgK/twLCLcHCwsHtwgLASQKCLcICgoItwgKASULCLYICwsItggL/tsKCLcICgoItwgKASULCLYICwsItggLCwi2CAsLCLYIC0k2Jv0AJTY2JQMAJjalbQgLCwhtCAsLCNtuBwsLB24ICgrTbQgLCwhtCAsLCAG2bggKCghuBwsL1G4HCwsHbggKCtNtCAsLCG0ICwsIAbZuCAoKCG4HCwvUbgcLCwduCAoKCNtuCAoKCG4HCwsHt/2TJjY2JgJtJjY2AAABAAABAAJJAkkAFQAAARQGBwEOASMiJicBLgE1NDYzITIWFQJJBgX/AAUNBwgNBf8ABQYWDwIADxUCJQgNBf8ABQYGBQEABQ0IDxUVDwAAAAEAAADbAkkCJQAUAAABFAYjISImNTQ2NwE+ATMyFhcBHgECSRUP/gAPFgYFAQAFDQgHDQUBAAUGAQAPFhYPBw4FAQAFBgYF/wAFDgABACUAkgFuAtsAFQAAAREUBiMiJicBLgE1NDY3AT4BMzIWFQFuFg8HDQb/AAUFBQUBAAYNBw8WArf+AA8WBgUBAAUOBwcNBgEABQUVDwAAAAEAAACSAUkC2wAVAAABFAYHAQ4BIyImNRE0NjMyFhcBHgEVAUkGBf8ABQ0HDxYWDwcNBQEABQYBtwcOBf8ABQYWDwIADxUFBf8ABg0HAAAAAgAAACUCSQNJABUAKwAAARQGBwEOASMiJicBLgE1NDYzITIWFTUUBiMhIiY1NDY3AT4BMzIWFwEeARUCSQYF/wAFDQcIDQX/AAUGFg8CAA8VFQ/+AA8WBgUBAAUNCAcNBQEABQYBSQcNBv8ABQUFBQEABg0HDxYWD9wPFhYPBw0FAQAFBgYF/wAFDQcAAAAABwAAAAAEAAMlAAsAFwAtADkARQBRAG0AABM0JiMiBhUUFjMyNhM0JiMiBhUUFjMyNhc3NiYnMSYGDwEOAQcGFhcWNjc2JiclNCYjIgYVFBYzMjYBNCYjIgYVFBYzMjYFNCYjIgYVFBYzMjYXFAYHDgEjISImJy4BNTQ3PgE3NjMyFx4BFxYV2yofHisrHh8qbiseHisrHh4r9TkEDw8OGwM6IjYJDC4sLE8LCRkcAXkrHh8qKh8eK/6SKx4eKyseHisBACseHisrHh4rtykoBRAJ/N4JEAUoKSgpi11dampdXYspKAElHisrHh8rKwEfHisrHh8rK/TaDxoEAw8P2gMrIyxPCwwuLCNAFBMeKyseHysrAYwfKiofHisrTx4rKx4fKyvhSow+CAkJCD2NSmleXYsoKSkoi11eaQAAAAACABoAdQJCAq8AJABJAAAlFAYPAQ4BIyImJwEuATU0NjcBPgEzMhYfAR4BFRQGDwEXHgEVMxQGDwEOASMiJicBLgE1NDY3AT4BMzIWHwEeARUUBg8BFx4BFQFmAwIdAwcDBAcC/vUCAwMCAQsCBwQDBwMdAgMDAuHhAgPcAwMdAgcEAwcD/vYDAwMDAQoDBwMEBwIdAwMDA+HhAwOlBAcDHAMDAwMBCgMHAwQHAgELAgMDAh0CCAMDCALh4AMHAwQHAxwDAwMDAQoDBwMEBwIBCwIDAwIdAggDAwgC4eADBwMAAAACAAcAdQIvAq8AJABJAAABFAYHAQ4BIyImLwEuATU0Nj8BJy4BNTQ2PwE+ATMyFhcBHgEVMxQGBwEOASMiJi8BLgE1NDY/AScuATU0Nj8BPgEzMhYXAR4BFQFUAwP+9gMHAwQHAh0CBAQC4eECBAQCHQIHBAMHAwEKAwPbAwL+9QIHBAMHAxwDAwMD4OADAwMDHAMHAwQHAgELAgMBkgMHA/72AwMDAxwDBwQDBwPg4QIIAwMIAh0CAwMC/vUCBwQDBwP+9gMDAwMcAwcEAwcD4OECCAMDCAIdAgMDAv71AgcEAAABABoAdQFmAq8AJAAAARQGDwEXHgEVFAYPAQ4BIyImJwEuATU0NjcBPgEzMhYfAR4BFQFmAwLh4QIDAwIdAwcDBAcC/vUCAwMCAQsCBwQDBwMdAgMCgAMIAuHgAwcDBAcDHAMDAwMBCgMHAwQHAgELAgMDAh0CBwQAAAAAAQAHAHUBVAKvACQAAAEUBgcBDgEjIiYvAS4BNTQ2PwEnLgE1NDY/AT4BMzIWFwEeARUBVAMD/vYDBwMEBwIdAgQEAuHhAgQEAh0CBwQDBwMBCgMDAZIDBwP+9gMDAwMcAwcEAwcD4OECCAMDCAIdAgMDAv71AgcEAAAAAAIAAAAABEkDtwAPAC4AAAERNCYjISIGFREUFjMhMjYTERQGIyEUFhUUBiMhIiY1NDY1ISImNRE0NjMhMhYVBAALB/xtBwsLBwOTBwtJNiX+ySQVD/7bDxUk/sklNjYlA5MlNgGAAdsICwsI/iUHCwsB4v2TJjYkOg8PFhYPDzklNiYCbSY2NiYAAAAAAgAAAAADbgNuABwAOQAAASIHDgEHBhUUFx4BFxYzMjc+ATc2NTQnLgEnJiMBFAcOAQcGIyInLgEnJjU0Nz4BNzYzMTIXHgEXFgG3QDk5VBkYGBlUOTlAQDk4VRgZGRhVODlAAbcjIndQUFtbUFB3IyIiI3dQUFtbUFB3IiMC7hkYVTg5QEA5OVQZGBgZVDk5QEA5OFUYGf7JW1BQdyIjIyJ3UFBbW1BQdyIjIyJ3UFAAAAAAAQAAAAADbgNuABsAAAEUBw4BBwYjIicuAScmNTQ3PgE3NjMyFx4BFxYDbiMid1BQW1tQUHcjIiIjd1BQW1tQUHciIwG3W1BQdyIjIyJ3UFBbW1BQdyIjIyJ3UFAAAAAAAwAfAAsEKgMaABUAJgA8AAAlBwYiJwEmNDcBNjIfARYUDwEXFhQHAQMOAS8BLgE3Ez4BHwEeAQcJAQYiLwEmND8BJyY0PwE2MhcBFhQHAWEdBg8F/vUFBQELBQ8GHQUF4eEFBQFR1QINByQHBwLVAg0HJAcHAgF4/vUFDwYcBgbg4AYGHAYPBQELBQWXHAYGAQoGDwUBCwUFHQUQBeHgBg8GAmL9HgcHAgoCDQcC4gcIAgoCDgf+jP72BgYcBg8G4OEFEAUdBQX+9QUPBgAAAAIAAP+3A24DtwAIABsAAAERHgEfAR4BFwUUFjMhERQGIyEiJjURNDYzIRECSQYKBekECAT+qSAXATcgF/0AFyAgFwHJApIBDgQIBOkECwYSFyD9pRcgIBcDkhcg/skAAAUAAP+3A24DtwAIABoAKwA8AE0AAAEeARchER4BFwMhERQGIyEiJjURNDYzIREUFhM1NCYjISIGHQEUFjMhMjY1PQE0JiMhIgYdARQWMyEyNjU9ATQmIyEiBh0BFBYzITI2NQNHBAgE/vIGCgUnATcgF/0AFyAgFwHJIHIKCP5uCAsLCAGSCAoKCP5uCAsLCAGSCAoKCP5uCAsLCAGSCAoCpwQLBgEOBAgE/rn9pRcgIBcDkhcg/skXIP5cJAgKCggkCAsLCJIkCAsLCCQICgoIkiUHCwsHJQgKCggAAAAAAQAAAAADXANuADsAAAEhHgEVFAcOAQcGIyInLgEnJjU0Nz4BNzYzMhceARcWFwcuASMiBw4BBwYVFBceARcWMzI3PgE3NjcjNQG3AZ4DBB4eb05NX1tQUHcjIiIjd1BQWywpKUogIR13GVZAODIxShYVFRZKMTI4QS4tOw8PBPkB9hEjFV5PT3EgICIjd1BQW1tQUHciIwgIHhUVG3MYLBYWSzIzOToyM0sWFRQVOiEhGJcAAQAS/8kD7gOfADoAAAEUBw4BBwYjIicuAScmNTQ3PgE3NjcVBgcOAQcGFRQXHgEXFjMyNz4BNzY1NCcuAScmJzUWFx4BFxYVA+4nJ4ZaWmZmWlqGJychIHFNTVk/NTZOFhcdHWNDQkxMQkNjHR0XFk42NT9ZTU1xICEBt2ZaWoYnJycnhlpaZl1TU4IrKw2CDSAhXzs8QkxCQ2MdHR0dY0NCTEI8O18hIA2CDSsrglNTXQAABAAN/7cEhgO3ABIAJQA9AG8AAAU0JiMiJjU0JiMiBhUUFjMyNjUJAS4BIyIHDgEHBhUUBw4BBwYHBRQGIyEUBiMiJjU3IS4BJzcWFx4BFxYXExcWFAcBBiYvASY2PwEuATU2Nz4BNzY1NDc+ATc2Ny4BNTQ2MzIWFRQGBx4BFzc2FhcCUgUEIjAFBAQFOykEBf7NAfYWZFI4KSo2DQ0FBRMPDxQDBiwe/wBVPTxWVQGxMEERPwsTEy0aGhkxMAQG+9IFEAQwBQEFawYFHyEhNBEREBE+LS05AgMgFxcgAgNKax3vBg8FEgQFMCIEBQUEKTsFBAEPAbItSRMSNyAgGzczMlwqKSZrHis8VlU9STaDTjdAMjFNHB0VAxw3Bg8F/GEFAQY3Bg8FXAgTChsnJ3FNTWgpKSpFGRkJBQsGFyAgFwYLBQtMMs8FAQYAAAAAAgAAAAAEkgNuAAUACwAAJRUhETMRARMhEQkBBJL7bkkDbpL8SQEAAUlJSQNu/NsCSf4AAUkBSv62AAAABAAA/7cEAAO3ABYAKgA9AEkAAAEyFhceARclJgcOAQcGByc2Nz4BNzYzBRMWFx4BFxY3AyYnLgEnJjU0NjcFFhcWBgcGBw4BJxM2NzYmJyYnJzIWFRQGIyImNTQ2Af5Cgz1DZiD+WC0rK0gcHA+dJS0tZjg3OP5VwRQfH0wqKy2DXE9QdCEhLCcDiyEBATs5OlNDkkjoGQsMAg8PHr1IZWVISGVlA7ciIydtQBYDCwstIiEr8y0kIzEMDej+hikfICgHCAn+/g4tLYZWVmBNjzxgV1taqEhIMCcgAwFkJisrVSkpIgNlR0hlZUhHZQAAAgATAAAD7QNuAAMAaAAAATcjBwEHDgErAQczMhYXHgEPAQ4BKwEHDgErASImJy4BPwEjBw4BKwEiJicuAT8BIyImJy4BPwE+ATsBNyMiJicuAT8BPgE7ATc+ATsBMhYXHgEPATM3PgE7ATIWFx4BDwEzMhYXHgEHAjYlkSUCSCACCQe6JbIEBwMDAgIgAQoGuy4CCgaABAgDAwEBLJEuAgoGgQMIAwICASyxBQcDAgIBIAIJB7olsgQHAwMCAiABCga7LgIKB4AEBwMDAQEskS4CCgeAAwgDAgIBLLEFBwMCAgEBbpKSASCABgiSBAMECASABgi7BggEAwMJBLK7BggEAwMJBLIEAwMJBIAGCJIEAwMJBIAGCLsGCAQDBAgEsrsGCAQDBAgEsgQDBAgEAAQAAAAAA24DbgAQAEQAYQB+AAABFRQGKwEiJj0BNDY7ATIWFRMUBgcOAR0BFAYrASImPQE0Njc+ATU0JiMiBgcOAQcOASMiJi8BLgE3PgEzMTIXHgEXFhUDIgcOAQcGFRQXHgEXFjMyNz4BNzY1NCcuAScmIwEUBw4BBwYjIicuAScmNTQ3PgE3NjMxMhceARcWAfcLB1wICgoIXAcLkkMfFhoLB1wICjwfGR4zHA8eCgkUEAMHBQMFAj4GAgQjY0EjJCM5EhLSTEJDYx0dHR1jQ0JMS0NDYx0dHR1jQ0NLAbcjIndQUFtbUFB3IyIiI3dQUFtbUFB3IiMBCVsICwsIWwgKCggBHD06Eg0UDRMHCwsHJzUsDgwVFBkgCAcGFhMEAwECLwQPBjc2DQ0vHyAlAQAdHWNDQ0tMQkNjHR0dHWNDQkxLQ0NjHR3+kltQUHciIyMid1BQW1tQUHciIyMid1BQAAAAAAEAAAABAAAU8s37Xw889QALBAAAAAAA1yprLgAAAADXKmsuAAD/twSSA7cAAAAIAAIAAAAAAAAAAQAAA8D/wAAABJIAAAAABJIAAQAAAAAAAAAAAAAAAAAAADMEAAAAAAAAAAAAAAACAAAAAtsAAAO3AAAEAAAABAAARQMlAD8DbgAAA24AAANuAAADbgAABAAAAAQAAAACSQAAA7sAAAMAAGMCtwA+BAAACQSSAAAESQAABAAAAAMlAAAEAAAlBEkAAANuAAADtwAAAkkAAAJJAAABkgAlAUkAAAJJAAAEAAAAAlsAGgI3AAcBgAAaAVsABwRJAAADbgAAA24AAARJAB8DbgAAA24AAANcAAAEAAASBJIADQSSAAAENwAABAAAEwNuAAAAAAAAAAoAFAAeAHQA0AFSAZAB7ALCAwADcgQGBLYFYgWiBhoGRAZwBswG/AjUCUAJcgoGCsYLCgveDAYMLAxUDHwMxA1kDdYOSA6GDsQPCg9kD5QP/BAsEJwQ9hFQEfgSFhKOEyYT2gABAAAAMwFVAAoAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEAAgAAAAEAAAAAAAIABwAzAAEAAAAAAAMAAgAnAAEAAAAAAAQAAgBIAAEAAAAAAAUACwAGAAEAAAAAAAYAAgAtAAEAAAAAAAoAGgBOAAMAAQQJAAEABAACAAMAAQQJAAIADgA6AAMAAQQJAAMABAApAAMAAQQJAAQABABKAAMAAQQJAAUAFgARAAMAAQQJAAYABAAvAAMAAQQJAAoANABoZmEAZgBhVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwZmEAZgBhZmEAZgBhUmVndWxhcgBSAGUAZwB1AGwAYQByZmEAZgBhRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format('woff'); + font-weight: normal; + font-style: normal; +} +[class^="fa-"],[class*=" fa-"]{font-family:'fa' !important;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes "fa-spin"{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg);}}@keyframes "fa-spin"{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg);}} +.fa-square-o:before{content:"\f096";}.fa-user:before{content:"\f007"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before{content:"\f00d"}.fa-remove:before{content:"\f00d"}.fa-times:before{content:"\f00d"}.fa-cog:before{content:"\f013"}.fa-gear:before{content:"\f013"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-list:before{content:"\f03a"}.fa-map-marker:before{content:"\f041"}.fa-check-square-o:before{content:"\f046"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-exclamation-triangle:before{content:"\f071"}.fa-warning:before{content:"\f071"}.fa-bar-chart:before{content:"\f080"}.fa-bar-chart-o:before{content:"\f080"}.fa-cogs:before{content:"\f085"}.fa-gears:before{content:"\f085"}.fa-external-link:before{content:"\f08e"}.fa-bell-o:before{content:"\f0a2"}.fa-group:before{content:"\f0c0"}.fa-users:before{content:"\f0c0"}.fa-bars:before{content:"\f0c9"}.fa-navicon:before{content:"\f0c9"}.fa-reorder:before{content:"\f0c9"}.fa-table:before{content:"\f0ce"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-sort:before{content:"\f0dc"}.fa-unsorted:before{content:"\f0dc"}.fa-dashboard:before{content:"\f0e4"}.fa-tachometer:before{content:"\f0e4"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-desktop:before{content:"\f108"}.fa-circle-o:before{content:"\f10c"}.fa-circle:before{content:"\f111"}.fa-code:before{content:"\f121"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-google:before{content:"\f1a0"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-area-chart:before{content:"\f1fe"}.fa-chrome:before{content:"\f268"}.fa-hashtag:before{content:"\f292"}.fa-question-circle-o:before{content:"\f29c"} diff --git a/goaccess++/resources/css/fa.min.css.tmp b/goaccess++/resources/css/fa.min.css.tmp new file mode 100644 index 0000000..ef407be --- /dev/null +++ b/goaccess++/resources/css/fa.min.css.tmp @@ -0,0 +1 @@ +@font-face {font-family: 'fa';src: url(data:application/font-woff;charset=utf-8;base64,d09GRgABAAAAAC2sAAsAAAAALWAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABPUy8yAAABCAAAAGAAAABgDxIPHGNtYXAAAAFoAAABbAAAAWzzYPN8Z2FzcAAAAtQAAAAIAAAACAAAABBnbHlmAAAC3AAAJ7QAACe0PqRPf2hlYWQAACqQAAAANgAAADYSBhrHaGhlYQAAKsgAAAAkAAAAJAhUBIZobXR4AAAq7AAAAMwAAADMpCoCC2xvY2EAACu4AAAAaAAAAGjyrvuebWF4cAAALCAAAAAgAAAAIAA+AVduYW1lAAAsQAAAAUoAAAFKIhWTsnBvc3QAAC2MAAAAIAAAACAAAwAAAAMDVgGQAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAQAAA8pwDwP/AAEADwABAAAAAAQAAAAAAAAAAAAAAIAAAAAAAAwAAAAMAAAAcAAEAAwAAABwAAwABAAAAHAAEAVAAAABQAEAABQAQAAEAIPAH8AnwDfAT8BfwIvA68EHwRvBU8HHwgPCF8I7wlvCi8MDwyfDO8Nrw3PDk8QHxBfEI8QzxEfEh8VzxoPHO8ffx/vJo8pLynP/9//8AAAAAACDwB/AJ8AvwE/AW8CHwOvBB8EbwU/Bx8IDwhfCO8JbwovDA8MnwzvDX8Nzw5PEA8QTxCPEM8RHxIfFb8aDxzvH38f7yaPKS8pz//f//AAH/4w/9D/wP+w/2D/QP6w/UD84Pyg++D6IPlA+QD4gPgQ92D1kPUQ9ND0UPRA89DyIPIA8eDxsPFw8IDs8OjA5fDjcOMQ3IDZ8NlgADAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAH//wAPAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAIAAAAAAtsDbgAbADcAACUUBiMhIiY1NDc+ATc2Mx4BMzI2NzIXHgEXFhUDFAcOAQcGIyInLgEnJjU0Nz4BNzYzMhceARcWAttHMv4YMkgICColJDgjWzU0XCM4JCQqCAiSERE8KCgtLigoOxESEhE7KCguLSgoPBERlz5ZWT45OTpdHh0hKCghHR5dOjk5AfstKCg8ERERETwoKC0uKCg7ERISETsoKAAAAAAEAAAASQO3A24AEAAhADEAQQAAARUUBiMhIiY9ATQ2MyEyFhURFRQGIyEiJj0BNDYzITIWFQEVFAYjISImPQE0NjMhMhYRFRQGIyEiJj0BNDYzITIWAbcrHv7bHisrHgElHisrHv7bHisrHgElHisCACse/tseKyseASUeKyse/tseKyseASUeKwFu3B4rKx7cHisrHgG33B4rKx7cHisrHv5J3B4rKx7cHisrAZncHisrHtweKysABgAAAEkEAANuAA8AHwAvAD8ATwBfAAAlFRQGKwEiJj0BNDY7ATIWERUUBisBIiY9ATQ2OwEyFgEVFAYjISImPQE0NjMhMhYBFRQGKwEiJj0BNDY7ATIWARUUBiMhIiY9ATQ2MyEyFhEVFAYjISImPQE0NjMhMhYBJSEWtxcgIBe3FiEhFrcXICAXtxYhAtsgF/3cFyAgFwIkFyD9JSEWtxcgIBe3FiEC2yAX/dwXICAXAiQXICAX/dwXICAXAiQXIO5uFyAgF24WISEBDm0XICAXbRcgIP7FbhcgIBduFiEhAjNuFyAgF24XICD+xG0XICAXbRcgIAEObhcgIBduFyAgAAABAEUAUQO7AvgAJAAAARQGBwEOASMiJicBLgE1NDY/AT4BMzIWHwEBPgEzMhYfAR4BFQO7CAj+FAcVCgsVB/7jCAgICE4IFAsKFQioAXYIFQoLFAhOCAgCcwoVB/4UCAgICAEdBxULChUHTggICAioAXcICAgITgcVCwAAAQA/AD8C5gLmADwAACUUBg8BDgEjIiYvAQcOASMiJi8BLgE1NDY/AScuATU0Nj8BPgEzMhYfATc+ATMyFh8BHgEVFAYPARceARUC5gkHTggUCwsUCKioBxULChUHTggICAioqAgICAhOBxUKCxUHqKgIFAsLFAhOBwkJB6ioBwnDChUHTggICAioqAgICAhOBxUKCxUHqKgIFAsLFAhOBwkJB6ioBwkJB04IFAsLFAioqAcVCwAAAAIAAAAAA24DbgALAJIAAAE0JiMiBhUUFjMyNiUVFAYPAQ4BBx4BFx4BFRQGBw4BIyImLwEOAQcOAQcOASsBIiYvAS4BJwcOASMiJicuAScuATU0Njc+ATcuAS8BLgE9ATQ2PwE+ATcuAScuATU0Njc+ATMyFh8BPgE3PgE3PgE7ATIWHwEeARc3PgEzMhYXHgEXHgEVFAYHDgEHHgEfAR4BFQJJVjw9VVU9PFYBJQkHagUKBw4fEAIEAwMKVQ8EBwRPDBoOAwYHAgsIfwcMARANGg1QAwgDBAgDFjYSAgICAw4fDwgMBGgICQkGawQLBw8eEAMDAwILVQ8DCANPDRoNAwcHAgsHfwgMARANGgxRAwcEBAcDFzYSAgIDAg4fDwcMBWgHCgG3PFZWPD1VVXt/Bg0BEA4aDBUnEwMIAwQHAw1ZAwI+BgsFGjYaBwkKB2kFCgY9AgMDAxUzGAMHBAMHAxMnFA4cDw8BDAh+Bw0BEA4aDRQnEwMHBAQGAw5ZBAI9BgsEGzYaBwkKB2oECgc9AwMEAhUzGQMGBAQGAxQmFA4cDhACDAcAAAAAAwAA/7cDbgO3ABMAHAAmAAABHgEVERQGIyEiJjURNDYzITIWFwcVMy4BLwEuARMRIyImPQEhESEDRxAXIBf9ABcgIBcCABc3EEzXAwcDsgMO1e4XIP5JAtwC3hA3F/1uFyAgFwOSFyAXECfXCA0DswMH/JkCSSAX7vySAAMAAAAAA24DbgAVADEATQAAAREUBisBIiY9ATQ2OwE1NDY7ATIWFRc0Jy4BJyYjIgcOAQcGFRQXHgEXFjMyNz4BNzY3FAcOAQcGIyInLgEnJjU0Nz4BNzYzMhceARcWAgALB7cICgoIgAoIJQcL7hkYVTg5QEA5OVQZGBgZVDk5QEA5OFUYGYAjIndQUFtbUFB3IyIiI3dQUFtbUFB3IiMCgP8ACAoKCCUHC8kICgoIyUA5OFUYGRkYVTg5QEA5OVQZGBgZVDk5QFtQUHciIyMid1BQW1tQUHciIyMid1BQAAAAAAIAAAAAA24DbgA0AGcAAAEwFBUGBw4BBwYjIicuAScmJwcOASMiJjURNDYzITIWFRQGDwEeATMyNjc+ATc+ATsBMhYVExEUBiMhIiY1NDY/AS4BIyIGBw4BBw4BKwEiJj0BNjc+ATc2MzIXHgEXFhc3PgEzMhYVA18SKCdvRkVPKikpTCMkHkoFDQcPFhYPAQAPFQYFTihoN0yFKAoNBwIJBm4ICg8WD/8ADxUFBU8oaDdMhSgLDAgCCAdxCAsTJyhwRkZPKikpTSMkHkoGDQcPFgFbAwFLQD9bGRkICB8XFh1KBQUVDwEADxYWDwcNBk4mKUtBECESBgcLCAHK/wAPFhYPBw0FTyYoSkERIREGBwsHBExAP1oaGQgJHxYXHEkFBhUPAAAACAAAAEkEAANuABAAIAAwAEEAUgBjAHQAhAAAExUUBisBIiY9ATQ2OwEyFhU1FRQGKwEiJj0BNDY7ATIWNRUUBisBIiY9ATQ2OwEyFgEVFAYjISImPQE0NjMhMhYVNRUUBiMhIiY9ATQ2MyEyFhU1FRQGIyEiJj0BNDYzITIWFRMRNCYjISIGFREUFjMhMjY1ExEUBiMhIiY1ETQ2MyEyFtsLByQICwsIJAcLCwckCAsLCCQHCwsHJAgLCwgkBwsCkwsI/dwHCwsHAiQICwsI/dwHCwsHAiQICwsI/dwHCwsHAiQIC0kLB/y2BwsLBwNKBwtJNiX8tiU2NiUDSiU2ARIkCAsLCCQICwsIkyUHCwsHJQcLC4slBwsLByUHCwv+1CQICwsIJAgLCwiTJQcLCwclBwsLB5IlBwsLByUHCwsH/m4B2wcLCwf+JQgLCwgCbf2TJjY2JgJtJjY2AAAAAAgAAABJBAADbgAQACEAMQBCAFIAYwBzAIMAADcVFAYrASImPQE0NjsBMhYVNRUUBisBIiY9ATQ2OwEyFhU1FRQGKwEiJj0BNDY7ATIWARUUBiMhIiY9ATQ2MyEyFhUBFRQGKwEiJj0BNDY7ATIWARUUBiMhIiY9ATQ2MyEyFhU1FRQGIyEiJj0BNDYzITIWNRUUBiMhIiY9ATQ2MyEyFpILB24HCwsHbgcLCwduBwsLB24HCwsHbgcLCwduBwsDbgsH/QAICwsIAwAHC/ySCwduBwsLB24HCwNuCwf9AAgLCwgDAAcLCwf9AAgLCwgDAAcLCwf9AAgLCwgDAAcLyW4HCwsHbgcLCwfcbgcLCwduBwsLB9tuBwsLB24HCwv+Qm4HCwsHbgcLCwcCkm0ICwsIbQgLC/5CbgcLCwduBwsLB9tuBwsLB24HCwvUbQgLCwhtCAsLAAAAAgAAAAACSQNuAAsAKAAAATQmIyIGFRQWMzI2NxQGBwMOASMiJicDLgE1NDc+ATc2MzIXHgEXFhUBt1Y8PVZWPTxWkggL0AkkFBUkCdALCBcXTzY1PTw2NU8XFwJJPVVVPTxWVjwaNRf+RhMWFhMBuhc1Gj01NVAXFxcXUDU1PQACAAAASQOpA24AOgBQAAABFRQGIyEiJjURNDYzITIWFx4BFxYGDwEOASMiJiMuASMhIgYVERQWMyEyNj0BNDY/AT4BMzIWFx4BFRMBBiIvASY0PwE2Mh8BATYyHwEWFAcDJWFE/iVFYGBFAdsRIhAEBQEBAwMcAwcDAQMBBw0G/iUmNjYmAdsmNQMDJAMHAwIDAgUHhP4uDSYO9Q4OPg4mDpYBcg0mDj8NDQGjtURhYUQB20RhBwgBBwUECQMcAwMBAgI2Jv4lJjY2JpEDBwIlAwMBAQIJBgEY/i8ODvUOJg4+Dg6WAXIODj8OJQ4AAAABAGMAGgKdA50AFQAACQIWFA8BBiInASY0NwE2Mh8BFhQHAp3+0QEvCwtfCh4L/lgLCwGoCx4KXwsLAwv+0P7RCx4KXwsLAagKHgsBqAsLXwoeCwABAD4AGgJ5A50AFQAACQEGIi8BJjQ3CQEmND8BNjIXARYUBwJ5/lgLHgtfCgoBMP7QCgpfCx4LAagKCgHC/lgLC18KHgsBLwEwCx4KXwsL/lgLHgoAAAAAAwAJAAAD9wO3AA8AJgA8AAAlNTQmKwEiBh0BFBY7ATI2JxM0JicuASsBIgYHDgEVExQWOwEyNjUDARYUBw4BIyEiJicmNDcBPgEzMhYXAkkKCG4ICgoIbggKAQoCAwMHBH4EBwMDAgkMCGoHDAgBtwkKCiIT/JITIgoKCQG3CSMUFCMJpW0HDAwHbQgLC94BBgMGAgIEBAICBwP++wYHBwYCFvzbESYRERMTEREmEQMlERUVEQAAAAUAAAAABJIDbgADAAgADgATABgAAAERIxEBESMRMwEVIREzEQERIxEzNxEjETMBbpMBbpKSAkn7bkkC3JOT25KSAbf+2wElAST9twJJ/W5JA2782wIA/kkBt9z9bQKTAAYAAP+/BEkDrgALABcAIwCkAPwBVAAAATQmIyIGFRQWMzI2BTQmIyIGFRQWMzI2ETQmIyIGFRQWMzI2BxUUBg8BDgEHHgEXHgEVFAYHDgEjIiYvAQ4BBw4BBw4BKwEiJi8BLgEnBw4BIyImJy4BNTQ2Nz4BNy4BLwEuAT0BNDY/AT4BNy4BJy4BNTQ2Nz4BMzIWHwE+ATc+ATc+ATsBMhYfAR4BFzc+ATMyFhceARUUBgcOAQceAR8BHgEVARUUBiMOAQceARUUBgcOASMiJiciBiMiJiMOASMiJicuATU0NjcuASciJj0BNDY3PgE3LgE1MDY3PgEzMhYXPgEzMhYXPgE/ATIWFx4BMRQGBx4BFx4BFREVFAYHDgEHHgEVFAYHDgEjIiYnIgYjIiYjDgEjIiYnLgE1NDY3LgEnLgE9ATQ2Nz4BNy4BNTQ2Nz4BMzIWFzI2MzIWMz4BPwEyFhceARUUBgceARceARUCAFY8PVZWPTxWAbcrHh4rKx4eKyseHisrHh4r3AcGWAQJBgwaDgICAgIJRwwEBgJCCxUMAgUGAgkGagYLAQ0LFQtDAgYDBAYCDEcDAQ0ZDQYLA1cGCAgFWQMJBgwaDQICAQMIRw0DBgNBCxYLAgYFAgoGagYKAQ0LFgpDAwYDAwYDC0cCAgwaDAYKBFcGBwFuTAkDCQUEGQEBBUACBi4EBAkEBQgEBS4FAz8FAgEaBAYIBAhNTQgECAYEGgECBT8DBS4FBAgFBAkEDBoOBAJABQEBGQQFCQMJTEwJAwkFBBkBAQVAAgYuBAQJBAUIBAUuBQM/BQIBGgQGCAQITU0IBAgGBBoBAgU/AwUuBQQIBQQJBAwaDgQCQAUBARkEBQkDCUwBtzxWVjw9VVXoHisrHh4rKwJnHiwsHh4rK9JqBQsBDgsVCxEhEAIGAwMGAgxJAgIzBQkEFS4VBggIBlgDCQYzAgICAgtEDQMFAxAgEQsYDA0BCgZqBQsBDQwVCxEgEQIGAwMGAgxJAgIzBQkEFS4VBggJBlcECQUzAgICAwpFDAMFAxEfEQwXDA0BCgb+z1AGCwkOBwk+CAECAQMmPAYBAQY8JgMBAgEHPwkHDgkLBlAHCgEIDwcIPwgDAQImOwcBAQEBESEOAiUDAQMIPwgHDwgBCgcCSVAGCgEIDwcJPggBAgEDJTsGAQEGOyUDAQIBBz8JBw8IAQoGUAcKAQgPBwg/CAECAQImOwYBARAhDwElAwECAQg/CAcPCAEKBwAAAgAAAEkEAAO3ACgASwAAARUUBiMhIiY1ETQ2MyEyFh0BFAYjISIGFREUFjMhMjY9ATQ2OwEyFhUTERQGIyImLwEBDgEjIiYvAS4BNTQ2NwEnLgE1NDYzITIWFQMlYUT+JUVgYEUBkggKCgj+biY2NiYB2yY1CwgkCAvbFg8HDQVl/owDBwQDBwNBAgQEAgF1ZQUGFg8BJA8WAaW3RGFhRAHbRGELCCQICjYm/iUmNjYmtwcLCwcB7f7cDxYGBWX+iwMDAwNBAwcDBAcCAXVlBQ0HDxYWDwAAAgAAAEkDJQNuAA8AHwAAASEiBhURFBYzITI2NRE0JhcRFAYjISImNRE0NjMhMhYCgP4lJjY2JgHbJjU1f2FE/iVFYGBFAdtEYQMlNib+JSY2NiYB2yY2XP4lRGFhRAHbRGFhAAMAJf+3A9sDtwASADAAZwAABTQmIyImNTQmIyIGFRQWMzI2NSUhJicuAScmNTQnLgEnJiMiBw4BBwYVFAcOAQcGByEUBiMhFAYjIiY1ISImNTY3PgE3NjU0Nz4BNzY3LgE1NDYzMhYVFAYHFhceARcWFRQXHgEXFhcCCQUEIjAGAwQGOyoEBf6EAuYmHB0mCQoNDTYqKTg4KSo2DQ0KCSYdHCYDTise/wBWPDxW/wAeKx8hIDUREBERPi0tOQIDIBcXIAMCOS0tPhEREBE1ICEfEgQFMCIEBQUEKTsFBKQsMzN2RENNGyAgNxITExI3ICAbTUNEdjMzLB4rPFZWPCseGycncU1NaCkpKkUZGQkFCwYXICAXBgsFCRkZRSopKWhNTXEnJxsABgAA/7cESQO3ABoANgBCAF4AeACEAAABDgEHIyImNTQ3PgE3NjMyFjMyNjcOARUUFhcBFAYjISImNTQ3PgE3NjMyFjMyNjMyFx4BFxYVARQGIyImNTQ2MzIWARQHDgEHBiMiJy4BJyY1NDc+ATc2MzIXHgEXFgUUBisBLgEnPgE1NCYnHgEzMjYzMhceARcWAxQGIyImNTQ2MzIWAVMtTh1MK0QBAQ0ODxsJUjkUJhIBARgWAmRURf4NRVQIBysmJz8PaFZVaQ4/JyYrCAf9t1Y9PFZWPD1WAZIREjsoKC0uKCg7EhEREjsoKC4tKCg7EhEBSUQrTB1OLRcYAgESJhQ6UQkcDg4NAQFJVjw9VlY9PFYBtwEmIiswESIhQxkZMAYHChIKJ0sg/pRGTk5GMDo5YiEhT08hIWI5OjAC2j1WVj08Vlb+6C0oKDwRERERPCgoLS4oKDsREhIROygorjArIiYBIEsnChIKBwYwGRlDISIBSz1WVj08VlYAAAAAAwAAAEkDbgMlAA8AHwAvAAAlFRQGIyEiJj0BNDYzITIWERUUBiMhIiY9ATQ2MyEyFhEVFAYjISImPQE0NjMhMhYDbhYP/NwPFhYPAyQPFhYP/NwPFhYPAyQPFhYP/NwPFhYPAyQPFrdJDxYWD0kPFRUBFUkPFRUPSQ8WFgEWSQ8WFg9JDxYWAAoAAABJA7cDbgAQACAAMQBBAFEAYgByAIMAlACkAAAlNTQmKwEiBh0BFBY7ATI2NT0BNCYrASIGHQEUFjsBMjYFNTQmKwEiBh0BFBY7ATI2NQE1NCYrASIGHQEUFjsBMjYFNTQmKwEiBh0BFBY7ATI2BTU0JisBIgYdARQWOwEyNjUBNTQmKwEiBh0BFBY7ATI2BTU0JisBIgYdARQWOwEyNjU9ATQmKwEiBh0BFBY7ATI2NTcRFAYjISImNRE0NjMhMhYBJQsItwcLCwe3CAsLCLcHCwsHtwgLASQKCLcICgoItwgK/twLCLcHCwsHtwgLASQKCLcICgoItwgKASULCLYICwsItggL/tsKCLcICgoItwgKASULCLYICwsItggLCwi2CAsLCLYIC0k2Jv0AJTY2JQMAJjalbQgLCwhtCAsLCNtuBwsLB24ICgrTbQgLCwhtCAsLCAG2bggKCghuBwsL1G4HCwsHbggKCtNtCAsLCG0ICwsIAbZuCAoKCG4HCwvUbgcLCwduCAoKCNtuCAoKCG4HCwsHt/2TJjY2JgJtJjY2AAABAAABAAJJAkkAFQAAARQGBwEOASMiJicBLgE1NDYzITIWFQJJBgX/AAUNBwgNBf8ABQYWDwIADxUCJQgNBf8ABQYGBQEABQ0IDxUVDwAAAAEAAADbAkkCJQAUAAABFAYjISImNTQ2NwE+ATMyFhcBHgECSRUP/gAPFgYFAQAFDQgHDQUBAAUGAQAPFhYPBw4FAQAFBgYF/wAFDgABACUAkgFuAtsAFQAAAREUBiMiJicBLgE1NDY3AT4BMzIWFQFuFg8HDQb/AAUFBQUBAAYNBw8WArf+AA8WBgUBAAUOBwcNBgEABQUVDwAAAAEAAACSAUkC2wAVAAABFAYHAQ4BIyImNRE0NjMyFhcBHgEVAUkGBf8ABQ0HDxYWDwcNBQEABQYBtwcOBf8ABQYWDwIADxUFBf8ABg0HAAAAAgAAACUCSQNJABUAKwAAARQGBwEOASMiJicBLgE1NDYzITIWFTUUBiMhIiY1NDY3AT4BMzIWFwEeARUCSQYF/wAFDQcIDQX/AAUGFg8CAA8VFQ/+AA8WBgUBAAUNCAcNBQEABQYBSQcNBv8ABQUFBQEABg0HDxYWD9wPFhYPBw0FAQAFBgYF/wAFDQcAAAAABwAAAAAEAAMlAAsAFwAtADkARQBRAG0AABM0JiMiBhUUFjMyNhM0JiMiBhUUFjMyNhc3NiYnMSYGDwEOAQcGFhcWNjc2JiclNCYjIgYVFBYzMjYBNCYjIgYVFBYzMjYFNCYjIgYVFBYzMjYXFAYHDgEjISImJy4BNTQ3PgE3NjMyFx4BFxYV2yofHisrHh8qbiseHisrHh4r9TkEDw8OGwM6IjYJDC4sLE8LCRkcAXkrHh8qKh8eK/6SKx4eKyseHisBACseHisrHh4rtykoBRAJ/N4JEAUoKSgpi11dampdXYspKAElHisrHh8rKwEfHisrHh8rK/TaDxoEAw8P2gMrIyxPCwwuLCNAFBMeKyseHysrAYwfKiofHisrTx4rKx4fKyvhSow+CAkJCD2NSmleXYsoKSkoi11eaQAAAAACABoAdQJCAq8AJABJAAAlFAYPAQ4BIyImJwEuATU0NjcBPgEzMhYfAR4BFRQGDwEXHgEVMxQGDwEOASMiJicBLgE1NDY3AT4BMzIWHwEeARUUBg8BFx4BFQFmAwIdAwcDBAcC/vUCAwMCAQsCBwQDBwMdAgMDAuHhAgPcAwMdAgcEAwcD/vYDAwMDAQoDBwMEBwIdAwMDA+HhAwOlBAcDHAMDAwMBCgMHAwQHAgELAgMDAh0CCAMDCALh4AMHAwQHAxwDAwMDAQoDBwMEBwIBCwIDAwIdAggDAwgC4eADBwMAAAACAAcAdQIvAq8AJABJAAABFAYHAQ4BIyImLwEuATU0Nj8BJy4BNTQ2PwE+ATMyFhcBHgEVMxQGBwEOASMiJi8BLgE1NDY/AScuATU0Nj8BPgEzMhYXAR4BFQFUAwP+9gMHAwQHAh0CBAQC4eECBAQCHQIHBAMHAwEKAwPbAwL+9QIHBAMHAxwDAwMD4OADAwMDHAMHAwQHAgELAgMBkgMHA/72AwMDAxwDBwQDBwPg4QIIAwMIAh0CAwMC/vUCBwQDBwP+9gMDAwMcAwcEAwcD4OECCAMDCAIdAgMDAv71AgcEAAABABoAdQFmAq8AJAAAARQGDwEXHgEVFAYPAQ4BIyImJwEuATU0NjcBPgEzMhYfAR4BFQFmAwLh4QIDAwIdAwcDBAcC/vUCAwMCAQsCBwQDBwMdAgMCgAMIAuHgAwcDBAcDHAMDAwMBCgMHAwQHAgELAgMDAh0CBwQAAAAAAQAHAHUBVAKvACQAAAEUBgcBDgEjIiYvAS4BNTQ2PwEnLgE1NDY/AT4BMzIWFwEeARUBVAMD/vYDBwMEBwIdAgQEAuHhAgQEAh0CBwQDBwMBCgMDAZIDBwP+9gMDAwMcAwcEAwcD4OECCAMDCAIdAgMDAv71AgcEAAAAAAIAAAAABEkDtwAPAC4AAAERNCYjISIGFREUFjMhMjYTERQGIyEUFhUUBiMhIiY1NDY1ISImNRE0NjMhMhYVBAALB/xtBwsLBwOTBwtJNiX+ySQVD/7bDxUk/sklNjYlA5MlNgGAAdsICwsI/iUHCwsB4v2TJjYkOg8PFhYPDzklNiYCbSY2NiYAAAAAAgAAAAADbgNuABwAOQAAASIHDgEHBhUUFx4BFxYzMjc+ATc2NTQnLgEnJiMBFAcOAQcGIyInLgEnJjU0Nz4BNzYzMTIXHgEXFgG3QDk5VBkYGBlUOTlAQDk4VRgZGRhVODlAAbcjIndQUFtbUFB3IyIiI3dQUFtbUFB3IiMC7hkYVTg5QEA5OVQZGBgZVDk5QEA5OFUYGf7JW1BQdyIjIyJ3UFBbW1BQdyIjIyJ3UFAAAAAAAQAAAAADbgNuABsAAAEUBw4BBwYjIicuAScmNTQ3PgE3NjMyFx4BFxYDbiMid1BQW1tQUHcjIiIjd1BQW1tQUHciIwG3W1BQdyIjIyJ3UFBbW1BQdyIjIyJ3UFAAAAAAAwAfAAsEKgMaABUAJgA8AAAlBwYiJwEmNDcBNjIfARYUDwEXFhQHAQMOAS8BLgE3Ez4BHwEeAQcJAQYiLwEmND8BJyY0PwE2MhcBFhQHAWEdBg8F/vUFBQELBQ8GHQUF4eEFBQFR1QINByQHBwLVAg0HJAcHAgF4/vUFDwYcBgbg4AYGHAYPBQELBQWXHAYGAQoGDwUBCwUFHQUQBeHgBg8GAmL9HgcHAgoCDQcC4gcIAgoCDgf+jP72BgYcBg8G4OEFEAUdBQX+9QUPBgAAAAIAAP+3A24DtwAIABsAAAERHgEfAR4BFwUUFjMhERQGIyEiJjURNDYzIRECSQYKBekECAT+qSAXATcgF/0AFyAgFwHJApIBDgQIBOkECwYSFyD9pRcgIBcDkhcg/skAAAUAAP+3A24DtwAIABoAKwA8AE0AAAEeARchER4BFwMhERQGIyEiJjURNDYzIREUFhM1NCYjISIGHQEUFjMhMjY1PQE0JiMhIgYdARQWMyEyNjU9ATQmIyEiBh0BFBYzITI2NQNHBAgE/vIGCgUnATcgF/0AFyAgFwHJIHIKCP5uCAsLCAGSCAoKCP5uCAsLCAGSCAoKCP5uCAsLCAGSCAoCpwQLBgEOBAgE/rn9pRcgIBcDkhcg/skXIP5cJAgKCggkCAsLCJIkCAsLCCQICgoIkiUHCwsHJQgKCggAAAAAAQAAAAADXANuADsAAAEhHgEVFAcOAQcGIyInLgEnJjU0Nz4BNzYzMhceARcWFwcuASMiBw4BBwYVFBceARcWMzI3PgE3NjcjNQG3AZ4DBB4eb05NX1tQUHcjIiIjd1BQWywpKUogIR13GVZAODIxShYVFRZKMTI4QS4tOw8PBPkB9hEjFV5PT3EgICIjd1BQW1tQUHciIwgIHhUVG3MYLBYWSzIzOToyM0sWFRQVOiEhGJcAAQAS/8kD7gOfADoAAAEUBw4BBwYjIicuAScmNTQ3PgE3NjcVBgcOAQcGFRQXHgEXFjMyNz4BNzY1NCcuAScmJzUWFx4BFxYVA+4nJ4ZaWmZmWlqGJychIHFNTVk/NTZOFhcdHWNDQkxMQkNjHR0XFk42NT9ZTU1xICEBt2ZaWoYnJycnhlpaZl1TU4IrKw2CDSAhXzs8QkxCQ2MdHR0dY0NCTEI8O18hIA2CDSsrglNTXQAABAAN/7cEhgO3ABIAJQA9AG8AAAU0JiMiJjU0JiMiBhUUFjMyNjUJAS4BIyIHDgEHBhUUBw4BBwYHBRQGIyEUBiMiJjU3IS4BJzcWFx4BFxYXExcWFAcBBiYvASY2PwEuATU2Nz4BNzY1NDc+ATc2Ny4BNTQ2MzIWFRQGBx4BFzc2FhcCUgUEIjAFBAQFOykEBf7NAfYWZFI4KSo2DQ0FBRMPDxQDBiwe/wBVPTxWVQGxMEERPwsTEy0aGhkxMAQG+9IFEAQwBQEFawYFHyEhNBEREBE+LS05AgMgFxcgAgNKax3vBg8FEgQFMCIEBQUEKTsFBAEPAbItSRMSNyAgGzczMlwqKSZrHis8VlU9STaDTjdAMjFNHB0VAxw3Bg8F/GEFAQY3Bg8FXAgTChsnJ3FNTWgpKSpFGRkJBQsGFyAgFwYLBQtMMs8FAQYAAAAAAgAAAAAEkgNuAAUACwAAJRUhETMRARMhEQkBBJL7bkkDbpL8SQEAAUlJSQNu/NsCSf4AAUkBSv62AAAABAAA/7cEAAO3ABYAKgA9AEkAAAEyFhceARclJgcOAQcGByc2Nz4BNzYzBRMWFx4BFxY3AyYnLgEnJjU0NjcFFhcWBgcGBw4BJxM2NzYmJyYnJzIWFRQGIyImNTQ2Af5Cgz1DZiD+WC0rK0gcHA+dJS0tZjg3OP5VwRQfH0wqKy2DXE9QdCEhLCcDiyEBATs5OlNDkkjoGQsMAg8PHr1IZWVISGVlA7ciIydtQBYDCwstIiEr8y0kIzEMDej+hikfICgHCAn+/g4tLYZWVmBNjzxgV1taqEhIMCcgAwFkJisrVSkpIgNlR0hlZUhHZQAAAgATAAAD7QNuAAMAaAAAATcjBwEHDgErAQczMhYXHgEPAQ4BKwEHDgErASImJy4BPwEjBw4BKwEiJicuAT8BIyImJy4BPwE+ATsBNyMiJicuAT8BPgE7ATc+ATsBMhYXHgEPATM3PgE7ATIWFx4BDwEzMhYXHgEHAjYlkSUCSCACCQe6JbIEBwMDAgIgAQoGuy4CCgaABAgDAwEBLJEuAgoGgQMIAwICASyxBQcDAgIBIAIJB7olsgQHAwMCAiABCga7LgIKB4AEBwMDAQEskS4CCgeAAwgDAgIBLLEFBwMCAgEBbpKSASCABgiSBAMECASABgi7BggEAwMJBLK7BggEAwMJBLIEAwMJBIAGCJIEAwMJBIAGCLsGCAQDBAgEsrsGCAQDBAgEsgQDBAgEAAQAAAAAA24DbgAQAEQAYQB+AAABFRQGKwEiJj0BNDY7ATIWFRMUBgcOAR0BFAYrASImPQE0Njc+ATU0JiMiBgcOAQcOASMiJi8BLgE3PgEzMTIXHgEXFhUDIgcOAQcGFRQXHgEXFjMyNz4BNzY1NCcuAScmIwEUBw4BBwYjIicuAScmNTQ3PgE3NjMxMhceARcWAfcLB1wICgoIXAcLkkMfFhoLB1wICjwfGR4zHA8eCgkUEAMHBQMFAj4GAgQjY0EjJCM5EhLSTEJDYx0dHR1jQ0JMS0NDYx0dHR1jQ0NLAbcjIndQUFtbUFB3IyIiI3dQUFtbUFB3IiMBCVsICwsIWwgKCggBHD06Eg0UDRMHCwsHJzUsDgwVFBkgCAcGFhMEAwECLwQPBjc2DQ0vHyAlAQAdHWNDQ0tMQkNjHR0dHWNDQkxLQ0NjHR3+kltQUHciIyMid1BQW1tQUHciIyMid1BQAAAAAAEAAAABAAAU8s37Xw889QALBAAAAAAA1yprLgAAAADXKmsuAAD/twSSA7cAAAAIAAIAAAAAAAAAAQAAA8D/wAAABJIAAAAABJIAAQAAAAAAAAAAAAAAAAAAADMEAAAAAAAAAAAAAAACAAAAAtsAAAO3AAAEAAAABAAARQMlAD8DbgAAA24AAANuAAADbgAABAAAAAQAAAACSQAAA7sAAAMAAGMCtwA+BAAACQSSAAAESQAABAAAAAMlAAAEAAAlBEkAAANuAAADtwAAAkkAAAJJAAABkgAlAUkAAAJJAAAEAAAAAlsAGgI3AAcBgAAaAVsABwRJAAADbgAAA24AAARJAB8DbgAAA24AAANcAAAEAAASBJIADQSSAAAENwAABAAAEwNuAAAAAAAAAAoAFAAeAHQA0AFSAZAB7ALCAwADcgQGBLYFYgWiBhoGRAZwBswG/AjUCUAJcgoGCsYLCgveDAYMLAxUDHwMxA1kDdYOSA6GDsQPCg9kD5QP/BAsEJwQ9hFQEfgSFhKOEyYT2gABAAAAMwFVAAoAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEAAgAAAAEAAAAAAAIABwAzAAEAAAAAAAMAAgAnAAEAAAAAAAQAAgBIAAEAAAAAAAUACwAGAAEAAAAAAAYAAgAtAAEAAAAAAAoAGgBOAAMAAQQJAAEABAACAAMAAQQJAAIADgA6AAMAAQQJAAMABAApAAMAAQQJAAQABABKAAMAAQQJAAUAFgARAAMAAQQJAAYABAAvAAMAAQQJAAoANABoZmEAZgBhVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwZmEAZgBhZmEAZgBhUmVndWxhcgBSAGUAZwB1AGwAYQByZmEAZgBhRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format('woff');font-weight: normal;font-style: normal;}[class^="fa-"],[class*=" fa-"]{font-family:'fa' !important;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes "fa-spin"{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg);}}@keyframes "fa-spin"{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg);}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg);}}.fa-square-o:before{content:"\f096";}.fa-user:before{content:"\f007"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before{content:"\f00d"}.fa-remove:before{content:"\f00d"}.fa-times:before{content:"\f00d"}.fa-cog:before{content:"\f013"}.fa-gear:before{content:"\f013"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-list:before{content:"\f03a"}.fa-map-marker:before{content:"\f041"}.fa-check-square-o:before{content:"\f046"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-exclamation-triangle:before{content:"\f071"}.fa-warning:before{content:"\f071"}.fa-bar-chart:before{content:"\f080"}.fa-bar-chart-o:before{content:"\f080"}.fa-cogs:before{content:"\f085"}.fa-gears:before{content:"\f085"}.fa-external-link:before{content:"\f08e"}.fa-bell-o:before{content:"\f0a2"}.fa-group:before{content:"\f0c0"}.fa-users:before{content:"\f0c0"}.fa-bars:before{content:"\f0c9"}.fa-navicon:before{content:"\f0c9"}.fa-reorder:before{content:"\f0c9"}.fa-table:before{content:"\f0ce"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-sort:before{content:"\f0dc"}.fa-unsorted:before{content:"\f0dc"}.fa-dashboard:before{content:"\f0e4"}.fa-tachometer:before{content:"\f0e4"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-desktop:before{content:"\f108"}.fa-circle-o:before{content:"\f10c"}.fa-circle:before{content:"\f111"}.fa-code:before{content:"\f121"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-google:before{content:"\f1a0"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-area-chart:before{content:"\f1fe"}.fa-chrome:before{content:"\f268"}.fa-hashtag:before{content:"\f292"}.fa-question-circle-o:before{content:"\f29c"} \ No newline at end of file diff --git a/goaccess++/resources/js/app.js b/goaccess++/resources/js/app.js new file mode 100644 index 0000000..4054ae5 --- /dev/null +++ b/goaccess++/resources/js/app.js @@ -0,0 +1,1793 @@ +/*jshint sub:true*/ +(function () { +'use strict'; + +// Syntactic sugar +function $(selector) { + return document.querySelector(selector); +} + +// Syntactic sugar & execute callback +function $$(selector, callback) { + var elems = document.querySelectorAll(selector); + for (var i = 0; i < elems.length; ++i) { + if (callback && typeof callback == 'function') + callback.call(this, elems[i]); + } +} + +var debounce = function (func, wait, now) { + var timeout; + return function debounced () { + var that = this, args = arguments; + function delayed() { + if (!now) + func.apply(that, args); + timeout = null; + } + if (timeout) { + clearTimeout(timeout); + } else if (now) { + func.apply(obj, args); + } + timeout = setTimeout(delayed, wait || 250); + }; +}; + +// global namespace +window.GoAccess = window.GoAccess || { + initialize: function (options) { + this.opts = options; + + this.AppState = {}; // current state app key-value store + this.AppTpls = {}; // precompiled templates + this.AppCharts = {}; // holds all rendered charts + this.AppUIData = (this.opts || {}).uiData || {}; // holds panel definitions + this.AppData = (this.opts || {}).panelData || {}; // hold raw data + this.AppWSConn = (this.opts || {}).wsConnection || {}; // WebSocket connection + this.i18n = (this.opts || {}).i18n || {}; // i18n report labels + this.AppPrefs = { + 'autoHideTables': true, + 'layout': 'horizontal', + 'perPage': 7, + 'theme': 'darkPurple', + }; + this.AppPrefs = GoAccess.Util.merge(this.AppPrefs, this.opts.prefs); + + if (GoAccess.Util.hasLocalStorage()) { + var ls = JSON.parse(localStorage.getItem('AppPrefs')); + this.AppPrefs = GoAccess.Util.merge(this.AppPrefs, ls); + } + if (Object.keys(this.AppWSConn).length) + this.setWebSocket(this.AppWSConn); + + }, + + getPanelUI: function (panel) { + return panel ? this.AppUIData[panel] : this.AppUIData; + }, + + getPrefs: function (panel) { + return panel ? this.AppPrefs[panel] : this.AppPrefs; + }, + + setPrefs: function () { + if (GoAccess.Util.hasLocalStorage()) { + localStorage.setItem('AppPrefs', JSON.stringify(GoAccess.getPrefs())); + } + }, + + getPanelData: function (panel) { + return panel ? this.AppData[panel] : this.AppData; + }, + + setWebSocket: function (wsConn) { + var host = null; + host = wsConn.url ? wsConn.url : window.location.hostname ? window.location.hostname : "localhost"; + var str = /^(wss?:\/\/)?[^\/]+:[0-9]{1,5}\//.test(host + "/") ? host : String(host + ':' + wsConn.port); + str = !/^wss?:\/\//i.test(str) ? (window.location.protocol === "https:" ? 'wss://' : 'ws://') + str : str; + + var socket = new WebSocket(str); + socket.onopen = function (event) { + GoAccess.Nav.WSOpen(); + }.bind(this); + + socket.onmessage = function (event) { + this.AppState['updated'] = true; + this.AppData = JSON.parse(event.data); + this.App.renderData(); + }.bind(this); + + socket.onclose = function (event) { + GoAccess.Nav.WSClose(); + }.bind(this); + }, +}; + +// HELPERS +GoAccess.Util = { + months: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul","Aug", "Sep", "Oct", "Nov", "Dec"], + + // Add all attributes of n to o + merge: function (o, n) { + var obj = {}, i = 0, il = arguments.length, key; + for (; i < il; i++) { + for (key in arguments[i]) { + if (arguments[i].hasOwnProperty(key)) { + obj[key] = arguments[i][key]; + } + } + } + return obj; + }, + + // hash a string + hashCode: function (s) { + return (s.split('').reduce(function (a, b) { + a = ((a << 5) - a) + b.charCodeAt(0); + return a&a; + }, 0) >>> 0).toString(16); + }, + + // Format bytes to human readable + formatBytes: function (bytes, decimals, numOnly) { + if (bytes == 0) + return numOnly ? 0 : '0 Byte'; + var k = 1024; + var dm = decimals + 1 || 2; + var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB']; + var i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + (numOnly ? '' : (' ' + sizes[i])); + }, + + // Validate number + isNumeric: function (n) { + return !isNaN(parseFloat(n)) && isFinite(n); + }, + + // Format microseconds to human readable + utime2str: function (usec) { + if (usec >= 864E8) + return ((usec) / 864E8).toFixed(2) + ' d'; + else if (usec >= 36E8) + return ((usec) / 36E8).toFixed(2) + ' h'; + else if (usec >= 6E7) + return ((usec) / 6E7).toFixed(2) + ' m'; + else if (usec >= 1E6) + return ((usec) / 1E6).toFixed(2) + ' s'; + else if (usec >= 1E3) + return ((usec) / 1E3).toFixed(2) + ' ms'; + return (usec).toFixed(2) + ' us'; + }, + + // Format date from 20120124 to 24/Jan/2012 + formatDate: function (str) { + var y = str.substr(0,4), m = str.substr(4,2) - 1, d = str.substr(6,2), + h = str.substr(8,2) || 0, i = str.substr(10, 2) || 0, s = str.substr(12, 2) || 0; + var date = new Date(y,m,d,h,i,s); + + var out = ('0' + date.getDate()).slice(-2) + '/' + this.months[date.getMonth()] + '/' + date.getFullYear(); + 10 <= str.length && (out += ":" + h); + 12 <= str.length && (out += ":" + i); + 14 <= str.length && (out += ":" + s); + return out; + }, + + // Format field value to human readable + fmtValue: function (value, dataType, decimals) { + var val = 0; + if (!dataType) + val = value; + + switch (dataType) { + case 'utime': + val = this.utime2str(value); + break; + case 'date': + val = this.formatDate(value); + break; + case 'numeric': + if (this.isNumeric(value)) + val = value.toLocaleString(); + break; + case 'bytes': + val = this.formatBytes(value, decimals); + break; + case 'percent': + val = parseFloat(value.replace(',', '.')).toFixed(2) + '%'; + break; + case 'time': + if (this.isNumeric(value)) + val = value.toLocaleString(); + break; + case 'secs': + val = value + ' secs'; + break; + default: + val = value; + } + + return value == 0 ? String(val) : val; + }, + + isPanelValid: function (panel) { + var data = GoAccess.getPanelData(), ui = GoAccess.getPanelUI(); + return (!ui.hasOwnProperty(panel) || !data.hasOwnProperty(panel) || !ui[panel].id); + }, + + // Attempts to extract the count from either an object or a scalar. + // e.g., item = Object {count: 14351, percent: 5.79} OR item = 4824825140 + getCount: function (item) { + if (this.isObject(item) && 'count' in item) + return item.count; + return item; + }, + + getPercent: function (item) { + if (this.isObject(item) && 'percent' in item) + return this.fmtValue(item.percent, 'percent'); + return null; + }, + + isObject: function (o) { + return o === Object(o); + }, + + setProp: function (o, s, v) { + var schema = o; + var a = s.split('.'); + for (var i = 0, n = a.length; i < n-1; ++i) { + var k = a[i]; + if (!schema[k]) + schema[k] = {}; + schema = schema[k]; + } + schema[a[n-1]] = v; + }, + + getProp: function (o, s) { + s = s.replace(/\[(\w+)\]/g, '.$1'); + s = s.replace(/^\./, ''); + var a = s.split('.'); + for (var i = 0, n = a.length; i < n; ++i) { + var k = a[i]; + if (this.isObject(o) && k in o) { + o = o[k]; + } else { + return; + } + } + return o; + }, + + hasLocalStorage: function () { + try { + localStorage.setItem('test', 'test'); + localStorage.removeItem('test'); + return true; + } catch(e) { + return false; + } + }, + + isWithinViewPort: function (el) { + var elemTop = el.getBoundingClientRect().top; + var elemBottom = el.getBoundingClientRect().bottom; + return elemTop < window.innerHeight && elemBottom >= 0; + }, +}; + +// OVERALL STATS +GoAccess.OverallStats = { + // Render each overall stats box + renderBox: function (data, ui, row, x, idx) { + var wrap = $('.wrap-general-items'); + + // create a new bootstrap row every 6 elements + if (idx % 6 == 0) { + row = document.createElement('div'); + row.setAttribute('class', 'row'); + wrap.appendChild(row); + } + + var box = document.createElement('div'); + box.innerHTML = GoAccess.AppTpls.General.items.render({ + 'id': x, + 'className': ui.items[x].className, + 'label': ui.items[x].label, + 'value': GoAccess.Util.fmtValue(data[x], ui.items[x].dataType), + }); + row.appendChild(box); + + return row; + }, + + // Render overall stats + renderData: function (data, ui) { + var idx = 0, row = null; + + $('.wrap-general').innerHTML = GoAccess.AppTpls.General.wrap.render(GoAccess.Util.merge(ui, { + 'lastUpdated': data.date_time, + 'from': data.start_date, + 'to': data.end_date, + })); + + // Iterate over general data object + for (var x in data) { + if (!data.hasOwnProperty(x) || !ui.items.hasOwnProperty(x)) + continue; + row = this.renderBox(data, ui, row, x, idx); + idx++; + } + }, + + // Render general/overall analyzed requests. + initialize: function () { + var ui = GoAccess.getPanelUI('general'); + var data = GoAccess.getPanelData('general'), i = 0; + + this.renderData(data, ui); + } +}; + +// RENDER PANELS +GoAccess.Nav = { + events: function () { + $('.nav-bars').onclick = function (e) { + e.stopPropagation(); + this.renderMenu(e); + }.bind(this); + + $('.nav-gears').onclick = function (e) { + e.stopPropagation(); + this.renderOpts(e); + }.bind(this); + + $('.nav-minibars').onclick = function (e) { + e.stopPropagation(); + this.renderOpts(e); + }.bind(this); + + $('body').onclick = function (e) { + $('nav').classList.remove('active'); + }.bind(this); + + $$('.export-json', function (item) { + item.onclick = function (e) { + this.downloadJSON(e); + }.bind(this); + }.bind(this)); + + $$('.theme-bright', function (item) { + item.onclick = function (e) { + this.setTheme('bright'); + }.bind(this); + }.bind(this)); + + $$('.theme-dark-blue', function (item) { + item.onclick = function (e) { + this.setTheme('darkBlue'); + }.bind(this); + }.bind(this)); + + $$('.theme-dark-gray', function (item) { + item.onclick = function (e) { + this.setTheme('darkGray'); + }.bind(this); + }.bind(this)); + + $$('.theme-dark-purple', function (item) { + item.onclick = function (e) { + this.setTheme('darkPurple'); + }.bind(this); + }.bind(this)); + + $$('.layout-horizontal', function (item) { + item.onclick = function (e) { + this.setLayout('horizontal'); + }.bind(this); + }.bind(this)); + + $$('.layout-vertical', function (item) { + item.onclick = function (e) { + this.setLayout('vertical'); + }.bind(this); + }.bind(this)); + + $$('[data-perpage]', function (item) { + item.onclick = function (e) { + this.setPerPage(e); + }.bind(this); + }.bind(this)); + + $$('[data-show-tables]', function (item) { + item.onclick = function (e) { + this.toggleTables(); + }.bind(this); + }.bind(this)); + + $$('[data-autohide-tables]', function (item) { + item.onclick = function (e) { + this.toggleAutoHideTables(); + }.bind(this); + }.bind(this)); + }, + + downloadJSON: function (e) { + var targ = e.currentTarget; + var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(GoAccess.getPanelData())); + targ.href = 'data:' + data; + targ.download = 'goaccess-' + (+new Date()) + '.json'; + }, + + setLayout: function (layout) { + if ('horizontal' == layout) { + $('.container').classList.add('container-fluid'); + $('.container').classList.remove('container'); + } else if ('vertical' == layout) { + $('.container-fluid').classList.add('container'); + $('.container').classList.remove('container-fluid'); + } + + GoAccess.AppPrefs['layout'] = layout; + GoAccess.setPrefs(); + + GoAccess.Panels.initialize(); + GoAccess.Charts.initialize(); + GoAccess.Tables.initialize(); + }, + + toggleAutoHideTables: function (e) { + var autoHideTables = GoAccess.Tables.autoHideTables(); + $$('.table-wrapper', function (item) { + if (autoHideTables) { + item.classList.remove('hidden-xs'); + } else { + item.classList.add('hidden-xs'); + } + }.bind(this)); + + GoAccess.AppPrefs['autoHideTables'] = !autoHideTables; + GoAccess.setPrefs(); + }, + + toggleTables: function () { + var ui = GoAccess.getPanelUI(); + var showTables = GoAccess.Tables.showTables(); + Object.keys(ui).forEach(function (panel, idx) { + if (!GoAccess.Util.isPanelValid(panel)) + ui[panel]['table'] = !showTables; + }.bind(this)); + + GoAccess.AppPrefs['showTables'] = !showTables; + GoAccess.setPrefs(); + + GoAccess.Panels.initialize(); + GoAccess.Charts.initialize(); + GoAccess.Tables.initialize(); + }, + + setTheme: function (theme) { + if (!theme) + return; + + $('html').className = ''; + switch(theme) { + case 'darkGray': + $('html').classList.add('dark'); + $('html').classList.add('gray'); + break; + case 'darkBlue': + $('html').classList.add('dark'); + $('html').classList.add('blue'); + break; + case 'darkPurple': + $('html').classList.add('dark'); + $('html').classList.add('purple'); + break; + } + GoAccess.AppPrefs['theme'] = theme; + GoAccess.setPrefs(); + }, + + getIcon: function (key) { + switch(key) { + case 'visitors' : return 'users'; + case 'requests' : return 'file'; + case 'static_requests' : return 'file-text'; + case 'not_found' : return 'file-o'; + case 'hosts' : return 'user'; + case 'os' : return 'desktop'; + case 'browsers' : return 'chrome'; + case 'visit_time' : return 'clock-o'; + case 'vhosts' : return 'th-list'; + case 'referrers' : return 'external-link'; + case 'referring_sites' : return 'external-link'; + case 'keyphrases' : return 'google'; + case 'status_codes' : return 'warning'; + case 'remote_user' : return 'users'; + case 'geolocation' : return 'map-marker'; + default : return 'pie-chart'; + } + }, + + getItems: function () { + var ui = GoAccess.getPanelUI(), menu = []; + for (var panel in ui) { + if (GoAccess.Util.isPanelValid(panel)) + continue; + // Push valid panels to our navigation array + menu.push({ + 'current': window.location.hash.substr(1) == panel, + 'head': ui[panel].head, + 'key': panel, + 'icon': this.getIcon(panel), + }); + } + return menu; + }, + + setPerPage: function (e) { + GoAccess.AppPrefs['perPage'] = +e.currentTarget.getAttribute('data-perpage'); + GoAccess.App.renderData(); + GoAccess.setPrefs(); + }, + + getTheme: function () { + return GoAccess.AppPrefs.theme || 'darkGray'; + }, + + getLayout: function () { + return GoAccess.AppPrefs.layout || 'horizontal'; + }, + + getPerPage: function () { + return GoAccess.AppPrefs.perPage || 7; + }, + + // Render left-hand side navigation options. + renderOpts: function () { + var o = {}; + o[this.getLayout()] = true; + o[this.getTheme()] = true; + o['perPage' + this.getPerPage()] = true; + o['autoHideTables'] = GoAccess.Tables.autoHideTables(); + o['showTables'] = GoAccess.Tables.showTables(); + o['labels'] = GoAccess.i18n; + + $('.nav-list').innerHTML = GoAccess.AppTpls.Nav.opts.render(o); + $('nav').classList.toggle('active'); + this.events(); + }, + + // Render left-hand side navigation given the available panels. + renderMenu: function (e) { + $('.nav-list').innerHTML = GoAccess.AppTpls.Nav.menu.render({ + 'nav': this.getItems(), + 'overall': window.location.hash.substr(1) == '', + 'labels': GoAccess.i18n, + }); + $('nav').classList.toggle('active'); + this.events(); + }, + + WSStatus: function () { + if (Object.keys(GoAccess.AppWSConn).length) + $$('.nav-ws-status', function (item) { item.style.display = 'block'; }); + }, + + WSClose: function () { + $$('.nav-ws-status', function (item) { + item.classList.remove('connected'); + item.setAttribute('title', 'Disconnected'); + }); + }, + + WSOpen: function () { + $$('.nav-ws-status', function (item) { + item.classList.add('connected'); + item.setAttribute('title', 'Connected to ' + GoAccess.AppWSConn.url); + }); + }, + + // Render left-hand side navigation given the available panels. + renderWrap: function (nav) { + $('nav').innerHTML = GoAccess.AppTpls.Nav.wrap.render(GoAccess.i18n); + }, + + // Iterate over all available panels and render each. + initialize: function () { + this.setTheme(GoAccess.AppPrefs.theme); + this.renderWrap(); + this.WSStatus(); + this.events(); + } +}; + +// RENDER PANELS +GoAccess.Panels = { + events: function () { + $$('[data-toggle=dropdown]', function (item) { + item.onclick = function (e) { + this.openOpts(e.currentTarget); + }.bind(this); + item.onblur = function (e) { + this.closeOpts(e); + }.bind(this); + }.bind(this)); + + $$('[data-plot]', function (item) { + item.onclick = function (e) { + GoAccess.Charts.redrawChart(e.currentTarget); + }.bind(this); + }.bind(this)); + + $$('[data-chart]', function (item) { + item.onclick = function (e) { + GoAccess.Charts.toggleChart(e.currentTarget); + }.bind(this); + }.bind(this)); + + $$('[data-chart-type]', function (item) { + item.onclick = function (e) { + GoAccess.Charts.setChartType(e.currentTarget); + }.bind(this); + }.bind(this)); + + $$('[data-metric]', function (item) { + item.onclick = function (e) { + GoAccess.Tables.toggleColumn(e.currentTarget); + }.bind(this); + }.bind(this)); + }, + + openOpts: function (targ) { + var panel = targ.getAttribute('data-panel'); + targ.parentElement.classList.toggle('open'); + this.renderOpts(panel); + }, + + closeOpts: function (e) { + e.currentTarget.parentElement.classList.remove('open'); + // Trigger the click event on the target if not opening another menu + if (e.relatedTarget && e.relatedTarget.getAttribute('data-toggle') !== 'dropdown') + e.relatedTarget.click(); + }, + + setPlotSelection: function (ui, prefs) { + var chartType = ((prefs || {}).plot || {}).chartType || ui.plot[0].chartType; + var metric = ((prefs || {}).plot || {}).metric || ui.plot[0].className; + + ui[chartType] = true; + for (var i = 0, len = ui.plot.length; i < len; ++i) + if (ui.plot[i].className == metric) + ui.plot[i]['selected'] = true; + }, + + setColSelection: function (items, prefs) { + var columns = (prefs || {}).columns || {}; + for (var i = 0, len = items.length; i < len; ++i) + if ((items[i].key in columns) && columns[items[i].key]['hide']) + items[i]['hide'] = true; + }, + + setChartSelection: function (ui, prefs) { + ui['showChart'] = prefs && ('chart' in prefs) ? prefs.chart : true; + }, + + setOpts: function (panel) { + var ui = JSON.parse(JSON.stringify(GoAccess.getPanelUI(panel))), prefs = GoAccess.getPrefs(panel); + // set preferences selection upon opening panel options + this.setChartSelection(ui, prefs); + this.setPlotSelection(ui, prefs); + this.setColSelection(ui.items, prefs); + return GoAccess.Util.merge(ui, {'labels': GoAccess.i18n}); + }, + + renderOpts: function (panel) { + $('.panel-opts-' + panel).innerHTML = GoAccess.AppTpls.Panels.opts.render(this.setOpts(panel)); + this.events(); + }, + + enablePrev: function (panel) { + var $pagination = $('#panel-' + panel + ' .pagination a.panel-prev'); + if ($pagination) + $pagination.parentNode.classList.remove('disabled'); + }, + + disablePrev: function (panel) { + var $pagination = $('#panel-' + panel + ' .pagination a.panel-prev'); + if ($pagination) + $pagination.parentNode.classList.add('disabled'); + }, + + enableNext: function (panel) { + var $pagination = $('#panel-' + panel + ' .pagination a.panel-next'); + if ($pagination) + $pagination.parentNode.classList.remove('disabled'); + }, + + disableNext: function (panel) { + var $pagination = $('#panel-' + panel + ' .pagination a.panel-next'); + if ($pagination) + $pagination.parentNode.classList.add('disabled'); + }, + + enableFirst: function (panel) { + var $pagination = $('#panel-' + panel + ' .pagination a.panel-first'); + if ($pagination) + $pagination.parentNode.classList.remove('disabled'); + }, + + disableFirst: function (panel) { + var $pagination = $('#panel-' + panel + ' .pagination a.panel-first'); + if ($pagination) + $pagination.parentNode.classList.add('disabled'); + }, + + enableLast: function (panel) { + var $pagination = $('#panel-' + panel + ' .pagination a.panel-last'); + if ($pagination) + $pagination.parentNode.classList.remove('disabled'); + }, + + disableLast: function (panel) { + var $pagination = $('#panel-' + panel + ' .pagination a.panel-last'); + if ($pagination) + $pagination.parentNode.classList.add('disabled'); + }, + + enablePagination: function (panel) { + this.enablePrev(panel); + this.enableNext(panel); + this.enableFirst(panel); + this.enableLast(panel); + }, + + disablePagination: function (panel) { + this.disablePrev(panel); + this.disableNext(panel); + this.disableFirst(panel); + this.disableLast(panel); + }, + + hasSubItems: function (ui, data) { + for (var i = 0, len = data.length; i < len; ++i) { + if (!data[i].items) + return (ui['hasSubItems'] = false); + if (data[i].items.length) { + return (ui['hasSubItems'] = true); + } + } + return false; + }, + + setComputedData: function (panel, ui, data) { + this.hasSubItems(ui, data.data); + GoAccess.Charts.hasChart(panel, ui); + GoAccess.Tables.hasTable(ui); + }, + + // Render the given panel given a user interface definition. + renderPanel: function (panel, ui, col) { + // set some computed values before rendering panel structure + var data = GoAccess.getPanelData(panel); + this.setComputedData(panel, ui, data); + + // per panel wrapper + var box = document.createElement('div'); + box.id = 'panel-' + panel; + box.innerHTML = GoAccess.AppTpls.Panels.wrap.render(GoAccess.Util.merge(ui, { + 'labels': GoAccess.i18n + })); + col.appendChild(box); + + // Remove pagination if not enough data for the given panel + if (data.data.length <= GoAccess.getPrefs().perPage) + this.disablePagination(panel); + GoAccess.Tables.renderThead(panel, ui); + + return col; + }, + + createCol: function (row) { + var perRow = GoAccess.AppPrefs['layout'] == 'horizontal' ? 6 : 12; + + // set the number of columns based on current layout + var col = document.createElement('div'); + col.setAttribute('class', 'col-md-' + perRow + ' wrap-panel'); + row.appendChild(col); + + return col; + }, + + createRow: function (row, idx) { + var wrap = $('.wrap-panels'); + var every = GoAccess.AppPrefs['layout'] == 'horizontal' ? 2 : 1; + + // create a new bootstrap row every one or two elements depending on + // the layout + if (idx % every == 0) { + row = document.createElement('div'); + row.setAttribute('class', 'row' + (every == 2 ? ' equal' : '')); + wrap.appendChild(row); + } + + return row; + }, + + resetPanel: function (panel) { + var ui = GoAccess.getPanelUI(), idx = 0, row = null; + var ele = $('#panel-' + panel); + + if (GoAccess.Util.isPanelValid(panel)) + return false; + + var col = ele.parentNode; + col.removeChild(ele); + // Render panel given a user interface definition + this.renderPanel(panel, ui[panel], col); + this.events(); + }, + + // Iterate over all available panels and render each panel + // structure. + renderPanels: function () { + var ui = GoAccess.getPanelUI(), idx = 0, row = null, col = null; + + $('.wrap-panels').innerHTML = ''; + for (var panel in ui) { + if (GoAccess.Util.isPanelValid(panel)) + continue; + row = this.createRow(row, idx++); + col = this.createCol(row); + // Render panel given a user interface definition + col = this.renderPanel(panel, ui[panel], col); + } + }, + + initialize: function () { + this.renderPanels(); + this.events(); + } +}; + +// RENDER CHARTS +GoAccess.Charts = { + iter: function (callback) { + Object.keys(GoAccess.AppCharts).forEach(function (panel) { + // redraw chart only if it's within the viewport + if (!GoAccess.Util.isWithinViewPort($('#panel-' + panel))) + return; + if (callback && typeof callback === 'function') + callback.call(this, GoAccess.AppCharts[panel], panel); + }); + }, + + getMetricKeys: function (panel, key) { + return GoAccess.getPanelUI(panel)['items'].map(function (a) { return a[key]; }); + }, + + getPanelData: function (panel, data) { + // Grab ui plot data for the selected panel + var plot = GoAccess.Util.getProp(GoAccess.AppState, panel + '.plot'); + + // Grab the data for the selected panel + data = data || this.processChartData(GoAccess.getPanelData(panel).data); + return plot.chartReverse ? data.reverse() : data; + }, + + drawPlot: function (panel, plotUI, data) { + var chart = this.getChart(panel, plotUI, data); + if (!chart) + return; + + this.renderChart(panel, chart, data); + GoAccess.AppCharts[panel] = null; + GoAccess.AppCharts[panel] = chart; + }, + + setChartType: function (targ) { + var panel = targ.getAttribute('data-panel'); + var type = targ.getAttribute('data-chart-type'); + + GoAccess.Util.setProp(GoAccess.AppPrefs, panel + '.plot.chartType', type); + GoAccess.setPrefs(); + + var plotUI = GoAccess.Util.getProp(GoAccess.AppState, panel + '.plot'); + // Extract data for the selected panel and process it + this.drawPlot(panel, plotUI, this.getPanelData(panel)); + }, + + toggleChart: function (targ) { + var panel = targ.getAttribute('data-panel'); + var prefs = GoAccess.getPrefs(panel), + chart = prefs && ('chart' in prefs) ? prefs.chart : true; + + GoAccess.Util.setProp(GoAccess.AppPrefs, panel + '.chart', !chart); + GoAccess.setPrefs(); + + GoAccess.Panels.resetPanel(panel); + GoAccess.Charts.resetChart(panel); + GoAccess.Tables.renderFullTable(panel); + }, + + hasChart: function (panel, ui) { + var prefs = GoAccess.getPrefs(panel), + chart = prefs && ('chart' in prefs) ? prefs.chart : true; + ui['chart'] = ui.plot.length && chart && chart; + }, + + // Redraw a chart upon selecting a metric. + redrawChart: function (targ) { + var plot = targ.getAttribute('data-plot'); + var panel = targ.getAttribute('data-panel'); + var ui = GoAccess.getPanelUI(panel); + var plotUI = ui.plot; + + GoAccess.Util.setProp(GoAccess.AppPrefs, panel + '.plot.metric', plot); + GoAccess.setPrefs(); + + // Iterate over plot user interface definition + for (var x in plotUI) { + if (!plotUI.hasOwnProperty(x) || plotUI[x].className != plot) + continue; + + GoAccess.Util.setProp(GoAccess.AppState, panel + '.plot', plotUI[x]); + // Extract data for the selected panel and process it + this.drawPlot(panel, plotUI[x], this.getPanelData(panel)); + break; + } + }, + + // Iterate over the item properties and and extract the count value. + extractCount: function (item) { + var o = {}; + for (var prop in item) + o[prop] = GoAccess.Util.getCount(item[prop]); + return o; + }, + + // Extract an array of objects that D3 can consume to process the chart. + // e.g., o = Object {hits: 37402, visitors: 6949, bytes: + // 505881789, avgts: 118609, cumts: 4436224010…} + processChartData: function (data) { + var out = []; + for (var i = 0; i < data.length; ++i) + out.push(this.extractCount(data[i])); + return out; + }, + + findUIItem: function (panel, key) { + var items = GoAccess.getPanelUI(panel).items, o = {}; + for (var i = 0; i < items.length; ++i) { + if (items[i].key == key) + return items[i]; + } + return null; + }, + + getXKey: function (datum, key) { + var arr = []; + if (typeof key === 'string') + return datum[key]; + for (var prop in key) + arr.push(datum[key[prop]]); + return arr.join(' '); + }, + + getAreaSpline: function (panel, plotUI, data) { + var dualYaxis = plotUI['d3']['y1']; + + var chart = AreaChart(dualYaxis) + .labels({ + y0: plotUI['d3']['y0'].label, + y1: dualYaxis ? plotUI['d3']['y1'].label : '' + }) + .x(function (d) { + if ((((plotUI || {}).d3 || {}).x || {}).key) + return this.getXKey(d, plotUI['d3']['x']['key']); + return d.data; + }.bind(this)) + .y0(function (d) { + return +d[plotUI['d3']['y0']['key']]; + }) + .width($("#chart-" + panel).getBoundingClientRect().width) + .height(175) + .format({ + x: (this.findUIItem(panel, 'data') || {}).dataType || null, + y0: ((plotUI.d3 || {}).y0 || {}).format, + y1: ((plotUI.d3 || {}).y1 || {}).format, + }) + .opts(plotUI); + + dualYaxis && chart.y1(function (d) { + return +d[plotUI['d3']['y1']['key']]; + }); + + return chart; + }, + + getVBar: function (panel, plotUI, data) { + var dualYaxis = plotUI['d3']['y1']; + + var chart = BarChart(dualYaxis) + .labels({ + y0: plotUI['d3']['y0'].label, + y1: dualYaxis ? plotUI['d3']['y1'].label : '' + }) + .x(function (d) { + if ((((plotUI || {}).d3 || {}).x || {}).key) + return this.getXKey(d, plotUI['d3']['x']['key']); + return d.data; + }.bind(this)) + .y0(function (d) { + return +d[plotUI['d3']['y0']['key']]; + }) + .width($("#chart-" + panel).getBoundingClientRect().width) + .height(175) + .format({ + x: (this.findUIItem(panel, 'data') || {}).dataType || null, + y0: ((plotUI.d3 || {}).y0 || {}).format, + y1: ((plotUI.d3 || {}).y1 || {}).format, + }) + .opts(plotUI); + + dualYaxis && chart.y1(function (d) { + return +d[plotUI['d3']['y1']['key']]; + }); + + return chart; + }, + + getChartType: function (panel) { + var ui = GoAccess.getPanelUI(panel); + if (!ui.chart) + return ''; + + return GoAccess.Util.getProp(GoAccess.getPrefs(), panel + '.plot.chartType') || ui.plot[0].chartType; + }, + + getPlotUI: function (panel, ui) { + var metric = GoAccess.Util.getProp(GoAccess.getPrefs(), panel + '.plot.metric'); + if (!metric) + return ui.plot[0]; + return ui.plot.filter(function (v) { + return v.className == metric; + })[0]; + }, + + getChart: function (panel, plotUI, data) { + var chart = null; + + // Render given its type + switch (this.getChartType(panel)) { + case 'area-spline': + chart = this.getAreaSpline(panel, plotUI, data); + break; + case 'bar': + chart = this.getVBar(panel, plotUI, data); + break; + } + + return chart; + }, + + renderChart: function (panel, chart, data) { + // remove popup + d3.select('#chart-' + panel + '>.chart-tooltip-wrap') + .remove(); + // remove svg + d3.select('#chart-' + panel).select('svg') + .remove(); + // add chart to the document + d3.select("#chart-" + panel) + .datum(data) + .call(chart) + .append("div").attr("class", "chart-tooltip-wrap"); + }, + + addChart: function (panel, ui) { + var plotUI = null, chart = null; + + // Ensure it has a plot definition + if (!ui.plot || !ui.plot.length) + return; + + plotUI = this.getPlotUI(panel, ui); + // set ui plot data + GoAccess.Util.setProp(GoAccess.AppState, panel + '.plot', plotUI); + + // Grab the data for the selected panel + var data = this.getPanelData(panel); + if (!(chart = this.getChart(panel, plotUI, data))) + return; + + this.renderChart(panel, chart, data); + GoAccess.AppCharts[panel] = chart; + }, + + // Render all charts for the applicable panels. + renderCharts: function (ui) { + for (var panel in ui) { + if (!ui.hasOwnProperty(panel)) + continue; + this.addChart(panel, ui[panel]); + } + }, + + resetChart: function (panel) { + var ui = {}; + if (GoAccess.Util.isPanelValid(panel)) + return false; + + ui = GoAccess.getPanelUI(panel); + this.addChart(panel, ui); + }, + + // Reload (doesn't redraw) the given chart's data + reloadChart: function (chart, panel) { + var subItems = GoAccess.Tables.getSubItemsData(panel); + var data = (subItems.length ? subItems : GoAccess.getPanelData(panel).data).slice(0); + + d3.select("#chart-" + panel) + .datum(this.processChartData(this.getPanelData(panel, data))) + .call(chart.width($("#chart-" + panel).offsetWidth)); + }, + + // Reload (doesn't redraw) all chart's data + reloadCharts: function () { + this.iter(function (chart, panel) { + this.reloadChart(chart, panel); + }.bind(this)); + GoAccess.AppState.updated = false; + }, + + // Only redraw charts with current data + redrawCharts: function () { + this.iter(function (chart, panel) { + d3.select("#chart-" + panel).call(chart.width($("#chart-" + panel).offsetWidth)); + }); + }, + + initialize: function () { + this.renderCharts(GoAccess.getPanelUI()); + + // reload on scroll & redraw on resize + d3.select(window).on('scroll.charts', debounce(function () { + this.reloadCharts(); + }, 250, false).bind(this)).on('resize.charts', function () { + this.redrawCharts(); + }.bind(this)); + } +}; + +// RENDER TABLES +GoAccess.Tables = { + chartData: {}, // holds all panel sub items data that feeds the chart + + events: function () { + $$('.panel-next', function (item) { + item.onclick = function (e) { + var panel = e.currentTarget.getAttribute('data-panel'); + this.renderTable(panel, this.nextPage(panel)); + }.bind(this); + }.bind(this)); + + $$('.panel-prev', function (item) { + item.onclick = function (e) { + var panel = e.currentTarget.getAttribute('data-panel'); + this.renderTable(panel, this.prevPage(panel)); + }.bind(this); + }.bind(this)); + + $$('.panel-first', function (item) { + item.onclick = function (e) { + var panel = e.currentTarget.getAttribute('data-panel'); + this.renderTable(panel, "FIRST_PAGE"); + }.bind(this); + }.bind(this)); + + $$('.panel-last', function (item) { + item.onclick = function (e) { + var panel = e.currentTarget.getAttribute('data-panel'); + this.renderTable(panel, "LAST_PAGE"); + }.bind(this); + }.bind(this)); + + $$('.expandable>td', function (item) { + item.onclick = function (e) { + if (!window.getSelection().toString()) + this.toggleRow(e.currentTarget); + }.bind(this); + }.bind(this)); + + $$('.row-expandable.clickable', function (item) { + item.onclick = function (e) { + this.toggleRow(e.currentTarget); + }.bind(this); + }.bind(this)); + + $$('.sortable', function (item) { + item.onclick = function (e) { + this.sortColumn(e.currentTarget); + }.bind(this); + }.bind(this)); + }, + + toggleColumn: function (targ) { + var panel = targ.getAttribute('data-panel'); + var metric = targ.getAttribute('data-metric'); + + var columns = (GoAccess.getPrefs(panel) || {}).columns || {}; + if (metric in columns) { + delete columns[metric]; + } else { + GoAccess.Util.setProp(columns, metric + '.hide', true); + } + + GoAccess.Util.setProp(GoAccess.AppPrefs, panel + '.columns', columns); + GoAccess.setPrefs(); + + GoAccess.Tables.renderThead(panel, GoAccess.getPanelUI(panel)); + GoAccess.Tables.renderFullTable(panel); + }, + + sortColumn: function (ele) { + var field = ele.getAttribute('data-key'); + var order = ele.getAttribute('data-order'); + var panel = ele.parentElement.parentElement.parentElement.getAttribute('data-panel'); + + order = order ? 'asc' == order ? 'desc' : 'asc' : 'asc'; + GoAccess.App.sortData(panel, field, order); + GoAccess.Util.setProp(GoAccess.AppState, panel + '.sort', { + 'field': field, + 'order': order, + }); + this.renderThead(panel, GoAccess.getPanelUI(panel)); + this.renderTable(panel, this.getCurPage(panel)); + + GoAccess.Charts.reloadChart(GoAccess.AppCharts[panel], panel); + }, + + getDataByKey: function (panel, key) { + var data = GoAccess.getPanelData(panel).data; + for (var i = 0, n = data.length; i < n; ++i) { + if (GoAccess.Util.hashCode(data[i].data) == key) + return data[i]; + } + return null; + }, + + getSubItemsData: function (panel) { + var out = [], items = this.chartData[panel]; + for (var x in items) { + if (!items.hasOwnProperty(x)) + continue; + out = out.concat(items[x]); + } + return out; + }, + + addChartData: function (panel, key) { + var data = this.getDataByKey(panel, key); + var path = panel + '.' + key; + + if (!data || !data.items) + return []; + GoAccess.Util.setProp(this.chartData, path, data.items); + + return this.getSubItemsData(panel); + }, + + removeChartData: function (panel, key) { + if (GoAccess.Util.getProp(this.chartData, panel + '.' + key)) + delete this.chartData[panel][key]; + + if (!this.chartData[panel] || Object.keys(this.chartData[panel]).length == 0) + return GoAccess.getPanelData(panel).data; + + return this.getSubItemsData(panel); + }, + + isExpanded: function (panel, key) { + var path = panel + '.expanded.' + key; + return GoAccess.Util.getProp(GoAccess.AppState, path); + }, + + toggleExpanded: function (panel, key) { + var path = panel + '.expanded.' + key, ret = true; + + if (this.isExpanded(panel, key)) { + delete GoAccess.AppState[panel]['expanded'][key]; + } else { + GoAccess.Util.setProp(GoAccess.AppState, path, true), ret = false; + } + + return ret; + }, + + // Toggle children rows + toggleRow: function (ele) { + var hide = false, data = []; + var row = ele.parentNode; + var panel = row.getAttribute('data-panel'), key = row.getAttribute('data-key'); + var plotUI = GoAccess.AppCharts[panel].opts(); + + hide = this.toggleExpanded(panel, key); + this.renderTable(panel, this.getCurPage(panel)); + if (!plotUI.redrawOnExpand) + return; + + if (!hide) { + data = GoAccess.Charts.processChartData(this.addChartData(panel, key)); + } else { + data = GoAccess.Charts.processChartData(this.removeChartData(panel, key)); + } + GoAccess.Charts.drawPlot(panel, plotUI, data); + }, + + // Get current panel page + getCurPage: function (panel) { + return GoAccess.Util.getProp(GoAccess.AppState, panel + '.curPage') || 0; + }, + + // Page offset. + // e.g., Return Value: 11, curPage: 2 + pageOffSet: function (panel) { + return ((this.getCurPage(panel) - 1) * GoAccess.getPrefs().perPage); + }, + + // Get total number of pages given the number of items on array + getTotalPages: function (dataItems) { + return Math.ceil(dataItems.length / GoAccess.getPrefs().perPage); + }, + + // Get a shallow copy of a portion of the given data array and the + // current page. + getPage: function (panel, dataItems, page) { + var totalPages = this.getTotalPages(dataItems); + if (page < 1) + page = 1; + if (page > totalPages) + page = totalPages; + + GoAccess.Util.setProp(GoAccess.AppState, panel + '.curPage', page); + var start = this.pageOffSet(panel); + var end = start + GoAccess.getPrefs().perPage; + + return dataItems.slice(start, end); + }, + + // Get previous page + prevPage: function (panel) { + return this.getCurPage(panel) - 1; + }, + + // Get next page + nextPage: function (panel) { + return this.getCurPage(panel) + 1; + }, + + getMetaValue: function (ui, value) { + if ('meta' in ui) + return value[ui.meta]; + return null; + }, + + getMetaCell: function (ui, value) { + var val = this.getMetaValue(ui, value); + var max = (value || {}).max; + var min = (value || {}).min; + + // use metaType if exist else fallback to dataType + var vtype = ui.metaType || ui.dataType; + var className = ui.className || ''; + className += ui.dataType != 'string' ? 'text-right' : ''; + return { + 'className': className, + 'max' : max != undefined ? GoAccess.Util.fmtValue(max, vtype) : null, + 'min' : min != undefined ? GoAccess.Util.fmtValue(min, vtype) : null, + 'value' : val != undefined ? GoAccess.Util.fmtValue(val, vtype) : null, + 'title' : ui.meta, + 'label' : ui.metaLabel || null, + }; + }, + + hideColumn: function (panel, col) { + var columns = (GoAccess.getPrefs(panel) || {}).columns || {}; + return ((col in columns) && columns[col]['hide']); + }, + + showTables: function () { + return ('showTables' in GoAccess.getPrefs()) ? GoAccess.getPrefs().showTables : true; + }, + + autoHideTables: function () { + return ('autoHideTables' in GoAccess.getPrefs()) ? GoAccess.getPrefs().autoHideTables : true; + }, + + hasTable: function (ui) { + ui['table'] = this.showTables(); + ui['autoHideTables'] = this.autoHideTables(); + }, + + renderMetaRow: function (panel, ui) { + // find the table to set + var table = $('.table-' + panel + ' tbody.tbody-meta'); + if (!table) + return; + + var cells = [], uiItems = ui.items; + var data = GoAccess.getPanelData(panel).metadata; + for (var i = 0; i < uiItems.length; ++i) { + var item = uiItems[i]; + if (this.hideColumn(panel, item.key)) + continue; + var value = data[item.key]; + cells.push(this.getMetaCell(item, value)); + } + + table.innerHTML = GoAccess.AppTpls.Tables.meta.render({ + row: [{ + 'hasSubItems': ui.hasSubItems, + 'cells': cells + }] + }); + }, + + // Iterate over user interface definition properties + iterUIItems: function (panel, uiItems, dataItems, callback) { + var out = []; + for (var i = 0; i < uiItems.length; ++i) { + var uiItem = uiItems[i]; + if (this.hideColumn(panel, uiItem.key)) + continue; + // Data for the current user interface property. + // e.g., dataItem = Object {count: 13949, percent: 5.63} + var dataItem = dataItems[uiItem.key]; + // Apply the callback and push return data to output array + if (callback && typeof callback == 'function') { + var ret = callback.call(this, panel, uiItem, dataItem); + if (ret) out.push(ret); + } + } + return out; + }, + + // Return an object that can be consumed by the table template given a user + // interface definition and a cell value object. + // e.g., value = Object {count: 14351, percent: 5.79} + getObjectCell: function (panel, ui, value) { + var className = ui.className || ''; + className += ui.dataType != 'string' ? 'text-right' : ''; + return { + 'className': className, + 'percent': GoAccess.Util.getPercent(value), + 'value': GoAccess.Util.fmtValue(GoAccess.Util.getCount(value), ui.dataType) + }; + }, + + // Given a data item object, set all the row cells and return a + // table row that the template can consume. + renderRow: function (panel, callback, ui, dataItem, idx, subItem, parentId, expanded) { + var shadeParent = ((!subItem && idx % 2 != 0) ? 'shaded' : ''); + var shadeChild = ((parentId % 2 != 0) ? 'shaded' : ''); + return { + 'panel' : panel, + 'idx' : !subItem && (String((idx + 1) + this.pageOffSet(panel))), + 'key' : !subItem ? GoAccess.Util.hashCode(dataItem.data) : '', + 'expanded' : !subItem && expanded, + 'parentId' : subItem ? String(parentId) : '', + 'className' : subItem ? 'child ' + shadeChild : 'parent ' + shadeParent, + 'hasSubItems' : ui.hasSubItems, + 'items' : dataItem.items ? dataItem.items.length : 0, + 'cells' : callback.call(this), + }; + }, + + renderRows: function (rows, panel, ui, dataItems, subItem, parentId) { + subItem = subItem || false; + // no data rows + if (dataItems.length == 0 && ui.items.length) { + rows.push({ + cells: [{ + className: 'text-center', + colspan: ui.items.length + 1, + value: 'No data on this panel.' + }] + }); + } + + // Iterate over all data items for the given panel and + // generate a table row per date item. + var cellcb = null; + for (var i = 0; i < dataItems.length; ++i) { + var dataItem = dataItems[i], data = null, expanded = false; + switch(typeof dataItem) { + case 'string': + data = dataItem; + cellcb = function () { + return { + 'colspan': ui.items.length, + 'value': data + }; + }; + break; + default: + data = dataItem.data; + cellcb = this.iterUIItems.bind(this, panel, ui.items, dataItem, this.getObjectCell.bind(this)); + } + + expanded = this.isExpanded(panel, GoAccess.Util.hashCode(data)); + rows.push(this.renderRow(panel, cellcb, ui, dataItem, i, subItem, parentId, expanded)); + if (dataItem.items && dataItem.items.length && expanded) { + this.renderRows(rows, panel, ui, dataItem.items, true, i, expanded); + } + } + }, + + // Entry point to render all data rows into the table + renderDataRows: function (panel, ui, dataItems, page) { + // find the table to set + var table = $('.table-' + panel + ' tbody.tbody-data'); + if (!table) + return; + + dataItems = this.getPage(panel, dataItems, page); + var rows = []; + this.renderRows(rows, panel, ui, dataItems); + if (rows.length == 0) + return; + + table.innerHTML = GoAccess.AppTpls.Tables.data.render({ + rows: rows + }); + }, + + togglePagination: function (panel, page, dataItems) { + GoAccess.Panels.enablePagination(panel); + // Disable pagination next button if last page is reached + if (page >= this.getTotalPages(dataItems)) { + GoAccess.Panels.disableNext(panel); + GoAccess.Panels.disableLast(panel); + } + if (page <= 1) { + GoAccess.Panels.disablePrev(panel); + GoAccess.Panels.disableFirst(panel); + } + }, + + renderTable: function (panel, page) { + var dataItems = GoAccess.getPanelData(panel).data; + var ui = GoAccess.getPanelUI(panel); + + if (page === "LAST_PAGE") { + page = this.getTotalPages(dataItems); + } else if (page === "FIRST_PAGE") { + page = 1; + } + + this.togglePagination(panel, page, dataItems); + // Render data rows + this.renderDataRows(panel, ui, dataItems, page); + this.events(); + }, + + renderFullTable: function (panel) { + var ui = GoAccess.getPanelUI(panel), page = 0; + // panel's data + var data = GoAccess.getPanelData(panel); + // render meta data + if (data.hasOwnProperty('metadata')) + this.renderMetaRow(panel, ui); + + // render actual data + if (data.hasOwnProperty('data')) { + page = this.getCurPage(panel); + this.togglePagination(panel, page, data.data); + this.renderDataRows(panel, ui, data.data, page); + } + }, + + // Iterate over all panels and determine which ones should contain + // a data table. + renderTables: function (force) { + var ui = GoAccess.getPanelUI(); + for (var panel in ui) { + if (GoAccess.Util.isPanelValid(panel) || !this.showTables()) + continue; + if (force || GoAccess.Util.isWithinViewPort($('#panel-' + panel))) + this.renderFullTable(panel); + } + }, + + // Given a UI panel definition, make a copy of it and assign the sort + // fields to the template object to render + sort2Tpl: function (panel, ui) { + var uiClone = JSON.parse(JSON.stringify(ui)), out = []; + var sort = GoAccess.Util.getProp(GoAccess.AppState, panel + '.sort'); + + for (var i = 0, len = uiClone.items.length; i < len; ++i) { + var item = uiClone.items[i]; + if (this.hideColumn(panel, item.key)) + continue; + + item['sort'] = false; + if (item.key == sort.field && sort.order) { + item['sort'] = true; + item[sort.order.toLowerCase()] = true; + } + out.push(item); + } + uiClone.items = out; + + return uiClone; + }, + + renderThead: function (panel, ui) { + var $thead = $('.table-' + panel + '>thead'), $colgroup = $('.table-' + panel + '>colgroup'); + if ($thead && $colgroup && this.showTables()) { + ui = this.sort2Tpl(panel, ui); + + $thead.innerHTML = GoAccess.AppTpls.Tables.head.render(ui); + $colgroup.innerHTML = GoAccess.AppTpls.Tables.colgroup.render(ui); + } + }, + + reloadTables: function () { + this.renderTables(false); + this.events(); + }, + + initialize: function () { + this.renderTables(true); + this.events(); + + // redraw on scroll + d3.select(window).on('scroll.tables', debounce(function () { + this.reloadTables(); + }, 250, false).bind(this)); + }, +}; + +// Main App +GoAccess.App = { + hasFocus: true, + + tpl: function (tpl) { + return Hogan.compile(tpl); + }, + + setTpls: function () { + GoAccess.AppTpls = { + 'Nav': { + 'wrap': this.tpl($('#tpl-nav-wrap').innerHTML), + 'menu': this.tpl($('#tpl-nav-menu').innerHTML), + 'opts': this.tpl($('#tpl-nav-opts').innerHTML), + }, + 'Panels': { + 'wrap': this.tpl($('#tpl-panel').innerHTML), + 'opts': this.tpl($('#tpl-panel-opts').innerHTML), + }, + 'General': { + 'wrap': this.tpl($('#tpl-general').innerHTML), + 'items': this.tpl($('#tpl-general-items').innerHTML), + }, + 'Tables': { + 'colgroup': this.tpl($('#tpl-table-colgroup').innerHTML), + 'head': this.tpl($('#tpl-table-thead').innerHTML), + 'meta': this.tpl($('#tpl-table-row-meta').innerHTML), + 'data': this.tpl($('#tpl-table-row').innerHTML), + }, + }; + }, + + sortField: function (o, field) { + var f = o[field]; + if (GoAccess.Util.isObject(f) && (f !== null)) + f = o[field].count; + return f; + }, + + sortData: function (panel, field, order) { + // panel's data + var panelData = GoAccess.getPanelData(panel).data; + panelData.sort(function (a, b) { + a = this.sortField(a, field); + b = this.sortField(b, field); + + if (typeof a === 'string' && typeof b === 'string') + return 'asc' == order ? a.localeCompare(b) : b.localeCompare(a); + return 'asc' == order ? a - b : b - a; + }.bind(this)); + }, + + setInitSort: function () { + var ui = GoAccess.getPanelUI(); + for (var panel in ui) { + if (GoAccess.Util.isPanelValid(panel)) + continue; + GoAccess.Util.setProp(GoAccess.AppState, panel + '.sort', ui[panel].sort); + } + }, + + // Verify if we need to sort panels upon data re-entry + verifySort: function () { + var ui = GoAccess.getPanelUI(); + for (var panel in ui) { + if (GoAccess.Util.isPanelValid(panel)) + continue; + var sort = GoAccess.Util.getProp(GoAccess.AppState, panel + '.sort'); + // do not sort panels if they still hold the same sort properties + if (JSON.stringify(sort) === JSON.stringify(ui[panel].sort)) + continue; + this.sortData(panel, sort.field, sort.order); + } + }, + + initDom: function () { + $('nav').classList.remove('hide'); + $('.container').classList.remove('hide'); + $('.spinner').classList.add('hide'); + + if (GoAccess.AppPrefs['layout'] == 'horizontal') { + $('.container').classList.add('container-fluid'); + $('.container-fluid').classList.remove('container'); + } + }, + + renderData: function () { + // update data and charts if tab/document has focus + if (!this.hasFocus) + return; + + this.verifySort(); + GoAccess.OverallStats.initialize(); + + // do not rerender tables/charts if data hasn't changed + if (!GoAccess.AppState.updated) + return; + + GoAccess.Charts.reloadCharts(); + GoAccess.Tables.reloadTables(); + }, + + initialize: function () { + this.setInitSort(); + this.setTpls(); + GoAccess.Nav.initialize(); + this.initDom(); + GoAccess.OverallStats.initialize(); + GoAccess.Panels.initialize(); + GoAccess.Charts.initialize(); + GoAccess.Tables.initialize(); + }, +}; + +// Adds the visibilitychange EventListener +document.addEventListener('visibilitychange', function () { + // fires when user switches tabs, apps, etc. + if (document.visibilityState === 'hidden') + GoAccess.App.hasFocus = false; + + // fires when app transitions from hidden or user returns to the app/tab. + if (document.visibilityState === 'visible') { + var hasFocus = GoAccess.App.hasFocus; + GoAccess.App.hasFocus = true; + hasFocus || GoAccess.App.renderData(); + } +}); + +// Init app +window.onload = function () { + GoAccess.initialize({ + 'i18n': window.json_i18n, + 'uiData': window.user_interface, + 'panelData': window.json_data, + 'wsConnection': window.connection || null, + 'prefs': window.html_prefs || {}, + }); + GoAccess.App.initialize(); +}; +}()); diff --git a/goaccess++/resources/js/app.js.tmp b/goaccess++/resources/js/app.js.tmp new file mode 100644 index 0000000..1e71e4c --- /dev/null +++ b/goaccess++/resources/js/app.js.tmp @@ -0,0 +1 @@ +/*jshint sub:true*/(function () {'use strict';function $(selector) {return document.querySelector(selector);}function $$(selector, callback) {var elems = document.querySelectorAll(selector);for (var i = 0; i < elems.length; ++i) {if (callback && typeof callback == 'function')callback.call(this, elems[i]);}}var debounce = function (func, wait, now) {var timeout;return function debounced () {var that = this, args = arguments;function delayed() {if (!now)func.apply(that, args);timeout = null;}if (timeout) {clearTimeout(timeout);} else if (now) {func.apply(obj, args);}timeout = setTimeout(delayed, wait || 250);};};window.GoAccess = window.GoAccess || {initialize: function (options) {this.opts = options;this.AppState = {};this.AppTpls = {};this.AppCharts = {};this.AppUIData = (this.opts || {}).uiData || {};this.AppData = (this.opts || {}).panelData || {};this.AppWSConn = (this.opts || {}).wsConnection || {};this.i18n = (this.opts || {}).i18n || {};this.AppPrefs = {'autoHideTables': true,'layout': 'horizontal','perPage': 7,'theme': 'darkPurple',};this.AppPrefs = GoAccess.Util.merge(this.AppPrefs, this.opts.prefs);if (GoAccess.Util.hasLocalStorage()) {var ls = JSON.parse(localStorage.getItem('AppPrefs'));this.AppPrefs = GoAccess.Util.merge(this.AppPrefs, ls);}if (Object.keys(this.AppWSConn).length)this.setWebSocket(this.AppWSConn);},getPanelUI: function (panel) {return panel ? this.AppUIData[panel] : this.AppUIData;},getPrefs: function (panel) {return panel ? this.AppPrefs[panel] : this.AppPrefs;},setPrefs: function () {if (GoAccess.Util.hasLocalStorage()) {localStorage.setItem('AppPrefs', JSON.stringify(GoAccess.getPrefs()));}},getPanelData: function (panel) {return panel ? this.AppData[panel] : this.AppData;},setWebSocket: function (wsConn) {var host = null;host = wsConn.url ? wsConn.url : window.location.hostname ? window.location.hostname : "localhost";var str = /^(wss?:\/\/)?[^\/]+:[0-9]{1,5}\//.test(host + "/") ? host : String(host + ':' + wsConn.port);str = !/^wss?:\/\//i.test(str) ? (window.location.protocol === "https:" ? 'wss://' : 'ws://') + str : str;var socket = new WebSocket(str);socket.onopen = function (event) {GoAccess.Nav.WSOpen();}.bind(this);socket.onmessage = function (event) {this.AppState['updated'] = true;this.AppData = JSON.parse(event.data);this.App.renderData();}.bind(this);socket.onclose = function (event) {GoAccess.Nav.WSClose();}.bind(this);},};GoAccess.Util = {months: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul","Aug", "Sep", "Oct", "Nov", "Dec"],merge: function (o, n) {var obj = {}, i = 0, il = arguments.length, key;for (; i < il; i++) {for (key in arguments[i]) {if (arguments[i].hasOwnProperty(key)) {obj[key] = arguments[i][key];}}}return obj;},hashCode: function (s) {return (s.split('').reduce(function (a, b) {a = ((a << 5) - a) + b.charCodeAt(0);return a&a;}, 0) >>> 0).toString(16);},formatBytes: function (bytes, decimals, numOnly) {if (bytes == 0)return numOnly ? 0 : '0 Byte';var k = 1024;var dm = decimals + 1 || 2;var sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];var i = Math.floor(Math.log(bytes) / Math.log(k));return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + (numOnly ? '' : (' ' + sizes[i]));},isNumeric: function (n) {return !isNaN(parseFloat(n)) && isFinite(n);},utime2str: function (usec) {if (usec >= 864E8)return ((usec) / 864E8).toFixed(2) + ' d';else if (usec >= 36E8)return ((usec) / 36E8).toFixed(2) + ' h';else if (usec >= 6E7)return ((usec) / 6E7).toFixed(2) + ' m';else if (usec >= 1E6)return ((usec) / 1E6).toFixed(2) + ' s';else if (usec >= 1E3)return ((usec) / 1E3).toFixed(2) + ' ms';return (usec).toFixed(2) + ' us';},formatDate: function (str) {var y = str.substr(0,4), m = str.substr(4,2) - 1, d = str.substr(6,2),h = str.substr(8,2) || 0, i = str.substr(10, 2) || 0, s = str.substr(12, 2) || 0;var date = new Date(y,m,d,h,i,s);var out = ('0' + date.getDate()).slice(-2) + '/' + this.months[date.getMonth()] + '/' + date.getFullYear();10 <= str.length && (out += ":" + h);12 <= str.length && (out += ":" + i);14 <= str.length && (out += ":" + s);return out;},fmtValue: function (value, dataType, decimals) {var val = 0;if (!dataType)val = value;switch (dataType) {case 'utime':val = this.utime2str(value);break;case 'date':val = this.formatDate(value);break;case 'numeric':if (this.isNumeric(value))val = value.toLocaleString();break;case 'bytes':val = this.formatBytes(value, decimals);break;case 'percent':val = parseFloat(value.replace(',', '.')).toFixed(2) + '%';break;case 'time':if (this.isNumeric(value))val = value.toLocaleString();break;case 'secs':val = value + ' secs';break;default:val = value;}return value == 0 ? String(val) : val;},isPanelValid: function (panel) {var data = GoAccess.getPanelData(), ui = GoAccess.getPanelUI();return (!ui.hasOwnProperty(panel) || !data.hasOwnProperty(panel) || !ui[panel].id);},getCount: function (item) {if (this.isObject(item) && 'count' in item)return item.count;return item;},getPercent: function (item) {if (this.isObject(item) && 'percent' in item)return this.fmtValue(item.percent, 'percent');return null;},isObject: function (o) {return o === Object(o);},setProp: function (o, s, v) {var schema = o;var a = s.split('.');for (var i = 0, n = a.length; i < n-1; ++i) {var k = a[i];if (!schema[k])schema[k] = {};schema = schema[k];}schema[a[n-1]] = v;},getProp: function (o, s) {s = s.replace(/\[(\w+)\]/g, '.$1');s = s.replace(/^\./, '');var a = s.split('.');for (var i = 0, n = a.length; i < n; ++i) {var k = a[i];if (this.isObject(o) && k in o) {o = o[k];} else {return;}}return o;},hasLocalStorage: function () {try {localStorage.setItem('test', 'test');localStorage.removeItem('test');return true;} catch(e) {return false;}},isWithinViewPort: function (el) {var elemTop = el.getBoundingClientRect().top;var elemBottom = el.getBoundingClientRect().bottom;return elemTop < window.innerHeight && elemBottom >= 0;},};GoAccess.OverallStats = {renderBox: function (data, ui, row, x, idx) {var wrap = $('.wrap-general-items');if (idx % 6 == 0) {row = document.createElement('div');row.setAttribute('class', 'row');wrap.appendChild(row);}var box = document.createElement('div');box.innerHTML = GoAccess.AppTpls.General.items.render({'id': x,'className': ui.items[x].className,'label': ui.items[x].label,'value': GoAccess.Util.fmtValue(data[x], ui.items[x].dataType),});row.appendChild(box);return row;},renderData: function (data, ui) {var idx = 0, row = null;$('.wrap-general').innerHTML = GoAccess.AppTpls.General.wrap.render(GoAccess.Util.merge(ui, {'lastUpdated': data.date_time,'from': data.start_date,'to': data.end_date,}));for (var x in data) {if (!data.hasOwnProperty(x) || !ui.items.hasOwnProperty(x))continue;row = this.renderBox(data, ui, row, x, idx);idx++;}},initialize: function () {var ui = GoAccess.getPanelUI('general');var data = GoAccess.getPanelData('general'), i = 0;this.renderData(data, ui);}};GoAccess.Nav = {events: function () {$('.nav-bars').onclick = function (e) {e.stopPropagation();this.renderMenu(e);}.bind(this);$('.nav-gears').onclick = function (e) {e.stopPropagation();this.renderOpts(e);}.bind(this);$('.nav-minibars').onclick = function (e) {e.stopPropagation();this.renderOpts(e);}.bind(this);$('body').onclick = function (e) {$('nav').classList.remove('active');}.bind(this);$$('.export-json', function (item) {item.onclick = function (e) {this.downloadJSON(e);}.bind(this);}.bind(this));$$('.theme-bright', function (item) {item.onclick = function (e) {this.setTheme('bright');}.bind(this);}.bind(this));$$('.theme-dark-blue', function (item) {item.onclick = function (e) {this.setTheme('darkBlue');}.bind(this);}.bind(this));$$('.theme-dark-gray', function (item) {item.onclick = function (e) {this.setTheme('darkGray');}.bind(this);}.bind(this));$$('.theme-dark-purple', function (item) {item.onclick = function (e) {this.setTheme('darkPurple');}.bind(this);}.bind(this));$$('.layout-horizontal', function (item) {item.onclick = function (e) {this.setLayout('horizontal');}.bind(this);}.bind(this));$$('.layout-vertical', function (item) {item.onclick = function (e) {this.setLayout('vertical');}.bind(this);}.bind(this));$$('[data-perpage]', function (item) {item.onclick = function (e) {this.setPerPage(e);}.bind(this);}.bind(this));$$('[data-show-tables]', function (item) {item.onclick = function (e) {this.toggleTables();}.bind(this);}.bind(this));$$('[data-autohide-tables]', function (item) {item.onclick = function (e) {this.toggleAutoHideTables();}.bind(this);}.bind(this));},downloadJSON: function (e) {var targ = e.currentTarget;var data = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(GoAccess.getPanelData()));targ.href = 'data:' + data;targ.download = 'goaccess-' + (+new Date()) + '.json';},setLayout: function (layout) {if ('horizontal' == layout) {$('.container').classList.add('container-fluid');$('.container').classList.remove('container');} else if ('vertical' == layout) {$('.container-fluid').classList.add('container');$('.container').classList.remove('container-fluid');}GoAccess.AppPrefs['layout'] = layout;GoAccess.setPrefs();GoAccess.Panels.initialize();GoAccess.Charts.initialize();GoAccess.Tables.initialize();},toggleAutoHideTables: function (e) {var autoHideTables = GoAccess.Tables.autoHideTables();$$('.table-wrapper', function (item) {if (autoHideTables) {item.classList.remove('hidden-xs');} else {item.classList.add('hidden-xs');}}.bind(this));GoAccess.AppPrefs['autoHideTables'] = !autoHideTables;GoAccess.setPrefs();},toggleTables: function () {var ui = GoAccess.getPanelUI();var showTables = GoAccess.Tables.showTables();Object.keys(ui).forEach(function (panel, idx) {if (!GoAccess.Util.isPanelValid(panel))ui[panel]['table'] = !showTables;}.bind(this));GoAccess.AppPrefs['showTables'] = !showTables;GoAccess.setPrefs();GoAccess.Panels.initialize();GoAccess.Charts.initialize();GoAccess.Tables.initialize();},setTheme: function (theme) {if (!theme)return;$('html').className = '';switch(theme) {case 'darkGray':$('html').classList.add('dark');$('html').classList.add('gray');break;case 'darkBlue':$('html').classList.add('dark');$('html').classList.add('blue');break;case 'darkPurple':$('html').classList.add('dark');$('html').classList.add('purple');break;}GoAccess.AppPrefs['theme'] = theme;GoAccess.setPrefs();},getIcon: function (key) {switch(key) {case 'visitors' : return 'users';case 'requests' : return 'file';case 'static_requests' : return 'file-text';case 'not_found' : return 'file-o';case 'hosts' : return 'user';case 'os' : return 'desktop';case 'browsers' : return 'chrome';case 'visit_time' : return 'clock-o';case 'vhosts' : return 'th-list';case 'referrers' : return 'external-link';case 'referring_sites' : return 'external-link';case 'keyphrases' : return 'google';case 'status_codes' : return 'warning';case 'remote_user' : return 'users';case 'geolocation' : return 'map-marker';default : return 'pie-chart';}},getItems: function () {var ui = GoAccess.getPanelUI(), menu = [];for (var panel in ui) {if (GoAccess.Util.isPanelValid(panel))continue;menu.push({'current': window.location.hash.substr(1) == panel,'head': ui[panel].head,'key': panel,'icon': this.getIcon(panel),});}return menu;},setPerPage: function (e) {GoAccess.AppPrefs['perPage'] = +e.currentTarget.getAttribute('data-perpage');GoAccess.App.renderData();GoAccess.setPrefs();},getTheme: function () {return GoAccess.AppPrefs.theme || 'darkGray';},getLayout: function () {return GoAccess.AppPrefs.layout || 'horizontal';},getPerPage: function () {return GoAccess.AppPrefs.perPage || 7;},renderOpts: function () {var o = {};o[this.getLayout()] = true;o[this.getTheme()] = true;o['perPage' + this.getPerPage()] = true;o['autoHideTables'] = GoAccess.Tables.autoHideTables();o['showTables'] = GoAccess.Tables.showTables();o['labels'] = GoAccess.i18n;$('.nav-list').innerHTML = GoAccess.AppTpls.Nav.opts.render(o);$('nav').classList.toggle('active');this.events();},renderMenu: function (e) {$('.nav-list').innerHTML = GoAccess.AppTpls.Nav.menu.render({'nav': this.getItems(),'overall': window.location.hash.substr(1) == '','labels': GoAccess.i18n,});$('nav').classList.toggle('active');this.events();},WSStatus: function () {if (Object.keys(GoAccess.AppWSConn).length)$$('.nav-ws-status', function (item) { item.style.display = 'block'; });},WSClose: function () {$$('.nav-ws-status', function (item) {item.classList.remove('connected');item.setAttribute('title', 'Disconnected');});},WSOpen: function () {$$('.nav-ws-status', function (item) {item.classList.add('connected');item.setAttribute('title', 'Connected to ' + GoAccess.AppWSConn.url);});},renderWrap: function (nav) {$('nav').innerHTML = GoAccess.AppTpls.Nav.wrap.render(GoAccess.i18n);},initialize: function () {this.setTheme(GoAccess.AppPrefs.theme);this.renderWrap();this.WSStatus();this.events();}};GoAccess.Panels = {events: function () {$$('[data-toggle=dropdown]', function (item) {item.onclick = function (e) {this.openOpts(e.currentTarget);}.bind(this);item.onblur = function (e) {this.closeOpts(e);}.bind(this);}.bind(this));$$('[data-plot]', function (item) {item.onclick = function (e) {GoAccess.Charts.redrawChart(e.currentTarget);}.bind(this);}.bind(this));$$('[data-chart]', function (item) {item.onclick = function (e) {GoAccess.Charts.toggleChart(e.currentTarget);}.bind(this);}.bind(this));$$('[data-chart-type]', function (item) {item.onclick = function (e) {GoAccess.Charts.setChartType(e.currentTarget);}.bind(this);}.bind(this));$$('[data-metric]', function (item) {item.onclick = function (e) {GoAccess.Tables.toggleColumn(e.currentTarget);}.bind(this);}.bind(this));},openOpts: function (targ) {var panel = targ.getAttribute('data-panel');targ.parentElement.classList.toggle('open');this.renderOpts(panel);},closeOpts: function (e) {e.currentTarget.parentElement.classList.remove('open');if (e.relatedTarget && e.relatedTarget.getAttribute('data-toggle') !== 'dropdown')e.relatedTarget.click();},setPlotSelection: function (ui, prefs) {var chartType = ((prefs || {}).plot || {}).chartType || ui.plot[0].chartType;var metric = ((prefs || {}).plot || {}).metric || ui.plot[0].className;ui[chartType] = true;for (var i = 0, len = ui.plot.length; i < len; ++i)if (ui.plot[i].className == metric)ui.plot[i]['selected'] = true;},setColSelection: function (items, prefs) {var columns = (prefs || {}).columns || {};for (var i = 0, len = items.length; i < len; ++i)if ((items[i].key in columns) && columns[items[i].key]['hide'])items[i]['hide'] = true;},setChartSelection: function (ui, prefs) {ui['showChart'] = prefs && ('chart' in prefs) ? prefs.chart : true;},setOpts: function (panel) {var ui = JSON.parse(JSON.stringify(GoAccess.getPanelUI(panel))), prefs = GoAccess.getPrefs(panel);this.setChartSelection(ui, prefs);this.setPlotSelection(ui, prefs);this.setColSelection(ui.items, prefs);return GoAccess.Util.merge(ui, {'labels': GoAccess.i18n});},renderOpts: function (panel) {$('.panel-opts-' + panel).innerHTML = GoAccess.AppTpls.Panels.opts.render(this.setOpts(panel));this.events();},enablePrev: function (panel) {var $pagination = $('#panel-' + panel + ' .pagination a.panel-prev');if ($pagination)$pagination.parentNode.classList.remove('disabled');},disablePrev: function (panel) {var $pagination = $('#panel-' + panel + ' .pagination a.panel-prev');if ($pagination)$pagination.parentNode.classList.add('disabled');},enableNext: function (panel) {var $pagination = $('#panel-' + panel + ' .pagination a.panel-next');if ($pagination)$pagination.parentNode.classList.remove('disabled');},disableNext: function (panel) {var $pagination = $('#panel-' + panel + ' .pagination a.panel-next');if ($pagination)$pagination.parentNode.classList.add('disabled');},enableFirst: function (panel) {var $pagination = $('#panel-' + panel + ' .pagination a.panel-first');if ($pagination)$pagination.parentNode.classList.remove('disabled');},disableFirst: function (panel) {var $pagination = $('#panel-' + panel + ' .pagination a.panel-first');if ($pagination)$pagination.parentNode.classList.add('disabled');},enableLast: function (panel) {var $pagination = $('#panel-' + panel + ' .pagination a.panel-last');if ($pagination)$pagination.parentNode.classList.remove('disabled');},disableLast: function (panel) {var $pagination = $('#panel-' + panel + ' .pagination a.panel-last');if ($pagination)$pagination.parentNode.classList.add('disabled');},enablePagination: function (panel) {this.enablePrev(panel);this.enableNext(panel);this.enableFirst(panel);this.enableLast(panel);},disablePagination: function (panel) {this.disablePrev(panel);this.disableNext(panel);this.disableFirst(panel);this.disableLast(panel);},hasSubItems: function (ui, data) {for (var i = 0, len = data.length; i < len; ++i) {if (!data[i].items)return (ui['hasSubItems'] = false);if (data[i].items.length) {return (ui['hasSubItems'] = true);}}return false;},setComputedData: function (panel, ui, data) {this.hasSubItems(ui, data.data);GoAccess.Charts.hasChart(panel, ui);GoAccess.Tables.hasTable(ui);},renderPanel: function (panel, ui, col) {var data = GoAccess.getPanelData(panel);this.setComputedData(panel, ui, data);var box = document.createElement('div');box.id = 'panel-' + panel;box.innerHTML = GoAccess.AppTpls.Panels.wrap.render(GoAccess.Util.merge(ui, {'labels': GoAccess.i18n}));col.appendChild(box);if (data.data.length <= GoAccess.getPrefs().perPage)this.disablePagination(panel);GoAccess.Tables.renderThead(panel, ui);return col;},createCol: function (row) {var perRow = GoAccess.AppPrefs['layout'] == 'horizontal' ? 6 : 12;var col = document.createElement('div');col.setAttribute('class', 'col-md-' + perRow + ' wrap-panel');row.appendChild(col);return col;},createRow: function (row, idx) {var wrap = $('.wrap-panels');var every = GoAccess.AppPrefs['layout'] == 'horizontal' ? 2 : 1;if (idx % every == 0) {row = document.createElement('div');row.setAttribute('class', 'row' + (every == 2 ? ' equal' : ''));wrap.appendChild(row);}return row;},resetPanel: function (panel) {var ui = GoAccess.getPanelUI(), idx = 0, row = null;var ele = $('#panel-' + panel);if (GoAccess.Util.isPanelValid(panel))return false;var col = ele.parentNode;col.removeChild(ele);this.renderPanel(panel, ui[panel], col);this.events();},renderPanels: function () {var ui = GoAccess.getPanelUI(), idx = 0, row = null, col = null;$('.wrap-panels').innerHTML = '';for (var panel in ui) {if (GoAccess.Util.isPanelValid(panel))continue;row = this.createRow(row, idx++);col = this.createCol(row);col = this.renderPanel(panel, ui[panel], col);}},initialize: function () {this.renderPanels();this.events();}};GoAccess.Charts = {iter: function (callback) {Object.keys(GoAccess.AppCharts).forEach(function (panel) {if (!GoAccess.Util.isWithinViewPort($('#panel-' + panel)))return;if (callback && typeof callback === 'function')callback.call(this, GoAccess.AppCharts[panel], panel);});},getMetricKeys: function (panel, key) {return GoAccess.getPanelUI(panel)['items'].map(function (a) { return a[key]; });},getPanelData: function (panel, data) {var plot = GoAccess.Util.getProp(GoAccess.AppState, panel + '.plot');data = data || this.processChartData(GoAccess.getPanelData(panel).data);return plot.chartReverse ? data.reverse() : data;},drawPlot: function (panel, plotUI, data) {var chart = this.getChart(panel, plotUI, data);if (!chart)return;this.renderChart(panel, chart, data);GoAccess.AppCharts[panel] = null;GoAccess.AppCharts[panel] = chart;},setChartType: function (targ) {var panel = targ.getAttribute('data-panel');var type = targ.getAttribute('data-chart-type');GoAccess.Util.setProp(GoAccess.AppPrefs, panel + '.plot.chartType', type);GoAccess.setPrefs();var plotUI = GoAccess.Util.getProp(GoAccess.AppState, panel + '.plot');this.drawPlot(panel, plotUI, this.getPanelData(panel));},toggleChart: function (targ) {var panel = targ.getAttribute('data-panel');var prefs = GoAccess.getPrefs(panel),chart = prefs && ('chart' in prefs) ? prefs.chart : true;GoAccess.Util.setProp(GoAccess.AppPrefs, panel + '.chart', !chart);GoAccess.setPrefs();GoAccess.Panels.resetPanel(panel);GoAccess.Charts.resetChart(panel);GoAccess.Tables.renderFullTable(panel);},hasChart: function (panel, ui) {var prefs = GoAccess.getPrefs(panel),chart = prefs && ('chart' in prefs) ? prefs.chart : true;ui['chart'] = ui.plot.length && chart && chart;},redrawChart: function (targ) {var plot = targ.getAttribute('data-plot');var panel = targ.getAttribute('data-panel');var ui = GoAccess.getPanelUI(panel);var plotUI = ui.plot;GoAccess.Util.setProp(GoAccess.AppPrefs, panel + '.plot.metric', plot);GoAccess.setPrefs();for (var x in plotUI) {if (!plotUI.hasOwnProperty(x) || plotUI[x].className != plot)continue;GoAccess.Util.setProp(GoAccess.AppState, panel + '.plot', plotUI[x]);this.drawPlot(panel, plotUI[x], this.getPanelData(panel));break;}},extractCount: function (item) {var o = {};for (var prop in item)o[prop] = GoAccess.Util.getCount(item[prop]);return o;},processChartData: function (data) {var out = [];for (var i = 0; i < data.length; ++i)out.push(this.extractCount(data[i]));return out;},findUIItem: function (panel, key) {var items = GoAccess.getPanelUI(panel).items, o = {};for (var i = 0; i < items.length; ++i) {if (items[i].key == key)return items[i];}return null;},getXKey: function (datum, key) {var arr = [];if (typeof key === 'string')return datum[key];for (var prop in key)arr.push(datum[key[prop]]);return arr.join(' ');},getAreaSpline: function (panel, plotUI, data) {var dualYaxis = plotUI['d3']['y1'];var chart = AreaChart(dualYaxis).labels({y0: plotUI['d3']['y0'].label,y1: dualYaxis ? plotUI['d3']['y1'].label : ''}).x(function (d) {if ((((plotUI || {}).d3 || {}).x || {}).key)return this.getXKey(d, plotUI['d3']['x']['key']);return d.data;}.bind(this)).y0(function (d) {return +d[plotUI['d3']['y0']['key']];}).width($("#chart-" + panel).getBoundingClientRect().width).height(175).format({x: (this.findUIItem(panel, 'data') || {}).dataType || null,y0: ((plotUI.d3 || {}).y0 || {}).format,y1: ((plotUI.d3 || {}).y1 || {}).format,}).opts(plotUI);dualYaxis && chart.y1(function (d) {return +d[plotUI['d3']['y1']['key']];});return chart;},getVBar: function (panel, plotUI, data) {var dualYaxis = plotUI['d3']['y1'];var chart = BarChart(dualYaxis).labels({y0: plotUI['d3']['y0'].label,y1: dualYaxis ? plotUI['d3']['y1'].label : ''}).x(function (d) {if ((((plotUI || {}).d3 || {}).x || {}).key)return this.getXKey(d, plotUI['d3']['x']['key']);return d.data;}.bind(this)).y0(function (d) {return +d[plotUI['d3']['y0']['key']];}).width($("#chart-" + panel).getBoundingClientRect().width).height(175).format({x: (this.findUIItem(panel, 'data') || {}).dataType || null,y0: ((plotUI.d3 || {}).y0 || {}).format,y1: ((plotUI.d3 || {}).y1 || {}).format,}).opts(plotUI);dualYaxis && chart.y1(function (d) {return +d[plotUI['d3']['y1']['key']];});return chart;},getChartType: function (panel) {var ui = GoAccess.getPanelUI(panel);if (!ui.chart)return '';return GoAccess.Util.getProp(GoAccess.getPrefs(), panel + '.plot.chartType') || ui.plot[0].chartType;},getPlotUI: function (panel, ui) {var metric = GoAccess.Util.getProp(GoAccess.getPrefs(), panel + '.plot.metric');if (!metric)return ui.plot[0];return ui.plot.filter(function (v) {return v.className == metric;})[0];},getChart: function (panel, plotUI, data) {var chart = null;switch (this.getChartType(panel)) {case 'area-spline':chart = this.getAreaSpline(panel, plotUI, data);break;case 'bar':chart = this.getVBar(panel, plotUI, data);break;}return chart;},renderChart: function (panel, chart, data) {d3.select('#chart-' + panel + '>.chart-tooltip-wrap').remove();d3.select('#chart-' + panel).select('svg').remove();d3.select("#chart-" + panel).datum(data).call(chart).append("div").attr("class", "chart-tooltip-wrap");},addChart: function (panel, ui) {var plotUI = null, chart = null;if (!ui.plot || !ui.plot.length)return;plotUI = this.getPlotUI(panel, ui);GoAccess.Util.setProp(GoAccess.AppState, panel + '.plot', plotUI);var data = this.getPanelData(panel);if (!(chart = this.getChart(panel, plotUI, data)))return;this.renderChart(panel, chart, data);GoAccess.AppCharts[panel] = chart;},renderCharts: function (ui) {for (var panel in ui) {if (!ui.hasOwnProperty(panel))continue;this.addChart(panel, ui[panel]);}},resetChart: function (panel) {var ui = {};if (GoAccess.Util.isPanelValid(panel))return false;ui = GoAccess.getPanelUI(panel);this.addChart(panel, ui);},reloadChart: function (chart, panel) {var subItems = GoAccess.Tables.getSubItemsData(panel);var data = (subItems.length ? subItems : GoAccess.getPanelData(panel).data).slice(0);d3.select("#chart-" + panel).datum(this.processChartData(this.getPanelData(panel, data))).call(chart.width($("#chart-" + panel).offsetWidth));},reloadCharts: function () {this.iter(function (chart, panel) {this.reloadChart(chart, panel);}.bind(this));GoAccess.AppState.updated = false;},redrawCharts: function () {this.iter(function (chart, panel) {d3.select("#chart-" + panel).call(chart.width($("#chart-" + panel).offsetWidth));});},initialize: function () {this.renderCharts(GoAccess.getPanelUI());d3.select(window).on('scroll.charts', debounce(function () {this.reloadCharts();}, 250, false).bind(this)).on('resize.charts', function () {this.redrawCharts();}.bind(this));}};GoAccess.Tables = {chartData: {},events: function () {$$('.panel-next', function (item) {item.onclick = function (e) {var panel = e.currentTarget.getAttribute('data-panel');this.renderTable(panel, this.nextPage(panel));}.bind(this);}.bind(this));$$('.panel-prev', function (item) {item.onclick = function (e) {var panel = e.currentTarget.getAttribute('data-panel');this.renderTable(panel, this.prevPage(panel));}.bind(this);}.bind(this));$$('.panel-first', function (item) {item.onclick = function (e) {var panel = e.currentTarget.getAttribute('data-panel');this.renderTable(panel, "FIRST_PAGE");}.bind(this);}.bind(this));$$('.panel-last', function (item) {item.onclick = function (e) {var panel = e.currentTarget.getAttribute('data-panel');this.renderTable(panel, "LAST_PAGE");}.bind(this);}.bind(this));$$('.expandable>td', function (item) {item.onclick = function (e) {if (!window.getSelection().toString())this.toggleRow(e.currentTarget);}.bind(this);}.bind(this));$$('.row-expandable.clickable', function (item) {item.onclick = function (e) {this.toggleRow(e.currentTarget);}.bind(this);}.bind(this));$$('.sortable', function (item) {item.onclick = function (e) {this.sortColumn(e.currentTarget);}.bind(this);}.bind(this));},toggleColumn: function (targ) {var panel = targ.getAttribute('data-panel');var metric = targ.getAttribute('data-metric');var columns = (GoAccess.getPrefs(panel) || {}).columns || {};if (metric in columns) {delete columns[metric];} else {GoAccess.Util.setProp(columns, metric + '.hide', true);}GoAccess.Util.setProp(GoAccess.AppPrefs, panel + '.columns', columns);GoAccess.setPrefs();GoAccess.Tables.renderThead(panel, GoAccess.getPanelUI(panel));GoAccess.Tables.renderFullTable(panel);},sortColumn: function (ele) {var field = ele.getAttribute('data-key');var order = ele.getAttribute('data-order');var panel = ele.parentElement.parentElement.parentElement.getAttribute('data-panel');order = order ? 'asc' == order ? 'desc' : 'asc' : 'asc';GoAccess.App.sortData(panel, field, order);GoAccess.Util.setProp(GoAccess.AppState, panel + '.sort', {'field': field,'order': order,});this.renderThead(panel, GoAccess.getPanelUI(panel));this.renderTable(panel, this.getCurPage(panel));GoAccess.Charts.reloadChart(GoAccess.AppCharts[panel], panel);},getDataByKey: function (panel, key) {var data = GoAccess.getPanelData(panel).data;for (var i = 0, n = data.length; i < n; ++i) {if (GoAccess.Util.hashCode(data[i].data) == key)return data[i];}return null;},getSubItemsData: function (panel) {var out = [], items = this.chartData[panel];for (var x in items) {if (!items.hasOwnProperty(x))continue;out = out.concat(items[x]);}return out;},addChartData: function (panel, key) {var data = this.getDataByKey(panel, key);var path = panel + '.' + key;if (!data || !data.items)return [];GoAccess.Util.setProp(this.chartData, path, data.items);return this.getSubItemsData(panel);},removeChartData: function (panel, key) {if (GoAccess.Util.getProp(this.chartData, panel + '.' + key))delete this.chartData[panel][key];if (!this.chartData[panel] || Object.keys(this.chartData[panel]).length == 0)return GoAccess.getPanelData(panel).data;return this.getSubItemsData(panel);},isExpanded: function (panel, key) {var path = panel + '.expanded.' + key;return GoAccess.Util.getProp(GoAccess.AppState, path);},toggleExpanded: function (panel, key) {var path = panel + '.expanded.' + key, ret = true;if (this.isExpanded(panel, key)) {delete GoAccess.AppState[panel]['expanded'][key];} else {GoAccess.Util.setProp(GoAccess.AppState, path, true), ret = false;}return ret;},toggleRow: function (ele) {var hide = false, data = [];var row = ele.parentNode;var panel = row.getAttribute('data-panel'), key = row.getAttribute('data-key');var plotUI = GoAccess.AppCharts[panel].opts();hide = this.toggleExpanded(panel, key);this.renderTable(panel, this.getCurPage(panel));if (!plotUI.redrawOnExpand)return;if (!hide) {data = GoAccess.Charts.processChartData(this.addChartData(panel, key));} else {data = GoAccess.Charts.processChartData(this.removeChartData(panel, key));}GoAccess.Charts.drawPlot(panel, plotUI, data);},getCurPage: function (panel) {return GoAccess.Util.getProp(GoAccess.AppState, panel + '.curPage') || 0;},pageOffSet: function (panel) {return ((this.getCurPage(panel) - 1) * GoAccess.getPrefs().perPage);},getTotalPages: function (dataItems) {return Math.ceil(dataItems.length / GoAccess.getPrefs().perPage);},getPage: function (panel, dataItems, page) {var totalPages = this.getTotalPages(dataItems);if (page < 1)page = 1;if (page > totalPages)page = totalPages;GoAccess.Util.setProp(GoAccess.AppState, panel + '.curPage', page);var start = this.pageOffSet(panel);var end = start + GoAccess.getPrefs().perPage;return dataItems.slice(start, end);},prevPage: function (panel) {return this.getCurPage(panel) - 1;},nextPage: function (panel) {return this.getCurPage(panel) + 1;},getMetaValue: function (ui, value) {if ('meta' in ui)return value[ui.meta];return null;},getMetaCell: function (ui, value) {var val = this.getMetaValue(ui, value);var max = (value || {}).max;var min = (value || {}).min;var vtype = ui.metaType || ui.dataType;var className = ui.className || '';className += ui.dataType != 'string' ? 'text-right' : '';return {'className': className,'max' : max != undefined ? GoAccess.Util.fmtValue(max, vtype) : null,'min' : min != undefined ? GoAccess.Util.fmtValue(min, vtype) : null,'value' : val != undefined ? GoAccess.Util.fmtValue(val, vtype) : null,'title' : ui.meta,'label' : ui.metaLabel || null,};},hideColumn: function (panel, col) {var columns = (GoAccess.getPrefs(panel) || {}).columns || {};return ((col in columns) && columns[col]['hide']);},showTables: function () {return ('showTables' in GoAccess.getPrefs()) ? GoAccess.getPrefs().showTables : true;},autoHideTables: function () {return ('autoHideTables' in GoAccess.getPrefs()) ? GoAccess.getPrefs().autoHideTables : true;},hasTable: function (ui) {ui['table'] = this.showTables();ui['autoHideTables'] = this.autoHideTables();},renderMetaRow: function (panel, ui) {var table = $('.table-' + panel + ' tbody.tbody-meta');if (!table)return;var cells = [], uiItems = ui.items;var data = GoAccess.getPanelData(panel).metadata;for (var i = 0; i < uiItems.length; ++i) {var item = uiItems[i];if (this.hideColumn(panel, item.key))continue;var value = data[item.key];cells.push(this.getMetaCell(item, value));}table.innerHTML = GoAccess.AppTpls.Tables.meta.render({row: [{'hasSubItems': ui.hasSubItems,'cells': cells}]});},iterUIItems: function (panel, uiItems, dataItems, callback) {var out = [];for (var i = 0; i < uiItems.length; ++i) {var uiItem = uiItems[i];if (this.hideColumn(panel, uiItem.key))continue;var dataItem = dataItems[uiItem.key];if (callback && typeof callback == 'function') {var ret = callback.call(this, panel, uiItem, dataItem);if (ret) out.push(ret);}}return out;},getObjectCell: function (panel, ui, value) {var className = ui.className || '';className += ui.dataType != 'string' ? 'text-right' : '';return {'className': className,'percent': GoAccess.Util.getPercent(value),'value': GoAccess.Util.fmtValue(GoAccess.Util.getCount(value), ui.dataType)};},renderRow: function (panel, callback, ui, dataItem, idx, subItem, parentId, expanded) {var shadeParent = ((!subItem && idx % 2 != 0) ? 'shaded' : '');var shadeChild = ((parentId % 2 != 0) ? 'shaded' : '');return {'panel' : panel,'idx' : !subItem && (String((idx + 1) + this.pageOffSet(panel))),'key' : !subItem ? GoAccess.Util.hashCode(dataItem.data) : '','expanded' : !subItem && expanded,'parentId' : subItem ? String(parentId) : '','className' : subItem ? 'child ' + shadeChild : 'parent ' + shadeParent,'hasSubItems' : ui.hasSubItems,'items' : dataItem.items ? dataItem.items.length : 0,'cells' : callback.call(this),};},renderRows: function (rows, panel, ui, dataItems, subItem, parentId) {subItem = subItem || false;if (dataItems.length == 0 && ui.items.length) {rows.push({cells: [{className: 'text-center',colspan: ui.items.length + 1,value: 'No data on this panel.'}]});}var cellcb = null;for (var i = 0; i < dataItems.length; ++i) {var dataItem = dataItems[i], data = null, expanded = false;switch(typeof dataItem) {case 'string':data = dataItem;cellcb = function () {return {'colspan': ui.items.length,'value': data};};break;default:data = dataItem.data;cellcb = this.iterUIItems.bind(this, panel, ui.items, dataItem, this.getObjectCell.bind(this));}expanded = this.isExpanded(panel, GoAccess.Util.hashCode(data));rows.push(this.renderRow(panel, cellcb, ui, dataItem, i, subItem, parentId, expanded));if (dataItem.items && dataItem.items.length && expanded) {this.renderRows(rows, panel, ui, dataItem.items, true, i, expanded);}}},renderDataRows: function (panel, ui, dataItems, page) {var table = $('.table-' + panel + ' tbody.tbody-data');if (!table)return;dataItems = this.getPage(panel, dataItems, page);var rows = [];this.renderRows(rows, panel, ui, dataItems);if (rows.length == 0)return;table.innerHTML = GoAccess.AppTpls.Tables.data.render({rows: rows});},togglePagination: function (panel, page, dataItems) {GoAccess.Panels.enablePagination(panel);if (page >= this.getTotalPages(dataItems)) {GoAccess.Panels.disableNext(panel);GoAccess.Panels.disableLast(panel);}if (page <= 1) {GoAccess.Panels.disablePrev(panel);GoAccess.Panels.disableFirst(panel);}},renderTable: function (panel, page) {var dataItems = GoAccess.getPanelData(panel).data;var ui = GoAccess.getPanelUI(panel);if (page === "LAST_PAGE") {page = this.getTotalPages(dataItems);} else if (page === "FIRST_PAGE") {page = 1;}this.togglePagination(panel, page, dataItems);this.renderDataRows(panel, ui, dataItems, page);this.events();},renderFullTable: function (panel) {var ui = GoAccess.getPanelUI(panel), page = 0;var data = GoAccess.getPanelData(panel);if (data.hasOwnProperty('metadata'))this.renderMetaRow(panel, ui);if (data.hasOwnProperty('data')) {page = this.getCurPage(panel);this.togglePagination(panel, page, data.data);this.renderDataRows(panel, ui, data.data, page);}},renderTables: function (force) {var ui = GoAccess.getPanelUI();for (var panel in ui) {if (GoAccess.Util.isPanelValid(panel) || !this.showTables())continue;if (force || GoAccess.Util.isWithinViewPort($('#panel-' + panel)))this.renderFullTable(panel);}},sort2Tpl: function (panel, ui) {var uiClone = JSON.parse(JSON.stringify(ui)), out = [];var sort = GoAccess.Util.getProp(GoAccess.AppState, panel + '.sort');for (var i = 0, len = uiClone.items.length; i < len; ++i) {var item = uiClone.items[i];if (this.hideColumn(panel, item.key))continue;item['sort'] = false;if (item.key == sort.field && sort.order) {item['sort'] = true;item[sort.order.toLowerCase()] = true;}out.push(item);}uiClone.items = out;return uiClone;},renderThead: function (panel, ui) {var $thead = $('.table-' + panel + '>thead'), $colgroup = $('.table-' + panel + '>colgroup');if ($thead && $colgroup && this.showTables()) {ui = this.sort2Tpl(panel, ui);$thead.innerHTML = GoAccess.AppTpls.Tables.head.render(ui);$colgroup.innerHTML = GoAccess.AppTpls.Tables.colgroup.render(ui);}},reloadTables: function () {this.renderTables(false);this.events();},initialize: function () {this.renderTables(true);this.events();d3.select(window).on('scroll.tables', debounce(function () {this.reloadTables();}, 250, false).bind(this));},};GoAccess.App = {hasFocus: true,tpl: function (tpl) {return Hogan.compile(tpl);},setTpls: function () {GoAccess.AppTpls = {'Nav': {'wrap': this.tpl($('#tpl-nav-wrap').innerHTML),'menu': this.tpl($('#tpl-nav-menu').innerHTML),'opts': this.tpl($('#tpl-nav-opts').innerHTML),},'Panels': {'wrap': this.tpl($('#tpl-panel').innerHTML),'opts': this.tpl($('#tpl-panel-opts').innerHTML),},'General': {'wrap': this.tpl($('#tpl-general').innerHTML),'items': this.tpl($('#tpl-general-items').innerHTML),},'Tables': {'colgroup': this.tpl($('#tpl-table-colgroup').innerHTML),'head': this.tpl($('#tpl-table-thead').innerHTML),'meta': this.tpl($('#tpl-table-row-meta').innerHTML),'data': this.tpl($('#tpl-table-row').innerHTML),},};},sortField: function (o, field) {var f = o[field];if (GoAccess.Util.isObject(f) && (f !== null))f = o[field].count;return f;},sortData: function (panel, field, order) {var panelData = GoAccess.getPanelData(panel).data;panelData.sort(function (a, b) {a = this.sortField(a, field);b = this.sortField(b, field);if (typeof a === 'string' && typeof b === 'string')return 'asc' == order ? a.localeCompare(b) : b.localeCompare(a);return 'asc' == order ? a - b : b - a;}.bind(this));},setInitSort: function () {var ui = GoAccess.getPanelUI();for (var panel in ui) {if (GoAccess.Util.isPanelValid(panel))continue;GoAccess.Util.setProp(GoAccess.AppState, panel + '.sort', ui[panel].sort);}},verifySort: function () {var ui = GoAccess.getPanelUI();for (var panel in ui) {if (GoAccess.Util.isPanelValid(panel))continue;var sort = GoAccess.Util.getProp(GoAccess.AppState, panel + '.sort');if (JSON.stringify(sort) === JSON.stringify(ui[panel].sort))continue;this.sortData(panel, sort.field, sort.order);}},initDom: function () {$('nav').classList.remove('hide');$('.container').classList.remove('hide');$('.spinner').classList.add('hide');if (GoAccess.AppPrefs['layout'] == 'horizontal') {$('.container').classList.add('container-fluid');$('.container-fluid').classList.remove('container');}},renderData: function () {if (!this.hasFocus)return;this.verifySort();GoAccess.OverallStats.initialize();if (!GoAccess.AppState.updated)return;GoAccess.Charts.reloadCharts();GoAccess.Tables.reloadTables();},initialize: function () {this.setInitSort();this.setTpls();GoAccess.Nav.initialize();this.initDom();GoAccess.OverallStats.initialize();GoAccess.Panels.initialize();GoAccess.Charts.initialize();GoAccess.Tables.initialize();},};document.addEventListener('visibilitychange', function () {if (document.visibilityState === 'hidden')GoAccess.App.hasFocus = false;if (document.visibilityState === 'visible') {var hasFocus = GoAccess.App.hasFocus;GoAccess.App.hasFocus = true;hasFocus || GoAccess.App.renderData();}});window.onload = function () {GoAccess.initialize({'i18n': window.json_i18n,'uiData': window.user_interface,'panelData': window.json_data,'wsConnection': window.connection || null,'prefs': window.html_prefs || {},});GoAccess.App.initialize();};}()); \ No newline at end of file diff --git a/goaccess++/resources/js/charts.js b/goaccess++/resources/js/charts.js new file mode 100644 index 0000000..3111546 --- /dev/null +++ b/goaccess++/resources/js/charts.js @@ -0,0 +1,1067 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2018 Gerardo Orellana <hello @ goaccess.io> + */ + +'use strict'; + +// This is faster than calculating the exact length of each label. +// e.g., getComputedTextLength(), slice()... +function truncate(text, width) { + text.each(function () { + var parent = this.parentNode, $d3parent = d3.select(parent); + var gw = $d3parent.node().getBBox(); + var x = (Math.min(gw.width, width) / 2) * -1; + // adjust wrapper <svg> width + if ('svg' == parent.nodeName) { + $d3parent.attr('width', width).attr('x', x); + } + // wrap <text> within an svg + else { + $d3parent.insert('svg', function () { + return this; + }.bind(this)) + .attr('class', 'wrap-text') + .attr('width', width) + .attr('x', x) + .append(function () { + return this; + }.bind(this)); + } + }); +} + +function AreaChart(dualYaxis) { + var opts = {}; + var margin = { + top : 20, + right : 50, + bottom : 40, + left : 50, + }, + height = 170, + nTicks = 10, + padding = 10, + width = 760; + var labels = { x: 'Unnamed', y0: 'Unnamed', y1: 'Unnamed' }; + var format = { x: null, y0: null, y1: null}; + + var xValue = function (d) { + return d[0]; + }, + yValue0 = function (d) { + return d[1]; + }, + yValue1 = function (d) { + return d[2]; + }; + + var xScale = d3.scale.ordinal(); + var yScale0 = d3.scale.linear().nice(); + var yScale1 = d3.scale.linear().nice(); + + var xAxis = d3.svg.axis() + .scale(xScale) + .orient('bottom') + .tickFormat(function (d) { + if (format.x) + return GoAccess.Util.fmtValue(d, format.x); + return d; + }); + + var yAxis0 = d3.svg.axis() + .scale(yScale0) + .orient('left') + .tickFormat(function (d) { + return d3.format('.2s')(d); + }); + + var yAxis1 = d3.svg.axis() + .scale(yScale1) + .orient('right') + .tickFormat(function (d) { + if (format.y1) + return GoAccess.Util.fmtValue(d, format.y1); + return d3.format('.2s')(d); + }); + + var xGrid = d3.svg.axis() + .scale(xScale) + .orient('bottom'); + + var yGrid = d3.svg.axis() + .scale(yScale0) + .orient('left'); + + var area0 = d3.svg.area() + .interpolate('cardinal') + .x(X) + .y(Y0); + var area1 = d3.svg.area() + .interpolate('cardinal') + .x(X) + .y(Y1); + + var line0 = d3.svg.line() + .interpolate('cardinal') + .x(X) + .y(Y0); + var line1 = d3.svg.line() + .interpolate('cardinal') + .x(X) + .y(Y1); + + // The x-accessor for the path generator; xScale ∘ xValue. + function X(d) { + return xScale(d[0]); + } + + // The x-accessor for the path generator; yScale0 yValue0. + function Y0(d) { + return yScale0(d[1]); + } + + // The x-accessor for the path generator; yScale0 yValue0. + function Y1(d) { + return yScale1(d[2]); + } + + function innerW() { + return width - margin.left - margin.right; + } + + function innerH() { + return height - margin.top - margin.bottom; + } + + function getXTicks(data) { + if (data.length < nTicks) + return xScale.domain(); + + return d3.range(0, data.length, Math.ceil(data.length / nTicks)).map(function (d) { + return xScale.domain()[d]; + }); + } + + function getYTicks(scale) { + var domain = scale.domain(); + return d3.range(domain[0], domain[1], Math.ceil(domain[1] / nTicks)); + } + + // Convert data to standard representation greedily; + // this is needed for nondeterministic accessors. + function mapData(data) { + var _datum = function (d, i) { + var datum = [xValue.call(data, d, i), yValue0.call(data, d, i)]; + dualYaxis && datum.push(yValue1.call(data, d, i)); + return datum; + }; + return data.map(function (d, i) { + return _datum(d, i); + }); + } + + function updateScales(data) { + // Update the x-scale. + xScale.domain(data.map(function (d) { + return d[0]; + })) + .rangePoints([0, innerW()], 1); + + // Update the y-scale. + yScale0.domain([0, d3.max(data, function (d) { + return d[1]; + })]) + .range([innerH(), 0]); + + // Update the y-scale. + dualYaxis && yScale1.domain([0, d3.max(data, function (d) { + return d[2]; + })]) + .range([innerH(), 0]); + } + + function toggleOpacity(ele, op) { + d3.select(ele.parentNode).selectAll('.' + (ele.getAttribute('data-yaxis') == 'y0' ? 'y1' : 'y0')).attr('style', op); + } + + function setLegendLabels(svg) { + // Legend Color + var rect = svg.selectAll('rect.legend.y0').data([null]); + rect.enter().append('rect') + .attr('class', 'legend y0') + .attr('data-yaxis', 'y0') + .on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }) + .on('mouseleave', function (d, i) { toggleOpacity(this, null); }) + .attr('y', (height - 15)); + rect + .attr('x', (width / 2) - 100); + + // Legend Labels + var text = svg.selectAll('text.legend.y0').data([null]); + text.enter().append('text') + .attr('class', 'legend y0') + .attr('data-yaxis', 'y0') + .on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }) + .on('mouseleave', function (d, i) { toggleOpacity(this, null); }) + .attr('y', (height - 6)); + text + .attr('x', (width / 2) - 85) + .text(labels.y0); + + if (!dualYaxis) + return; + + // Legend Labels + rect = svg.selectAll('rect.legend.y1').data([null]); + rect.enter().append('rect') + .attr('class', 'legend y1') + .attr('data-yaxis', 'y1') + .on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }) + .on('mouseleave', function (d, i) { toggleOpacity(this, null); }) + .attr('y', (height - 15)); + rect + .attr('x', (width / 2)); + + // Legend Labels + text = svg.selectAll('text.legend.y1').data([null]); + text.enter().append('text') + .attr('class', 'legend y1') + .attr('data-yaxis', 'y1') + .on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }) + .on('mouseleave', function (d, i) { toggleOpacity(this, null); }) + .attr('y', (height - 6)); + text + .attr('x', (width / 2) + 15) + .text(labels.y1); + } + + function setAxisLabels(svg) { + // Labels + svg.selectAll('text.axis-label.y0').data([null]) + .enter().append('text') + .attr('class', 'axis-label y0') + .attr('y', 10) + .attr('x', 53) + .text(labels.y0); + + if (!dualYaxis) + return; + + // Labels + var tEnter = svg.selectAll('text.axis-label.y1').data([null]); + tEnter.enter().append('text') + .attr('class', 'axis-label y1') + .attr('y', 10) + .text(labels.y1); + dualYaxis && tEnter + .attr('x', width - 25); + } + + function createSkeleton(svg) { + // Otherwise, create the skeletal chart. + var gEnter = svg.enter().append('svg').append('g'); + + // Lines + gEnter.append('g') + .attr('class', 'line line0 y0'); + dualYaxis && gEnter.append('g') + .attr('class', 'line line1 y1'); + + // Areas + gEnter.append('g') + .attr('class', 'area area0 y0'); + dualYaxis && gEnter.append('g') + .attr('class', 'area area1 y1'); + + // Points + gEnter.append('g') + .attr('class', 'points y0'); + dualYaxis && gEnter.append('g') + .attr('class', 'points y1'); + + // Grid + gEnter.append('g') + .attr('class', 'x grid'); + gEnter.append('g') + .attr('class', 'y grid'); + + // Axis + gEnter.append('g') + .attr('class', 'x axis'); + gEnter.append('g') + .attr('class', 'y0 axis'); + dualYaxis && gEnter.append('g') + .attr('class', 'y1 axis'); + + // Rects + gEnter.append('g') + .attr('class', 'rects'); + + setAxisLabels(svg); + setLegendLabels(svg); + + // Mouseover line + gEnter.append('line') + .attr('y2', innerH()) + .attr('y1', 0) + .attr('class', 'indicator'); + } + + function pathLen(d) { + return d.node().getTotalLength(); + } + + function addLine(g, data, line, cName) { + // Update the line path. + var path = g.select('g.' + cName).selectAll('path.' + cName) + .data([data]); + // enter + path + .enter() + .append('svg:path') + .attr('d', line) + .attr('class', cName) + .attr('stroke-dasharray', function (d) { + var pl = pathLen(d3.select(this)); + return pl + ' ' + pl; + }) + .attr('stroke-dashoffset', function (d) { + return pathLen(d3.select(this)); + }); + // update + path + .attr('d', line) + .transition() + .attr('stroke-dasharray', function (d) { + var pl = pathLen(d3.select(this)); + return pl + ' ' + pl; + }) + .duration(2000) + .attr('stroke-dashoffset', 0); + // remove elements + path.exit().remove(); + } + + function addArea(g, data, cb, cName) { + // Update the area path. + var area = g.select('g.' + cName).selectAll('path.' + cName) + .data([data]); + area + .enter() + .append('svg:path') + .attr('class', cName); + area + .attr('d', cb); + // remove elements + area.exit().remove(); + } + + // Update the area path and lines. + function addAreaLines(g, data) { + // Update the area path. + addArea(g, data, area0.y0(yScale0.range()[0]), 'area0'); + // Update the line path. + addLine(g, data, line0, 'line0'); + // Update the area path. + addArea(g, data, area1.y1(yScale1.range()[0]), 'area1'); + // Update the line path. + addLine(g, data, line1, 'line1'); + } + + // Update chart points + function addPoints(g, data) { + var radius = data.length > 100 ? 1 : 2.5; + + var points = g.select('g.points.y0').selectAll('circle.point') + .data(data); + points + .enter() + .append('svg:circle') + .attr('r', radius) + .attr('class', 'point'); + points + .attr('cx', function (d) { return xScale(d[0]); }) + .attr('cy', function (d) { return yScale0(d[1]); }); + // remove elements + points.exit().remove(); + + if (!dualYaxis) + return; + + points = g.select('g.points.y1').selectAll('circle.point') + .data(data); + points + .enter() + .append('svg:circle') + .attr('r', radius) + .attr('class', 'point'); + points + .attr('cx', function (d) { return xScale(d[0]); }) + .attr('cy', function (d) { return yScale1(d[2]); }); + // remove elements + points.exit().remove(); + } + + function addAxis(g, data) { + var xTicks = getXTicks(data); + var tickDistance = xTicks.length > 1 ? (xScale(xTicks[1]) - xScale(xTicks[0])) : innerW(); + var labelW = tickDistance - padding; + + // Update the x-axis. + g.select('.x.axis') + .attr('transform', 'translate(0,' + yScale0.range()[0] + ')') + .call(xAxis.tickValues(xTicks)) + .selectAll(".tick text") + .call(truncate, labelW > 0 ? labelW : innerW()); + + // Update the y0-axis. + g.select('.y0.axis') + .call(yAxis0.tickValues(getYTicks(yScale0))); + + if (!dualYaxis) + return; + + // Update the y1-axis. + g.select('.y1.axis') + .attr('transform', 'translate(' + innerW() + ', 0)') + .call(yAxis1.tickValues(getYTicks(yScale1))); + } + + // Update the X-Y grid. + function addGrid(g, data) { + g.select('.x.grid') + .attr('transform', 'translate(0,' + yScale0.range()[0] + ')') + .call(xGrid + .tickValues(getXTicks(data)) + .tickSize(-innerH(), 0, 0) + .tickFormat('') + ); + + g.select('.y.grid') + .call(yGrid + .tickValues(getYTicks(yScale0)) + .tickSize(-innerW(), 0, 0) + .tickFormat('') + ); + } + + function formatTooltip(data, i) { + var d = data.slice(0); + + d[0] = (format.x) ? GoAccess.Util.fmtValue(d[0], format.x) : d[0]; + d[1] = (format.y0) ? GoAccess.Util.fmtValue(d[1], format.y0) : d3.format(',')(d[1]); + dualYaxis && (d[2] = (format.y1) ? GoAccess.Util.fmtValue(d[2], format.y1) : d3.format(',')(d[2])); + + var template = d3.select('#tpl-chart-tooltip').html(); + return Hogan.compile(template).render({ + 'data': d + }); + } + + function mouseover(_self, selection, data, idx) { + var tooltip = selection.select('.chart-tooltip-wrap'); + tooltip.html(formatTooltip(data, idx)) + .style('left', (xScale(data[0])) + 'px') + .style('top', (d3.mouse(_self)[1] + 10) + 'px') + .style('display', 'block'); + + selection.select('line.indicator') + .style('display', 'block') + .attr('transform', 'translate(' + xScale(data[0]) + ',' + 0 + ')'); + } + + function mouseout(selection, g) { + var tooltip = selection.select('.chart-tooltip-wrap'); + tooltip.style('display', 'none'); + + g.select('line.indicator').style('display', 'none'); + } + + function addRects(selection, g, data) { + var w = (innerW() / data.length); + + var rects = g.select('g.rects').selectAll('rect') + .data(data); + rects + .enter() + .append('svg:rect') + .attr('height', innerH()) + .attr('class', 'point'); + rects + .attr('width', d3.functor(w)) + .attr('x', function (d, i) { return (w * i); }) + .attr('y', 0) + .on('mousemove', function (d, i) { + mouseover(this, selection, d, i); + }) + .on('mouseleave', function (d, i) { + mouseout(selection, g); + }); + // remove elements + rects.exit().remove(); + } + + function chart(selection) { + selection.each(function (data) { + // normalize data + data = mapData(data); + // updates X-Y scales + updateScales(data); + + // Select the svg element, if it exists. + var svg = d3.select(this).selectAll('svg').data([data]); + createSkeleton(svg); + + // Update the outer dimensions. + svg.attr({ + 'width': width, + 'height': height + }); + + // Update the inner dimensions. + var g = svg.select('g') + .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); + + // Add grid + addGrid(g, data); + // Add chart lines and areas + addAreaLines(g, data); + // Add chart points + addPoints(g, data); + // Add axis + addAxis(g, data); + // Add rects + addRects(selection, g, data); + }); + } + + chart.opts = function (_) { + if (!arguments.length) return opts; + opts = _; + return chart; + }; + + chart.format = function (_) { + if (!arguments.length) return format; + format = _; + return chart; + }; + + chart.labels = function (_) { + if (!arguments.length) return labels; + labels = _; + return chart; + }; + + chart.margin = function (_) { + if (!arguments.length) return margin; + margin = _; + return chart; + }; + + chart.width = function (_) { + if (!arguments.length) return width; + width = _; + return chart; + }; + + chart.height = function (_) { + if (!arguments.length) return height; + height = _; + return chart; + }; + + chart.x = function (_) { + if (!arguments.length) return xValue; + xValue = _; + return chart; + }; + + chart.y0 = function (_) { + if (!arguments.length) return yValue0; + yValue0 = _; + return chart; + }; + + chart.y1 = function (_) { + if (!arguments.length) return yValue1; + yValue1 = _; + return chart; + }; + + return chart; +} + +function BarChart(dualYaxis) { + var opts = {}; + var margin = { + top : 20, + right : 50, + bottom : 40, + left : 50, + }, + height = 170, + nTicks = 10, + padding = 10, + width = 760; + var labels = { x: 'Unnamed', y0: 'Unnamed', y1: 'Unnamed' }; + var format = { x: null, y0: null, y1: null}; + + var xValue = function (d) { + return d[0]; + }, + yValue0 = function (d) { + return d[1]; + }, + yValue1 = function (d) { + return d[2]; + }; + + var xScale = d3.scale.ordinal(); + var yScale0 = d3.scale.linear().nice(); + var yScale1 = d3.scale.linear().nice(); + + var xAxis = d3.svg.axis() + .scale(xScale) + .orient('bottom') + .tickFormat(function (d) { + if (format.x) + return GoAccess.Util.fmtValue(d, format.x); + return d; + }); + + var yAxis0 = d3.svg.axis() + .scale(yScale0) + .orient('left') + .tickFormat(function (d) { + return d3.format('.2s')(d); + }); + + var yAxis1 = d3.svg.axis() + .scale(yScale1) + .orient('right') + .tickFormat(function (d) { + if (format.y1) + return GoAccess.Util.fmtValue(d, format.y1); + return d3.format('.2s')(d); + }); + + var xGrid = d3.svg.axis() + .scale(xScale) + .orient('bottom'); + + var yGrid = d3.svg.axis() + .scale(yScale0) + .orient('left'); + + function innerW() { + return width - margin.left - margin.right; + } + + function innerH() { + return height - margin.top - margin.bottom; + } + + function getXTicks(data) { + if (data.length < nTicks) + return xScale.domain(); + + return d3.range(0, data.length, Math.ceil(data.length / nTicks)).map(function (d) { + return xScale.domain()[d]; + }); + } + + function getYTicks(scale) { + var domain = scale.domain(); + return d3.range(domain[0], domain[1], Math.ceil(domain[1] / nTicks)); + } + + // Convert data to standard representation greedily; + // this is needed for nondeterministic accessors. + function mapData(data) { + var _datum = function (d, i) { + var datum = [xValue.call(data, d, i), yValue0.call(data, d, i)]; + dualYaxis && datum.push(yValue1.call(data, d, i)); + return datum; + }; + return data.map(function (d, i) { + return _datum(d, i); + }); + } + + function updateScales(data) { + // Update the x-scale. + xScale.domain(data.map(function (d) { + return d[0]; + })) + .rangeBands([0, innerW()], 0.1); + + // Update the y-scale. + yScale0.domain([0, d3.max(data, function (d) { + return d[1]; + })]) + .range([innerH(), 0]); + + // Update the y-scale. + dualYaxis && yScale1.domain([0, d3.max(data, function (d) { + return d[2]; + })]) + .range([innerH(), 0]); + } + + function toggleOpacity(ele, op) { + d3.select(ele.parentNode).selectAll('.' + (ele.getAttribute('data-yaxis') == 'y0' ? 'y1' : 'y0')).attr('style', op); + } + + function setLegendLabels(svg) { + // Legend Color + var rect = svg.selectAll('rect.legend.y0').data([null]); + rect.enter().append('rect') + .attr('class', 'legend y0') + .attr('data-yaxis', 'y0') + .on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }) + .on('mouseleave', function (d, i) { toggleOpacity(this, null); }) + .attr('y', (height - 15)); + rect + .attr('x', (width / 2) - 100); + + // Legend Labels + var text = svg.selectAll('text.legend.y0').data([null]); + text.enter().append('text') + .attr('class', 'legend y0') + .attr('data-yaxis', 'y0') + .on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }) + .on('mouseleave', function (d, i) { toggleOpacity(this, null); }) + .attr('y', (height - 6)); + text + .attr('x', (width / 2) - 85) + .text(labels.y0); + + if (!dualYaxis) + return; + + // Legend Labels + rect = svg.selectAll('rect.legend.y1').data([null]); + rect.enter().append('rect') + .attr('class', 'legend y1') + .attr('data-yaxis', 'y1') + .on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }) + .on('mouseleave', function (d, i) { toggleOpacity(this, null); }) + .attr('y', (height - 15)); + rect + .attr('x', (width / 2)); + + // Legend Labels + text = svg.selectAll('text.legend.y1').data([null]); + text.enter().append('text') + .attr('class', 'legend y1') + .attr('data-yaxis', 'y1') + .on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }) + .on('mouseleave', function (d, i) { toggleOpacity(this, null); }) + .attr('y', (height - 6)); + text + .attr('x', (width / 2) + 15) + .text(labels.y1); + } + + function setAxisLabels(svg) { + // Labels + svg.selectAll('text.axis-label.y0').data([null]) + .enter().append('text') + .attr('class', 'axis-label y0') + .attr('y', 10) + .attr('x', 53) + .text(labels.y0); + + if (!dualYaxis) + return; + + // Labels + var tEnter = svg.selectAll('text.axis-label.y1').data([null]); + tEnter.enter().append('text') + .attr('class', 'axis-label y1') + .attr('y', 10) + .text(labels.y1); + dualYaxis && tEnter + .attr('x', width - 25); + } + + function createSkeleton(svg) { + // Otherwise, create the skeletal chart. + var gEnter = svg.enter().append('svg').append('g'); + + // Grid + gEnter.append('g') + .attr('class', 'x grid'); + gEnter.append('g') + .attr('class', 'y grid'); + + // Axis + gEnter.append('g') + .attr('class', 'x axis'); + gEnter.append('g') + .attr('class', 'y0 axis'); + dualYaxis && gEnter.append('g') + .attr('class', 'y1 axis'); + + // Bars + gEnter.append('g') + .attr('class', 'bars y0'); + dualYaxis && gEnter.append('g') + .attr('class', 'bars y1'); + + // Rects + gEnter.append('g') + .attr('class', 'rects'); + + setAxisLabels(svg); + setLegendLabels(svg); + + // Mouseover line + gEnter.append('line') + .attr('y2', innerH()) + .attr('y1', 0) + .attr('class', 'indicator'); + } + + // Update the area path and lines. + function addBars(g, data) { + var bars = g.select('g.bars.y0').selectAll('rect.bar') + .data(data); + // enter + bars + .enter() + .append('svg:rect') + .attr('class', 'bar') + .attr('height', 0) + .attr('width', function (d, i) { return xScale.rangeBand() / 2; }) + .attr('x', function (d, i) { return xScale(d[0]); }) + .attr('y', function (d, i) { return innerH(); }); + // update + bars + .attr('width', xScale.rangeBand() / 2) + .attr('x', function (d) { return xScale(d[0]); }) + .transition() + .delay(function (d, i) { return i / data.length * 1000; }) + .duration(500) + .attr('height', function (d, i) { return innerH() - yScale0(d[1]); }) + .attr('y', function (d, i) { return yScale0(d[1]); }); + // remove elements + bars.exit().remove(); + + if (!dualYaxis) + return; + + bars = g.select('g.bars.y1').selectAll('rect.bar') + .data(data); + // enter + bars + .enter() + .append('svg:rect') + .attr('class', 'bar') + .attr('height', 0) + .attr('width', function (d, i) { return xScale.rangeBand() / 2; }) + .attr('x', function (d) { return (xScale(d[0]) + xScale.rangeBand() / 2); }) + .attr('y', function (d, i) { return innerH(); }); + // update + bars + .attr('width', xScale.rangeBand() / 2) + .attr('x', function (d) { return (xScale(d[0]) + xScale.rangeBand() / 2); }) + .transition() + .delay(function (d, i) { return i / data.length * 1000; }) + .duration(500) + .attr('height', function (d, i) { return innerH() - yScale1(d[2]); }) + .attr('y', function (d, i) { return yScale1(d[2]); }); + // remove elements + bars.exit().remove(); + } + + function addAxis(g, data) { + var xTicks = getXTicks(data); + var tickDistance = xTicks.length > 1 ? (xScale(xTicks[1]) - xScale(xTicks[0])) : innerW(); + var labelW = tickDistance - padding; + + // Update the x-axis. + g.select('.x.axis') + .attr('transform', 'translate(0,' + yScale0.range()[0] + ')') + .call(xAxis.tickValues(xTicks)) + .selectAll(".tick text") + .call(truncate, labelW > 0 ? labelW : innerW()); + + // Update the y0-axis. + g.select('.y0.axis') + .call(yAxis0.tickValues(getYTicks(yScale0))); + + if (!dualYaxis) + return; + + // Update the y1-axis. + g.select('.y1.axis') + .attr('transform', 'translate(' + innerW() + ', 0)') + .call(yAxis1.tickValues(getYTicks(yScale1))); + } + + // Update the X-Y grid. + function addGrid(g, data) { + g.select('.x.grid') + .attr('transform', 'translate(0,' + yScale0.range()[0] + ')') + .call(xGrid + .tickValues(getXTicks(data)) + .tickSize(-innerH(), 0, 0) + .tickFormat('') + ); + + g.select('.y.grid') + .call(yGrid + .tickValues(getYTicks(yScale0)) + .tickSize(-innerW(), 0, 0) + .tickFormat('') + ); + } + + function formatTooltip(data, i) { + var d = data.slice(0); + + d[0] = (format.x) ? GoAccess.Util.fmtValue(d[0], format.x) : d[0]; + d[1] = (format.y0) ? GoAccess.Util.fmtValue(d[1], format.y0) : d3.format(',')(d[1]); + dualYaxis && (d[2] = (format.y1) ? GoAccess.Util.fmtValue(d[2], format.y1) : d3.format(',')(d[2])); + + var template = d3.select('#tpl-chart-tooltip').html(); + return Hogan.compile(template).render({ + 'data': d + }); + } + + function mouseover(_self, selection, data, idx) { + var left = xScale(data[0]) + (xScale.rangeBand() / 2); + var tooltip = selection.select('.chart-tooltip-wrap'); + tooltip.html(formatTooltip(data, idx)) + .style('left', left + 'px') + .style('top', (d3.mouse(_self)[1] + 10) + 'px') + .style('display', 'block'); + + selection.select('line.indicator') + .style('display', 'block') + .attr('transform', 'translate(' + left + ',' + 0 + ')'); + } + + function mouseout(selection, g) { + var tooltip = selection.select('.chart-tooltip-wrap'); + tooltip.style('display', 'none'); + + g.select('line.indicator').style('display', 'none'); + } + + function addRects(selection, g, data) { + var w = (innerW() / data.length); + + var rects = g.select('g.rects').selectAll('rect') + .data(data); + rects + .enter() + .append('svg:rect') + .attr('height', innerH()) + .attr('class', 'point'); + rects + .attr('width', d3.functor(w)) + .attr('x', function (d, i) { return (w * i); }) + .attr('y', 0) + .on('mousemove', function (d, i) { + mouseover(this, selection, d, i); + }) + .on('mouseleave', function (d, i) { + mouseout(selection, g); + }); + // remove elements + rects.exit().remove(); + } + + function chart(selection) { + selection.each(function (data) { + // normalize data + data = mapData(data); + // updates X-Y scales + updateScales(data); + + // Select the svg element, if it exists. + var svg = d3.select(this).selectAll('svg').data([data]); + createSkeleton(svg); + + // Update the outer dimensions. + svg.attr({ + 'width': width, + 'height': height + }); + + // Update the inner dimensions. + var g = svg.select('g') + .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); + + // Add grid + addGrid(g, data); + // Add axis + addAxis(g, data); + // Add chart lines and areas + addBars(g, data); + // Add rects + addRects(selection, g, data); + }); + } + + chart.opts = function (_) { + if (!arguments.length) return opts; + opts = _; + return chart; + }; + + chart.format = function (_) { + if (!arguments.length) return format; + format = _; + return chart; + }; + + chart.labels = function (_) { + if (!arguments.length) return labels; + labels = _; + return chart; + }; + + chart.width = function (_) { + if (!arguments.length) return width; + width = _; + return chart; + }; + + chart.height = function (_) { + if (!arguments.length) return height; + height = _; + return chart; + }; + + chart.x = function (_) { + if (!arguments.length) return xValue; + xValue = _; + return chart; + }; + + chart.y0 = function (_) { + if (!arguments.length) return yValue0; + yValue0 = _; + return chart; + }; + + chart.y1 = function (_) { + if (!arguments.length) return yValue1; + yValue1 = _; + return chart; + }; + + return chart; +} diff --git a/goaccess++/resources/js/charts.js.tmp b/goaccess++/resources/js/charts.js.tmp new file mode 100644 index 0000000..c9ee93d --- /dev/null +++ b/goaccess++/resources/js/charts.js.tmp @@ -0,0 +1 @@ +/*** ______ ___* / ____/___ / | _____________ __________* / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/* / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ )* \____/\____/_/ |_\___/\___/\___/____/____/** The MIT License (MIT)* Copyright (c) 2009-2018 Gerardo Orellana <hello @ goaccess.io>*/'use strict';function truncate(text, width) {text.each(function () {var parent = this.parentNode, $d3parent = d3.select(parent);var gw = $d3parent.node().getBBox();var x = (Math.min(gw.width, width) / 2) * -1;if ('svg' == parent.nodeName) {$d3parent.attr('width', width).attr('x', x);}else {$d3parent.insert('svg', function () {return this;}.bind(this)).attr('class', 'wrap-text').attr('width', width).attr('x', x).append(function () {return this;}.bind(this));}});}function AreaChart(dualYaxis) {var opts = {};var margin = {top : 20,right : 50,bottom : 40,left : 50,},height = 170,nTicks = 10,padding = 10,width = 760;var labels = { x: 'Unnamed', y0: 'Unnamed', y1: 'Unnamed' };var format = { x: null, y0: null, y1: null};var xValue = function (d) {return d[0];},yValue0 = function (d) {return d[1];},yValue1 = function (d) {return d[2];};var xScale = d3.scale.ordinal();var yScale0 = d3.scale.linear().nice();var yScale1 = d3.scale.linear().nice();var xAxis = d3.svg.axis().scale(xScale).orient('bottom').tickFormat(function (d) {if (format.x)return GoAccess.Util.fmtValue(d, format.x);return d;});var yAxis0 = d3.svg.axis().scale(yScale0).orient('left').tickFormat(function (d) {return d3.format('.2s')(d);});var yAxis1 = d3.svg.axis().scale(yScale1).orient('right').tickFormat(function (d) {if (format.y1)return GoAccess.Util.fmtValue(d, format.y1);return d3.format('.2s')(d);});var xGrid = d3.svg.axis().scale(xScale).orient('bottom');var yGrid = d3.svg.axis().scale(yScale0).orient('left');var area0 = d3.svg.area().interpolate('cardinal').x(X).y(Y0);var area1 = d3.svg.area().interpolate('cardinal').x(X).y(Y1);var line0 = d3.svg.line().interpolate('cardinal').x(X).y(Y0);var line1 = d3.svg.line().interpolate('cardinal').x(X).y(Y1);function X(d) {return xScale(d[0]);}function Y0(d) {return yScale0(d[1]);}function Y1(d) {return yScale1(d[2]);}function innerW() {return width - margin.left - margin.right;}function innerH() {return height - margin.top - margin.bottom;}function getXTicks(data) {if (data.length < nTicks)return xScale.domain();return d3.range(0, data.length, Math.ceil(data.length / nTicks)).map(function (d) {return xScale.domain()[d];});}function getYTicks(scale) {var domain = scale.domain();return d3.range(domain[0], domain[1], Math.ceil(domain[1] / nTicks));}function mapData(data) {var _datum = function (d, i) {var datum = [xValue.call(data, d, i), yValue0.call(data, d, i)];dualYaxis && datum.push(yValue1.call(data, d, i));return datum;};return data.map(function (d, i) {return _datum(d, i);});}function updateScales(data) {xScale.domain(data.map(function (d) {return d[0];})).rangePoints([0, innerW()], 1);yScale0.domain([0, d3.max(data, function (d) {return d[1];})]).range([innerH(), 0]);dualYaxis && yScale1.domain([0, d3.max(data, function (d) {return d[2];})]).range([innerH(), 0]);}function toggleOpacity(ele, op) {d3.select(ele.parentNode).selectAll('.' + (ele.getAttribute('data-yaxis') == 'y0' ? 'y1' : 'y0')).attr('style', op);}function setLegendLabels(svg) {var rect = svg.selectAll('rect.legend.y0').data([null]);rect.enter().append('rect').attr('class', 'legend y0').attr('data-yaxis', 'y0').on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }).on('mouseleave', function (d, i) { toggleOpacity(this, null); }).attr('y', (height - 15));rect.attr('x', (width / 2) - 100);var text = svg.selectAll('text.legend.y0').data([null]);text.enter().append('text').attr('class', 'legend y0').attr('data-yaxis', 'y0').on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }).on('mouseleave', function (d, i) { toggleOpacity(this, null); }).attr('y', (height - 6));text.attr('x', (width / 2) - 85).text(labels.y0);if (!dualYaxis)return;rect = svg.selectAll('rect.legend.y1').data([null]);rect.enter().append('rect').attr('class', 'legend y1').attr('data-yaxis', 'y1').on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }).on('mouseleave', function (d, i) { toggleOpacity(this, null); }).attr('y', (height - 15));rect.attr('x', (width / 2));text = svg.selectAll('text.legend.y1').data([null]);text.enter().append('text').attr('class', 'legend y1').attr('data-yaxis', 'y1').on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }).on('mouseleave', function (d, i) { toggleOpacity(this, null); }).attr('y', (height - 6));text.attr('x', (width / 2) + 15).text(labels.y1);}function setAxisLabels(svg) {svg.selectAll('text.axis-label.y0').data([null]).enter().append('text').attr('class', 'axis-label y0').attr('y', 10).attr('x', 53).text(labels.y0);if (!dualYaxis)return;var tEnter = svg.selectAll('text.axis-label.y1').data([null]);tEnter.enter().append('text').attr('class', 'axis-label y1').attr('y', 10).text(labels.y1);dualYaxis && tEnter.attr('x', width - 25);}function createSkeleton(svg) {var gEnter = svg.enter().append('svg').append('g');gEnter.append('g').attr('class', 'line line0 y0');dualYaxis && gEnter.append('g').attr('class', 'line line1 y1');gEnter.append('g').attr('class', 'area area0 y0');dualYaxis && gEnter.append('g').attr('class', 'area area1 y1');gEnter.append('g').attr('class', 'points y0');dualYaxis && gEnter.append('g').attr('class', 'points y1');gEnter.append('g').attr('class', 'x grid');gEnter.append('g').attr('class', 'y grid');gEnter.append('g').attr('class', 'x axis');gEnter.append('g').attr('class', 'y0 axis');dualYaxis && gEnter.append('g').attr('class', 'y1 axis');gEnter.append('g').attr('class', 'rects');setAxisLabels(svg);setLegendLabels(svg);gEnter.append('line').attr('y2', innerH()).attr('y1', 0).attr('class', 'indicator');}function pathLen(d) {return d.node().getTotalLength();}function addLine(g, data, line, cName) {var path = g.select('g.' + cName).selectAll('path.' + cName).data([data]);path.enter().append('svg:path').attr('d', line).attr('class', cName).attr('stroke-dasharray', function (d) {var pl = pathLen(d3.select(this));return pl + ' ' + pl;}).attr('stroke-dashoffset', function (d) {return pathLen(d3.select(this));});path.attr('d', line).transition().attr('stroke-dasharray', function (d) {var pl = pathLen(d3.select(this));return pl + ' ' + pl;}).duration(2000).attr('stroke-dashoffset', 0);path.exit().remove();}function addArea(g, data, cb, cName) {var area = g.select('g.' + cName).selectAll('path.' + cName).data([data]);area.enter().append('svg:path').attr('class', cName);area.attr('d', cb);area.exit().remove();}function addAreaLines(g, data) {addArea(g, data, area0.y0(yScale0.range()[0]), 'area0');addLine(g, data, line0, 'line0');addArea(g, data, area1.y1(yScale1.range()[0]), 'area1');addLine(g, data, line1, 'line1');}function addPoints(g, data) {var radius = data.length > 100 ? 1 : 2.5;var points = g.select('g.points.y0').selectAll('circle.point').data(data);points.enter().append('svg:circle').attr('r', radius).attr('class', 'point');points.attr('cx', function (d) { return xScale(d[0]); }).attr('cy', function (d) { return yScale0(d[1]); });points.exit().remove();if (!dualYaxis)return;points = g.select('g.points.y1').selectAll('circle.point').data(data);points.enter().append('svg:circle').attr('r', radius).attr('class', 'point');points.attr('cx', function (d) { return xScale(d[0]); }).attr('cy', function (d) { return yScale1(d[2]); });points.exit().remove();}function addAxis(g, data) {var xTicks = getXTicks(data);var tickDistance = xTicks.length > 1 ? (xScale(xTicks[1]) - xScale(xTicks[0])) : innerW();var labelW = tickDistance - padding;g.select('.x.axis').attr('transform', 'translate(0,' + yScale0.range()[0] + ')').call(xAxis.tickValues(xTicks)).selectAll(".tick text").call(truncate, labelW > 0 ? labelW : innerW());g.select('.y0.axis').call(yAxis0.tickValues(getYTicks(yScale0)));if (!dualYaxis)return;g.select('.y1.axis').attr('transform', 'translate(' + innerW() + ', 0)').call(yAxis1.tickValues(getYTicks(yScale1)));}function addGrid(g, data) {g.select('.x.grid').attr('transform', 'translate(0,' + yScale0.range()[0] + ')').call(xGrid.tickValues(getXTicks(data)).tickSize(-innerH(), 0, 0).tickFormat(''));g.select('.y.grid').call(yGrid.tickValues(getYTicks(yScale0)).tickSize(-innerW(), 0, 0).tickFormat(''));}function formatTooltip(data, i) {var d = data.slice(0);d[0] = (format.x) ? GoAccess.Util.fmtValue(d[0], format.x) : d[0];d[1] = (format.y0) ? GoAccess.Util.fmtValue(d[1], format.y0) : d3.format(',')(d[1]);dualYaxis && (d[2] = (format.y1) ? GoAccess.Util.fmtValue(d[2], format.y1) : d3.format(',')(d[2]));var template = d3.select('#tpl-chart-tooltip').html();return Hogan.compile(template).render({'data': d});}function mouseover(_self, selection, data, idx) {var tooltip = selection.select('.chart-tooltip-wrap');tooltip.html(formatTooltip(data, idx)).style('left', (xScale(data[0])) + 'px').style('top', (d3.mouse(_self)[1] + 10) + 'px').style('display', 'block');selection.select('line.indicator').style('display', 'block').attr('transform', 'translate(' + xScale(data[0]) + ',' + 0 + ')');}function mouseout(selection, g) {var tooltip = selection.select('.chart-tooltip-wrap');tooltip.style('display', 'none');g.select('line.indicator').style('display', 'none');}function addRects(selection, g, data) {var w = (innerW() / data.length);var rects = g.select('g.rects').selectAll('rect').data(data);rects.enter().append('svg:rect').attr('height', innerH()).attr('class', 'point');rects.attr('width', d3.functor(w)).attr('x', function (d, i) { return (w * i); }).attr('y', 0).on('mousemove', function (d, i) {mouseover(this, selection, d, i);}).on('mouseleave', function (d, i) {mouseout(selection, g);});rects.exit().remove();}function chart(selection) {selection.each(function (data) {data = mapData(data);updateScales(data);var svg = d3.select(this).selectAll('svg').data([data]);createSkeleton(svg);svg.attr({'width': width,'height': height});var g = svg.select('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');addGrid(g, data);addAreaLines(g, data);addPoints(g, data);addAxis(g, data);addRects(selection, g, data);});}chart.opts = function (_) {if (!arguments.length) return opts;opts = _;return chart;};chart.format = function (_) {if (!arguments.length) return format;format = _;return chart;};chart.labels = function (_) {if (!arguments.length) return labels;labels = _;return chart;};chart.margin = function (_) {if (!arguments.length) return margin;margin = _;return chart;};chart.width = function (_) {if (!arguments.length) return width;width = _;return chart;};chart.height = function (_) {if (!arguments.length) return height;height = _;return chart;};chart.x = function (_) {if (!arguments.length) return xValue;xValue = _;return chart;};chart.y0 = function (_) {if (!arguments.length) return yValue0;yValue0 = _;return chart;};chart.y1 = function (_) {if (!arguments.length) return yValue1;yValue1 = _;return chart;};return chart;}function BarChart(dualYaxis) {var opts = {};var margin = {top : 20,right : 50,bottom : 40,left : 50,},height = 170,nTicks = 10,padding = 10,width = 760;var labels = { x: 'Unnamed', y0: 'Unnamed', y1: 'Unnamed' };var format = { x: null, y0: null, y1: null};var xValue = function (d) {return d[0];},yValue0 = function (d) {return d[1];},yValue1 = function (d) {return d[2];};var xScale = d3.scale.ordinal();var yScale0 = d3.scale.linear().nice();var yScale1 = d3.scale.linear().nice();var xAxis = d3.svg.axis().scale(xScale).orient('bottom').tickFormat(function (d) {if (format.x)return GoAccess.Util.fmtValue(d, format.x);return d;});var yAxis0 = d3.svg.axis().scale(yScale0).orient('left').tickFormat(function (d) {return d3.format('.2s')(d);});var yAxis1 = d3.svg.axis().scale(yScale1).orient('right').tickFormat(function (d) {if (format.y1)return GoAccess.Util.fmtValue(d, format.y1);return d3.format('.2s')(d);});var xGrid = d3.svg.axis().scale(xScale).orient('bottom');var yGrid = d3.svg.axis().scale(yScale0).orient('left');function innerW() {return width - margin.left - margin.right;}function innerH() {return height - margin.top - margin.bottom;}function getXTicks(data) {if (data.length < nTicks)return xScale.domain();return d3.range(0, data.length, Math.ceil(data.length / nTicks)).map(function (d) {return xScale.domain()[d];});}function getYTicks(scale) {var domain = scale.domain();return d3.range(domain[0], domain[1], Math.ceil(domain[1] / nTicks));}function mapData(data) {var _datum = function (d, i) {var datum = [xValue.call(data, d, i), yValue0.call(data, d, i)];dualYaxis && datum.push(yValue1.call(data, d, i));return datum;};return data.map(function (d, i) {return _datum(d, i);});}function updateScales(data) {xScale.domain(data.map(function (d) {return d[0];})).rangeBands([0, innerW()], 0.1);yScale0.domain([0, d3.max(data, function (d) {return d[1];})]).range([innerH(), 0]);dualYaxis && yScale1.domain([0, d3.max(data, function (d) {return d[2];})]).range([innerH(), 0]);}function toggleOpacity(ele, op) {d3.select(ele.parentNode).selectAll('.' + (ele.getAttribute('data-yaxis') == 'y0' ? 'y1' : 'y0')).attr('style', op);}function setLegendLabels(svg) {var rect = svg.selectAll('rect.legend.y0').data([null]);rect.enter().append('rect').attr('class', 'legend y0').attr('data-yaxis', 'y0').on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }).on('mouseleave', function (d, i) { toggleOpacity(this, null); }).attr('y', (height - 15));rect.attr('x', (width / 2) - 100);var text = svg.selectAll('text.legend.y0').data([null]);text.enter().append('text').attr('class', 'legend y0').attr('data-yaxis', 'y0').on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }).on('mouseleave', function (d, i) { toggleOpacity(this, null); }).attr('y', (height - 6));text.attr('x', (width / 2) - 85).text(labels.y0);if (!dualYaxis)return;rect = svg.selectAll('rect.legend.y1').data([null]);rect.enter().append('rect').attr('class', 'legend y1').attr('data-yaxis', 'y1').on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }).on('mouseleave', function (d, i) { toggleOpacity(this, null); }).attr('y', (height - 15));rect.attr('x', (width / 2));text = svg.selectAll('text.legend.y1').data([null]);text.enter().append('text').attr('class', 'legend y1').attr('data-yaxis', 'y1').on('mousemove', function (d, i) { toggleOpacity(this, 'opacity:0.1'); }).on('mouseleave', function (d, i) { toggleOpacity(this, null); }).attr('y', (height - 6));text.attr('x', (width / 2) + 15).text(labels.y1);}function setAxisLabels(svg) {svg.selectAll('text.axis-label.y0').data([null]).enter().append('text').attr('class', 'axis-label y0').attr('y', 10).attr('x', 53).text(labels.y0);if (!dualYaxis)return;var tEnter = svg.selectAll('text.axis-label.y1').data([null]);tEnter.enter().append('text').attr('class', 'axis-label y1').attr('y', 10).text(labels.y1);dualYaxis && tEnter.attr('x', width - 25);}function createSkeleton(svg) {var gEnter = svg.enter().append('svg').append('g');gEnter.append('g').attr('class', 'x grid');gEnter.append('g').attr('class', 'y grid');gEnter.append('g').attr('class', 'x axis');gEnter.append('g').attr('class', 'y0 axis');dualYaxis && gEnter.append('g').attr('class', 'y1 axis');gEnter.append('g').attr('class', 'bars y0');dualYaxis && gEnter.append('g').attr('class', 'bars y1');gEnter.append('g').attr('class', 'rects');setAxisLabels(svg);setLegendLabels(svg);gEnter.append('line').attr('y2', innerH()).attr('y1', 0).attr('class', 'indicator');}function addBars(g, data) {var bars = g.select('g.bars.y0').selectAll('rect.bar').data(data);bars.enter().append('svg:rect').attr('class', 'bar').attr('height', 0).attr('width', function (d, i) { return xScale.rangeBand() / 2; }).attr('x', function (d, i) { return xScale(d[0]); }).attr('y', function (d, i) { return innerH(); });bars.attr('width', xScale.rangeBand() / 2).attr('x', function (d) { return xScale(d[0]); }).transition().delay(function (d, i) { return i / data.length * 1000; }).duration(500).attr('height', function (d, i) { return innerH() - yScale0(d[1]); }).attr('y', function (d, i) { return yScale0(d[1]); });bars.exit().remove();if (!dualYaxis)return;bars = g.select('g.bars.y1').selectAll('rect.bar').data(data);bars.enter().append('svg:rect').attr('class', 'bar').attr('height', 0).attr('width', function (d, i) { return xScale.rangeBand() / 2; }).attr('x', function (d) { return (xScale(d[0]) + xScale.rangeBand() / 2); }).attr('y', function (d, i) { return innerH(); });bars.attr('width', xScale.rangeBand() / 2).attr('x', function (d) { return (xScale(d[0]) + xScale.rangeBand() / 2); }).transition().delay(function (d, i) { return i / data.length * 1000; }).duration(500).attr('height', function (d, i) { return innerH() - yScale1(d[2]); }).attr('y', function (d, i) { return yScale1(d[2]); });bars.exit().remove();}function addAxis(g, data) {var xTicks = getXTicks(data);var tickDistance = xTicks.length > 1 ? (xScale(xTicks[1]) - xScale(xTicks[0])) : innerW();var labelW = tickDistance - padding;g.select('.x.axis').attr('transform', 'translate(0,' + yScale0.range()[0] + ')').call(xAxis.tickValues(xTicks)).selectAll(".tick text").call(truncate, labelW > 0 ? labelW : innerW());g.select('.y0.axis').call(yAxis0.tickValues(getYTicks(yScale0)));if (!dualYaxis)return;g.select('.y1.axis').attr('transform', 'translate(' + innerW() + ', 0)').call(yAxis1.tickValues(getYTicks(yScale1)));}function addGrid(g, data) {g.select('.x.grid').attr('transform', 'translate(0,' + yScale0.range()[0] + ')').call(xGrid.tickValues(getXTicks(data)).tickSize(-innerH(), 0, 0).tickFormat(''));g.select('.y.grid').call(yGrid.tickValues(getYTicks(yScale0)).tickSize(-innerW(), 0, 0).tickFormat(''));}function formatTooltip(data, i) {var d = data.slice(0);d[0] = (format.x) ? GoAccess.Util.fmtValue(d[0], format.x) : d[0];d[1] = (format.y0) ? GoAccess.Util.fmtValue(d[1], format.y0) : d3.format(',')(d[1]);dualYaxis && (d[2] = (format.y1) ? GoAccess.Util.fmtValue(d[2], format.y1) : d3.format(',')(d[2]));var template = d3.select('#tpl-chart-tooltip').html();return Hogan.compile(template).render({'data': d});}function mouseover(_self, selection, data, idx) {var left = xScale(data[0]) + (xScale.rangeBand() / 2);var tooltip = selection.select('.chart-tooltip-wrap');tooltip.html(formatTooltip(data, idx)).style('left', left + 'px').style('top', (d3.mouse(_self)[1] + 10) + 'px').style('display', 'block');selection.select('line.indicator').style('display', 'block').attr('transform', 'translate(' + left + ',' + 0 + ')');}function mouseout(selection, g) {var tooltip = selection.select('.chart-tooltip-wrap');tooltip.style('display', 'none');g.select('line.indicator').style('display', 'none');}function addRects(selection, g, data) {var w = (innerW() / data.length);var rects = g.select('g.rects').selectAll('rect').data(data);rects.enter().append('svg:rect').attr('height', innerH()).attr('class', 'point');rects.attr('width', d3.functor(w)).attr('x', function (d, i) { return (w * i); }).attr('y', 0).on('mousemove', function (d, i) {mouseover(this, selection, d, i);}).on('mouseleave', function (d, i) {mouseout(selection, g);});rects.exit().remove();}function chart(selection) {selection.each(function (data) {data = mapData(data);updateScales(data);var svg = d3.select(this).selectAll('svg').data([data]);createSkeleton(svg);svg.attr({'width': width,'height': height});var g = svg.select('g').attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');addGrid(g, data);addAxis(g, data);addBars(g, data);addRects(selection, g, data);});}chart.opts = function (_) {if (!arguments.length) return opts;opts = _;return chart;};chart.format = function (_) {if (!arguments.length) return format;format = _;return chart;};chart.labels = function (_) {if (!arguments.length) return labels;labels = _;return chart;};chart.width = function (_) {if (!arguments.length) return width;width = _;return chart;};chart.height = function (_) {if (!arguments.length) return height;height = _;return chart;};chart.x = function (_) {if (!arguments.length) return xValue;xValue = _;return chart;};chart.y0 = function (_) {if (!arguments.length) return yValue0;yValue0 = _;return chart;};chart.y1 = function (_) {if (!arguments.length) return yValue1;yValue1 = _;return chart;};return chart;} \ No newline at end of file diff --git a/goaccess++/resources/js/d3.v3.min.js b/goaccess++/resources/js/d3.v3.min.js new file mode 100644 index 0000000..1984d17 --- /dev/null +++ b/goaccess++/resources/js/d3.v3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c +},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r +},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.6"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Dl.call(this),v=e(d=m||ta.mouse(this)),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t +},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5)); +return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/goaccess++/resources/js/d3.v3.min.js.tmp b/goaccess++/resources/js/d3.v3.min.js.tmp new file mode 100644 index 0000000..e0383a1 --- /dev/null +++ b/goaccess++/resources/js/d3.v3.min.js.tmp @@ -0,0 +1 @@ +!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.6"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||(n({type:"zoomend"}),d=null)}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(Dl.call(this),v=e(d=m||ta.mouse(this)),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t.toLowerCase())||/^(#|rgb\(|hsl\()/i.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/goaccess++/resources/js/hogan.min.js b/goaccess++/resources/js/hogan.min.js new file mode 100644 index 0000000..437c5d4 --- /dev/null +++ b/goaccess++/resources/js/hogan.min.js @@ -0,0 +1,5 @@ +/** +* @preserve Copyright 2012 Twitter, Inc. +* @license http://www.apache.org/licenses/LICENSE-2.0.txt +*/ +var Hogan={};!function(t){function n(t,n,e){var i;return n&&"object"==typeof n&&(void 0!==n[t]?i=n[t]:e&&n.get&&"function"==typeof n.get&&(i=n.get(t))),i}function e(t,n,e,i,r,s){function a(){}function o(){}a.prototype=t,o.prototype=t.subs;var u,c=new a;c.subs=new o,c.subsText={},c.buf="",i=i||{},c.stackSubs=i,c.subsText=s;for(u in n)i[u]||(i[u]=n[u]);for(u in i)c.subs[u]=i[u];r=r||{},c.stackPartials=r;for(u in e)r[u]||(r[u]=e[u]);for(u in r)c.partials[u]=r[u];return c}function i(t){return String(null===t||void 0===t?"":t)}function r(t){return t=i(t),l.test(t)?t.replace(s,"&").replace(a,"<").replace(o,">").replace(u,"'").replace(c,"""):t}t.Template=function(t,n,e,i){t=t||{},this.r=t.code||this.r,this.c=e,this.options=i||{},this.text=n||"",this.partials=t.partials||{},this.subs=t.subs||{},this.buf=""},t.Template.prototype={r:function(){return""},v:r,t:i,render:function(t,n,e){return this.ri([t],n||{},e)},ri:function(t,n,e){return this.r(t,n,e)},ep:function(t,n){var i=this.partials[t],r=n[i.name];if(i.instance&&i.base==r)return i.instance;if("string"==typeof r){if(!this.c)throw new Error("No compiler available.");r=this.c.compile(r,this.options)}if(!r)return null;if(this.partials[t].base=r,i.subs){n.stackText||(n.stackText={});for(key in i.subs)n.stackText[key]||(n.stackText[key]=void 0!==this.activeSub&&n.stackText[this.activeSub]?n.stackText[this.activeSub]:this.text);r=e(r,i.subs,i.partials,this.stackSubs,this.stackPartials,n.stackText)}return this.partials[t].instance=r,r},rp:function(t,n,e,i){var r=this.ep(t,e);return r?r.ri(n,e,i):""},rs:function(t,n,e){var i=t[t.length-1];if(!f(i))return void e(t,n,this);for(var r=0;r<i.length;r++)t.push(i[r]),e(t,n,this),t.pop()},s:function(t,n,e,i,r,s,a){var o;return f(t)&&0===t.length?!1:("function"==typeof t&&(t=this.ms(t,n,e,i,r,s,a)),o=!!t,!i&&o&&n&&n.push("object"==typeof t?t:n[n.length-1]),o)},d:function(t,e,i,r){var s,a=t.split("."),o=this.f(a[0],e,i,r),u=this.options.modelGet,c=null;if("."===t&&f(e[e.length-2]))o=e[e.length-1];else for(var l=1;l<a.length;l++)s=n(a[l],o,u),void 0!==s?(c=o,o=s):o="";return r&&!o?!1:(r||"function"!=typeof o||(e.push(c),o=this.mv(o,e,i),e.pop()),o)},f:function(t,e,i,r){for(var s=!1,a=null,o=!1,u=this.options.modelGet,c=e.length-1;c>=0;c--)if(a=e[c],s=n(t,a,u),void 0!==s){o=!0;break}return o?(r||"function"!=typeof s||(s=this.mv(s,e,i)),s):r?!1:""},ls:function(t,n,e,r,s){var a=this.options.delimiters;return this.options.delimiters=s,this.b(this.ct(i(t.call(n,r)),n,e)),this.options.delimiters=a,!1},ct:function(t,n,e){if(this.options.disableLambda)throw new Error("Lambda features disabled.");return this.c.compile(t,this.options).render(n,e)},b:function(t){this.buf+=t},fl:function(){var t=this.buf;return this.buf="",t},ms:function(t,n,e,i,r,s,a){var o,u=n[n.length-1],c=t.call(u);return"function"==typeof c?i?!0:(o=this.activeSub&&this.subsText&&this.subsText[this.activeSub]?this.subsText[this.activeSub]:this.text,this.ls(c,u,e,o.substring(r,s),a)):c},mv:function(t,n,e){var r=n[n.length-1],s=t.call(r);return"function"==typeof s?this.ct(i(s.call(r)),r,e):s},sub:function(t,n,e,i){var r=this.subs[t];r&&(this.activeSub=t,r(n,e,this,i),this.activeSub=!1)}};var s=/&/g,a=/</g,o=/>/g,u=/\'/g,c=/\"/g,l=/[&<>\"\']/,f=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)}}("undefined"!=typeof exports?exports:Hogan),function(t){function n(t){"}"===t.n.substr(t.n.length-1)&&(t.n=t.n.substring(0,t.n.length-1))}function e(t){return t.trim?t.trim():t.replace(/^\s*|\s*$/g,"")}function i(t,n,e){if(n.charAt(e)!=t.charAt(0))return!1;for(var i=1,r=t.length;r>i;i++)if(n.charAt(e+i)!=t.charAt(i))return!1;return!0}function r(n,e,i,o){var u=[],c=null,l=null,f=null;for(l=i[i.length-1];n.length>0;){if(f=n.shift(),l&&"<"==l.tag&&!(f.tag in k))throw new Error("Illegal content in < super tag.");if(t.tags[f.tag]<=t.tags.$||s(f,o))i.push(f),f.nodes=r(n,f.tag,i,o);else{if("/"==f.tag){if(0===i.length)throw new Error("Closing tag without opener: /"+f.n);if(c=i.pop(),f.n!=c.n&&!a(f.n,c.n,o))throw new Error("Nesting error: "+c.n+" vs. "+f.n);return c.end=f.i,u}"\n"==f.tag&&(f.last=0==n.length||"\n"==n[0].tag)}u.push(f)}if(i.length>0)throw new Error("missing closing tag: "+i.pop().n);return u}function s(t,n){for(var e=0,i=n.length;i>e;e++)if(n[e].o==t.n)return t.tag="#",!0}function a(t,n,e){for(var i=0,r=e.length;r>i;i++)if(e[i].c==t&&e[i].o==n)return!0}function o(t){var n=[];for(var e in t)n.push('"'+c(e)+'": function(c,p,t,i) {'+t[e]+"}");return"{ "+n.join(",")+" }"}function u(t){var n=[];for(var e in t.partials)n.push('"'+c(e)+'":{name:"'+c(t.partials[e].name)+'", '+u(t.partials[e])+"}");return"partials: {"+n.join(",")+"}, subs: "+o(t.subs)}function c(t){return t.replace(m,"\\\\").replace(v,'\\"').replace(b,"\\n").replace(d,"\\r").replace(x,"\\u2028").replace(w,"\\u2029")}function l(t){return~t.indexOf(".")?"d":"f"}function f(t,n){var e="<"+(n.prefix||""),i=e+t.n+y++;return n.partials[i]={name:t.n,partials:{}},n.code+='t.b(t.rp("'+c(i)+'",c,p,"'+(t.indent||"")+'"));',i}function h(t,n){n.code+="t.b(t.t(t."+l(t.n)+'("'+c(t.n)+'",c,p,0)));'}function p(t){return"t.b("+t+");"}var g=/\S/,v=/\"/g,b=/\n/g,d=/\r/g,m=/\\/g,x=/\u2028/,w=/\u2029/;t.tags={"#":1,"^":2,"<":3,$:4,"/":5,"!":6,">":7,"=":8,_v:9,"{":10,"&":11,_t:12},t.scan=function(r,s){function a(){m.length>0&&(x.push({tag:"_t",text:new String(m)}),m="")}function o(){for(var n=!0,e=y;e<x.length;e++)if(n=t.tags[x[e].tag]<t.tags._v||"_t"==x[e].tag&&null===x[e].text.match(g),!n)return!1;return n}function u(t,n){if(a(),t&&o())for(var e,i=y;i<x.length;i++)x[i].text&&((e=x[i+1])&&">"==e.tag&&(e.indent=x[i].text.toString()),x.splice(i,1));else n||x.push({tag:"\n"});w=!1,y=x.length}function c(t,n){var i="="+S,r=t.indexOf(i,n),s=e(t.substring(t.indexOf("=",n)+1,r)).split(" ");return T=s[0],S=s[s.length-1],r+i.length-1}var l=r.length,f=0,h=1,p=2,v=f,b=null,d=null,m="",x=[],w=!1,k=0,y=0,T="{{",S="}}";for(s&&(s=s.split(" "),T=s[0],S=s[1]),k=0;l>k;k++)v==f?i(T,r,k)?(--k,a(),v=h):"\n"==r.charAt(k)?u(w):m+=r.charAt(k):v==h?(k+=T.length-1,d=t.tags[r.charAt(k+1)],b=d?r.charAt(k+1):"_v","="==b?(k=c(r,k),v=f):(d&&k++,v=p),w=k):i(S,r,k)?(x.push({tag:b,n:e(m),otag:T,ctag:S,i:"/"==b?w-T.length:k+S.length}),m="",k+=S.length-1,v=f,"{"==b&&("}}"==S?k++:n(x[x.length-1]))):m+=r.charAt(k);return u(w,!0),x};var k={_t:!0,"\n":!0,$:!0,"/":!0};t.stringify=function(n){return"{code: function (c,p,i) { "+t.wrapMain(n.code)+" },"+u(n)+"}"};var y=0;t.generate=function(n,e,i){y=0;var r={code:"",subs:{},partials:{}};return t.walk(n,r),i.asString?this.stringify(r,e,i):this.makeTemplate(r,e,i)},t.wrapMain=function(t){return'var t=this;t.b(i=i||"");'+t+"return t.fl();"},t.template=t.Template,t.makeTemplate=function(t,n,e){var i=this.makePartials(t);return i.code=new Function("c","p","i",this.wrapMain(t.code)),new this.template(i,n,this,e)},t.makePartials=function(t){var n,e={subs:{},partials:t.partials,name:t.name};for(n in e.partials)e.partials[n]=this.makePartials(e.partials[n]);for(n in t.subs)e.subs[n]=new Function("c","p","t","i",t.subs[n]);return e},t.codegen={"#":function(n,e){e.code+="if(t.s(t."+l(n.n)+'("'+c(n.n)+'",c,p,1),c,p,0,'+n.i+","+n.end+',"'+n.otag+" "+n.ctag+'")){t.rs(c,p,function(c,p,t){',t.walk(n.nodes,e),e.code+="});c.pop();}"},"^":function(n,e){e.code+="if(!t.s(t."+l(n.n)+'("'+c(n.n)+'",c,p,1),c,p,1,0,0,"")){',t.walk(n.nodes,e),e.code+="};"},">":f,"<":function(n,e){var i={partials:{},code:"",subs:{},inPartial:!0};t.walk(n.nodes,i);var r=e.partials[f(n,e)];r.subs=i.subs,r.partials=i.partials},$:function(n,e){var i={subs:{},code:"",partials:e.partials,prefix:n.n};t.walk(n.nodes,i),e.subs[n.n]=i.code,e.inPartial||(e.code+='t.sub("'+c(n.n)+'",c,p,i);')},"\n":function(t,n){n.code+=p('"\\n"'+(t.last?"":" + i"))},_v:function(t,n){n.code+="t.b(t.v(t."+l(t.n)+'("'+c(t.n)+'",c,p,0)));'},_t:function(t,n){n.code+=p('"'+c(t.text)+'"')},"{":h,"&":h},t.walk=function(n,e){for(var i,r=0,s=n.length;s>r;r++)i=t.codegen[n[r].tag],i&&i(n[r],e);return e},t.parse=function(t,n,e){return e=e||{},r(t,"",[],e.sectionTags||[])},t.cache={},t.cacheKey=function(t,n){return[t,!!n.asString,!!n.disableLambda,n.delimiters,!!n.modelGet].join("||")},t.compile=function(n,e){e=e||{};var i=t.cacheKey(n,e),r=this.cache[i];if(r){var s=r.partials;for(var a in s)delete s[a].instance;return r}return r=this.generate(this.parse(this.scan(n,e.delimiters),n,e),n,e),this.cache[i]=r}}("undefined"!=typeof exports?exports:Hogan); \ No newline at end of file diff --git a/goaccess++/resources/js/hogan.min.js.tmp b/goaccess++/resources/js/hogan.min.js.tmp new file mode 100644 index 0000000..9d0688e --- /dev/null +++ b/goaccess++/resources/js/hogan.min.js.tmp @@ -0,0 +1 @@ +/*** @preserve Copyright 2012 Twitter, Inc.* @license http://www.apache.org/licenses/LICENSE-2.0.txt*/var Hogan={};!function(t){function n(t,n,e){var i;return n&&"object"==typeof n&&(void 0!==n[t]?i=n[t]:e&&n.get&&"function"==typeof n.get&&(i=n.get(t))),i}function e(t,n,e,i,r,s){function a(){}function o(){}a.prototype=t,o.prototype=t.subs;var u,c=new a;c.subs=new o,c.subsText={},c.buf="",i=i||{},c.stackSubs=i,c.subsText=s;for(u in n)i[u]||(i[u]=n[u]);for(u in i)c.subs[u]=i[u];r=r||{},c.stackPartials=r;for(u in e)r[u]||(r[u]=e[u]);for(u in r)c.partials[u]=r[u];return c}function i(t){return String(null===t||void 0===t?"":t)}function r(t){return t=i(t),l.test(t)?t.replace(s,"&").replace(a,"<").replace(o,">").replace(u,"'").replace(c,"""):t}t.Template=function(t,n,e,i){t=t||{},this.r=t.code||this.r,this.c=e,this.options=i||{},this.text=n||"",this.partials=t.partials||{},this.subs=t.subs||{},this.buf=""},t.Template.prototype={r:function(){return""},v:r,t:i,render:function(t,n,e){return this.ri([t],n||{},e)},ri:function(t,n,e){return this.r(t,n,e)},ep:function(t,n){var i=this.partials[t],r=n[i.name];if(i.instance&&i.base==r)return i.instance;if("string"==typeof r){if(!this.c)throw new Error("No compiler available.");r=this.c.compile(r,this.options)}if(!r)return null;if(this.partials[t].base=r,i.subs){n.stackText||(n.stackText={});for(key in i.subs)n.stackText[key]||(n.stackText[key]=void 0!==this.activeSub&&n.stackText[this.activeSub]?n.stackText[this.activeSub]:this.text);r=e(r,i.subs,i.partials,this.stackSubs,this.stackPartials,n.stackText)}return this.partials[t].instance=r,r},rp:function(t,n,e,i){var r=this.ep(t,e);return r?r.ri(n,e,i):""},rs:function(t,n,e){var i=t[t.length-1];if(!f(i))return void e(t,n,this);for(var r=0;r<i.length;r++)t.push(i[r]),e(t,n,this),t.pop()},s:function(t,n,e,i,r,s,a){var o;return f(t)&&0===t.length?!1:("function"==typeof t&&(t=this.ms(t,n,e,i,r,s,a)),o=!!t,!i&&o&&n&&n.push("object"==typeof t?t:n[n.length-1]),o)},d:function(t,e,i,r){var s,a=t.split("."),o=this.f(a[0],e,i,r),u=this.options.modelGet,c=null;if("."===t&&f(e[e.length-2]))o=e[e.length-1];else for(var l=1;l<a.length;l++)s=n(a[l],o,u),void 0!==s?(c=o,o=s):o="";return r&&!o?!1:(r||"function"!=typeof o||(e.push(c),o=this.mv(o,e,i),e.pop()),o)},f:function(t,e,i,r){for(var s=!1,a=null,o=!1,u=this.options.modelGet,c=e.length-1;c>=0;c--)if(a=e[c],s=n(t,a,u),void 0!==s){o=!0;break}return o?(r||"function"!=typeof s||(s=this.mv(s,e,i)),s):r?!1:""},ls:function(t,n,e,r,s){var a=this.options.delimiters;return this.options.delimiters=s,this.b(this.ct(i(t.call(n,r)),n,e)),this.options.delimiters=a,!1},ct:function(t,n,e){if(this.options.disableLambda)throw new Error("Lambda features disabled.");return this.c.compile(t,this.options).render(n,e)},b:function(t){this.buf+=t},fl:function(){var t=this.buf;return this.buf="",t},ms:function(t,n,e,i,r,s,a){var o,u=n[n.length-1],c=t.call(u);return"function"==typeof c?i?!0:(o=this.activeSub&&this.subsText&&this.subsText[this.activeSub]?this.subsText[this.activeSub]:this.text,this.ls(c,u,e,o.substring(r,s),a)):c},mv:function(t,n,e){var r=n[n.length-1],s=t.call(r);return"function"==typeof s?this.ct(i(s.call(r)),r,e):s},sub:function(t,n,e,i){var r=this.subs[t];r&&(this.activeSub=t,r(n,e,this,i),this.activeSub=!1)}};var s=/&/g,a=/</g,o=/>/g,u=/\'/g,c=/\"/g,l=/[&<>\"\']/,f=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)}}("undefined"!=typeof exports?exports:Hogan),function(t){function n(t){"}"===t.n.substr(t.n.length-1)&&(t.n=t.n.substring(0,t.n.length-1))}function e(t){return t.trim?t.trim():t.replace(/^\s*|\s*$/g,"")}function i(t,n,e){if(n.charAt(e)!=t.charAt(0))return!1;for(var i=1,r=t.length;r>i;i++)if(n.charAt(e+i)!=t.charAt(i))return!1;return!0}function r(n,e,i,o){var u=[],c=null,l=null,f=null;for(l=i[i.length-1];n.length>0;){if(f=n.shift(),l&&"<"==l.tag&&!(f.tag in k))throw new Error("Illegal content in < super tag.");if(t.tags[f.tag]<=t.tags.$||s(f,o))i.push(f),f.nodes=r(n,f.tag,i,o);else{if("/"==f.tag){if(0===i.length)throw new Error("Closing tag without opener: /"+f.n);if(c=i.pop(),f.n!=c.n&&!a(f.n,c.n,o))throw new Error("Nesting error: "+c.n+" vs. "+f.n);return c.end=f.i,u}"\n"==f.tag&&(f.last=0==n.length||"\n"==n[0].tag)}u.push(f)}if(i.length>0)throw new Error("missing closing tag: "+i.pop().n);return u}function s(t,n){for(var e=0,i=n.length;i>e;e++)if(n[e].o==t.n)return t.tag="#",!0}function a(t,n,e){for(var i=0,r=e.length;r>i;i++)if(e[i].c==t&&e[i].o==n)return!0}function o(t){var n=[];for(var e in t)n.push('"'+c(e)+'": function(c,p,t,i) {'+t[e]+"}");return"{ "+n.join(",")+" }"}function u(t){var n=[];for(var e in t.partials)n.push('"'+c(e)+'":{name:"'+c(t.partials[e].name)+'", '+u(t.partials[e])+"}");return"partials: {"+n.join(",")+"}, subs: "+o(t.subs)}function c(t){return t.replace(m,"\\\\").replace(v,'\\"').replace(b,"\\n").replace(d,"\\r").replace(x,"\\u2028").replace(w,"\\u2029")}function l(t){return~t.indexOf(".")?"d":"f"}function f(t,n){var e="<"+(n.prefix||""),i=e+t.n+y++;return n.partials[i]={name:t.n,partials:{}},n.code+='t.b(t.rp("'+c(i)+'",c,p,"'+(t.indent||"")+'"));',i}function h(t,n){n.code+="t.b(t.t(t."+l(t.n)+'("'+c(t.n)+'",c,p,0)));'}function p(t){return"t.b("+t+");"}var g=/\S/,v=/\"/g,b=/\n/g,d=/\r/g,m=/\\/g,x=/\u2028/,w=/\u2029/;t.tags={"#":1,"^":2,"<":3,$:4,"/":5,"!":6,">":7,"=":8,_v:9,"{":10,"&":11,_t:12},t.scan=function(r,s){function a(){m.length>0&&(x.push({tag:"_t",text:new String(m)}),m="")}function o(){for(var n=!0,e=y;e<x.length;e++)if(n=t.tags[x[e].tag]<t.tags._v||"_t"==x[e].tag&&null===x[e].text.match(g),!n)return!1;return n}function u(t,n){if(a(),t&&o())for(var e,i=y;i<x.length;i++)x[i].text&&((e=x[i+1])&&">"==e.tag&&(e.indent=x[i].text.toString()),x.splice(i,1));else n||x.push({tag:"\n"});w=!1,y=x.length}function c(t,n){var i="="+S,r=t.indexOf(i,n),s=e(t.substring(t.indexOf("=",n)+1,r)).split(" ");return T=s[0],S=s[s.length-1],r+i.length-1}var l=r.length,f=0,h=1,p=2,v=f,b=null,d=null,m="",x=[],w=!1,k=0,y=0,T="{{",S="}}";for(s&&(s=s.split(" "),T=s[0],S=s[1]),k=0;l>k;k++)v==f?i(T,r,k)?(--k,a(),v=h):"\n"==r.charAt(k)?u(w):m+=r.charAt(k):v==h?(k+=T.length-1,d=t.tags[r.charAt(k+1)],b=d?r.charAt(k+1):"_v","="==b?(k=c(r,k),v=f):(d&&k++,v=p),w=k):i(S,r,k)?(x.push({tag:b,n:e(m),otag:T,ctag:S,i:"/"==b?w-T.length:k+S.length}),m="",k+=S.length-1,v=f,"{"==b&&("}}"==S?k++:n(x[x.length-1]))):m+=r.charAt(k);return u(w,!0),x};var k={_t:!0,"\n":!0,$:!0,"/":!0};t.stringify=function(n){return"{code: function (c,p,i) { "+t.wrapMain(n.code)+" },"+u(n)+"}"};var y=0;t.generate=function(n,e,i){y=0;var r={code:"",subs:{},partials:{}};return t.walk(n,r),i.asString?this.stringify(r,e,i):this.makeTemplate(r,e,i)},t.wrapMain=function(t){return'var t=this;t.b(i=i||"");'+t+"return t.fl();"},t.template=t.Template,t.makeTemplate=function(t,n,e){var i=this.makePartials(t);return i.code=new Function("c","p","i",this.wrapMain(t.code)),new this.template(i,n,this,e)},t.makePartials=function(t){var n,e={subs:{},partials:t.partials,name:t.name};for(n in e.partials)e.partials[n]=this.makePartials(e.partials[n]);for(n in t.subs)e.subs[n]=new Function("c","p","t","i",t.subs[n]);return e},t.codegen={"#":function(n,e){e.code+="if(t.s(t."+l(n.n)+'("'+c(n.n)+'",c,p,1),c,p,0,'+n.i+","+n.end+',"'+n.otag+" "+n.ctag+'")){t.rs(c,p,function(c,p,t){',t.walk(n.nodes,e),e.code+="});c.pop();}"},"^":function(n,e){e.code+="if(!t.s(t."+l(n.n)+'("'+c(n.n)+'",c,p,1),c,p,1,0,0,"")){',t.walk(n.nodes,e),e.code+="};"},">":f,"<":function(n,e){var i={partials:{},code:"",subs:{},inPartial:!0};t.walk(n.nodes,i);var r=e.partials[f(n,e)];r.subs=i.subs,r.partials=i.partials},$:function(n,e){var i={subs:{},code:"",partials:e.partials,prefix:n.n};t.walk(n.nodes,i),e.subs[n.n]=i.code,e.inPartial||(e.code+='t.sub("'+c(n.n)+'",c,p,i);')},"\n":function(t,n){n.code+=p('"\\n"'+(t.last?"":" + i"))},_v:function(t,n){n.code+="t.b(t.v(t."+l(t.n)+'("'+c(t.n)+'",c,p,0)));'},_t:function(t,n){n.code+=p('"'+c(t.text)+'"')},"{":h,"&":h},t.walk=function(n,e){for(var i,r=0,s=n.length;s>r;r++)i=t.codegen[n[r].tag],i&&i(n[r],e);return e},t.parse=function(t,n,e){return e=e||{},r(t,"",[],e.sectionTags||[])},t.cache={},t.cacheKey=function(t,n){return[t,!!n.asString,!!n.disableLambda,n.delimiters,!!n.modelGet].join("||")},t.compile=function(n,e){e=e||{};var i=t.cacheKey(n,e),r=this.cache[i];if(r){var s=r.partials;for(var a in s)delete s[a].instance;return r}return r=this.generate(this.parse(this.scan(n,e.delimiters),n,e),n,e),this.cache[i]=r}}("undefined"!=typeof exports?exports:Hogan); \ No newline at end of file diff --git a/goaccess++/resources/tpls.html b/goaccess++/resources/tpls.html new file mode 100644 index 0000000..584b3e0 --- /dev/null +++ b/goaccess++/resources/tpls.html @@ -0,0 +1,276 @@ +<!-- TPL General --> +<script id="tpl-general" type="text/template"> + <h4 class="hidden-xs gheader">{{head}}<span class="pull-right">{{#from}}<span class="from">{{from}}</span>{{/from}}{{#to}} — <span class="to">{{to}}</span>{{/to}}</span></h4> + <h5 class="visible-xs hidden-sm hidden-md hidden-lg gheader">{{head}}  {{#from}}<span class="from">{{from}}</span>{{/from}}{{#to}} — <span class="to">{{to}}</span>{{/to}}</h5> + <div class="wrap-general-items"></div> +</script> + +<!-- TPL General Items --> +<script id="tpl-general-items" type="text/template"> + <div class="col-md-2"> + <div class="grid-module {{#className}}{{className}}{{/className}}{{^className}}gray{{/className}}"> + <div class="col-title"> + <i class="fa fa-bar-chart"></i> {{#label}}{{label}}{{/label}} + </div> + <h3 id="{{id}}" style="padding-top: 0;">{{value}}</h3> + </div> + </div> +</script> + +<!-- TPL Panel Table --> +<script id="tpl-table-row" type="text/template"> + {{#rows}} + <tr class="{{#className}}{{className}}{{/className}} {{#hasSubItems}}{{#items}}expandable{{/items}}{{/hasSubItems}}" {{#idx}}data-pid="{{idx}}"{{/idx}} data-panel="{{panel}}" {{#key}}data-key="{{key}}"{{/key}}> + {{#hasSubItems}} + <td class="row-expandable text-center {{#items}}clickable{{/items}}"> + {{#items}}<i class="fa {{#expanded}}fa-caret-down{{/expanded}}{{^expanded}}fa fa-caret-right{{/expanded}}"></i>{{/items}} + {{^items}}<i></i>{{/items}} + </td> + {{/hasSubItems}} + <td class="row-idx text-right"> + {{#idx}}{{idx}}{{/idx}} + </td> + {{#cells}} + <td class="{{className}}" {{#colspan}}colspan="{{colspan}}"{{/colspan}}> + <span class="value">{{{value}}}</span>{{#percent}}<span class="percent"> ({{percent}})</span>{{/percent}} + </td> + {{/cells}} + </tr> + {{/rows}} +</script> + +<!-- TPL Panel Table Meta --> +<script id="tpl-table-row-meta" type="text/template"> + {{#row}} + <tr> + {{#hasSubItems}} + <td class=""></td> + {{/hasSubItems}} + <td class=""></td> + {{#cells}} + <td class="{{className}}" {{#colspan}}colspan="{{colspan}}"{{/colspan}}> + {{#value}} + <h4 class="value"><span title="{{title}}">{{value}}</span>{{#label}}<small> {{label}}</small>{{/label}}{{#max}}<br><small>Max: {{max}}</small>{{/max}}{{#min}}<br><small>Min: {{min}}</small>{{/min}}</h4> + {{/value}} + </td> + {{/cells}} + </tr> + {{/row}} +</script> + +<!-- TPL Table thead --> +<script id="tpl-table-thead" type="text/template"> + <tr> + {{#hasSubItems}} + <th></th> + {{/hasSubItems}} + <th>#</th> + {{#items}} + <th class="{{dataType}} {{#key}}sortable{{/key}}" data-key="{{key}}" {{#sort}}data-order="{{#asc}}asc{{/asc}}{{^asc}}desc{{/asc}}"{{/sort}}> + {{label}} <i class="fa fa-{{^sort}}sort{{/sort}}{{#sort}}{{#asc}}caret-up{{/asc}}{{^asc}}caret-down{{/asc}}{{/sort}}"></i> + </th> + {{/items}} + </tr> +</script> + +<!-- TPL Panel Options DropDown --> +<script id="tpl-panel-opts" type="text/template"> + <li class="dropdown-header">{{ labels.chart_opts }}</li> + <li><a href="javascript:void(0);" data-panel="{{id}}" data-chart="{{showChart}}"><i class="fa fa-{{#showChart}}check-{{/showChart}}square-o"></i> {{labels.chart}}</a></li> + + {{#plot.length}} + <li class="dropdown-header">{{ labels.type }}</li> + <li><a href="javascript:void(0);" data-panel="{{id}}" data-chart-type="area-spline"><i class="fa fa-circle{{^area-spline}}-o{{/area-spline}}"></i> {{labels.area_spline}}</a></li> + <li><a href="javascript:void(0);" data-panel="{{id}}" data-chart-type="bar"><i class="fa fa-circle{{^bar}}-o{{/bar}}"></i> {{labels.bar}}</a></li> + <li class="dropdown-header">{{labels.plot_metric}}</li> + {{#plot}} + <li><a href="javascript:void(0);" data-panel="{{id}}" data-plot="{{className}}" class="panel-plot-{{className}}"><i class="fa fa-circle{{^selected}}-o{{/selected}}"></i> {{label}}</a></li> + {{/plot}} + {{/plot.length}} + + <li class="dropdown-header">{{labels.table_columns}}</li> + {{#items}} + <li><a href="javascript:void(0);" data-panel="{{id}}" data-metric="{{key}}"><i class="fa fa-{{^hide}}check-{{/hide}}square-o"></i> {{label}}</a></li> + {{/items}} +</script> + +<!-- TPL Table colgroup --> +<script id="tpl-table-colgroup" type="text/template"> + {{#hasSubItems}} + <col style="width: 2%;"> <!-- right-caret --> + {{/hasSubItems}} + <col style="width: 3%;"> <!-- row # --> + {{#items}} + <col style="width:{{colWidth}}"> + {{/items}} +</script> + +<!-- TPL Panel --> +<script id="tpl-panel" type="text/template"> + <div class="row"> + <div class="col-md-12"> + <div class="form-group clearfix panel-header"> + <h4 class="pull-left hidden-xs gheader" id="{{id}}">{{head}}<br><small>{{desc}}</small></h4> + <h5 class="pull-left visible-xs hidden-sm hidden-md hidden-lg gheader" id="{{id}}">{{head}}<br><small>{{desc}}</small></h5> + <div class="panel-plot-wrap"> + <div class="dropdown"> + <button class="btn btn-default btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" data-panel="{{id}}"> + <i class="fa fa-gear"></i> {{labels.panel_opts}} <span class="fa fa-caret-down"></span> + </button> + <ul class="dropdown-menu dropdown-menu-right panel-opts-{{id}}"> + </ul> + </div> + </div> + </div> + </div> + </div> + {{#chart}} + <div class="row"> + <div class="col-md-12"> + <div id="chart-{{id}}" class="chart-wrap"></div> + </div> + </div> + {{/chart}} + {{#table}} + <div class="row clearfix table-wrapper {{#autoHideTables}}hidden-xs{{/autoHideTables}}"> + <div class="col-md-12"> + <div class="table-responsive"> + <table data-panel="{{id}}" class="table table-borderless table-hover table-{{id}}"> + <colgroup> + </colgroup> + <thead> + </thead> + <tbody class="tbody-meta"> + </tbody> + <tbody class="tbody-data"> + </tbody> + </table> + </div> + + <ul class="pagination pagination-sm pull-left"> + <li class="disabled"> + <a class="panel-first" href="javascript:void(0);" aria-label="{{labels.first}}" data-panel="{{id}}" title="{{labels.first}}"> + <i class="fa fa-angle-double-left"></i> + </a> + </li> + <li class="disabled"> + <a class="panel-prev" href="javascript:void(0);" aria-label="{{labels.previous}}" data-panel="{{id}}" title="{{labels.previous}}"> + <i class="fa fa-angle-left"></i> + </a> + </li> + <li> + <a class="panel-next" href="javascript:void(0);" aria-label="{{labels.next}}" data-panel="{{id}}" title="{{labels.next}}"> + <i class="fa fa-angle-right"></i> + </a> + </li> + <li> + <a class="panel-last" href="javascript:void(0);" aria-label="{{labels.last}}" data-panel="{{id}}" title="{{labels.last}}"> + <i class="fa fa-angle-double-right"></i> + </a> + </li> + </ul> + </div> + </div> + {{/table}} +</script> + +<!-- TPL Nav Bar wrapper --> +<script id="tpl-nav-wrap" type="text/template"> + <div class="nav-bars fa fa-bars"></div> + <div class="nav-gears fa fa-cog"></div> + <div class="nav-ws-status fa fa-circle"></div> + <div class="nav-list"></div> + <div class="powered hidden-xs hidden-sm">by <a href="https://goaccess.io/">GoAccess</a> <span>v{{version}}</span> and <a href="http://gwsocket.io/">GWSocket</a></div> +</script> + +<!-- TPL Nav Bar items --> +<script id="tpl-nav-menu" type="text/template"> + <h3>{{labels.panels}}</h3> + <ul> + <li {{#overall}}class="active"{{/overall}}><a href="#"><i class="fa fa-bar-chart"></i> {{labels.thead}}</a></li> + {{#nav}} + <li {{#current}}class="active"{{/current}}><a href="#{{key}}"><i class="fa fa-{{icon}}"></i> {{head}}</a></li> + {{/nav}} + </ul> +</script> + +<!-- TPL Nav Bar options --> +<script id="tpl-nav-opts" type="text/template"> + <h3><i class="fa fa-hashtag"></i> {{labels.theme}}</h3> + <ul> + <li {{#darkGray}}class="active"{{/darkGray}}> + <a href="javascript:void(0);" class="theme-dark-gray"><i class="fa fa-circle{{^darkGray}}-o{{/darkGray}}"></i> {{labels.dark_gray}}</a> + </li> + <li {{#bright}}class="active"{{/bright}}> + <a href="javascript:void(0);" class="theme-bright"><i class="fa fa-circle{{^bright}}-o{{/bright}}"></i> {{labels.bright}}</a> + </li> + <li {{#darkBlue}}class="active"{{/darkBlue}}> + <a href="javascript:void(0);" class="theme-dark-blue"><i class="fa fa-circle{{^darkBlue}}-o{{/darkBlue}}"></i> {{labels.dark_blue}}</a> + </li> + <li {{#darkPurple}}class="active"{{/darkPurple}}> + <a href="javascript:void(0);" class="theme-dark-purple"><i class="fa fa-circle{{^darkPurple}}-o{{/darkPurple}}"></i> {{labels.dark_purple}}</a> + </li> + </ul> + <h3><i class="fa fa-list-alt"></i> {{labels.panels}}</h3> + <ul class="perpage-wrap"> + <li class="dropdown-header"><i class="fa fa-list"></i> {{labels.items_per_page}}</li> + <li {{#perPage5}}class="active"{{/perPage5}}> + <a href="javascript:void(0);" data-perpage="5"><i class="fa fa-circle{{^perPage5}}-o{{/perPage5}}"></i> 5</a> + </li> + <li {{#perPage7}}class="active"{{/perPage7}}> + <a href="javascript:void(0);" data-perpage="7"><i class="fa fa-circle{{^perPage7}}-o{{/perPage7}}"></i> 7</a> + </li> + <li {{#perPage10}}class="active"{{/perPage10}}> + <a href="javascript:void(0);" data-perpage="10"><i class="fa fa-circle{{^perPage10}}-o{{/perPage10}}"></i> 10</a> + </li> + <li {{#perPage15}}class="active"{{/perPage15}}> + <a href="javascript:void(0);" data-perpage="15"><i class="fa fa-circle{{^perPage15}}-o{{/perPage15}}"></i> 15</a> + </li> + <li {{#perPage20}}class="active"{{/perPage20}}> + <a href="javascript:void(0);" data-perpage="20"><i class="fa fa-circle{{^perPage20}}-o{{/perPage20}}"></i> 20</a> + </li> + <li class="dropdown-header"><i class="fa fa-table"></i> {{labels.tables}}</li> + <li {{#showTables}}class="active"{{/showTables}}> + <a href="javascript:void(0);" data-show-tables="1"><i class="fa fa-{{#showTables}}check-{{/showTables}}square-o"></i> {{labels.display_tables}}</a> + </li> + <li {{#autoHideTables}}class="active"{{/autoHideTables}}> + <a href="javascript:void(0);" data-autohide-tables="1" title="{{labels.ah_small_title}}"> + <i class="fa fa-{{#autoHideTables}}check-{{/autoHideTables}}square-o"></i> {{labels.ah_small}} + </a> + </li> + </ul> + <h3><i class="fa fa-th-large"></i> {{labels.layout}}</h3> + <ul> + <li {{#horizontal}}class="active"{{/horizontal}}> + <a href="javascript:void(0);" class="layout-horizontal"><i class="fa fa-circle{{^horizontal}}-o{{/horizontal}}"></i> {{labels.horizontal}}</a> + </li> + <li {{#vertical}}class="active"{{/vertical}}> + <a href="javascript:void(0);" class="layout-vertical"><i class="fa fa-circle{{^vertical}}-o{{/vertical}}"></i> {{labels.vertical}}</a> + </li> + </ul> + <h3><i class="fa fa-cog"></i> {{labels.file_opts}}</h3> + <ul> + <li><a href="javascript:void(0);" class="export-json"><i class="fa fa-code"></i> {{labels.export_json}}</a></li> + </ul> +</script> + +<!-- TPL Chart tooltip --> +<script id="tpl-chart-tooltip" type="text/template"> + <table class="chart-tooltip"> + <tbody> + <tr> + <th colspan="2">{{data.0}}</th> + </tr> + <tr> + <td class="name"><span class="blue"></span>hits</td> + <td class="value">{{data.1}}</td> + </tr> + {{#data.2}} + <tr> + <td class="name"><span class="red"></span>visitors</td> + <td class="value">{{data.2}}</td> + </tr> + {{/data.2}} + </tbody> + </table> +</script> diff --git a/goaccess++/resources/tpls.html.tmp b/goaccess++/resources/tpls.html.tmp new file mode 100644 index 0000000..e864ed3 --- /dev/null +++ b/goaccess++/resources/tpls.html.tmp @@ -0,0 +1 @@ +<!-- TPL General --><script id="tpl-general" type="text/template"><h4 class="hidden-xs gheader">{{head}}<span class="pull-right">{{#from}}<span class="from">{{from}}</span>{{/from}}{{#to}} — <span class="to">{{to}}</span>{{/to}}</span></h4><h5 class="visible-xs hidden-sm hidden-md hidden-lg gheader">{{head}}  {{#from}}<span class="from">{{from}}</span>{{/from}}{{#to}} — <span class="to">{{to}}</span>{{/to}}</h5><div class="wrap-general-items"></div></script><!-- TPL General Items --><script id="tpl-general-items" type="text/template"><div class="col-md-2"><div class="grid-module {{#className}}{{className}}{{/className}}{{^className}}gray{{/className}}"><div class="col-title"><i class="fa fa-bar-chart"></i> {{#label}}{{label}}{{/label}}</div><h3 id="{{id}}" style="padding-top: 0;">{{value}}</h3></div></div></script><!-- TPL Panel Table --><script id="tpl-table-row" type="text/template">{{#rows}}<tr class="{{#className}}{{className}}{{/className}} {{#hasSubItems}}{{#items}}expandable{{/items}}{{/hasSubItems}}" {{#idx}}data-pid="{{idx}}"{{/idx}} data-panel="{{panel}}" {{#key}}data-key="{{key}}"{{/key}}>{{#hasSubItems}}<td class="row-expandable text-center {{#items}}clickable{{/items}}">{{#items}}<i class="fa {{#expanded}}fa-caret-down{{/expanded}}{{^expanded}}fa fa-caret-right{{/expanded}}"></i>{{/items}}{{^items}}<i></i>{{/items}}</td>{{/hasSubItems}}<td class="row-idx text-right">{{#idx}}{{idx}}{{/idx}}</td>{{#cells}}<td class="{{className}}" {{#colspan}}colspan="{{colspan}}"{{/colspan}}><span class="value">{{{value}}}</span>{{#percent}}<span class="percent"> ({{percent}})</span>{{/percent}}</td>{{/cells}}</tr>{{/rows}}</script><!-- TPL Panel Table Meta --><script id="tpl-table-row-meta" type="text/template">{{#row}}<tr>{{#hasSubItems}}<td class=""></td>{{/hasSubItems}}<td class=""></td>{{#cells}}<td class="{{className}}" {{#colspan}}colspan="{{colspan}}"{{/colspan}}>{{#value}}<h4 class="value"><span title="{{title}}">{{value}}</span>{{#label}}<small> {{label}}</small>{{/label}}{{#max}}<br><small>Max: {{max}}</small>{{/max}}{{#min}}<br><small>Min: {{min}}</small>{{/min}}</h4>{{/value}}</td>{{/cells}}</tr>{{/row}}</script><!-- TPL Table thead --><script id="tpl-table-thead" type="text/template"><tr>{{#hasSubItems}}<th></th>{{/hasSubItems}}<th>#</th>{{#items}}<th class="{{dataType}} {{#key}}sortable{{/key}}" data-key="{{key}}" {{#sort}}data-order="{{#asc}}asc{{/asc}}{{^asc}}desc{{/asc}}"{{/sort}}>{{label}} <i class="fa fa-{{^sort}}sort{{/sort}}{{#sort}}{{#asc}}caret-up{{/asc}}{{^asc}}caret-down{{/asc}}{{/sort}}"></i></th>{{/items}}</tr></script><!-- TPL Panel Options DropDown --><script id="tpl-panel-opts" type="text/template"><li class="dropdown-header">{{ labels.chart_opts }}</li><li><a href="javascript:void(0);" data-panel="{{id}}" data-chart="{{showChart}}"><i class="fa fa-{{#showChart}}check-{{/showChart}}square-o"></i> {{labels.chart}}</a></li>{{#plot.length}}<li class="dropdown-header">{{ labels.type }}</li><li><a href="javascript:void(0);" data-panel="{{id}}" data-chart-type="area-spline"><i class="fa fa-circle{{^area-spline}}-o{{/area-spline}}"></i> {{labels.area_spline}}</a></li><li><a href="javascript:void(0);" data-panel="{{id}}" data-chart-type="bar"><i class="fa fa-circle{{^bar}}-o{{/bar}}"></i> {{labels.bar}}</a></li><li class="dropdown-header">{{labels.plot_metric}}</li>{{#plot}}<li><a href="javascript:void(0);" data-panel="{{id}}" data-plot="{{className}}" class="panel-plot-{{className}}"><i class="fa fa-circle{{^selected}}-o{{/selected}}"></i> {{label}}</a></li>{{/plot}}{{/plot.length}}<li class="dropdown-header">{{labels.table_columns}}</li>{{#items}}<li><a href="javascript:void(0);" data-panel="{{id}}" data-metric="{{key}}"><i class="fa fa-{{^hide}}check-{{/hide}}square-o"></i> {{label}}</a></li>{{/items}}</script><!-- TPL Table colgroup --><script id="tpl-table-colgroup" type="text/template">{{#hasSubItems}}<col style="width: 2%;"> <!-- right-caret -->{{/hasSubItems}}<col style="width: 3%;"> <!-- row # -->{{#items}}<col style="width:{{colWidth}}">{{/items}}</script><!-- TPL Panel --><script id="tpl-panel" type="text/template"><div class="row"><div class="col-md-12"><div class="form-group clearfix panel-header"><h4 class="pull-left hidden-xs gheader" id="{{id}}">{{head}}<br><small>{{desc}}</small></h4><h5 class="pull-left visible-xs hidden-sm hidden-md hidden-lg gheader" id="{{id}}">{{head}}<br><small>{{desc}}</small></h5><div class="panel-plot-wrap"><div class="dropdown"><button class="btn btn-default btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" data-panel="{{id}}"><i class="fa fa-gear"></i> {{labels.panel_opts}} <span class="fa fa-caret-down"></span></button><ul class="dropdown-menu dropdown-menu-right panel-opts-{{id}}"></ul></div></div></div></div></div>{{#chart}}<div class="row"><div class="col-md-12"><div id="chart-{{id}}" class="chart-wrap"></div></div></div>{{/chart}}{{#table}}<div class="row clearfix table-wrapper {{#autoHideTables}}hidden-xs{{/autoHideTables}}"><div class="col-md-12"><div class="table-responsive"><table data-panel="{{id}}" class="table table-borderless table-hover table-{{id}}"><colgroup></colgroup><thead></thead><tbody class="tbody-meta"></tbody><tbody class="tbody-data"></tbody></table></div><ul class="pagination pagination-sm pull-left"><li class="disabled"><a class="panel-first" href="javascript:void(0);" aria-label="{{labels.first}}" data-panel="{{id}}" title="{{labels.first}}"><i class="fa fa-angle-double-left"></i></a></li><li class="disabled"><a class="panel-prev" href="javascript:void(0);" aria-label="{{labels.previous}}" data-panel="{{id}}" title="{{labels.previous}}"><i class="fa fa-angle-left"></i></a></li><li><a class="panel-next" href="javascript:void(0);" aria-label="{{labels.next}}" data-panel="{{id}}" title="{{labels.next}}"><i class="fa fa-angle-right"></i></a></li><li><a class="panel-last" href="javascript:void(0);" aria-label="{{labels.last}}" data-panel="{{id}}" title="{{labels.last}}"><i class="fa fa-angle-double-right"></i></a></li></ul></div></div>{{/table}}</script><!-- TPL Nav Bar wrapper --><script id="tpl-nav-wrap" type="text/template"><div class="nav-bars fa fa-bars"></div><div class="nav-gears fa fa-cog"></div><div class="nav-ws-status fa fa-circle"></div><div class="nav-list"></div><div class="powered hidden-xs hidden-sm">by <a href="https://goaccess.io/">GoAccess</a> <span>v{{version}}</span> and <a href="http://gwsocket.io/">GWSocket</a></div></script><!-- TPL Nav Bar items --><script id="tpl-nav-menu" type="text/template"><h3>{{labels.panels}}</h3><ul><li {{#overall}}class="active"{{/overall}}><a href="#"><i class="fa fa-bar-chart"></i> {{labels.thead}}</a></li>{{#nav}}<li {{#current}}class="active"{{/current}}><a href="#{{key}}"><i class="fa fa-{{icon}}"></i> {{head}}</a></li>{{/nav}}</ul></script><!-- TPL Nav Bar options --><script id="tpl-nav-opts" type="text/template"><h3><i class="fa fa-hashtag"></i> {{labels.theme}}</h3><ul><li {{#darkGray}}class="active"{{/darkGray}}><a href="javascript:void(0);" class="theme-dark-gray"><i class="fa fa-circle{{^darkGray}}-o{{/darkGray}}"></i> {{labels.dark_gray}}</a></li><li {{#bright}}class="active"{{/bright}}><a href="javascript:void(0);" class="theme-bright"><i class="fa fa-circle{{^bright}}-o{{/bright}}"></i> {{labels.bright}}</a></li><li {{#darkBlue}}class="active"{{/darkBlue}}><a href="javascript:void(0);" class="theme-dark-blue"><i class="fa fa-circle{{^darkBlue}}-o{{/darkBlue}}"></i> {{labels.dark_blue}}</a></li><li {{#darkPurple}}class="active"{{/darkPurple}}><a href="javascript:void(0);" class="theme-dark-purple"><i class="fa fa-circle{{^darkPurple}}-o{{/darkPurple}}"></i> {{labels.dark_purple}}</a></li></ul><h3><i class="fa fa-list-alt"></i> {{labels.panels}}</h3><ul class="perpage-wrap"><li class="dropdown-header"><i class="fa fa-list"></i> {{labels.items_per_page}}</li><li {{#perPage5}}class="active"{{/perPage5}}><a href="javascript:void(0);" data-perpage="5"><i class="fa fa-circle{{^perPage5}}-o{{/perPage5}}"></i> 5</a></li><li {{#perPage7}}class="active"{{/perPage7}}><a href="javascript:void(0);" data-perpage="7"><i class="fa fa-circle{{^perPage7}}-o{{/perPage7}}"></i> 7</a></li><li {{#perPage10}}class="active"{{/perPage10}}><a href="javascript:void(0);" data-perpage="10"><i class="fa fa-circle{{^perPage10}}-o{{/perPage10}}"></i> 10</a></li><li {{#perPage15}}class="active"{{/perPage15}}><a href="javascript:void(0);" data-perpage="15"><i class="fa fa-circle{{^perPage15}}-o{{/perPage15}}"></i> 15</a></li><li {{#perPage20}}class="active"{{/perPage20}}><a href="javascript:void(0);" data-perpage="20"><i class="fa fa-circle{{^perPage20}}-o{{/perPage20}}"></i> 20</a></li><li class="dropdown-header"><i class="fa fa-table"></i> {{labels.tables}}</li><li {{#showTables}}class="active"{{/showTables}}><a href="javascript:void(0);" data-show-tables="1"><i class="fa fa-{{#showTables}}check-{{/showTables}}square-o"></i> {{labels.display_tables}}</a></li><li {{#autoHideTables}}class="active"{{/autoHideTables}}><a href="javascript:void(0);" data-autohide-tables="1" title="{{labels.ah_small_title}}"><i class="fa fa-{{#autoHideTables}}check-{{/autoHideTables}}square-o"></i> {{labels.ah_small}}</a></li></ul><h3><i class="fa fa-th-large"></i> {{labels.layout}}</h3><ul><li {{#horizontal}}class="active"{{/horizontal}}><a href="javascript:void(0);" class="layout-horizontal"><i class="fa fa-circle{{^horizontal}}-o{{/horizontal}}"></i> {{labels.horizontal}}</a></li><li {{#vertical}}class="active"{{/vertical}}><a href="javascript:void(0);" class="layout-vertical"><i class="fa fa-circle{{^vertical}}-o{{/vertical}}"></i> {{labels.vertical}}</a></li></ul><h3><i class="fa fa-cog"></i> {{labels.file_opts}}</h3><ul><li><a href="javascript:void(0);" class="export-json"><i class="fa fa-code"></i> {{labels.export_json}}</a></li></ul></script><!-- TPL Chart tooltip --><script id="tpl-chart-tooltip" type="text/template"><table class="chart-tooltip"><tbody><tr><th colspan="2">{{data.0}}</th></tr><tr><td class="name"><span class="blue"></span>hits</td><td class="value">{{data.1}}</td></tr>{{#data.2}}<tr><td class="name"><span class="red"></span>visitors</td><td class="value">{{data.2}}</td></tr>{{/data.2}}</tbody></table></script> \ No newline at end of file diff --git a/goaccess++/src/.deps/.dirstamp b/goaccess++/src/.deps/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/goaccess++/src/.deps/base64.Po b/goaccess++/src/.deps/base64.Po new file mode 100644 index 0000000..9cd55dd --- /dev/null +++ b/goaccess++/src/.deps/base64.Po @@ -0,0 +1,151 @@ +src/base64.o: src/base64.c /usr/include/stdc-predef.h \ + /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/base64.h + +/usr/include/stdc-predef.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/base64.h: diff --git a/goaccess++/src/.deps/bin2c.Po b/goaccess++/src/.deps/bin2c.Po new file mode 100644 index 0000000..d42955d --- /dev/null +++ b/goaccess++/src/.deps/bin2c.Po @@ -0,0 +1,185 @@ +src/bin2c.o: src/bin2c.c /usr/include/stdc-predef.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/stdlib.h /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/assert.h + +/usr/include/stdc-predef.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/assert.h: diff --git a/goaccess++/src/.deps/browsers.Po b/goaccess++/src/.deps/browsers.Po new file mode 100644 index 0000000..d512671 --- /dev/null +++ b/goaccess++/src/.deps/browsers.Po @@ -0,0 +1,250 @@ +src/browsers.o: src/browsers.c /usr/include/stdc-predef.h \ + /usr/include/errno.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/browsers.h \ + src/error.h src/commons.h src/config.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/curses.h \ + /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/errno.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/browsers.h: + +src/error.h: + +src/commons.h: + +src/config.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/color.Po b/goaccess++/src/.deps/color.Po new file mode 100644 index 0000000..5299254 --- /dev/null +++ b/goaccess++/src/.deps/color.Po @@ -0,0 +1,253 @@ +src/color.o: src/color.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/errno.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/color.h \ + src/commons.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/gslist.h src/util.h \ + src/xmalloc.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/errno.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/color.h: + +src/commons.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/gslist.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/commons.Po b/goaccess++/src/.deps/commons.Po new file mode 100644 index 0000000..38334b5 --- /dev/null +++ b/goaccess++/src/.deps/commons.Po @@ -0,0 +1,264 @@ +src/commons.o: src/commons.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/time.h /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/unistd.h /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/commons.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/labels.h /usr/include/libintl.h \ + /usr/include/locale.h /usr/include/x86_64-linux-gnu/bits/locale.h \ + src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/commons.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/csv.Po b/goaccess++/src/.deps/csv.Po new file mode 100644 index 0000000..2ff32fa --- /dev/null +++ b/goaccess++/src/.deps/csv.Po @@ -0,0 +1,344 @@ +src/csv.o: src/csv.c /usr/include/stdc-predef.h /usr/include/ctype.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/unistd.h /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/csv.h src/config.h \ + src/parser.h src/commons.h src/settings.h src/gkhash.h src/gslist.h \ + src/gstorage.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/ui.h /usr/include/pthread.h \ + /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h src/labels.h \ + /usr/include/libintl.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/color.h src/sort.h \ + src/util.h + +/usr/include/stdc-predef.h: + +/usr/include/ctype.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/csv.h: + +src/config.h: + +src/parser.h: + +src/commons.h: + +src/settings.h: + +src/gkhash.h: + +src/gslist.h: + +src/gstorage.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/ui.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/color.h: + +src/sort.h: + +src/util.h: diff --git a/goaccess++/src/.deps/error.Po b/goaccess++/src/.deps/error.Po new file mode 100644 index 0000000..38cff93 --- /dev/null +++ b/goaccess++/src/.deps/error.Po @@ -0,0 +1,313 @@ +src/error.o: src/error.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/signal.h \ + /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/signum-generic.h \ + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h \ + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/ss_flags.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h \ + /usr/include/x86_64-linux-gnu/bits/signal_ext.h /usr/include/execinfo.h \ + /usr/include/unistd.h /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/error.h \ + src/commons.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/curses.h \ + /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/labels.h /usr/include/libintl.h \ + /usr/include/locale.h /usr/include/x86_64-linux-gnu/bits/locale.h \ + src/parser.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/signum-generic.h: + +/usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-arch.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigval_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h: + +/usr/include/x86_64-linux-gnu/bits/sigevent-consts.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/types/stack_t.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/bits/ss_flags.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/x86_64-linux-gnu/bits/signal_ext.h: + +/usr/include/execinfo.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/error.h: + +src/commons.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/parser.h: diff --git a/goaccess++/src/.deps/gdashboard.Po b/goaccess++/src/.deps/gdashboard.Po new file mode 100644 index 0000000..b095058 --- /dev/null +++ b/goaccess++/src/.deps/gdashboard.Po @@ -0,0 +1,312 @@ +src/gdashboard.o: src/gdashboard.c /usr/include/stdc-predef.h \ + /usr/include/ctype.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/unistd.h /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h /usr/include/regex.h \ + src/gdashboard.h src/config.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/ui.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2.h /usr/include/unctrl.h \ + /usr/include/curses.h /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h src/labels.h \ + /usr/include/libintl.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/color.h src/commons.h \ + src/sort.h src/parser.h src/gkhash.h src/gslist.h src/gstorage.h \ + src/khash.h /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/uio_lim.h src/error.h src/settings.h \ + src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/ctype.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/include/regex.h: + +src/gdashboard.h: + +src/config.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/ui.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/types/wint_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/wctype-wchar.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/color.h: + +src/commons.h: + +src/sort.h: + +src/parser.h: + +src/gkhash.h: + +src/gslist.h: + +src/gstorage.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/uio_lim.h: + +src/error.h: + +src/settings.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/gdns.Po b/goaccess++/src/.deps/gdns.Po new file mode 100644 index 0000000..404afec --- /dev/null +++ b/goaccess++/src/.deps/gdns.Po @@ -0,0 +1,414 @@ +src/gdns.o: src/gdns.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/pthread.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/arpa/inet.h \ + /usr/include/ctype.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/netdb.h /usr/include/rpc/netdb.h \ + /usr/include/x86_64-linux-gnu/bits/netdb.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/gdns.h src/gkhash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h src/gslist.h src/gstorage.h \ + src/commons.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/parser.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/goaccess.h src/ui.h \ + src/labels.h /usr/include/libintl.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/color.h src/sort.h \ + src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/pthread.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/arpa/inet.h: + +/usr/include/ctype.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/netdb.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/gdns.h: + +src/gkhash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +src/gslist.h: + +src/gstorage.h: + +src/commons.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/parser.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/goaccess.h: + +src/ui.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/color.h: + +src/sort.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/geoip1.Po b/goaccess++/src/.deps/geoip1.Po new file mode 100644 index 0000000..8539f92 --- /dev/null +++ b/goaccess++/src/.deps/geoip1.Po @@ -0,0 +1,304 @@ +src/geoip1.o: src/geoip1.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/GeoIP.h /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/arpa/inet.h /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/GeoIPCity.h \ + /usr/include/GeoIP.h src/geoip1.h src/commons.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/util.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/GeoIP.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/GeoIPCity.h: + +/usr/include/GeoIP.h: + +src/geoip1.h: + +src/commons.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/util.h: diff --git a/goaccess++/src/.deps/geoip2.Po b/goaccess++/src/.deps/geoip2.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/goaccess++/src/.deps/geoip2.Po @@ -0,0 +1 @@ +# dummy diff --git a/goaccess++/src/.deps/gholder.Po b/goaccess++/src/.deps/gholder.Po new file mode 100644 index 0000000..4df1970 --- /dev/null +++ b/goaccess++/src/.deps/gholder.Po @@ -0,0 +1,348 @@ +src/gholder.o: src/gholder.c /usr/include/stdc-predef.h \ + /usr/include/pthread.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/arpa/inet.h \ + src/gkhash.h /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h \ + /usr/include/stdint.h /usr/include/x86_64-linux-gnu/bits/wchar.h \ + src/gslist.h src/gstorage.h src/commons.h src/config.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/parser.h \ + src/geoip1.h src/gholder.h src/sort.h src/error.h /usr/include/curses.h \ + /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/gdns.h src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/pthread.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/arpa/inet.h: + +src/gkhash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +src/gslist.h: + +src/gstorage.h: + +src/commons.h: + +src/config.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/parser.h: + +src/geoip1.h: + +src/gholder.h: + +src/sort.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/gdns.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/gkhash.Po b/goaccess++/src/.deps/gkhash.Po new file mode 100644 index 0000000..2409eab --- /dev/null +++ b/goaccess++/src/.deps/gkhash.Po @@ -0,0 +1,280 @@ +src/gkhash.o: src/gkhash.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/errno.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/gkhash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/gslist.h \ + src/gstorage.h src/commons.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/parser.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/sort.h src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/errno.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/gkhash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/gslist.h: + +src/gstorage.h: + +src/commons.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/parser.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/sort.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/gmenu.Po b/goaccess++/src/.deps/gmenu.Po new file mode 100644 index 0000000..75a2ac0 --- /dev/null +++ b/goaccess++/src/.deps/gmenu.Po @@ -0,0 +1,264 @@ +src/gmenu.o: src/gmenu.c /usr/include/stdc-predef.h /usr/include/ctype.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/gmenu.h \ + src/config.h /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/xmalloc.h src/ui.h /usr/include/pthread.h \ + /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h src/labels.h \ + /usr/include/libintl.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/color.h src/commons.h \ + src/sort.h src/parser.h + +/usr/include/stdc-predef.h: + +/usr/include/ctype.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/gmenu.h: + +src/config.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/xmalloc.h: + +src/ui.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/color.h: + +src/commons.h: + +src/sort.h: + +src/parser.h: diff --git a/goaccess++/src/.deps/goaccess.Po b/goaccess++/src/.deps/goaccess.Po new file mode 100644 index 0000000..a4246bb --- /dev/null +++ b/goaccess++/src/.deps/goaccess.Po @@ -0,0 +1,497 @@ +src/goaccess.o: src/goaccess.c /usr/include/stdc-predef.h \ + /usr/include/assert.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h /usr/include/ctype.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/locale.h /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/config.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl2.h /usr/include/pthread.h \ + /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h /usr/include/signal.h \ + /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/signum-generic.h \ + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h \ + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/ss_flags.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h \ + /usr/include/x86_64-linux-gnu/bits/signal_ext.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/gkhash.h \ + src/gslist.h src/gstorage.h src/commons.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/parser.h \ + src/geoip1.h src/browsers.h src/csv.h src/settings.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/gdashboard.h src/ui.h src/labels.h \ + /usr/include/libintl.h src/color.h src/sort.h src/gdns.h src/gholder.h \ + src/goaccess.h src/gwsocket.h src/websocket.h /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h src/json.h src/options.h \ + src/output.h src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/assert.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/locale.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/config.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl2.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/signum-generic.h: + +/usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-arch.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigval_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h: + +/usr/include/x86_64-linux-gnu/bits/sigevent-consts.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/types/stack_t.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/bits/ss_flags.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/x86_64-linux-gnu/bits/signal_ext.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/gkhash.h: + +src/gslist.h: + +src/gstorage.h: + +src/commons.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/parser.h: + +src/geoip1.h: + +src/browsers.h: + +src/csv.h: + +src/settings.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/gdashboard.h: + +src/ui.h: + +src/labels.h: + +/usr/include/libintl.h: + +src/color.h: + +src/sort.h: + +src/gdns.h: + +src/gholder.h: + +src/goaccess.h: + +src/gwsocket.h: + +src/websocket.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +src/json.h: + +src/options.h: + +src/output.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/gslist.Po b/goaccess++/src/.deps/gslist.Po new file mode 100644 index 0000000..3e7e4bb --- /dev/null +++ b/goaccess++/src/.deps/gslist.Po @@ -0,0 +1,191 @@ +src/gslist.o: src/gslist.c /usr/include/stdc-predef.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/ctype.h src/gslist.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/ctype.h: + +src/gslist.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/gstorage.Po b/goaccess++/src/.deps/gstorage.Po new file mode 100644 index 0000000..fc5ad28 --- /dev/null +++ b/goaccess++/src/.deps/gstorage.Po @@ -0,0 +1,260 @@ +src/gstorage.o: src/gstorage.c /usr/include/stdc-predef.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/gkhash.h \ + src/gslist.h src/gstorage.h src/commons.h src/config.h \ + /usr/include/time.h /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/parser.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/gkhash.h: + +src/gslist.h: + +src/gstorage.h: + +src/commons.h: + +src/config.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/parser.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/gwsocket.Po b/goaccess++/src/.deps/gwsocket.Po new file mode 100644 index 0000000..50e1d7f --- /dev/null +++ b/goaccess++/src/.deps/gwsocket.Po @@ -0,0 +1,469 @@ +src/gwsocket.o: src/gwsocket.c /usr/include/stdc-predef.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/signal.h \ + /usr/include/x86_64-linux-gnu/bits/signum.h \ + /usr/include/x86_64-linux-gnu/bits/signum-generic.h \ + /usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-arch.h \ + /usr/include/x86_64-linux-gnu/bits/siginfo-consts.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigval_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h \ + /usr/include/x86_64-linux-gnu/bits/sigevent-consts.h \ + /usr/include/x86_64-linux-gnu/bits/sigaction.h \ + /usr/include/x86_64-linux-gnu/bits/sigcontext.h \ + /usr/include/x86_64-linux-gnu/bits/types/stack_t.h \ + /usr/include/x86_64-linux-gnu/sys/ucontext.h \ + /usr/include/x86_64-linux-gnu/bits/sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/ss_flags.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/sigthread.h \ + /usr/include/x86_64-linux-gnu/bits/signal_ext.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl2.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/gwsocket.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h src/websocket.h \ + /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/gslist.h \ + src/commons.h src/config.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/goaccess.h src/ui.h \ + src/labels.h /usr/include/libintl.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/color.h src/sort.h \ + src/parser.h src/json.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/signal.h: + +/usr/include/x86_64-linux-gnu/bits/signum.h: + +/usr/include/x86_64-linux-gnu/bits/signum-generic.h: + +/usr/include/x86_64-linux-gnu/bits/types/sig_atomic_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/siginfo_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigval_t.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-arch.h: + +/usr/include/x86_64-linux-gnu/bits/siginfo-consts.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigval_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigevent_t.h: + +/usr/include/x86_64-linux-gnu/bits/sigevent-consts.h: + +/usr/include/x86_64-linux-gnu/bits/sigaction.h: + +/usr/include/x86_64-linux-gnu/bits/sigcontext.h: + +/usr/include/x86_64-linux-gnu/bits/types/stack_t.h: + +/usr/include/x86_64-linux-gnu/sys/ucontext.h: + +/usr/include/x86_64-linux-gnu/bits/sigstack.h: + +/usr/include/x86_64-linux-gnu/bits/ss_flags.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sigstack.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/x86_64-linux-gnu/bits/sigthread.h: + +/usr/include/x86_64-linux-gnu/bits/signal_ext.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl2.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/gwsocket.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +src/websocket.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/gslist.h: + +src/commons.h: + +src/config.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/goaccess.h: + +src/ui.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/color.h: + +src/sort.h: + +src/parser.h: + +src/json.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/json.Po b/goaccess++/src/.deps/json.Po new file mode 100644 index 0000000..3a2c909 --- /dev/null +++ b/goaccess++/src/.deps/json.Po @@ -0,0 +1,406 @@ +src/json.o: src/json.c /usr/include/stdc-predef.h /usr/include/errno.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/ctype.h /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/unistd.h /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h /usr/include/inttypes.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/json.h \ + src/config.h src/parser.h src/commons.h src/gkhash.h src/gslist.h \ + src/gstorage.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/ui.h /usr/include/pthread.h \ + /usr/include/sched.h /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h src/labels.h \ + /usr/include/libintl.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/color.h src/sort.h \ + src/util.h src/websocket.h /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/errno.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/json.h: + +src/config.h: + +src/parser.h: + +src/commons.h: + +src/gkhash.h: + +src/gslist.h: + +src/gstorage.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/ui.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/color.h: + +src/sort.h: + +src/util.h: + +src/websocket.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/opesys.Po b/goaccess++/src/.deps/opesys.Po new file mode 100644 index 0000000..726c11a --- /dev/null +++ b/goaccess++/src/.deps/opesys.Po @@ -0,0 +1,238 @@ +src/opesys.o: src/opesys.c /usr/include/stdc-predef.h \ + /usr/include/ctype.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/opesys.h \ + src/settings.h /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h \ + /usr/include/stdint.h /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/commons.h \ + src/config.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h src/util.h \ + src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/ctype.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/opesys.h: + +src/settings.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/commons.h: + +src/config.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/options.Po b/goaccess++/src/.deps/options.Po new file mode 100644 index 0000000..bda2d63 --- /dev/null +++ b/goaccess++/src/.deps/options.Po @@ -0,0 +1,336 @@ +src/options.o: src/options.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/getopt.h /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_ext.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/GeoIP.h /usr/include/arpa/inet.h /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h src/options.h src/error.h \ + src/commons.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/curses.h \ + /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/labels.h /usr/include/libintl.h \ + /usr/include/locale.h /usr/include/x86_64-linux-gnu/bits/locale.h \ + src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/getopt.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_ext.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/GeoIP.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +src/options.h: + +src/error.h: + +src/commons.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/output.Po b/goaccess++/src/.deps/output.Po new file mode 100644 index 0000000..84dea80 --- /dev/null +++ b/goaccess++/src/.deps/output.Po @@ -0,0 +1,398 @@ +src/output.o: src/output.c /usr/include/stdc-predef.h \ + /usr/include/errno.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/ctype.h /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/output.h \ + src/config.h src/commons.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/parser.h \ + src/gkhash.h src/gslist.h src/gstorage.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/gwsocket.h \ + /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h src/websocket.h \ + /usr/include/netinet/in.h /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h src/json.h src/ui.h src/labels.h \ + /usr/include/libintl.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/color.h src/sort.h \ + src/util.h src/xmalloc.h src/tpls.h src/bootstrapcss.h src/facss.h \ + src/appcss.h src/d3js.h src/hoganjs.h src/chartsjs.h src/appjs.h + +/usr/include/stdc-predef.h: + +/usr/include/errno.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/output.h: + +src/config.h: + +src/commons.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/parser.h: + +src/gkhash.h: + +src/gslist.h: + +src/gstorage.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/gwsocket.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +src/websocket.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +src/json.h: + +src/ui.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/color.h: + +src/sort.h: + +src/util.h: + +src/xmalloc.h: + +src/tpls.h: + +src/bootstrapcss.h: + +src/facss.h: + +src/appcss.h: + +src/d3js.h: + +src/hoganjs.h: + +src/chartsjs.h: + +src/appjs.h: diff --git a/goaccess++/src/.deps/parser.Po b/goaccess++/src/.deps/parser.Po new file mode 100644 index 0000000..fddf0f5 --- /dev/null +++ b/goaccess++/src/.deps/parser.Po @@ -0,0 +1,375 @@ +src/parser.o: src/parser.c /usr/include/stdc-predef.h \ + /usr/include/ctype.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + src/config.h /usr/include/arpa/inet.h /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket-constants.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/strings.h /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/gkhash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h src/gslist.h src/gstorage.h \ + src/commons.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h \ + /usr/include/x86_64-linux-gnu/bits/xopen_lim.h \ + /usr/include/x86_64-linux-gnu/bits/uio_lim.h src/parser.h src/geoip1.h \ + src/browsers.h src/goaccess.h src/ui.h /usr/include/curses.h \ + /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2.h /usr/include/unctrl.h \ + /usr/include/curses.h /usr/include/pthread.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h src/labels.h \ + /usr/include/libintl.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h src/color.h src/sort.h \ + src/error.h src/settings.h src/opesys.h src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/ctype.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +src/config.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket-constants.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/gkhash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +src/gslist.h: + +src/gstorage.h: + +src/commons.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +/usr/include/x86_64-linux-gnu/bits/xopen_lim.h: + +/usr/include/x86_64-linux-gnu/bits/uio_lim.h: + +src/parser.h: + +src/geoip1.h: + +src/browsers.h: + +src/goaccess.h: + +src/ui.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/types/wint_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/wctype-wchar.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +/usr/include/pthread.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/color.h: + +src/sort.h: + +src/error.h: + +src/settings.h: + +src/opesys.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/settings.Po b/goaccess++/src/.deps/settings.Po new file mode 100644 index 0000000..ab8fecd --- /dev/null +++ b/goaccess++/src/.deps/settings.Po @@ -0,0 +1,283 @@ +src/settings.o: src/settings.c /usr/include/stdc-predef.h \ + /usr/include/ctype.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/unistd.h /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + src/settings.h /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h \ + /usr/include/stdint.h /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h src/commons.h \ + src/config.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h src/error.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/labels.h /usr/include/libintl.h \ + /usr/include/locale.h /usr/include/x86_64-linux-gnu/bits/locale.h \ + src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/ctype.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +src/settings.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +src/commons.h: + +src/config.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +src/error.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/sha1.Po b/goaccess++/src/.deps/sha1.Po new file mode 100644 index 0000000..e7756bb --- /dev/null +++ b/goaccess++/src/.deps/sha1.Po @@ -0,0 +1,171 @@ +src/sha1.o: src/sha1.c /usr/include/stdc-predef.h /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/sha1.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h + +/usr/include/stdc-predef.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/sha1.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: diff --git a/goaccess++/src/.deps/sort.Po b/goaccess++/src/.deps/sort.Po new file mode 100644 index 0000000..a93cd26 --- /dev/null +++ b/goaccess++/src/.deps/sort.Po @@ -0,0 +1,257 @@ +src/sort.o: src/sort.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/getopt.h /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_ext.h /usr/include/errno.h \ + /usr/include/x86_64-linux-gnu/bits/errno.h /usr/include/linux/errno.h \ + /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + src/error.h src/commons.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/curses.h \ + /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/util.h src/sort.h src/parser.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/getopt.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_ext.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +src/error.h: + +src/commons.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/util.h: + +src/sort.h: + +src/parser.h: diff --git a/goaccess++/src/.deps/tcabdb.Po b/goaccess++/src/.deps/tcabdb.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/goaccess++/src/.deps/tcabdb.Po @@ -0,0 +1 @@ +# dummy diff --git a/goaccess++/src/.deps/tcbtdb.Po b/goaccess++/src/.deps/tcbtdb.Po new file mode 100644 index 0000000..9ce06a8 --- /dev/null +++ b/goaccess++/src/.deps/tcbtdb.Po @@ -0,0 +1 @@ +# dummy diff --git a/goaccess++/src/.deps/ui.Po b/goaccess++/src/.deps/ui.Po new file mode 100644 index 0000000..869248a --- /dev/null +++ b/goaccess++/src/.deps/ui.Po @@ -0,0 +1,348 @@ +src/ui.o: src/ui.c /usr/include/stdc-predef.h src/config.h \ + /usr/include/pthread.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h /usr/include/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/sched.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h \ + /usr/include/x86_64-linux-gnu/bits/cpu-set.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/setjmp.h /usr/include/ctype.h \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/inttypes.h /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h \ + /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/locale.h \ + /usr/include/x86_64-linux-gnu/bits/locale.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/ui.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h /usr/include/stdio.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/labels.h /usr/include/libintl.h src/color.h \ + src/commons.h src/sort.h src/parser.h src/gkhash.h src/gslist.h \ + src/gstorage.h src/khash.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/error.h \ + src/settings.h src/gmenu.h src/goaccess.h src/util.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +src/config.h: + +/usr/include/pthread.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/sched.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_sched_param.h: + +/usr/include/x86_64-linux-gnu/bits/cpu-set.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/x86_64-linux-gnu/bits/setjmp.h: + +/usr/include/ctype.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/inttypes.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/ui.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/include/stdio.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/labels.h: + +/usr/include/libintl.h: + +src/color.h: + +src/commons.h: + +src/sort.h: + +src/parser.h: + +src/gkhash.h: + +src/gslist.h: + +src/gstorage.h: + +src/khash.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/error.h: + +src/settings.h: + +src/gmenu.h: + +src/goaccess.h: + +src/util.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/util.Po b/goaccess++/src/.deps/util.Po new file mode 100644 index 0000000..18271a0 --- /dev/null +++ b/goaccess++/src/.deps/util.Po @@ -0,0 +1,310 @@ +src/util.o: src/util.c /usr/include/stdc-predef.h \ + /usr/include/arpa/inet.h /usr/include/features.h \ + /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket-constants.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h /usr/include/ctype.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/netdb.h /usr/include/x86_64-linux-gnu/bits/netdb.h \ + /usr/include/unistd.h /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/util.h src/error.h \ + src/commons.h src/config.h /usr/include/curses.h \ + /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/types/wint_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/wctype-wchar.h \ + /usr/include/x86_64-linux-gnu/bits/wchar2.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/labels.h /usr/include/libintl.h \ + /usr/include/locale.h /usr/include/x86_64-linux-gnu/bits/locale.h \ + src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/arpa/inet.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket-constants.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/ctype.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/util.h: + +src/error.h: + +src/commons.h: + +src/config.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/types/wint_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/wctype-wchar.h: + +/usr/include/x86_64-linux-gnu/bits/wchar2.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/labels.h: + +/usr/include/libintl.h: + +/usr/include/locale.h: + +/usr/include/x86_64-linux-gnu/bits/locale.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/websocket.Po b/goaccess++/src/.deps/websocket.Po new file mode 100644 index 0000000..0b5e6d2 --- /dev/null +++ b/goaccess++/src/.deps/websocket.Po @@ -0,0 +1,412 @@ +src/websocket.o: src/websocket.c /usr/include/stdc-predef.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h \ + /usr/include/arpa/inet.h /usr/include/netinet/in.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h \ + /usr/include/x86_64-linux-gnu/sys/socket.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h \ + /usr/include/x86_64-linux-gnu/bits/socket.h \ + /usr/include/x86_64-linux-gnu/bits/socket_type.h \ + /usr/include/x86_64-linux-gnu/bits/sockaddr.h \ + /usr/include/x86_64-linux-gnu/asm/socket.h \ + /usr/include/asm-generic/socket.h /usr/include/linux/posix_types.h \ + /usr/include/linux/stddef.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/posix_types_64.h \ + /usr/include/asm-generic/posix_types.h \ + /usr/include/x86_64-linux-gnu/asm/bitsperlong.h \ + /usr/include/asm-generic/bitsperlong.h \ + /usr/include/x86_64-linux-gnu/asm/sockios.h \ + /usr/include/asm-generic/sockios.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h \ + /usr/include/x86_64-linux-gnu/bits/socket2.h \ + /usr/include/x86_64-linux-gnu/bits/in.h /usr/include/ctype.h \ + /usr/include/errno.h /usr/include/x86_64-linux-gnu/bits/errno.h \ + /usr/include/linux/errno.h /usr/include/x86_64-linux-gnu/asm/errno.h \ + /usr/include/asm-generic/errno.h /usr/include/asm-generic/errno-base.h \ + /usr/include/fcntl.h /usr/include/x86_64-linux-gnu/bits/fcntl.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl-linux.h \ + /usr/include/x86_64-linux-gnu/bits/stat.h \ + /usr/include/x86_64-linux-gnu/bits/fcntl2.h /usr/include/netdb.h \ + /usr/include/rpc/netdb.h /usr/include/x86_64-linux-gnu/bits/netdb.h \ + /usr/include/x86_64-linux-gnu/sys/stat.h \ + /usr/include/x86_64-linux-gnu/sys/time.h \ + /usr/include/x86_64-linux-gnu/sys/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctls.h \ + /usr/include/x86_64-linux-gnu/asm/ioctls.h \ + /usr/include/asm-generic/ioctls.h /usr/include/linux/ioctl.h \ + /usr/include/x86_64-linux-gnu/asm/ioctl.h \ + /usr/include/asm-generic/ioctl.h \ + /usr/include/x86_64-linux-gnu/bits/ioctl-types.h \ + /usr/include/x86_64-linux-gnu/sys/ttydefaults.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/unistd.h /usr/include/x86_64-linux-gnu/bits/posix_opt.h \ + /usr/include/x86_64-linux-gnu/bits/environments.h \ + /usr/include/x86_64-linux-gnu/bits/confname.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_posix.h \ + /usr/include/x86_64-linux-gnu/bits/getopt_core.h \ + /usr/include/x86_64-linux-gnu/bits/unistd.h \ + /usr/include/x86_64-linux-gnu/bits/unistd_ext.h src/config.h \ + src/websocket.h /usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h \ + /usr/include/limits.h /usr/include/x86_64-linux-gnu/bits/posix1_lim.h \ + /usr/include/x86_64-linux-gnu/bits/local_lim.h \ + /usr/include/linux/limits.h \ + /usr/include/x86_64-linux-gnu/bits/posix2_lim.h src/gslist.h \ + src/base64.h src/error.h src/commons.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h /usr/include/curses.h \ + /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/sha1.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +/usr/include/arpa/inet.h: + +/usr/include/netinet/in.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/x86_64-linux-gnu/sys/socket.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_iovec.h: + +/usr/include/x86_64-linux-gnu/bits/socket.h: + +/usr/include/x86_64-linux-gnu/bits/socket_type.h: + +/usr/include/x86_64-linux-gnu/bits/sockaddr.h: + +/usr/include/x86_64-linux-gnu/asm/socket.h: + +/usr/include/asm-generic/socket.h: + +/usr/include/linux/posix_types.h: + +/usr/include/linux/stddef.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/posix_types_64.h: + +/usr/include/asm-generic/posix_types.h: + +/usr/include/x86_64-linux-gnu/asm/bitsperlong.h: + +/usr/include/asm-generic/bitsperlong.h: + +/usr/include/x86_64-linux-gnu/asm/sockios.h: + +/usr/include/asm-generic/sockios.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_osockaddr.h: + +/usr/include/x86_64-linux-gnu/bits/socket2.h: + +/usr/include/x86_64-linux-gnu/bits/in.h: + +/usr/include/ctype.h: + +/usr/include/errno.h: + +/usr/include/x86_64-linux-gnu/bits/errno.h: + +/usr/include/linux/errno.h: + +/usr/include/x86_64-linux-gnu/asm/errno.h: + +/usr/include/asm-generic/errno.h: + +/usr/include/asm-generic/errno-base.h: + +/usr/include/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl-linux.h: + +/usr/include/x86_64-linux-gnu/bits/stat.h: + +/usr/include/x86_64-linux-gnu/bits/fcntl2.h: + +/usr/include/netdb.h: + +/usr/include/rpc/netdb.h: + +/usr/include/x86_64-linux-gnu/bits/netdb.h: + +/usr/include/x86_64-linux-gnu/sys/stat.h: + +/usr/include/x86_64-linux-gnu/sys/time.h: + +/usr/include/x86_64-linux-gnu/sys/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctls.h: + +/usr/include/x86_64-linux-gnu/asm/ioctls.h: + +/usr/include/asm-generic/ioctls.h: + +/usr/include/linux/ioctl.h: + +/usr/include/x86_64-linux-gnu/asm/ioctl.h: + +/usr/include/asm-generic/ioctl.h: + +/usr/include/x86_64-linux-gnu/bits/ioctl-types.h: + +/usr/include/x86_64-linux-gnu/sys/ttydefaults.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/posix_opt.h: + +/usr/include/x86_64-linux-gnu/bits/environments.h: + +/usr/include/x86_64-linux-gnu/bits/confname.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_posix.h: + +/usr/include/x86_64-linux-gnu/bits/getopt_core.h: + +/usr/include/x86_64-linux-gnu/bits/unistd.h: + +/usr/include/x86_64-linux-gnu/bits/unistd_ext.h: + +src/config.h: + +src/websocket.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/limits.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/syslimits.h: + +/usr/include/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix1_lim.h: + +/usr/include/x86_64-linux-gnu/bits/local_lim.h: + +/usr/include/linux/limits.h: + +/usr/include/x86_64-linux-gnu/bits/posix2_lim.h: + +src/gslist.h: + +src/base64.h: + +src/error.h: + +src/commons.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/sha1.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.deps/xmalloc.Po b/goaccess++/src/.deps/xmalloc.Po new file mode 100644 index 0000000..7241dfa --- /dev/null +++ b/goaccess++/src/.deps/xmalloc.Po @@ -0,0 +1,230 @@ +src/xmalloc.o: src/xmalloc.c /usr/include/stdc-predef.h \ + /usr/include/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/libc-header-start.h \ + /usr/include/features.h /usr/include/x86_64-linux-gnu/sys/cdefs.h \ + /usr/include/x86_64-linux-gnu/bits/wordsize.h \ + /usr/include/x86_64-linux-gnu/bits/long-double.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs.h \ + /usr/include/x86_64-linux-gnu/gnu/stubs-64.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h \ + /usr/include/x86_64-linux-gnu/bits/types.h \ + /usr/include/x86_64-linux-gnu/bits/timesize.h \ + /usr/include/x86_64-linux-gnu/bits/typesizes.h \ + /usr/include/x86_64-linux-gnu/bits/time64.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/FILE.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h \ + /usr/include/x86_64-linux-gnu/bits/stdio_lim.h \ + /usr/include/x86_64-linux-gnu/bits/sys_errlist.h \ + /usr/include/x86_64-linux-gnu/bits/stdio.h \ + /usr/include/x86_64-linux-gnu/bits/stdio2.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h /usr/include/stdint.h \ + /usr/include/x86_64-linux-gnu/bits/wchar.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-intn.h \ + /usr/include/x86_64-linux-gnu/bits/stdint-uintn.h /usr/include/stdlib.h \ + /usr/include/x86_64-linux-gnu/bits/waitflags.h \ + /usr/include/x86_64-linux-gnu/bits/waitstatus.h \ + /usr/include/x86_64-linux-gnu/bits/floatn.h \ + /usr/include/x86_64-linux-gnu/bits/floatn-common.h \ + /usr/include/x86_64-linux-gnu/sys/types.h \ + /usr/include/x86_64-linux-gnu/bits/types/clock_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/clockid_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/time_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/timer_t.h /usr/include/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endian.h \ + /usr/include/x86_64-linux-gnu/bits/endianness.h \ + /usr/include/x86_64-linux-gnu/bits/byteswap.h \ + /usr/include/x86_64-linux-gnu/bits/uintn-identity.h \ + /usr/include/x86_64-linux-gnu/sys/select.h \ + /usr/include/x86_64-linux-gnu/bits/select.h \ + /usr/include/x86_64-linux-gnu/bits/types/sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h \ + /usr/include/x86_64-linux-gnu/bits/select2.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes.h \ + /usr/include/x86_64-linux-gnu/bits/thread-shared-types.h \ + /usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h \ + /usr/include/x86_64-linux-gnu/bits/struct_mutex.h \ + /usr/include/x86_64-linux-gnu/bits/struct_rwlock.h /usr/include/alloca.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib-float.h \ + /usr/include/x86_64-linux-gnu/bits/stdlib.h /usr/include/string.h \ + /usr/include/x86_64-linux-gnu/bits/types/locale_t.h \ + /usr/include/x86_64-linux-gnu/bits/types/__locale_t.h \ + /usr/include/strings.h \ + /usr/include/x86_64-linux-gnu/bits/strings_fortified.h \ + /usr/include/x86_64-linux-gnu/bits/string_fortified.h src/error.h \ + src/commons.h src/config.h /usr/include/time.h \ + /usr/include/x86_64-linux-gnu/bits/time.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_tm.h \ + /usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h \ + /usr/include/curses.h /usr/include/ncurses_dll.h \ + /usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h /usr/include/unctrl.h \ + /usr/include/curses.h src/settings.h src/xmalloc.h + +/usr/include/stdc-predef.h: + +/usr/include/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/libc-header-start.h: + +/usr/include/features.h: + +/usr/include/x86_64-linux-gnu/sys/cdefs.h: + +/usr/include/x86_64-linux-gnu/bits/wordsize.h: + +/usr/include/x86_64-linux-gnu/bits/long-double.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs.h: + +/usr/include/x86_64-linux-gnu/gnu/stubs-64.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stddef.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdarg.h: + +/usr/include/x86_64-linux-gnu/bits/types.h: + +/usr/include/x86_64-linux-gnu/bits/timesize.h: + +/usr/include/x86_64-linux-gnu/bits/typesizes.h: + +/usr/include/x86_64-linux-gnu/bits/time64.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__mbstate_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__fpos64_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/FILE.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_FILE.h: + +/usr/include/x86_64-linux-gnu/bits/stdio_lim.h: + +/usr/include/x86_64-linux-gnu/bits/sys_errlist.h: + +/usr/include/x86_64-linux-gnu/bits/stdio.h: + +/usr/include/x86_64-linux-gnu/bits/stdio2.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdint.h: + +/usr/include/stdint.h: + +/usr/include/x86_64-linux-gnu/bits/wchar.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-intn.h: + +/usr/include/x86_64-linux-gnu/bits/stdint-uintn.h: + +/usr/include/stdlib.h: + +/usr/include/x86_64-linux-gnu/bits/waitflags.h: + +/usr/include/x86_64-linux-gnu/bits/waitstatus.h: + +/usr/include/x86_64-linux-gnu/bits/floatn.h: + +/usr/include/x86_64-linux-gnu/bits/floatn-common.h: + +/usr/include/x86_64-linux-gnu/sys/types.h: + +/usr/include/x86_64-linux-gnu/bits/types/clock_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/clockid_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/time_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/timer_t.h: + +/usr/include/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endian.h: + +/usr/include/x86_64-linux-gnu/bits/endianness.h: + +/usr/include/x86_64-linux-gnu/bits/byteswap.h: + +/usr/include/x86_64-linux-gnu/bits/uintn-identity.h: + +/usr/include/x86_64-linux-gnu/sys/select.h: + +/usr/include/x86_64-linux-gnu/bits/select.h: + +/usr/include/x86_64-linux-gnu/bits/types/sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__sigset_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timeval.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_timespec.h: + +/usr/include/x86_64-linux-gnu/bits/select2.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes.h: + +/usr/include/x86_64-linux-gnu/bits/thread-shared-types.h: + +/usr/include/x86_64-linux-gnu/bits/pthreadtypes-arch.h: + +/usr/include/x86_64-linux-gnu/bits/struct_mutex.h: + +/usr/include/x86_64-linux-gnu/bits/struct_rwlock.h: + +/usr/include/alloca.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-bsearch.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib-float.h: + +/usr/include/x86_64-linux-gnu/bits/stdlib.h: + +/usr/include/string.h: + +/usr/include/x86_64-linux-gnu/bits/types/locale_t.h: + +/usr/include/x86_64-linux-gnu/bits/types/__locale_t.h: + +/usr/include/strings.h: + +/usr/include/x86_64-linux-gnu/bits/strings_fortified.h: + +/usr/include/x86_64-linux-gnu/bits/string_fortified.h: + +src/error.h: + +src/commons.h: + +src/config.h: + +/usr/include/time.h: + +/usr/include/x86_64-linux-gnu/bits/time.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_tm.h: + +/usr/include/x86_64-linux-gnu/bits/types/struct_itimerspec.h: + +/usr/include/curses.h: + +/usr/include/ncurses_dll.h: + +/usr/lib/gcc/x86_64-linux-gnu/9/include/stdbool.h: + +/usr/include/unctrl.h: + +/usr/include/curses.h: + +src/settings.h: + +src/xmalloc.h: diff --git a/goaccess++/src/.dirstamp b/goaccess++/src/.dirstamp new file mode 100644 index 0000000..e69de29 diff --git a/goaccess++/src/appcss.h b/goaccess++/src/appcss.h new file mode 100644 index 0000000..f819816 --- /dev/null +++ b/goaccess++/src/appcss.h @@ -0,0 +1,1512 @@ +const char app_css[16588] = { + 0x2f, 0x2a, 0x20, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x20, 0x2a, + 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x2c, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x3a, 0x20, 0x23, 0x66, 0x30, 0x66, 0x30, 0x66, 0x30, 0x3b, 0x6f, + 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2d, 0x78, 0x3a, 0x20, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x7d, 0x68, 0x31, 0x20, + 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x20, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x6c, 0x65, 0x74, + 0x74, 0x65, 0x72, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, + 0x3a, 0x20, 0x2d, 0x33, 0x70, 0x78, 0x3b, 0x7d, 0x68, 0x33, 0x20, + 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x20, 0x32, 0x31, 0x70, 0x78, 0x3b, 0x6c, 0x65, 0x74, 0x74, 0x65, + 0x72, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x2d, 0x31, 0x70, 0x78, 0x3b, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, + 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x20, 0x30, 0x2c, + 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2e, 0x31, 0x35, 0x29, 0x3b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x32, 0x35, 0x70, 0x78, + 0x20, 0x30, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x3b, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x68, 0x31, 0x20, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30, 0x3b, + 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, + 0x35, 0x70, 0x78, 0x20, 0x30, 0x3b, 0x7d, 0x2e, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x2e, 0x65, 0x78, 0x70, + 0x61, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x64, 0x20, + 0x7b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x20, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x7d, 0x2e, 0x73, 0x70, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x39, 0x39, 0x39, 0x3b, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x20, 0x35, 0x30, 0x25, 0x3b, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, + 0x74, 0x65, 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x35, 0x30, 0x25, + 0x3b, 0x7d, 0x2e, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x64, 0x20, + 0x7b, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x39, + 0x30, 0x70, 0x78, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x3b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, + 0x65, 0x3b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x32, 0x30, + 0x70, 0x78, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x31, + 0x30, 0x30, 0x25, 0x20, 0x30, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x72, 0x6f, 0x74, 0x61, 0x74, + 0x65, 0x28, 0x2d, 0x39, 0x30, 0x64, 0x65, 0x67, 0x29, 0x3b, 0x7d, + 0x2e, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x64, 0x20, 0x61, 0x20, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x36, 0x33, + 0x36, 0x33, 0x36, 0x33, 0x3b, 0x7d, 0x2e, 0x70, 0x6f, 0x77, 0x65, + 0x72, 0x65, 0x64, 0x20, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x37, 0x62, + 0x63, 0x33, 0x3b, 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x37, + 0x62, 0x63, 0x33, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3a, 0x20, 0x33, 0x70, 0x78, 0x20, 0x32, 0x35, 0x70, 0x78, 0x3b, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72, 0x63, + 0x61, 0x73, 0x65, 0x3b, 0x7d, 0x2e, 0x67, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x7b, 0x6c, 0x65, 0x74, 0x74, 0x65, 0x72, 0x2d, + 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x2d, 0x31, + 0x70, 0x78, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x75, 0x70, 0x70, + 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x3b, 0x7d, 0x68, 0x35, 0x2e, + 0x67, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x6c, 0x65, + 0x74, 0x74, 0x65, 0x72, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x30, 0x3b, 0x7d, 0x2e, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x68, 0x34, + 0x2e, 0x67, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, + 0x32, 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x2e, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x2e, 0x67, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x73, 0x6d, 0x61, 0x6c, + 0x6c, 0x20, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x20, 0x36, 0x39, 0x25, 0x3b, 0x7d, 0x2f, 0x2a, 0x20, + 0x4e, 0x41, 0x56, 0x49, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x20, + 0x2a, 0x2f, 0x6e, 0x61, 0x76, 0x20, 0x7b, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x2e, + 0x32, 0x73, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x31, 0x43, 0x31, 0x43, 0x31, 0x43, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x20, 0x33, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x23, 0x35, 0x62, 0x63, 0x30, 0x64, 0x65, 0x3b, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x30, 0x30, + 0x25, 0x3b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x2d, 0x32, 0x33, + 0x36, 0x70, 0x78, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, + 0x77, 0x3a, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x69, + 0x78, 0x65, 0x64, 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x30, 0x3b, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x2e, 0x32, 0x73, 0x3b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x33, 0x30, 0x30, 0x70, 0x78, + 0x3b, 0x7a, 0x2d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x32, + 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x2e, 0x6e, 0x61, 0x76, 0x2d, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x6f, 0x76, 0x65, + 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2d, 0x79, 0x3a, 0x20, 0x61, 0x75, + 0x74, 0x6f, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x33, + 0x35, 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x3a, 0x20, 0x34, 0x30, 0x70, 0x78, 0x20, 0x32, 0x30, + 0x70, 0x78, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x6e, 0x61, + 0x76, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x61, 0x20, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x72, 0x67, 0x62, + 0x61, 0x28, 0x32, 0x34, 0x30, 0x2c, 0x32, 0x34, 0x30, 0x2c, 0x32, + 0x34, 0x30, 0x2c, 0x2e, 0x37, 0x29, 0x3b, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x32, 0x2e, 0x37, 0x65, + 0x6d, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x20, 0x33, 0x30, 0x30, 0x3b, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x3a, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, + 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x20, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x7b, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x65, 0x65, 0x65, + 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x20, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x3b, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x20, 0x30, 0x3b, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, + 0x3a, 0x20, 0x2e, 0x39, 0x37, 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x7e, 0x20, 0x23, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x7b, 0x6f, 0x70, 0x61, 0x63, + 0x69, 0x74, 0x79, 0x3a, 0x20, 0x2e, 0x33, 0x3b, 0x7d, 0x6e, 0x61, + 0x76, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x2e, 0x6e, + 0x61, 0x76, 0x2d, 0x62, 0x61, 0x72, 0x73, 0x2c, 0x6e, 0x61, 0x76, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x2e, 0x6e, 0x61, + 0x76, 0x2d, 0x67, 0x65, 0x61, 0x72, 0x73, 0x2c, 0x6e, 0x61, 0x76, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x2e, 0x6e, 0x61, + 0x76, 0x2d, 0x77, 0x73, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x20, 0x7b, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x20, + 0x30, 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x2e, 0x6e, 0x61, 0x76, + 0x2d, 0x62, 0x61, 0x72, 0x73, 0x2c, 0x6e, 0x61, 0x76, 0x20, 0x2e, + 0x6e, 0x61, 0x76, 0x2d, 0x67, 0x65, 0x61, 0x72, 0x73, 0x2c, 0x6e, + 0x61, 0x76, 0x20, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x77, 0x73, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x7b, 0x2d, 0x77, 0x65, + 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x6f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x20, 0x2e, 0x32, 0x73, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, + 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x20, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, + 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x33, 0x36, 0x70, 0x78, + 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x33, 0x32, + 0x70, 0x78, 0x3b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x31, 0x33, + 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x20, 0x33, 0x32, 0x70, 0x78, 0x3b, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x69, + 0x78, 0x65, 0x64, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x33, 0x30, 0x70, 0x78, 0x3b, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x20, 0x2e, 0x32, + 0x73, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x33, 0x32, + 0x70, 0x78, 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x2e, 0x6e, 0x61, + 0x76, 0x2d, 0x67, 0x65, 0x61, 0x72, 0x73, 0x20, 0x7b, 0x74, 0x6f, + 0x70, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x70, 0x78, 0x3b, 0x6f, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x30, 0x2e, 0x36, 0x3b, + 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x77, + 0x73, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2c, 0x2e, 0x6e, + 0x61, 0x76, 0x2d, 0x77, 0x73, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x2e, 0x6d, 0x69, 0x6e, 0x69, 0x20, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x36, 0x41, 0x36, 0x41, 0x36, 0x41, + 0x3b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x20, 0x68, 0x65, + 0x6c, 0x70, 0x3b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, + 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3b, + 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x77, + 0x73, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x20, 0x32, 0x35, 0x70, 0x78, 0x3b, 0x74, + 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x32, 0x35, 0x70, 0x78, 0x3b, 0x7d, + 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x77, 0x73, 0x2d, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x2e, 0x6d, 0x69, 0x6e, 0x69, 0x20, 0x7b, 0x74, + 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x34, 0x70, 0x78, 0x3b, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x20, 0x35, 0x30, 0x70, 0x78, 0x3b, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x62, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x7d, 0x2e, 0x6e, 0x61, 0x76, + 0x2d, 0x77, 0x73, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x7b, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x35, 0x44, 0x42, + 0x35, 0x36, 0x41, 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x6c, 0x69, + 0x20, 0x61, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x33, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x30, 0x30, 0x2c, + 0x32, 0x30, 0x30, 0x2c, 0x32, 0x30, 0x30, 0x2c, 0x2e, 0x35, 0x29, + 0x3b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x3b, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x20, 0x32, 0x33, 0x35, 0x70, 0x78, 0x3b, 0x6f, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x30, 0x3b, 0x6f, 0x76, 0x65, + 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, 0x68, 0x69, 0x64, 0x64, + 0x65, 0x6e, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x20, 0x39, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x74, + 0x65, 0x78, 0x74, 0x2d, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, + 0x77, 0x3a, 0x20, 0x65, 0x6c, 0x6c, 0x69, 0x70, 0x73, 0x69, 0x73, + 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72, + 0x63, 0x61, 0x73, 0x65, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x6f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x20, 0x2e, 0x32, 0x73, 0x3b, 0x77, 0x68, 0x69, 0x74, + 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, 0x6e, 0x6f, + 0x77, 0x72, 0x61, 0x70, 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x6c, 0x69, 0x20, 0x61, 0x20, + 0x7b, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x20, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x6f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x3a, 0x20, 0x31, 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x20, + 0x6c, 0x69, 0x20, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x6e, 0x61, 0x76, 0x20, 0x6c, 0x69, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x20, 0x61, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x72, 0x67, 0x62, 0x61, + 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x2e, 0x31, 0x29, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x35, 0x42, 0x43, 0x30, 0x44, 0x45, 0x3b, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x65, 0x65, 0x65, + 0x3b, 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x75, 0x6c, 0x20, 0x7b, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x20, 0x30, 0x3b, 0x6c, 0x69, 0x73, 0x74, 0x2d, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x7d, + 0x2f, 0x2a, 0x20, 0x4e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x20, 0x2d, 0x2d, 0x20, 0x49, 0x63, 0x6f, 0x6e, + 0x20, 0x2a, 0x2f, 0x6e, 0x61, 0x76, 0x20, 0x61, 0x2c, 0x6e, 0x61, + 0x76, 0x20, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x7b, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, + 0x7d, 0x6e, 0x61, 0x76, 0x20, 0x68, 0x33, 0x20, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x46, 0x20, 0x21, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x6d, + 0x65, 0x64, 0x69, 0x75, 0x6d, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, + 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x62, 0x6f, 0x6c, + 0x64, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x32, + 0x30, 0x70, 0x78, 0x20, 0x32, 0x35, 0x70, 0x78, 0x20, 0x31, 0x30, + 0x70, 0x78, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x20, 0x75, 0x70, 0x70, + 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x3b, 0x7d, 0x2f, 0x2a, 0x20, + 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x20, 0x2a, + 0x2f, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x73, 0x63, 0x72, + 0x65, 0x65, 0x6e, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x6d, 0x61, + 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x37, 0x36, + 0x37, 0x70, 0x78, 0x29, 0x20, 0x7b, 0x2e, 0x72, 0x6f, 0x77, 0x2d, + 0x6f, 0x66, 0x66, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x20, 0x7b, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x2e, 0x32, 0x35, 0x73, 0x20, 0x65, 0x61, 0x73, 0x65, + 0x2d, 0x6f, 0x75, 0x74, 0x3b, 0x2d, 0x6f, 0x2d, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x6c, + 0x6c, 0x20, 0x2e, 0x32, 0x35, 0x73, 0x20, 0x65, 0x61, 0x73, 0x65, + 0x2d, 0x6f, 0x75, 0x74, 0x3b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, + 0x65, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x2e, 0x32, 0x35, 0x73, + 0x20, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x6f, 0x75, 0x74, 0x3b, 0x7d, + 0x2e, 0x72, 0x6f, 0x77, 0x2d, 0x6f, 0x66, 0x66, 0x63, 0x61, 0x6e, + 0x76, 0x61, 0x73, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x7b, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x30, 0x3b, 0x7d, 0x2e, + 0x72, 0x6f, 0x77, 0x2d, 0x6f, 0x66, 0x66, 0x63, 0x61, 0x6e, 0x76, + 0x61, 0x73, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x7b, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x20, 0x30, 0x3b, 0x7d, 0x2e, 0x72, 0x6f, 0x77, + 0x2d, 0x6f, 0x66, 0x66, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x2d, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x2e, 0x73, 0x69, 0x64, 0x65, 0x62, + 0x61, 0x72, 0x2d, 0x6f, 0x66, 0x66, 0x63, 0x61, 0x6e, 0x76, 0x61, + 0x73, 0x20, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x2d, + 0x35, 0x30, 0x25, 0x3b, 0x7d, 0x2e, 0x72, 0x6f, 0x77, 0x2d, 0x6f, + 0x66, 0x66, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x2e, 0x73, 0x69, 0x64, 0x65, 0x62, 0x61, 0x72, 0x2d, + 0x6f, 0x66, 0x66, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x20, 0x7b, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x2d, 0x35, 0x30, 0x25, 0x3b, + 0x7d, 0x2e, 0x72, 0x6f, 0x77, 0x2d, 0x6f, 0x66, 0x66, 0x63, 0x61, + 0x6e, 0x76, 0x61, 0x73, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x7b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x20, 0x35, 0x30, 0x25, 0x3b, 0x7d, 0x2e, 0x72, + 0x6f, 0x77, 0x2d, 0x6f, 0x66, 0x66, 0x63, 0x61, 0x6e, 0x76, 0x61, + 0x73, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x20, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x35, + 0x30, 0x25, 0x3b, 0x7d, 0x2e, 0x73, 0x69, 0x64, 0x65, 0x62, 0x61, + 0x72, 0x2d, 0x6f, 0x66, 0x66, 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, + 0x20, 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x74, + 0x6f, 0x70, 0x3a, 0x20, 0x30, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x20, 0x35, 0x30, 0x25, 0x3b, 0x7d, 0x3b, 0x7d, 0x40, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x37, 0x36, 0x38, 0x70, 0x78, + 0x29, 0x20, 0x7b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x20, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, + 0x37, 0x35, 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x3b, 0x7d, 0x40, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x34, 0x38, 0x30, 0x70, 0x78, + 0x29, 0x20, 0x7b, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x68, 0x35, 0x2c, 0x2e, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x68, + 0x35, 0x20, 0x7b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x3a, 0x20, 0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, + 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, + 0x65, 0x6c, 0x6c, 0x69, 0x70, 0x73, 0x69, 0x73, 0x3b, 0x7d, 0x2e, + 0x77, 0x72, 0x61, 0x70, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x6c, 0x20, 0x68, 0x35, 0x20, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x20, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x77, 0x72, 0x61, + 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x68, 0x35, 0x20, + 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x37, 0x30, 0x25, + 0x7d, 0x7d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x20, 0x7b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, + 0x37, 0x35, 0x70, 0x78, 0x3b, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x20, 0x31, 0x31, 0x32, 0x30, 0x70, 0x78, 0x29, 0x20, + 0x7b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x20, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x39, 0x37, + 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x3b, 0x7d, 0x40, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x20, 0x31, 0x33, 0x32, 0x30, 0x70, 0x78, 0x29, + 0x20, 0x7b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x20, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, + 0x31, 0x37, 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x3b, 0x7d, 0x40, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x39, 0x39, 0x32, 0x70, 0x78, + 0x29, 0x20, 0x7b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x20, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x20, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x7d, 0x3b, 0x7d, 0x40, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x37, 0x36, 0x38, 0x70, 0x78, + 0x29, 0x20, 0x7b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x20, 0x7b, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x20, 0x35, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x35, + 0x70, 0x78, 0x3b, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x2d, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30, 0x20, 0x31, 0x30, 0x70, 0x78, + 0x3b, 0x7d, 0x7d, 0x2f, 0x2a, 0x20, 0x50, 0x41, 0x4e, 0x45, 0x4c, + 0x20, 0x53, 0x54, 0x59, 0x4c, 0x45, 0x53, 0x20, 0x2a, 0x2f, 0x2e, + 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, + 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x20, 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x3b, 0x7d, 0x64, 0x69, 0x76, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x64, 0x69, 0x76, + 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x46, 0x3b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x30, + 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x20, 0x30, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x70, + 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x67, 0x62, + 0x61, 0x28, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, + 0x30, 0x2e, 0x31, 0x35, 0x29, 0x3b, 0x7d, 0x2f, 0x2a, 0x20, 0x50, + 0x41, 0x4e, 0x45, 0x4c, 0x20, 0x54, 0x41, 0x42, 0x4c, 0x45, 0x53, + 0x20, 0x2a, 0x2f, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x6c, 0x65, 0x73, 0x73, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x74, 0x72, 0x20, 0x74, 0x64, 0x2c, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x20, 0x74, 0x72, 0x20, 0x74, 0x68, 0x2c, 0x2e, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x61, 0x64, 0x20, 0x74, 0x72, 0x20, 0x74, 0x68, + 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x7d, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x74, 0x68, 0x65, 0x61, 0x64, 0x20, 0x74, 0x72, 0x20, 0x74, + 0x68, 0x20, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x70, + 0x78, 0x3b, 0x7d, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x2e, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x2e, 0x77, 0x72, 0x61, + 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x20, 0x7b, 0x74, + 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, + 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x7d, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x2e, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x20, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x38, 0x39, + 0x38, 0x39, 0x38, 0x39, 0x3b, 0x7d, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x74, 0x64, 0x2c, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x74, 0x68, 0x20, 0x7b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, 0x6e, 0x6f, 0x77, 0x72, + 0x61, 0x70, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, + 0x3a, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x7d, 0x2e, + 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x2e, 0x73, 0x6f, + 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x7b, 0x63, 0x75, 0x72, + 0x73, 0x6f, 0x72, 0x3a, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x3b, 0x7d, 0x2f, 0x2a, 0x20, 0x74, 0x68, 0x65, 0x61, 0x64, + 0x20, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x2a, 0x2f, 0x2e, 0x77, 0x72, + 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x7b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, + 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, + 0x23, 0x43, 0x37, 0x43, 0x37, 0x43, 0x37, 0x3b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, + 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, + 0x23, 0x43, 0x37, 0x43, 0x37, 0x43, 0x37, 0x3b, 0x7d, 0x2e, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x74, 0x72, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x46, 0x31, 0x46, 0x31, 0x46, 0x31, 0x3b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x32, 0x32, 0x3b, 0x7d, 0x2e, + 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x6d, 0x65, 0x74, 0x61, + 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x20, 0x7b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x36, 0x35, 0x25, + 0x3b, 0x7d, 0x2f, 0x2a, 0x20, 0x74, 0x68, 0x65, 0x61, 0x64, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x20, 0x2a, 0x2f, 0x2e, 0x77, 0x72, 0x61, + 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x72, + 0x20, 0x74, 0x64, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x70, 0x78, + 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x46, 0x31, 0x46, + 0x31, 0x46, 0x31, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x65, 0x72, + 0x3b, 0x7d, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, + 0x61, 0x74, 0x61, 0x20, 0x74, 0x64, 0x3a, 0x6c, 0x61, 0x73, 0x74, + 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x20, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x7d, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x64, 0x2e, + 0x72, 0x6f, 0x77, 0x2d, 0x69, 0x64, 0x78, 0x20, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x38, 0x39, 0x38, 0x39, 0x38, + 0x39, 0x3b, 0x7d, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x2b, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x20, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, + 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x70, 0x78, + 0x3b, 0x7d, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, + 0x61, 0x74, 0x61, 0x20, 0x74, 0x72, 0x2e, 0x73, 0x68, 0x61, 0x64, + 0x65, 0x64, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x46, 0x37, 0x46, 0x37, 0x46, 0x37, 0x3b, 0x7d, 0x2e, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x20, + 0x74, 0x72, 0x2e, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x46, 0x37, 0x46, 0x37, 0x46, 0x37, 0x3b, 0x7d, 0x2e, + 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, 0x61, + 0x20, 0x74, 0x72, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x20, 0x74, + 0x64, 0x3a, 0x6e, 0x74, 0x68, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x28, 0x31, 0x29, 0x2c, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x2d, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x72, 0x2e, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x20, 0x74, 0x64, 0x3a, 0x6e, 0x74, 0x68, 0x2d, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x32, 0x29, 0x20, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x7d, 0x2e, 0x77, 0x72, + 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0x74, 0x72, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x7b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x45, 0x45, 0x45, 0x3b, + 0x7d, 0x2f, 0x2a, 0x20, 0x47, 0x45, 0x4e, 0x45, 0x52, 0x41, 0x4c, + 0x20, 0x2a, 0x2f, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x7b, 0x70, 0x6f, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x3b, 0x7d, 0x2e, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, + 0x46, 0x46, 0x46, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x34, 0x70, 0x78, + 0x3b, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x2d, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x20, 0x30, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, 0x62, 0x73, 0x6f, + 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x20, 0x30, 0x3b, 0x7a, 0x2d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, + 0x20, 0x31, 0x3b, 0x7d, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, + 0x70, 0x6c, 0x6f, 0x74, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x20, 0x7b, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x61, + 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x20, 0x30, 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x20, + 0x31, 0x38, 0x70, 0x78, 0x3b, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x7b, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x38, 0x35, 0x25, 0x3b, + 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, 0x65, + 0x6c, 0x6c, 0x69, 0x70, 0x73, 0x69, 0x73, 0x3b, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x20, 0x31, + 0x70, 0x78, 0x20, 0x31, 0x70, 0x78, 0x20, 0x30, 0x20, 0x23, 0x46, + 0x46, 0x46, 0x3b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x3a, 0x20, 0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, + 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, + 0x25, 0x3b, 0x7d, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x46, + 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x72, 0x67, 0x62, + 0x28, 0x33, 0x36, 0x2c, 0x20, 0x33, 0x36, 0x2c, 0x20, 0x33, 0x36, + 0x29, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, + 0x20, 0x35, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x37, 0x70, 0x78, 0x3b, 0x7d, 0x2e, 0x67, 0x72, + 0x69, 0x64, 0x2d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x68, + 0x33, 0x20, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x20, 0x32, 0x35, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x3a, 0x20, 0x30, 0x3b, 0x6f, 0x76, 0x65, 0x72, + 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, + 0x6e, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x6f, 0x76, 0x65, 0x72, + 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, 0x65, 0x6c, 0x6c, 0x69, 0x70, + 0x73, 0x69, 0x73, 0x3b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, 0x6e, 0x6f, 0x77, 0x72, 0x61, + 0x70, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, + 0x30, 0x25, 0x3b, 0x7d, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, + 0x70, 0x3a, 0x20, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x23, 0x30, 0x46, 0x31, 0x32, 0x31, 0x34, 0x3b, 0x7d, + 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x34, 0x70, + 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x39, 0x45, + 0x39, 0x45, 0x39, 0x45, 0x3b, 0x7d, 0x2e, 0x67, 0x72, 0x69, 0x64, + 0x2d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x72, 0x65, 0x64, + 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, + 0x70, 0x3a, 0x20, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x23, 0x46, 0x46, 0x33, 0x30, 0x33, 0x45, 0x3b, 0x7d, + 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x7b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x34, 0x70, 0x78, + 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x30, 0x30, 0x44, + 0x34, 0x45, 0x31, 0x3b, 0x7d, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x67, 0x72, 0x65, 0x65, + 0x6e, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, + 0x6f, 0x70, 0x3a, 0x20, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x23, 0x35, 0x44, 0x42, 0x35, 0x36, 0x41, 0x3b, + 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x61, + 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x37, 0x36, + 0x37, 0x70, 0x78, 0x29, 0x20, 0x7b, 0x2e, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2d, 0x70, 0x6c, 0x6f, 0x74, 0x2d, 0x77, 0x72, 0x61, 0x70, + 0x20, 0x7b, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, + 0x3b, 0x7d, 0x2e, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x65, 0x64, 0x20, + 0x7b, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x30, + 0x70, 0x78, 0x3b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x32, 0x35, + 0x70, 0x78, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, + 0x6d, 0x3a, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x3b, + 0x7d, 0x7d, 0x2f, 0x2a, 0x20, 0x43, 0x48, 0x41, 0x52, 0x54, 0x53, + 0x20, 0x2a, 0x2f, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x77, + 0x72, 0x61, 0x70, 0x20, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x35, + 0x70, 0x78, 0x3b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b, + 0x7d, 0x73, 0x76, 0x67, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, + 0x7d, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x20, 0x70, 0x61, 0x74, 0x68, + 0x20, 0x7b, 0x66, 0x69, 0x6c, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x73, 0x74, + 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, 0x62, 0x6c, 0x61, 0x63, 0x6b, + 0x3b, 0x73, 0x68, 0x61, 0x70, 0x65, 0x2d, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x63, 0x72, 0x69, 0x73, + 0x70, 0x45, 0x64, 0x67, 0x65, 0x73, 0x3b, 0x73, 0x74, 0x72, 0x6f, + 0x6b, 0x65, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, + 0x3b, 0x7d, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x79, 0x20, 0x2e, + 0x74, 0x69, 0x63, 0x6b, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, + 0x67, 0x72, 0x69, 0x64, 0x2e, 0x78, 0x20, 0x2e, 0x74, 0x69, 0x63, + 0x6b, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x7b, 0x73, 0x68, 0x61, + 0x70, 0x65, 0x2d, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x63, 0x72, 0x69, 0x73, 0x70, 0x45, 0x64, 0x67, + 0x65, 0x73, 0x3b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, + 0x23, 0x39, 0x39, 0x39, 0x3b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, + 0x2d, 0x64, 0x61, 0x73, 0x68, 0x61, 0x72, 0x72, 0x61, 0x79, 0x3a, + 0x20, 0x33, 0x20, 0x33, 0x3b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, + 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x3b, 0x7d, + 0x2e, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x78, 0x20, 0x2e, 0x74, 0x69, + 0x63, 0x6b, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x61, 0x78, + 0x69, 0x73, 0x2e, 0x79, 0x30, 0x20, 0x2e, 0x74, 0x69, 0x63, 0x6b, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x61, 0x78, 0x69, 0x73, + 0x2e, 0x79, 0x31, 0x20, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x79, + 0x20, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x3a, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, + 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x3b, 0x73, 0x74, 0x72, 0x6f, 0x6b, + 0x65, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x3b, + 0x73, 0x68, 0x61, 0x70, 0x65, 0x2d, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x63, 0x72, 0x69, 0x73, 0x70, + 0x45, 0x64, 0x67, 0x65, 0x73, 0x3b, 0x7d, 0x2e, 0x62, 0x61, 0x72, + 0x73, 0x20, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x62, 0x61, 0x72, 0x20, + 0x7b, 0x73, 0x68, 0x61, 0x70, 0x65, 0x2d, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x63, 0x72, 0x69, 0x73, + 0x70, 0x45, 0x64, 0x67, 0x65, 0x73, 0x3b, 0x7d, 0x2e, 0x72, 0x65, + 0x63, 0x74, 0x73, 0x20, 0x72, 0x65, 0x63, 0x74, 0x20, 0x7b, 0x66, + 0x69, 0x6c, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x7d, 0x2e, 0x61, 0x72, 0x65, + 0x61, 0x20, 0x7b, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, + 0x20, 0x30, 0x2e, 0x32, 0x3b, 0x7d, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x73, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, + 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x3b, 0x7d, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x69, 0x6e, 0x64, + 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x7b, 0x66, 0x69, 0x6c, + 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x3b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x2d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x6e, 0x6f, + 0x6e, 0x65, 0x3b, 0x73, 0x68, 0x61, 0x70, 0x65, 0x2d, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x63, 0x72, + 0x69, 0x73, 0x70, 0x45, 0x64, 0x67, 0x65, 0x73, 0x3b, 0x73, 0x74, + 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, 0x23, 0x39, 0x39, 0x39, 0x3b, + 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x20, 0x31, 0x3b, 0x7d, 0x2e, 0x61, 0x72, 0x65, 0x61, + 0x30, 0x2c, 0x2e, 0x62, 0x61, 0x72, 0x73, 0x2e, 0x79, 0x30, 0x20, + 0x2e, 0x62, 0x61, 0x72, 0x2c, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x73, 0x2e, 0x79, 0x30, 0x2c, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x6c, + 0x65, 0x67, 0x65, 0x6e, 0x64, 0x2e, 0x79, 0x30, 0x20, 0x7b, 0x66, + 0x69, 0x6c, 0x6c, 0x3a, 0x20, 0x23, 0x34, 0x34, 0x37, 0x46, 0x42, + 0x33, 0x3b, 0x7d, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x31, 0x2c, 0x2e, + 0x62, 0x61, 0x72, 0x73, 0x2e, 0x79, 0x31, 0x20, 0x2e, 0x62, 0x61, + 0x72, 0x2c, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x79, + 0x31, 0x2c, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, + 0x6e, 0x64, 0x2e, 0x79, 0x31, 0x20, 0x7b, 0x66, 0x69, 0x6c, 0x6c, + 0x3a, 0x20, 0x23, 0x46, 0x46, 0x36, 0x38, 0x35, 0x34, 0x3b, 0x7d, + 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x30, 0x2c, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x31, 0x20, 0x7b, 0x66, 0x69, 0x6c, 0x6c, 0x3a, 0x20, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, + 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x20, 0x31, 0x3b, 0x7d, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x30, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, + 0x23, 0x30, 0x30, 0x37, 0x42, 0x43, 0x33, 0x3b, 0x7d, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x31, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, + 0x65, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x33, 0x30, 0x33, 0x45, 0x3b, + 0x7d, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x65, 0x78, 0x74, + 0x2c, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x2d, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x2c, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, + 0x6e, 0x64, 0x20, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x3a, 0x20, 0x31, + 0x30, 0x70, 0x78, 0x20, 0x73, 0x61, 0x6e, 0x73, 0x2d, 0x73, 0x65, + 0x72, 0x69, 0x66, 0x3b, 0x7d, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x2d, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x79, 0x30, 0x2c, 0x2e, 0x61, + 0x78, 0x69, 0x73, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x79, + 0x31, 0x20, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6e, 0x63, + 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x65, 0x6e, 0x64, 0x3b, 0x7d, 0x72, + 0x65, 0x63, 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x20, + 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x30, + 0x70, 0x78, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x2e, 0x6c, 0x65, 0x67, 0x65, 0x6e, + 0x64, 0x20, 0x7b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x20, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x7d, 0x2e, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x74, 0x65, 0x78, 0x74, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x20, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6e, + 0x63, 0x68, 0x6f, 0x72, 0x3a, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x3b, + 0x7d, 0x2f, 0x2a, 0x20, 0x43, 0x48, 0x41, 0x52, 0x54, 0x20, 0x54, + 0x4f, 0x4f, 0x4c, 0x54, 0x49, 0x50, 0x20, 0x2a, 0x2f, 0x2e, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, + 0x70, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x20, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x20, 0x30, 0x3b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x2d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, + 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, + 0x7a, 0x2d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x20, 0x31, 0x30, + 0x3b, 0x7d, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, + 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x7b, 0x2d, 0x6d, 0x6f, 0x7a, + 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x3a, 0x20, 0x37, 0x70, 0x78, 0x20, 0x37, 0x70, 0x78, 0x20, 0x31, + 0x32, 0x70, 0x78, 0x20, 0x2d, 0x39, 0x70, 0x78, 0x20, 0x23, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, + 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x3a, 0x20, 0x37, 0x70, 0x78, 0x20, 0x37, 0x70, 0x78, + 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, 0x2d, 0x39, 0x70, 0x78, 0x20, + 0x23, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x70, + 0x73, 0x65, 0x3a, 0x20, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, + 0x65, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x73, 0x70, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30, 0x3b, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x20, 0x37, + 0x70, 0x78, 0x20, 0x37, 0x70, 0x78, 0x20, 0x31, 0x32, 0x70, 0x78, + 0x20, 0x2d, 0x39, 0x70, 0x78, 0x20, 0x23, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x3b, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2d, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x3a, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x3b, 0x6f, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x30, 0x2e, 0x39, + 0x3b, 0x7d, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, + 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x74, 0x72, 0x20, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, + 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x43, 0x43, 0x43, 0x3b, + 0x7d, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, + 0x6c, 0x74, 0x69, 0x70, 0x20, 0x74, 0x68, 0x20, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x61, 0x61, 0x61, 0x3b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x46, 0x3b, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, + 0x31, 0x34, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x20, 0x33, 0x38, 0x30, 0x70, 0x78, 0x3b, + 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3a, 0x20, 0x32, 0x70, 0x78, 0x20, 0x35, 0x70, 0x78, + 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x20, + 0x65, 0x6c, 0x6c, 0x69, 0x70, 0x73, 0x69, 0x73, 0x3b, 0x77, 0x68, + 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x20, + 0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, 0x3b, 0x7d, 0x2e, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, + 0x20, 0x74, 0x64, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, + 0x64, 0x6f, 0x74, 0x74, 0x65, 0x64, 0x20, 0x23, 0x39, 0x39, 0x39, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x20, 0x31, 0x33, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3a, 0x20, 0x33, 0x70, 0x78, 0x20, 0x36, 0x70, 0x78, + 0x3b, 0x7d, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, + 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x74, 0x64, 0x20, 0x3e, 0x20, + 0x73, 0x70, 0x61, 0x6e, 0x20, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x3a, 0x20, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, + 0x36, 0x70, 0x78, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, + 0x31, 0x30, 0x70, 0x78, 0x3b, 0x7d, 0x2e, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x74, + 0x64, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x7b, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x20, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3b, 0x7d, 0x2e, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x2e, + 0x62, 0x6c, 0x75, 0x65, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x30, 0x30, 0x37, 0x42, 0x43, 0x33, 0x3b, 0x7d, + 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, + 0x74, 0x69, 0x70, 0x20, 0x2e, 0x72, 0x65, 0x64, 0x20, 0x7b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x33, 0x30, + 0x33, 0x45, 0x3b, 0x7d, 0x2f, 0x2a, 0x20, 0x44, 0x41, 0x52, 0x4b, + 0x20, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x20, 0x2a, 0x2f, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x20, 0x68, 0x31, 0x20, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, + 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, + 0x2c, 0x20, 0x30, 0x2e, 0x36, 0x29, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x20, 0x68, 0x33, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x20, 0x68, 0x34, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x68, + 0x35, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x72, + 0x67, 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x32, 0x35, 0x35, + 0x2c, 0x32, 0x35, 0x35, 0x2c, 0x30, 0x2e, 0x34, 0x29, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, + 0x65, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x20, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x20, 0x3e, 0x20, 0x64, 0x69, 0x76, 0x20, 0x3e, 0x20, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x44, 0x32, 0x44, 0x32, 0x44, 0x32, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x2d, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x74, 0x72, 0x20, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x46, 0x37, 0x46, 0x37, 0x46, + 0x37, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x20, + 0x74, 0x72, 0x20, 0x74, 0x64, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, + 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, 0x61, + 0x74, 0x61, 0x3e, 0x74, 0x72, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x72, 0x67, + 0x62, 0x61, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, + 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x30, 0x38, + 0x29, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x39, 0x65, 0x39, 0x65, + 0x39, 0x65, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x73, 0x68, 0x61, + 0x64, 0x6f, 0x77, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x68, 0x33, 0x20, 0x7b, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x46, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, + 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x46, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x20, 0x64, 0x69, 0x76, 0x2e, 0x77, 0x72, 0x61, + 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x64, + 0x69, 0x76, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x45, 0x45, 0x45, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30, 0x20, + 0x31, 0x30, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x32, + 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, 0x35, 0x2c, 0x20, 0x32, 0x35, + 0x35, 0x2c, 0x20, 0x30, 0x2e, 0x31, 0x35, 0x29, 0x3b, 0x7d, 0x2f, + 0x2a, 0x20, 0x44, 0x41, 0x52, 0x4b, 0x20, 0x42, 0x4c, 0x55, 0x45, + 0x20, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x20, 0x2a, 0x2f, 0x68, 0x74, + 0x6d, 0x6c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, + 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, + 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x32, + 0x35, 0x32, 0x42, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x32, + 0x35, 0x32, 0x42, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, + 0x65, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, 0x34, 0x43, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, + 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, + 0x35, 0x32, 0x42, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x6e, 0x61, 0x76, 0x20, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x23, 0x31, 0x38, 0x31, 0x42, 0x31, 0x46, 0x3b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, + 0x20, 0x23, 0x31, 0x46, 0x32, 0x33, 0x32, 0x38, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x64, + 0x69, 0x76, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x64, 0x69, 0x76, 0x20, 0x7b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, + 0x23, 0x31, 0x46, 0x32, 0x33, 0x32, 0x38, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x6d, 0x65, 0x74, 0x61, 0x20, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, + 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, 0x34, 0x43, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, + 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, 0x34, 0x43, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, + 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, 0x61, + 0x20, 0x74, 0x72, 0x2e, 0x73, 0x68, 0x61, 0x64, 0x65, 0x64, 0x20, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x31, 0x38, + 0x31, 0x42, 0x31, 0x46, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x67, 0x72, 0x61, 0x79, + 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, + 0x70, 0x3a, 0x20, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, 0x34, 0x43, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, + 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, + 0x65, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x31, 0x46, 0x32, 0x33, 0x32, 0x38, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, + 0x65, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x31, 0x46, 0x32, 0x33, 0x32, + 0x38, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, 0x34, + 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, + 0x75, 0x65, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, + 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, + 0x34, 0x43, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, + 0x31, 0x46, 0x32, 0x33, 0x32, 0x38, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, + 0x30, 0x46, 0x31, 0x32, 0x31, 0x34, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x2c, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, + 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x37, 0x37, 0x37, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, + 0x61, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, + 0x31, 0x46, 0x32, 0x33, 0x32, 0x38, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, 0x34, 0x43, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, + 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, + 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, + 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x66, + 0x6f, 0x63, 0x75, 0x73, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x30, 0x33, 0x37, 0x30, 0x42, 0x30, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x31, 0x46, 0x32, 0x33, + 0x32, 0x38, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, + 0x34, 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, + 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x6c, 0x69, 0x3e, + 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, + 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x46, + 0x46, 0x46, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, + 0x33, 0x42, 0x34, 0x34, 0x34, 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, + 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, + 0x35, 0x32, 0x42, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, + 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, + 0x62, 0x61, 0x72, 0x2d, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x2c, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, + 0x61, 0x72, 0x2d, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x20, 0x7b, 0x2d, + 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, + 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x20, 0x69, 0x6e, 0x73, + 0x65, 0x74, 0x20, 0x30, 0x20, 0x30, 0x20, 0x36, 0x70, 0x78, 0x20, + 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x2e, 0x33, 0x29, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x3a, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, + 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2c, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, + 0x76, 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, + 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x20, + 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x70, + 0x78, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x3a, 0x2d, + 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, 0x6f, + 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2d, 0x74, 0x68, 0x75, 0x6d, 0x62, + 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x62, 0x6c, 0x75, 0x65, + 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3a, 0x3a, 0x2d, 0x77, + 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, + 0x6c, 0x62, 0x61, 0x72, 0x2d, 0x74, 0x68, 0x75, 0x6d, 0x62, 0x20, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x33, 0x42, + 0x34, 0x34, 0x34, 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x35, 0x32, + 0x42, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x62, 0x6c, 0x75, 0x65, 0x20, 0x2e, 0x72, 0x65, 0x70, 0x6f, 0x72, + 0x74, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, + 0x31, 0x46, 0x32, 0x33, 0x32, 0x38, 0x3b, 0x7d, 0x2f, 0x2a, 0x20, + 0x44, 0x41, 0x52, 0x4b, 0x20, 0x47, 0x52, 0x45, 0x59, 0x20, 0x54, + 0x48, 0x45, 0x4d, 0x45, 0x20, 0x2a, 0x2f, 0x68, 0x74, 0x6d, 0x6c, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x2c, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x32, 0x31, 0x32, + 0x31, 0x32, 0x31, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x32, 0x31, 0x32, + 0x31, 0x32, 0x31, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x2d, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, + 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, + 0x23, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x33, 0x30, 0x33, + 0x30, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x67, 0x72, 0x61, 0x79, 0x20, 0x6e, 0x61, 0x76, 0x20, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x33, 0x36, 0x33, 0x37, 0x33, 0x37, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, + 0x31, 0x43, 0x31, 0x43, 0x31, 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x64, 0x69, 0x76, + 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x3e, 0x20, 0x64, 0x69, 0x76, 0x20, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x31, + 0x43, 0x31, 0x43, 0x31, 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x77, 0x72, 0x61, + 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x2d, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, + 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, + 0x33, 0x36, 0x33, 0x37, 0x33, 0x37, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, + 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, + 0x33, 0x36, 0x33, 0x37, 0x33, 0x37, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x77, 0x72, + 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, + 0x72, 0x2e, 0x73, 0x68, 0x61, 0x64, 0x65, 0x64, 0x20, 0x7b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, + 0x34, 0x38, 0x2c, 0x20, 0x34, 0x38, 0x2c, 0x20, 0x34, 0x38, 0x2c, + 0x20, 0x30, 0x2e, 0x34, 0x38, 0x29, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x67, 0x72, + 0x61, 0x79, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x23, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, + 0x79, 0x20, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x31, 0x43, 0x31, 0x43, + 0x31, 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, + 0x72, 0x61, 0x79, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x31, 0x32, + 0x31, 0x32, 0x31, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x33, 0x30, 0x33, + 0x30, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, + 0x61, 0x79, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x33, 0x36, + 0x33, 0x37, 0x33, 0x37, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x31, 0x43, 0x31, 0x43, 0x31, 0x43, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x30, 0x46, 0x31, 0x32, 0x31, 0x34, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, + 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, + 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, + 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3e, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x3e, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x37, 0x37, 0x37, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, + 0x69, 0x3e, 0x61, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x32, 0x31, 0x32, 0x31, 0x32, 0x31, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x33, 0x30, 0x33, 0x30, 0x33, + 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, + 0x61, 0x79, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, + 0x72, 0x61, 0x79, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x30, 0x33, 0x37, 0x30, 0x42, 0x30, + 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x31, + 0x32, 0x31, 0x32, 0x31, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x33, 0x30, + 0x33, 0x30, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x6c, + 0x69, 0x3e, 0x61, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x46, 0x46, 0x46, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x64, 0x72, 0x6f, + 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, + 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, + 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, + 0x65, 0x6e, 0x75, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x46, 0x46, 0x46, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, + 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, + 0x65, 0x6e, 0x75, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x32, 0x31, 0x32, 0x31, 0x32, 0x31, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x3a, 0x3a, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, + 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2d, 0x74, 0x72, 0x61, 0x63, + 0x6b, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, + 0x79, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3a, 0x3a, 0x2d, + 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, 0x6f, + 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2d, 0x74, 0x72, 0x61, 0x63, 0x6b, + 0x20, 0x7b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, + 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x20, + 0x69, 0x6e, 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x30, 0x20, 0x36, + 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, + 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x33, 0x29, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, + 0x79, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, + 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2c, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, + 0x61, 0x72, 0x20, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, + 0x31, 0x30, 0x70, 0x78, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, + 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, + 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2d, 0x74, 0x68, + 0x75, 0x6d, 0x62, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x67, + 0x72, 0x61, 0x79, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3a, + 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, + 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2d, 0x74, 0x68, 0x75, + 0x6d, 0x62, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, + 0x70, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, + 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x2e, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x3a, 0x20, 0x23, 0x33, 0x30, 0x33, 0x30, 0x33, 0x30, 0x3b, 0x7d, + 0x2f, 0x2a, 0x20, 0x44, 0x41, 0x52, 0x4b, 0x20, 0x43, 0x48, 0x41, + 0x52, 0x54, 0x53, 0x20, 0x2a, 0x2f, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x20, 0x73, 0x76, 0x67, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, + 0x61, 0x72, 0x65, 0x61, 0x20, 0x7b, 0x6f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x3a, 0x20, 0x30, 0x2e, 0x31, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x30, 0x2c, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x31, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x2d, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x30, 0x2c, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x62, 0x61, 0x72, 0x73, + 0x2e, 0x79, 0x30, 0x20, 0x2e, 0x62, 0x61, 0x72, 0x2c, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x20, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x6c, 0x65, + 0x67, 0x65, 0x6e, 0x64, 0x2e, 0x79, 0x30, 0x20, 0x7b, 0x66, 0x69, + 0x6c, 0x6c, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x37, 0x42, 0x43, 0x33, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x61, 0x72, + 0x65, 0x61, 0x31, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, + 0x62, 0x61, 0x72, 0x73, 0x2e, 0x79, 0x31, 0x20, 0x2e, 0x62, 0x61, + 0x72, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x79, 0x31, 0x2c, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x20, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x6c, 0x65, 0x67, + 0x65, 0x6e, 0x64, 0x2e, 0x79, 0x31, 0x20, 0x7b, 0x66, 0x69, 0x6c, + 0x6c, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x33, 0x30, 0x33, 0x45, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x2e, 0x79, 0x30, 0x20, 0x7b, 0x66, 0x69, 0x6c, + 0x6c, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x44, 0x34, 0x45, 0x31, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x30, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, + 0x20, 0x23, 0x30, 0x30, 0x37, 0x42, 0x43, 0x33, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x31, + 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, 0x23, + 0x46, 0x46, 0x33, 0x30, 0x33, 0x45, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x20, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2e, 0x79, 0x20, + 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x67, 0x72, 0x69, 0x64, + 0x2e, 0x78, 0x20, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x20, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, + 0x20, 0x23, 0x34, 0x34, 0x34, 0x37, 0x34, 0x42, 0x3b, 0x73, 0x74, + 0x72, 0x6f, 0x6b, 0x65, 0x2d, 0x64, 0x61, 0x73, 0x68, 0x61, 0x72, + 0x72, 0x61, 0x79, 0x3a, 0x20, 0x31, 0x20, 0x31, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x20, + 0x74, 0x65, 0x78, 0x74, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, + 0x2e, 0x61, 0x78, 0x69, 0x73, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x74, 0x65, 0x78, 0x74, + 0x2e, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x20, 0x7b, 0x66, 0x69, + 0x6c, 0x6c, 0x3a, 0x20, 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x61, 0x78, + 0x69, 0x73, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x7b, 0x73, 0x74, + 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, 0x23, 0x39, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, + 0x61, 0x78, 0x69, 0x73, 0x2e, 0x78, 0x20, 0x2e, 0x74, 0x69, 0x63, + 0x6b, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x20, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x2e, 0x79, 0x30, 0x20, + 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x61, 0x78, 0x69, 0x73, + 0x2e, 0x79, 0x31, 0x20, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, + 0x67, 0x72, 0x69, 0x64, 0x2e, 0x79, 0x20, 0x2e, 0x74, 0x69, 0x63, + 0x6b, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x7b, 0x73, 0x74, + 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, 0x23, 0x33, 0x42, 0x34, 0x34, + 0x34, 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, + 0x69, 0x70, 0x20, 0x74, 0x68, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x31, 0x63, 0x31, 0x63, 0x31, 0x63, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x20, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, + 0x74, 0x72, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, + 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, + 0x23, 0x33, 0x36, 0x33, 0x37, 0x33, 0x37, 0x3b, 0x7d, 0x2f, 0x2a, + 0x20, 0x44, 0x41, 0x52, 0x4b, 0x20, 0x50, 0x55, 0x52, 0x50, 0x4c, + 0x45, 0x20, 0x54, 0x48, 0x45, 0x4d, 0x45, 0x20, 0x2a, 0x2f, 0x68, + 0x74, 0x6d, 0x6c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, + 0x72, 0x70, 0x6c, 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x62, 0x6f, 0x64, 0x79, + 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x3a, 0x20, 0x23, 0x31, 0x65, 0x31, 0x65, 0x32, 0x66, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x31, 0x65, 0x31, 0x65, 0x32, + 0x66, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, + 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x65, 0x2d, + 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, + 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, + 0x23, 0x32, 0x62, 0x33, 0x35, 0x35, 0x33, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, + 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x31, + 0x38, 0x31, 0x38, 0x32, 0x33, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x6e, 0x61, + 0x76, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x65, 0x31, 0x34, 0x65, 0x63, + 0x61, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x3a, 0x20, 0x23, 0x31, 0x38, 0x31, 0x38, 0x32, 0x33, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x20, 0x64, 0x69, 0x76, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x64, 0x69, + 0x76, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x32, 0x37, 0x32, 0x39, 0x33, 0x64, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, + 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x32, 0x62, 0x33, 0x35, 0x35, 0x33, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, + 0x20, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x6d, 0x65, + 0x74, 0x61, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x23, 0x32, 0x62, 0x33, 0x35, 0x35, 0x33, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x23, 0x32, 0x62, 0x33, 0x35, 0x35, 0x33, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, + 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x2d, 0x64, 0x61, 0x74, 0x61, 0x20, 0x74, 0x72, 0x2e, 0x73, 0x68, + 0x61, 0x64, 0x65, 0x64, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x31, 0x65, 0x31, 0x65, 0x32, 0x66, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, + 0x65, 0x20, 0x2e, 0x67, 0x72, 0x61, 0x79, 0x20, 0x7b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x34, + 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x32, + 0x62, 0x33, 0x35, 0x35, 0x33, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x72, + 0x65, 0x64, 0x20, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x23, 0x66, 0x64, 0x35, 0x64, 0x39, 0x33, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, + 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x20, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, + 0x3a, 0x20, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x30, 0x30, 0x66, 0x32, 0x63, 0x33, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, + 0x20, 0x2e, 0x62, 0x6c, 0x75, 0x65, 0x20, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x34, 0x70, + 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x31, 0x66, + 0x38, 0x65, 0x66, 0x31, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x68, 0x33, 0x2c, + 0x20, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x20, 0x68, 0x34, 0x2c, 0x20, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x68, 0x35, + 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x39, + 0x61, 0x39, 0x61, 0x39, 0x61, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x67, + 0x72, 0x69, 0x64, 0x2d, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x3a, 0x20, 0x23, 0x32, 0x37, 0x32, 0x39, 0x33, 0x64, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, + 0x65, 0x20, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x2d, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x20, 0x68, 0x33, 0x20, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x46, 0x46, 0x46, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, + 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x31, 0x65, 0x31, 0x65, 0x32, 0x66, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x62, 0x33, 0x35, 0x35, 0x33, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, + 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, + 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x20, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, + 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x35, 0x39, 0x35, 0x39, 0x35, 0x66, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x31, 0x65, 0x31, 0x65, + 0x32, 0x66, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x62, 0x33, 0x35, + 0x35, 0x33, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, + 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x2c, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, + 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x37, 0x37, 0x37, 0x3b, 0x7d, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, + 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x31, 0x65, 0x31, 0x65, 0x32, 0x66, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x70, 0x78, + 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x33, 0x42, 0x34, + 0x34, 0x34, 0x43, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, + 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, + 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x30, 0x33, 0x37, 0x30, 0x42, 0x30, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x31, 0x38, 0x31, 0x38, 0x32, + 0x33, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, + 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, + 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x6c, 0x69, + 0x3e, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, + 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, + 0x65, 0x6e, 0x75, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x20, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x46, 0x46, 0x46, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x31, 0x38, 0x31, 0x38, 0x32, 0x33, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, + 0x65, 0x20, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x31, 0x65, 0x31, 0x65, 0x32, 0x66, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, + 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2d, + 0x74, 0x72, 0x61, 0x63, 0x6b, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, + 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x69, 0x76, 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, + 0x74, 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, + 0x2d, 0x74, 0x72, 0x61, 0x63, 0x6b, 0x20, 0x7b, 0x2d, 0x77, 0x65, + 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, + 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x74, + 0x20, 0x30, 0x20, 0x30, 0x20, 0x36, 0x70, 0x78, 0x20, 0x72, 0x67, + 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, + 0x33, 0x29, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, + 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, 0x7d, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x3a, 0x3a, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, + 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2c, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x69, 0x76, 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, + 0x69, 0x74, 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, + 0x72, 0x20, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x39, 0x45, 0x39, 0x45, 0x39, 0x45, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, + 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, + 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2d, 0x74, + 0x68, 0x75, 0x6d, 0x62, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, + 0x76, 0x65, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, + 0x2d, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x2d, + 0x74, 0x68, 0x75, 0x6d, 0x62, 0x20, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x31, 0x65, 0x31, 0x65, 0x32, 0x66, 0x3b, + 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x20, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, + 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x31, 0x38, 0x31, 0x38, 0x32, 0x33, + 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, + 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x20, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, 0x20, 0x23, 0x31, + 0x38, 0x31, 0x38, 0x32, 0x33, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, + 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x61, + 0x72, 0x65, 0x61, 0x30, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x62, 0x61, 0x72, + 0x73, 0x2e, 0x79, 0x30, 0x20, 0x2e, 0x62, 0x61, 0x72, 0x2c, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, + 0x20, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, 0x6e, + 0x64, 0x2e, 0x79, 0x30, 0x20, 0x7b, 0x66, 0x69, 0x6c, 0x6c, 0x3a, + 0x20, 0x23, 0x30, 0x30, 0x37, 0x42, 0x43, 0x33, 0x3b, 0x7d, 0x2e, + 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, + 0x20, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x31, 0x2c, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, + 0x62, 0x61, 0x72, 0x73, 0x2e, 0x79, 0x31, 0x20, 0x2e, 0x62, 0x61, + 0x72, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, + 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, + 0x2e, 0x79, 0x31, 0x2c, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, + 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x63, 0x74, 0x2e, + 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x2e, 0x79, 0x31, 0x20, 0x7b, + 0x66, 0x69, 0x6c, 0x6c, 0x3a, 0x20, 0x23, 0x64, 0x30, 0x34, 0x38, + 0x62, 0x36, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, + 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x73, 0x2e, 0x79, 0x30, 0x20, 0x7b, 0x66, 0x69, 0x6c, 0x6c, + 0x3a, 0x20, 0x23, 0x30, 0x30, 0x44, 0x34, 0x45, 0x31, 0x3b, 0x7d, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, 0x70, 0x75, 0x72, 0x70, 0x6c, + 0x65, 0x20, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x30, 0x20, 0x7b, 0x73, + 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, 0x20, 0x23, 0x30, 0x30, 0x37, + 0x42, 0x43, 0x33, 0x3b, 0x7d, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x2e, + 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x20, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x31, 0x20, 0x7b, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, 0x3a, + 0x20, 0x23, 0x64, 0x30, 0x34, 0x38, 0x62, 0x36, 0x3b, 0x7d, 0x00 +}; + +const int app_css_length = 16588; diff --git a/goaccess++/src/appjs.h b/goaccess++/src/appjs.h new file mode 100644 index 0000000..6b90833 --- /dev/null +++ b/goaccess++/src/appjs.h @@ -0,0 +1,3613 @@ +const char app_js[39696] = { + 0x2f, 0x2a, 0x6a, 0x73, 0x68, 0x69, 0x6e, 0x74, 0x20, 0x73, 0x75, + 0x62, 0x3a, 0x74, 0x72, 0x75, 0x65, 0x2a, 0x2f, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, + 0x27, 0x75, 0x73, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74, + 0x27, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x24, 0x28, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x29, + 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x29, 0x3b, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x24, 0x24, 0x28, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2c, 0x20, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x73, 0x20, 0x3d, 0x20, + 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x41, 0x6c, 0x6c, 0x28, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, + 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x20, 0x2b, 0x2b, 0x69, 0x29, 0x20, 0x7b, 0x69, + 0x66, 0x20, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x20, 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x27, + 0x29, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x65, + 0x6c, 0x65, 0x6d, 0x73, 0x5b, 0x69, 0x5d, 0x29, 0x3b, 0x7d, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x64, 0x65, 0x62, 0x6f, 0x75, 0x6e, 0x63, + 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x20, 0x77, 0x61, + 0x69, 0x74, 0x2c, 0x20, 0x6e, 0x6f, 0x77, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x62, 0x6f, 0x75, 0x6e, + 0x63, 0x65, 0x64, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x20, 0x61, 0x72, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x3b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x65, 0x6c, 0x61, + 0x79, 0x65, 0x64, 0x28, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x6e, 0x6f, 0x77, 0x29, 0x66, 0x75, 0x6e, 0x63, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x61, 0x74, 0x2c, 0x20, + 0x61, 0x72, 0x67, 0x73, 0x29, 0x3b, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x7d, + 0x69, 0x66, 0x20, 0x28, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x29, 0x20, 0x7b, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x28, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x29, 0x3b, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, + 0x66, 0x20, 0x28, 0x6e, 0x6f, 0x77, 0x29, 0x20, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x6f, 0x62, + 0x6a, 0x2c, 0x20, 0x61, 0x72, 0x67, 0x73, 0x29, 0x3b, 0x7d, 0x74, + 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x65, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x64, 0x65, + 0x6c, 0x61, 0x79, 0x65, 0x64, 0x2c, 0x20, 0x77, 0x61, 0x69, 0x74, + 0x20, 0x7c, 0x7c, 0x20, 0x32, 0x35, 0x30, 0x29, 0x3b, 0x7d, 0x3b, + 0x7d, 0x3b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x6f, 0x70, 0x74, 0x73, 0x20, 0x3d, 0x20, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, + 0x70, 0x6c, 0x73, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x55, 0x49, 0x44, 0x61, 0x74, + 0x61, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, + 0x70, 0x74, 0x73, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, + 0x75, 0x69, 0x44, 0x61, 0x74, 0x61, 0x20, 0x7c, 0x7c, 0x20, 0x7b, + 0x7d, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x44, + 0x61, 0x74, 0x61, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, 0x73, 0x20, 0x7c, 0x7c, 0x20, + 0x7b, 0x7d, 0x29, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, + 0x74, 0x61, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x3b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x57, 0x53, 0x43, 0x6f, 0x6e, + 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, + 0x70, 0x74, 0x73, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, + 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x3b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x69, 0x31, 0x38, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, 0x73, 0x20, 0x7c, 0x7c, + 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x69, 0x31, 0x38, 0x6e, 0x20, 0x7c, + 0x7c, 0x20, 0x7b, 0x7d, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, + 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x20, 0x20, 0x3d, 0x20, + 0x7b, 0x27, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x27, 0x3a, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x2c, 0x27, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x27, 0x3a, + 0x20, 0x27, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, + 0x6c, 0x27, 0x2c, 0x27, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, + 0x27, 0x3a, 0x20, 0x37, 0x2c, 0x27, 0x74, 0x68, 0x65, 0x6d, 0x65, + 0x27, 0x3a, 0x20, 0x27, 0x64, 0x61, 0x72, 0x6b, 0x50, 0x75, 0x72, + 0x70, 0x6c, 0x65, 0x27, 0x2c, 0x7d, 0x3b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x20, 0x3d, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, + 0x74, 0x69, 0x6c, 0x2e, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, + 0x73, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, + 0x73, 0x2e, 0x70, 0x72, 0x65, 0x66, 0x73, 0x29, 0x3b, 0x69, 0x66, + 0x20, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x68, 0x61, 0x73, 0x4c, 0x6f, 0x63, + 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x28, 0x29, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x73, 0x20, 0x3d, + 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x28, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, + 0x27, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x27, 0x29, + 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, + 0x72, 0x65, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x6d, + 0x65, 0x72, 0x67, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, + 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x2c, 0x20, 0x6c, 0x73, + 0x29, 0x3b, 0x7d, 0x69, 0x66, 0x20, 0x28, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x57, 0x53, 0x43, 0x6f, 0x6e, 0x6e, + 0x29, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x57, 0x65, 0x62, 0x53, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, + 0x70, 0x70, 0x57, 0x53, 0x43, 0x6f, 0x6e, 0x6e, 0x29, 0x3b, 0x7d, + 0x2c, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, + 0x3f, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x55, + 0x49, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x5d, 0x20, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, + 0x70, 0x55, 0x49, 0x44, 0x61, 0x74, 0x61, 0x3b, 0x7d, 0x2c, 0x67, + 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3f, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, + 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x20, 0x3a, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, + 0x73, 0x3b, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, + 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, + 0x2e, 0x68, 0x61, 0x73, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x28, 0x29, 0x29, 0x20, 0x7b, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x2e, 0x73, 0x65, 0x74, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x27, 0x41, + 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x27, 0x2c, 0x20, 0x4a, + 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, + 0x66, 0x79, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x29, + 0x29, 0x29, 0x3b, 0x7d, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3f, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x5b, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x20, 0x3a, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x44, 0x61, 0x74, 0x61, 0x3b, + 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, + 0x6b, 0x65, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, + 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x68, 0x6f, 0x73, 0x74, + 0x20, 0x3d, 0x20, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x2e, 0x75, + 0x72, 0x6c, 0x20, 0x3f, 0x20, 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x6e, + 0x2e, 0x75, 0x72, 0x6c, 0x20, 0x3a, 0x20, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3f, + 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6c, 0x6f, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x6f, 0x73, 0x74, 0x6e, + 0x61, 0x6d, 0x65, 0x20, 0x3a, 0x20, 0x22, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x2f, 0x5e, 0x28, 0x77, 0x73, + 0x73, 0x3f, 0x3a, 0x5c, 0x2f, 0x5c, 0x2f, 0x29, 0x3f, 0x5b, 0x5e, + 0x5c, 0x2f, 0x5d, 0x2b, 0x3a, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x7b, + 0x31, 0x2c, 0x35, 0x7d, 0x5c, 0x2f, 0x2f, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x28, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x2b, 0x20, 0x22, 0x2f, + 0x22, 0x29, 0x20, 0x3f, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x3a, + 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x68, 0x6f, 0x73, + 0x74, 0x20, 0x2b, 0x20, 0x27, 0x3a, 0x27, 0x20, 0x2b, 0x20, 0x77, + 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x2e, 0x70, 0x6f, 0x72, 0x74, 0x29, + 0x3b, 0x73, 0x74, 0x72, 0x20, 0x3d, 0x20, 0x21, 0x2f, 0x5e, 0x77, + 0x73, 0x73, 0x3f, 0x3a, 0x5c, 0x2f, 0x5c, 0x2f, 0x2f, 0x69, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x28, 0x73, 0x74, 0x72, 0x29, 0x20, 0x3f, + 0x20, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6c, 0x6f, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x68, + 0x74, 0x74, 0x70, 0x73, 0x3a, 0x22, 0x20, 0x3f, 0x20, 0x27, 0x77, + 0x73, 0x73, 0x3a, 0x2f, 0x2f, 0x27, 0x20, 0x3a, 0x20, 0x27, 0x77, + 0x73, 0x3a, 0x2f, 0x2f, 0x27, 0x29, 0x20, 0x2b, 0x20, 0x73, 0x74, + 0x72, 0x20, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x3d, 0x20, 0x6e, + 0x65, 0x77, 0x20, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, + 0x74, 0x28, 0x73, 0x74, 0x72, 0x29, 0x3b, 0x73, 0x6f, 0x63, 0x6b, + 0x65, 0x74, 0x2e, 0x6f, 0x6e, 0x6f, 0x70, 0x65, 0x6e, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x7b, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x4e, 0x61, 0x76, 0x2e, 0x57, + 0x53, 0x4f, 0x70, 0x65, 0x6e, 0x28, 0x29, 0x3b, 0x7d, 0x2e, 0x62, + 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x73, + 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6f, 0x6e, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x5b, 0x27, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x44, + 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x73, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x6f, 0x73, + 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x29, 0x20, 0x7b, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x4e, 0x61, + 0x76, 0x2e, 0x57, 0x53, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x29, + 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x29, 0x3b, 0x7d, 0x2c, 0x7d, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x20, 0x3d, + 0x20, 0x7b, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x3a, 0x20, 0x5b, + 0x22, 0x4a, 0x61, 0x6e, 0x22, 0x2c, 0x20, 0x22, 0x46, 0x65, 0x62, + 0x22, 0x2c, 0x20, 0x22, 0x4d, 0x61, 0x72, 0x22, 0x2c, 0x20, 0x22, + 0x41, 0x70, 0x72, 0x22, 0x2c, 0x20, 0x22, 0x4d, 0x61, 0x79, 0x22, + 0x2c, 0x20, 0x22, 0x4a, 0x75, 0x6e, 0x22, 0x2c, 0x20, 0x22, 0x4a, + 0x75, 0x6c, 0x22, 0x2c, 0x22, 0x41, 0x75, 0x67, 0x22, 0x2c, 0x20, + 0x22, 0x53, 0x65, 0x70, 0x22, 0x2c, 0x20, 0x22, 0x4f, 0x63, 0x74, + 0x22, 0x2c, 0x20, 0x22, 0x4e, 0x6f, 0x76, 0x22, 0x2c, 0x20, 0x22, + 0x44, 0x65, 0x63, 0x22, 0x5d, 0x2c, 0x6d, 0x65, 0x72, 0x67, 0x65, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x6f, 0x2c, 0x20, 0x6e, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6f, 0x62, 0x6a, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x2c, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x69, 0x6c, 0x20, 0x3d, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x6b, 0x65, 0x79, + 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x3b, 0x20, 0x69, 0x20, 0x3c, + 0x20, 0x69, 0x6c, 0x3b, 0x20, 0x69, 0x2b, 0x2b, 0x29, 0x20, 0x7b, + 0x66, 0x6f, 0x72, 0x20, 0x28, 0x6b, 0x65, 0x79, 0x20, 0x69, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5b, + 0x69, 0x5d, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5b, 0x69, 0x5d, 0x2e, + 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x28, 0x6b, 0x65, 0x79, 0x29, 0x29, 0x20, 0x7b, + 0x6f, 0x62, 0x6a, 0x5b, 0x6b, 0x65, 0x79, 0x5d, 0x20, 0x3d, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5b, 0x69, + 0x5d, 0x5b, 0x6b, 0x65, 0x79, 0x5d, 0x3b, 0x7d, 0x7d, 0x7d, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x62, 0x6a, 0x3b, 0x7d, + 0x2c, 0x68, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x73, + 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, + 0x73, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x27, 0x27, 0x29, + 0x2e, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x61, 0x2c, 0x20, 0x62, + 0x29, 0x20, 0x7b, 0x61, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x61, 0x20, + 0x3c, 0x3c, 0x20, 0x35, 0x29, 0x20, 0x2d, 0x20, 0x61, 0x29, 0x20, + 0x2b, 0x20, 0x62, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, + 0x65, 0x41, 0x74, 0x28, 0x30, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x26, 0x61, 0x3b, 0x7d, 0x2c, 0x20, 0x30, + 0x29, 0x20, 0x3e, 0x3e, 0x3e, 0x20, 0x30, 0x29, 0x2e, 0x74, 0x6f, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x36, 0x29, 0x3b, + 0x7d, 0x2c, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2c, 0x20, 0x64, + 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x2c, 0x20, 0x6e, 0x75, + 0x6d, 0x4f, 0x6e, 0x6c, 0x79, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, + 0x28, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x3d, 0x3d, 0x20, 0x30, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6d, + 0x4f, 0x6e, 0x6c, 0x79, 0x20, 0x3f, 0x20, 0x30, 0x20, 0x3a, 0x20, + 0x27, 0x30, 0x20, 0x42, 0x79, 0x74, 0x65, 0x27, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x6b, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x32, 0x34, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x64, 0x6d, 0x20, 0x3d, 0x20, 0x64, 0x65, + 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x20, 0x2b, 0x20, 0x31, 0x20, + 0x7c, 0x7c, 0x20, 0x32, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x69, + 0x7a, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x5b, 0x27, 0x42, 0x27, 0x2c, + 0x20, 0x27, 0x4b, 0x69, 0x42, 0x27, 0x2c, 0x20, 0x27, 0x4d, 0x69, + 0x42, 0x27, 0x2c, 0x20, 0x27, 0x47, 0x69, 0x42, 0x27, 0x2c, 0x20, + 0x27, 0x54, 0x69, 0x42, 0x27, 0x2c, 0x20, 0x27, 0x50, 0x69, 0x42, + 0x27, 0x5d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x62, 0x79, + 0x74, 0x65, 0x73, 0x29, 0x20, 0x2f, 0x20, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x6b, 0x29, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, + 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x28, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x20, 0x2f, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, + 0x28, 0x6b, 0x2c, 0x20, 0x69, 0x29, 0x29, 0x2e, 0x74, 0x6f, 0x46, + 0x69, 0x78, 0x65, 0x64, 0x28, 0x64, 0x6d, 0x29, 0x29, 0x20, 0x2b, + 0x20, 0x28, 0x6e, 0x75, 0x6d, 0x4f, 0x6e, 0x6c, 0x79, 0x20, 0x3f, + 0x20, 0x27, 0x27, 0x20, 0x3a, 0x20, 0x28, 0x27, 0x20, 0x27, 0x20, + 0x2b, 0x20, 0x73, 0x69, 0x7a, 0x65, 0x73, 0x5b, 0x69, 0x5d, 0x29, + 0x29, 0x3b, 0x7d, 0x2c, 0x69, 0x73, 0x4e, 0x75, 0x6d, 0x65, 0x72, + 0x69, 0x63, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x6e, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x21, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x6e, + 0x29, 0x29, 0x20, 0x26, 0x26, 0x20, 0x69, 0x73, 0x46, 0x69, 0x6e, + 0x69, 0x74, 0x65, 0x28, 0x6e, 0x29, 0x3b, 0x7d, 0x2c, 0x75, 0x74, + 0x69, 0x6d, 0x65, 0x32, 0x73, 0x74, 0x72, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x75, 0x73, 0x65, + 0x63, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x75, 0x73, 0x65, + 0x63, 0x20, 0x3e, 0x3d, 0x20, 0x38, 0x36, 0x34, 0x45, 0x38, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x28, 0x75, 0x73, + 0x65, 0x63, 0x29, 0x20, 0x2f, 0x20, 0x38, 0x36, 0x34, 0x45, 0x38, + 0x29, 0x2e, 0x74, 0x6f, 0x46, 0x69, 0x78, 0x65, 0x64, 0x28, 0x32, + 0x29, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x64, 0x27, 0x3b, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x75, 0x73, 0x65, 0x63, + 0x20, 0x3e, 0x3d, 0x20, 0x33, 0x36, 0x45, 0x38, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x28, 0x75, 0x73, 0x65, 0x63, + 0x29, 0x20, 0x2f, 0x20, 0x33, 0x36, 0x45, 0x38, 0x29, 0x2e, 0x74, + 0x6f, 0x46, 0x69, 0x78, 0x65, 0x64, 0x28, 0x32, 0x29, 0x20, 0x2b, + 0x20, 0x27, 0x20, 0x68, 0x27, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x69, 0x66, 0x20, 0x28, 0x75, 0x73, 0x65, 0x63, 0x20, 0x3e, 0x3d, + 0x20, 0x36, 0x45, 0x37, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x28, 0x28, 0x75, 0x73, 0x65, 0x63, 0x29, 0x20, 0x2f, 0x20, + 0x36, 0x45, 0x37, 0x29, 0x2e, 0x74, 0x6f, 0x46, 0x69, 0x78, 0x65, + 0x64, 0x28, 0x32, 0x29, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x6d, 0x27, + 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x75, + 0x73, 0x65, 0x63, 0x20, 0x3e, 0x3d, 0x20, 0x31, 0x45, 0x36, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x28, 0x75, 0x73, + 0x65, 0x63, 0x29, 0x20, 0x2f, 0x20, 0x31, 0x45, 0x36, 0x29, 0x2e, + 0x74, 0x6f, 0x46, 0x69, 0x78, 0x65, 0x64, 0x28, 0x32, 0x29, 0x20, + 0x2b, 0x20, 0x27, 0x20, 0x73, 0x27, 0x3b, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x69, 0x66, 0x20, 0x28, 0x75, 0x73, 0x65, 0x63, 0x20, 0x3e, + 0x3d, 0x20, 0x31, 0x45, 0x33, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x28, 0x28, 0x75, 0x73, 0x65, 0x63, 0x29, 0x20, 0x2f, + 0x20, 0x31, 0x45, 0x33, 0x29, 0x2e, 0x74, 0x6f, 0x46, 0x69, 0x78, + 0x65, 0x64, 0x28, 0x32, 0x29, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x6d, + 0x73, 0x27, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, + 0x75, 0x73, 0x65, 0x63, 0x29, 0x2e, 0x74, 0x6f, 0x46, 0x69, 0x78, + 0x65, 0x64, 0x28, 0x32, 0x29, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x75, + 0x73, 0x27, 0x3b, 0x7d, 0x2c, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x73, 0x74, 0x72, 0x29, 0x20, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x30, 0x2c, 0x34, + 0x29, 0x2c, 0x20, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x2e, + 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x34, 0x2c, 0x32, 0x29, + 0x20, 0x2d, 0x20, 0x31, 0x2c, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x73, + 0x74, 0x72, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x36, + 0x2c, 0x32, 0x29, 0x2c, 0x68, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x38, 0x2c, 0x32, + 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x30, 0x2c, 0x20, 0x69, 0x20, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, + 0x28, 0x31, 0x30, 0x2c, 0x20, 0x32, 0x29, 0x20, 0x20, 0x7c, 0x7c, + 0x20, 0x30, 0x2c, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, + 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, 0x31, 0x32, 0x2c, + 0x20, 0x32, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x30, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x64, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x6e, 0x65, + 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x28, 0x79, 0x2c, 0x6d, 0x2c, + 0x64, 0x2c, 0x68, 0x2c, 0x69, 0x2c, 0x73, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x28, 0x27, 0x30, + 0x27, 0x20, 0x2b, 0x20, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x67, 0x65, + 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x29, 0x2e, 0x73, 0x6c, + 0x69, 0x63, 0x65, 0x28, 0x2d, 0x32, 0x29, 0x20, 0x2b, 0x20, 0x27, + 0x2f, 0x27, 0x20, 0x2b, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, + 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x5b, 0x64, 0x61, 0x74, 0x65, 0x2e, + 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x28, 0x29, 0x5d, + 0x20, 0x2b, 0x20, 0x27, 0x2f, 0x27, 0x20, 0x2b, 0x20, 0x64, 0x61, + 0x74, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, + 0x65, 0x61, 0x72, 0x28, 0x29, 0x3b, 0x31, 0x30, 0x20, 0x3c, 0x3d, + 0x20, 0x73, 0x74, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x20, 0x26, 0x26, 0x20, 0x28, 0x6f, 0x75, 0x74, 0x20, 0x2b, 0x3d, + 0x20, 0x22, 0x3a, 0x22, 0x20, 0x2b, 0x20, 0x68, 0x29, 0x3b, 0x31, + 0x32, 0x20, 0x3c, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x20, 0x26, 0x26, 0x20, 0x28, 0x6f, 0x75, + 0x74, 0x20, 0x2b, 0x3d, 0x20, 0x22, 0x3a, 0x22, 0x20, 0x2b, 0x20, + 0x69, 0x29, 0x3b, 0x31, 0x34, 0x20, 0x3c, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x26, 0x26, + 0x20, 0x28, 0x6f, 0x75, 0x74, 0x20, 0x2b, 0x3d, 0x20, 0x22, 0x3a, + 0x22, 0x20, 0x2b, 0x20, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x7d, 0x2c, 0x66, 0x6d, + 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, + 0x2c, 0x20, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, + 0x20, 0x30, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x64, 0x61, 0x74, + 0x61, 0x54, 0x79, 0x70, 0x65, 0x29, 0x76, 0x61, 0x6c, 0x20, 0x3d, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3b, 0x73, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x7b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x75, + 0x74, 0x69, 0x6d, 0x65, 0x27, 0x3a, 0x76, 0x61, 0x6c, 0x20, 0x3d, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x75, 0x74, 0x69, 0x6d, 0x65, + 0x32, 0x73, 0x74, 0x72, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, + 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61, 0x73, 0x65, + 0x20, 0x27, 0x64, 0x61, 0x74, 0x65, 0x27, 0x3a, 0x76, 0x61, 0x6c, + 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, + 0x61, 0x73, 0x65, 0x20, 0x27, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, + 0x63, 0x27, 0x3a, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x69, 0x73, 0x4e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x28, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x29, 0x76, 0x61, 0x6c, 0x20, + 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x74, 0x6f, 0x4c, + 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x28, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61, + 0x73, 0x65, 0x20, 0x27, 0x62, 0x79, 0x74, 0x65, 0x73, 0x27, 0x3a, + 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x20, 0x64, 0x65, 0x63, + 0x69, 0x6d, 0x61, 0x6c, 0x73, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x70, 0x65, 0x72, + 0x63, 0x65, 0x6e, 0x74, 0x27, 0x3a, 0x76, 0x61, 0x6c, 0x20, 0x3d, + 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, + 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x28, 0x27, 0x2c, 0x27, 0x2c, 0x20, 0x27, 0x2e, + 0x27, 0x29, 0x29, 0x2e, 0x74, 0x6f, 0x46, 0x69, 0x78, 0x65, 0x64, + 0x28, 0x32, 0x29, 0x20, 0x2b, 0x20, 0x27, 0x25, 0x27, 0x3b, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, + 0x74, 0x69, 0x6d, 0x65, 0x27, 0x3a, 0x69, 0x66, 0x20, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x4e, 0x75, 0x6d, 0x65, 0x72, + 0x69, 0x63, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x29, 0x76, + 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, + 0x74, 0x6f, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x28, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x73, 0x65, 0x63, 0x73, + 0x27, 0x3a, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x73, 0x65, 0x63, 0x73, + 0x27, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3b, 0x7d, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x3d, + 0x20, 0x30, 0x20, 0x3f, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x28, 0x76, 0x61, 0x6c, 0x29, 0x20, 0x3a, 0x20, 0x76, 0x61, 0x6c, + 0x3b, 0x7d, 0x2c, 0x69, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, + 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, + 0x61, 0x28, 0x29, 0x2c, 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, + 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x21, 0x75, 0x69, 0x2e, + 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, + 0x7c, 0x7c, 0x20, 0x21, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x68, 0x61, + 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x79, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x21, 0x75, 0x69, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, + 0x2e, 0x69, 0x64, 0x29, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, + 0x7b, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x69, 0x74, 0x65, + 0x6d, 0x29, 0x20, 0x26, 0x26, 0x20, 0x27, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x6d, + 0x2e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x3b, 0x7d, 0x2c, 0x67, + 0x65, 0x74, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, + 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x26, 0x26, 0x20, + 0x27, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x27, 0x20, 0x69, + 0x6e, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x6d, 0x74, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x2e, + 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x27, 0x70, + 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x27, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x7d, + 0x2c, 0x69, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6f, + 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, + 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x28, 0x6f, 0x29, 0x3b, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x6f, 0x2c, 0x20, 0x73, 0x2c, 0x20, 0x76, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, + 0x61, 0x20, 0x3d, 0x20, 0x6f, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x61, + 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, + 0x27, 0x2e, 0x27, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, + 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x6e, + 0x20, 0x3d, 0x20, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6e, 0x2d, 0x31, 0x3b, 0x20, + 0x2b, 0x2b, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6b, + 0x20, 0x3d, 0x20, 0x61, 0x5b, 0x69, 0x5d, 0x3b, 0x69, 0x66, 0x20, + 0x28, 0x21, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5b, 0x6b, 0x5d, + 0x29, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5b, 0x6b, 0x5d, 0x20, + 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x20, 0x3d, 0x20, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5b, 0x6b, + 0x5d, 0x3b, 0x7d, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5b, 0x61, + 0x5b, 0x6e, 0x2d, 0x31, 0x5d, 0x5d, 0x20, 0x3d, 0x20, 0x76, 0x3b, + 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6f, + 0x2c, 0x20, 0x73, 0x29, 0x20, 0x7b, 0x73, 0x20, 0x3d, 0x20, 0x73, + 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x5c, + 0x5b, 0x28, 0x5c, 0x77, 0x2b, 0x29, 0x5c, 0x5d, 0x2f, 0x67, 0x2c, + 0x20, 0x27, 0x2e, 0x24, 0x31, 0x27, 0x29, 0x3b, 0x73, 0x20, 0x3d, + 0x20, 0x73, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, + 0x2f, 0x5e, 0x5c, 0x2e, 0x2f, 0x2c, 0x20, 0x27, 0x27, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x73, 0x2e, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x28, 0x27, 0x2e, 0x27, 0x29, 0x3b, 0x66, + 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, + 0x20, 0x30, 0x2c, 0x20, 0x6e, 0x20, 0x3d, 0x20, 0x61, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, + 0x6e, 0x3b, 0x20, 0x2b, 0x2b, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6b, 0x20, 0x3d, 0x20, 0x61, 0x5b, 0x69, 0x5d, 0x3b, + 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6f, 0x29, 0x20, 0x26, + 0x26, 0x20, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x6f, 0x29, 0x20, 0x7b, + 0x6f, 0x20, 0x3d, 0x20, 0x6f, 0x5b, 0x6b, 0x5d, 0x3b, 0x7d, 0x20, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x3b, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6f, 0x3b, 0x7d, 0x2c, 0x68, 0x61, 0x73, 0x4c, 0x6f, 0x63, 0x61, + 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, + 0x7b, 0x74, 0x72, 0x79, 0x20, 0x7b, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x73, 0x65, 0x74, + 0x49, 0x74, 0x65, 0x6d, 0x28, 0x27, 0x74, 0x65, 0x73, 0x74, 0x27, + 0x2c, 0x20, 0x27, 0x74, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x49, 0x74, 0x65, 0x6d, + 0x28, 0x27, 0x74, 0x65, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x7d, + 0x20, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x20, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x3b, 0x7d, 0x7d, 0x2c, 0x69, 0x73, 0x57, 0x69, 0x74, 0x68, + 0x69, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x50, 0x6f, 0x72, 0x74, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x6c, + 0x65, 0x6d, 0x54, 0x6f, 0x70, 0x20, 0x3d, 0x20, 0x65, 0x6c, 0x2e, + 0x67, 0x65, 0x74, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x74, 0x28, + 0x29, 0x2e, 0x74, 0x6f, 0x70, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x6c, 0x65, 0x6d, 0x42, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x3d, + 0x20, 0x65, 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x42, 0x6f, 0x75, 0x6e, + 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x63, 0x74, 0x28, 0x29, 0x2e, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x6c, + 0x65, 0x6d, 0x54, 0x6f, 0x70, 0x20, 0x3c, 0x20, 0x77, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x26, 0x26, 0x20, 0x65, 0x6c, 0x65, + 0x6d, 0x42, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x3e, 0x3d, 0x20, + 0x30, 0x3b, 0x7d, 0x2c, 0x7d, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, + 0x53, 0x74, 0x61, 0x74, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x42, 0x6f, 0x78, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x61, 0x74, + 0x61, 0x2c, 0x20, 0x75, 0x69, 0x2c, 0x20, 0x72, 0x6f, 0x77, 0x2c, + 0x20, 0x78, 0x2c, 0x20, 0x69, 0x64, 0x78, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x77, 0x72, 0x61, 0x70, 0x20, 0x3d, 0x20, 0x24, + 0x28, 0x27, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x67, 0x65, 0x6e, + 0x65, 0x72, 0x61, 0x6c, 0x2d, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x27, + 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x69, 0x64, 0x78, 0x20, 0x25, + 0x20, 0x36, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x72, + 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x64, 0x69, 0x76, 0x27, + 0x29, 0x3b, 0x72, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x72, 0x6f, 0x77, 0x27, + 0x29, 0x3b, 0x77, 0x72, 0x61, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x72, 0x6f, 0x77, + 0x29, 0x3b, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x62, 0x6f, 0x78, 0x20, + 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x28, 0x27, 0x64, 0x69, 0x76, 0x27, 0x29, 0x3b, 0x62, + 0x6f, 0x78, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, + 0x4c, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, 0x2e, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x7b, 0x27, + 0x69, 0x64, 0x27, 0x3a, 0x20, 0x78, 0x2c, 0x27, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x3a, 0x20, 0x75, 0x69, + 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x78, 0x5d, 0x2e, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x27, 0x3a, 0x20, 0x75, 0x69, 0x2e, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x78, 0x5d, 0x2e, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x2c, 0x27, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x3a, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, + 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x5b, 0x78, 0x5d, 0x2c, 0x20, + 0x75, 0x69, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x78, 0x5d, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x29, 0x2c, + 0x7d, 0x29, 0x3b, 0x72, 0x6f, 0x77, 0x2e, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x62, 0x6f, 0x78, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x6f, + 0x77, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x44, + 0x61, 0x74, 0x61, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x75, + 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x64, 0x78, + 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x3d, + 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x24, 0x28, 0x27, 0x2e, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, + 0x4c, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, 0x2e, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, + 0x6d, 0x65, 0x72, 0x67, 0x65, 0x28, 0x75, 0x69, 0x2c, 0x20, 0x7b, + 0x27, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x64, 0x27, 0x3a, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x61, + 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x2c, 0x27, 0x66, 0x72, + 0x6f, 0x6d, 0x27, 0x3a, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x2c, 0x27, + 0x74, 0x6f, 0x27, 0x3a, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x65, + 0x6e, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x65, 0x2c, 0x7d, 0x29, 0x29, + 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x78, + 0x20, 0x69, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, + 0x69, 0x66, 0x20, 0x28, 0x21, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x68, + 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x28, 0x78, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x21, 0x75, + 0x69, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x68, 0x61, 0x73, + 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x28, 0x78, 0x29, 0x29, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x3b, 0x72, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x42, 0x6f, 0x78, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x75, 0x69, 0x2c, 0x20, + 0x72, 0x6f, 0x77, 0x2c, 0x20, 0x78, 0x2c, 0x20, 0x69, 0x64, 0x78, + 0x29, 0x3b, 0x69, 0x64, 0x78, 0x2b, 0x2b, 0x3b, 0x7d, 0x7d, 0x2c, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, 0x3d, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, + 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x27, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x27, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, + 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x27, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x27, 0x29, 0x2c, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x28, + 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x75, 0x69, 0x29, 0x3b, 0x7d, + 0x7d, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x4e, 0x61, 0x76, 0x20, 0x3d, 0x20, 0x7b, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x24, 0x28, 0x27, 0x2e, 0x6e, + 0x61, 0x76, 0x2d, 0x62, 0x61, 0x72, 0x73, 0x27, 0x29, 0x2e, 0x6f, + 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, + 0x7b, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x70, + 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x3b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4d, + 0x65, 0x6e, 0x75, 0x28, 0x65, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x24, 0x28, + 0x27, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x67, 0x65, 0x61, 0x72, 0x73, + 0x27, 0x29, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x65, 0x29, 0x20, 0x7b, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x70, + 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x73, 0x28, 0x65, 0x29, 0x3b, + 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x3b, 0x24, 0x28, 0x27, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x6d, + 0x69, 0x6e, 0x69, 0x62, 0x61, 0x72, 0x73, 0x27, 0x29, 0x2e, 0x6f, + 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, + 0x7b, 0x65, 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x70, + 0x61, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x3b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4f, + 0x70, 0x74, 0x73, 0x28, 0x65, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x24, 0x28, + 0x27, 0x62, 0x6f, 0x64, 0x79, 0x27, 0x29, 0x2e, 0x6f, 0x6e, 0x63, + 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x24, + 0x28, 0x27, 0x6e, 0x61, 0x76, 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x28, 0x27, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x27, + 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x65, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x6a, 0x73, 0x6f, 0x6e, 0x27, 0x2c, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, + 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, + 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x6f, 0x77, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x4a, 0x53, 0x4f, 0x4e, 0x28, 0x65, + 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, + 0x2e, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x2d, 0x62, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, + 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x65, 0x74, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x28, 0x27, + 0x62, 0x72, 0x69, 0x67, 0x68, 0x74, 0x27, 0x29, 0x3b, 0x7d, 0x2e, + 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, + 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x74, 0x68, 0x65, + 0x6d, 0x65, 0x2d, 0x64, 0x61, 0x72, 0x6b, 0x2d, 0x62, 0x6c, 0x75, + 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, + 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, + 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x73, 0x65, 0x74, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x28, 0x27, 0x64, + 0x61, 0x72, 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x27, 0x29, 0x3b, 0x7d, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x74, 0x68, + 0x65, 0x6d, 0x65, 0x2d, 0x64, 0x61, 0x72, 0x6b, 0x2d, 0x67, 0x72, + 0x61, 0x79, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, + 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x65, 0x74, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x28, 0x27, + 0x64, 0x61, 0x72, 0x6b, 0x47, 0x72, 0x61, 0x79, 0x27, 0x29, 0x3b, + 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x74, + 0x68, 0x65, 0x6d, 0x65, 0x2d, 0x64, 0x61, 0x72, 0x6b, 0x2d, 0x70, + 0x75, 0x72, 0x70, 0x6c, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, + 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, + 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x68, 0x65, 0x6d, + 0x65, 0x28, 0x27, 0x64, 0x61, 0x72, 0x6b, 0x50, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x27, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, + 0x24, 0x28, 0x27, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2d, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x27, + 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, + 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x28, 0x27, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x27, 0x29, 0x3b, + 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x6c, + 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2d, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, + 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x74, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, + 0x28, 0x27, 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x27, + 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, + 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x65, 0x72, 0x70, 0x61, + 0x67, 0x65, 0x5d, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, + 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x65, 0x72, 0x50, 0x61, 0x67, + 0x65, 0x28, 0x65, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, + 0x24, 0x28, 0x27, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x73, 0x68, + 0x6f, 0x77, 0x2d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x5d, 0x27, + 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, + 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x6f, + 0x67, 0x67, 0x6c, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, + 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, + 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x61, 0x75, 0x74, 0x6f, 0x68, + 0x69, 0x64, 0x65, 0x2d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x5d, + 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x74, + 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x48, 0x69, + 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, 0x29, 0x3b, + 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x29, 0x3b, 0x7d, 0x2c, 0x64, 0x6f, 0x77, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x4a, 0x53, 0x4f, 0x4e, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x61, 0x72, 0x67, 0x20, + 0x3d, 0x20, 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3b, 0x63, 0x68, 0x61, 0x72, + 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, 0x2d, 0x38, 0x2c, 0x22, + 0x20, 0x2b, 0x20, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 0x52, + 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x28, + 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x69, 0x66, 0x79, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, + 0x61, 0x74, 0x61, 0x28, 0x29, 0x29, 0x29, 0x3b, 0x74, 0x61, 0x72, + 0x67, 0x2e, 0x68, 0x72, 0x65, 0x66, 0x20, 0x3d, 0x20, 0x27, 0x64, + 0x61, 0x74, 0x61, 0x3a, 0x27, 0x20, 0x2b, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x3b, 0x74, 0x61, 0x72, 0x67, 0x2e, 0x64, 0x6f, 0x77, 0x6e, + 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x27, 0x67, 0x6f, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x28, + 0x2b, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, + 0x29, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x6a, 0x73, 0x6f, 0x6e, 0x27, + 0x3b, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x4c, 0x61, 0x79, 0x6f, 0x75, + 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x29, 0x20, 0x7b, + 0x69, 0x66, 0x20, 0x28, 0x27, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, + 0x6e, 0x74, 0x61, 0x6c, 0x27, 0x20, 0x3d, 0x3d, 0x20, 0x6c, 0x61, + 0x79, 0x6f, 0x75, 0x74, 0x29, 0x20, 0x7b, 0x24, 0x28, 0x27, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x27, 0x29, + 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, + 0x61, 0x64, 0x64, 0x28, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x27, 0x29, + 0x3b, 0x24, 0x28, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x28, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x27, 0x29, 0x3b, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, + 0x66, 0x20, 0x28, 0x27, 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, + 0x6c, 0x27, 0x20, 0x3d, 0x3d, 0x20, 0x6c, 0x61, 0x79, 0x6f, 0x75, + 0x74, 0x29, 0x20, 0x7b, 0x24, 0x28, 0x27, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2d, 0x66, 0x6c, 0x75, 0x69, + 0x64, 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, + 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x27, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x27, 0x29, 0x3b, 0x24, 0x28, + 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, + 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x27, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2d, 0x66, 0x6c, + 0x75, 0x69, 0x64, 0x27, 0x29, 0x3b, 0x7d, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, + 0x66, 0x73, 0x5b, 0x27, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x27, + 0x5d, 0x20, 0x3d, 0x20, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x3b, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x29, 0x3b, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x61, 0x6e, 0x65, + 0x6c, 0x73, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x2e, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x29, + 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x74, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x41, 0x75, 0x74, 0x6f, 0x48, 0x69, + 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x48, + 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x3d, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x48, + 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, 0x29, + 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, + 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x61, + 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x27, 0x68, 0x69, 0x64, 0x64, 0x65, + 0x6e, 0x2d, 0x78, 0x73, 0x27, 0x29, 0x3b, 0x7d, 0x20, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64, + 0x28, 0x27, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, 0x78, 0x73, + 0x27, 0x29, 0x3b, 0x7d, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, + 0x66, 0x73, 0x5b, 0x27, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x27, 0x5d, 0x20, 0x3d, + 0x20, 0x21, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, + 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, + 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, + 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, 0x29, 0x3b, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x73, + 0x28, 0x75, 0x69, 0x29, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, + 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x69, 0x64, 0x78, + 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, + 0x69, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x69, + 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x75, 0x69, + 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x5b, 0x27, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x21, 0x73, 0x68, + 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3b, 0x7d, 0x2e, + 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, + 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, + 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x27, 0x73, 0x68, + 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x21, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x29, + 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, + 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x73, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, + 0x65, 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x3b, + 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x74, 0x68, 0x65, 0x6d, 0x65, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, + 0x28, 0x21, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x3b, 0x24, 0x28, 0x27, 0x68, 0x74, 0x6d, 0x6c, + 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x3b, 0x73, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x28, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x29, 0x20, 0x7b, + 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x64, 0x61, 0x72, 0x6b, 0x47, + 0x72, 0x61, 0x79, 0x27, 0x3a, 0x24, 0x28, 0x27, 0x68, 0x74, 0x6d, + 0x6c, 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, + 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x27, 0x64, 0x61, 0x72, + 0x6b, 0x27, 0x29, 0x3b, 0x24, 0x28, 0x27, 0x68, 0x74, 0x6d, 0x6c, + 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, + 0x74, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x27, 0x67, 0x72, 0x61, 0x79, + 0x27, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61, + 0x73, 0x65, 0x20, 0x27, 0x64, 0x61, 0x72, 0x6b, 0x42, 0x6c, 0x75, + 0x65, 0x27, 0x3a, 0x24, 0x28, 0x27, 0x68, 0x74, 0x6d, 0x6c, 0x27, + 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x2e, 0x61, 0x64, 0x64, 0x28, 0x27, 0x64, 0x61, 0x72, 0x6b, 0x27, + 0x29, 0x3b, 0x24, 0x28, 0x27, 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x29, + 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, + 0x61, 0x64, 0x64, 0x28, 0x27, 0x62, 0x6c, 0x75, 0x65, 0x27, 0x29, + 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61, 0x73, 0x65, + 0x20, 0x27, 0x64, 0x61, 0x72, 0x6b, 0x50, 0x75, 0x72, 0x70, 0x6c, + 0x65, 0x27, 0x3a, 0x24, 0x28, 0x27, 0x68, 0x74, 0x6d, 0x6c, 0x27, + 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x2e, 0x61, 0x64, 0x64, 0x28, 0x27, 0x64, 0x61, 0x72, 0x6b, 0x27, + 0x29, 0x3b, 0x24, 0x28, 0x27, 0x68, 0x74, 0x6d, 0x6c, 0x27, 0x29, + 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, + 0x61, 0x64, 0x64, 0x28, 0x27, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, + 0x27, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x7d, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, + 0x50, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x27, 0x74, 0x68, 0x65, 0x6d, + 0x65, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x65, + 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x73, + 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x29, 0x3b, 0x7d, + 0x2c, 0x67, 0x65, 0x74, 0x49, 0x63, 0x6f, 0x6e, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6b, 0x65, + 0x79, 0x29, 0x20, 0x7b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x28, + 0x6b, 0x65, 0x79, 0x29, 0x20, 0x7b, 0x63, 0x61, 0x73, 0x65, 0x20, + 0x27, 0x76, 0x69, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x73, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, 0x73, + 0x27, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x27, 0x66, 0x69, 0x6c, 0x65, 0x27, 0x3b, 0x63, 0x61, 0x73, + 0x65, 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x27, 0x20, 0x3a, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x66, 0x69, 0x6c, + 0x65, 0x2d, 0x74, 0x65, 0x78, 0x74, 0x27, 0x3b, 0x63, 0x61, 0x73, + 0x65, 0x20, 0x27, 0x6e, 0x6f, 0x74, 0x5f, 0x66, 0x6f, 0x75, 0x6e, + 0x64, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x66, 0x69, 0x6c, + 0x65, 0x2d, 0x6f, 0x27, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, + 0x68, 0x6f, 0x73, 0x74, 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, 0x27, 0x3b, + 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x6f, 0x73, 0x27, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, + 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x27, 0x3b, 0x63, 0x61, + 0x73, 0x65, 0x20, 0x27, 0x62, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, + 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x63, 0x68, + 0x72, 0x6f, 0x6d, 0x65, 0x27, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, + 0x27, 0x76, 0x69, 0x73, 0x69, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, + 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x63, 0x6c, 0x6f, 0x63, 0x6b, + 0x2d, 0x6f, 0x27, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x76, + 0x68, 0x6f, 0x73, 0x74, 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x27, 0x74, 0x68, 0x2d, 0x6c, 0x69, 0x73, 0x74, + 0x27, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x72, 0x65, 0x66, + 0x65, 0x72, 0x72, 0x65, 0x72, 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x27, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2d, + 0x6c, 0x69, 0x6e, 0x6b, 0x27, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, + 0x27, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x5f, + 0x73, 0x69, 0x74, 0x65, 0x73, 0x27, 0x20, 0x3a, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x27, 0x3b, 0x63, + 0x61, 0x73, 0x65, 0x20, 0x27, 0x6b, 0x65, 0x79, 0x70, 0x68, 0x72, + 0x61, 0x73, 0x65, 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x27, 0x3b, 0x63, 0x61, 0x73, 0x65, + 0x20, 0x27, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x63, 0x6f, + 0x64, 0x65, 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x27, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, + 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x75, 0x73, 0x65, 0x72, + 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x27, 0x75, 0x73, 0x65, 0x72, 0x73, 0x27, + 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x67, 0x65, 0x6f, 0x6c, + 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x27, 0x6d, 0x61, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x6b, 0x65, 0x72, + 0x27, 0x3b, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3a, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x27, 0x70, 0x69, 0x65, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x27, 0x3b, 0x7d, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x49, 0x74, 0x65, + 0x6d, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, + 0x69, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, + 0x49, 0x28, 0x29, 0x2c, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x20, 0x3d, + 0x20, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x69, 0x6e, 0x20, + 0x75, 0x69, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, + 0x2e, 0x69, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x56, 0x61, 0x6c, + 0x69, 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x6d, 0x65, 0x6e, + 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x27, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x27, 0x3a, 0x20, 0x77, 0x69, 0x6e, + 0x64, 0x6f, 0x77, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x75, 0x62, 0x73, + 0x74, 0x72, 0x28, 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x27, 0x68, 0x65, 0x61, 0x64, 0x27, 0x3a, + 0x20, 0x75, 0x69, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x2e, + 0x68, 0x65, 0x61, 0x64, 0x2c, 0x27, 0x6b, 0x65, 0x79, 0x27, 0x3a, + 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x27, 0x69, 0x63, 0x6f, + 0x6e, 0x27, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, + 0x74, 0x49, 0x63, 0x6f, 0x6e, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x2c, 0x7d, 0x29, 0x3b, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6d, 0x65, 0x6e, 0x75, 0x3b, 0x7d, 0x2c, 0x73, 0x65, + 0x74, 0x50, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, + 0x20, 0x7b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x27, 0x70, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x27, 0x5d, 0x20, 0x3d, 0x20, + 0x2b, 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, + 0x74, 0x61, 0x2d, 0x70, 0x65, 0x72, 0x70, 0x61, 0x67, 0x65, 0x27, + 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x41, 0x70, 0x70, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x44, + 0x61, 0x74, 0x61, 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, + 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x54, 0x68, + 0x65, 0x6d, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x2e, 0x74, + 0x68, 0x65, 0x6d, 0x65, 0x20, 0x7c, 0x7c, 0x20, 0x27, 0x64, 0x61, + 0x72, 0x6b, 0x47, 0x72, 0x61, 0x79, 0x27, 0x3b, 0x7d, 0x2c, 0x67, + 0x65, 0x74, 0x4c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, + 0x65, 0x66, 0x73, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x20, + 0x7c, 0x7c, 0x20, 0x27, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, + 0x74, 0x61, 0x6c, 0x27, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x50, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, + 0x73, 0x2e, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x20, 0x7c, + 0x7c, 0x20, 0x37, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x4f, 0x70, 0x74, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6f, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x6f, 0x5b, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x4c, 0x61, 0x79, + 0x6f, 0x75, 0x74, 0x28, 0x29, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x3b, 0x6f, 0x5b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, + 0x65, 0x74, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x28, 0x29, 0x5d, 0x20, + 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x6f, 0x5b, 0x27, 0x70, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x27, 0x20, 0x2b, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x65, 0x72, 0x50, + 0x61, 0x67, 0x65, 0x28, 0x29, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x3b, 0x6f, 0x5b, 0x27, 0x61, 0x75, 0x74, 0x6f, 0x48, + 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x27, 0x5d, + 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x61, 0x75, 0x74, + 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x28, 0x29, 0x3b, 0x6f, 0x5b, 0x27, 0x73, 0x68, 0x6f, 0x77, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x28, 0x29, 0x3b, 0x6f, 0x5b, 0x27, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x31, 0x38, 0x6e, + 0x3b, 0x24, 0x28, 0x27, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x6c, 0x69, + 0x73, 0x74, 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, + 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, + 0x2e, 0x4e, 0x61, 0x76, 0x2e, 0x6f, 0x70, 0x74, 0x73, 0x2e, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x6f, 0x29, 0x3b, 0x24, 0x28, + 0x27, 0x6e, 0x61, 0x76, 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x28, 0x27, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x27, 0x29, + 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x4d, 0x65, 0x6e, 0x75, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x24, + 0x28, 0x27, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x6c, 0x69, 0x73, 0x74, + 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, + 0x4c, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, 0x2e, 0x4e, + 0x61, 0x76, 0x2e, 0x6d, 0x65, 0x6e, 0x75, 0x2e, 0x72, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x28, 0x7b, 0x27, 0x6e, 0x61, 0x76, 0x27, 0x3a, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x49, 0x74, + 0x65, 0x6d, 0x73, 0x28, 0x29, 0x2c, 0x27, 0x6f, 0x76, 0x65, 0x72, + 0x61, 0x6c, 0x6c, 0x27, 0x3a, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, + 0x77, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x68, 0x61, 0x73, 0x68, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, + 0x28, 0x31, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x27, 0x27, 0x2c, 0x27, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x27, 0x3a, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x31, 0x38, 0x6e, + 0x2c, 0x7d, 0x29, 0x3b, 0x24, 0x28, 0x27, 0x6e, 0x61, 0x76, 0x27, + 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x2e, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x28, 0x27, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x27, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x29, 0x3b, 0x7d, + 0x2c, 0x57, 0x53, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, + 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x28, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x57, 0x53, 0x43, + 0x6f, 0x6e, 0x6e, 0x29, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x77, + 0x73, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, + 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x20, 0x69, 0x74, 0x65, 0x6d, + 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x27, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x27, 0x3b, 0x20, 0x7d, 0x29, 0x3b, 0x7d, 0x2c, 0x57, 0x53, + 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x24, 0x24, + 0x28, 0x27, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x77, 0x73, 0x2d, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, + 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x28, 0x27, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x27, 0x29, 0x3b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x73, + 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x28, 0x27, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x27, 0x2c, 0x20, 0x27, + 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x27, 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x7d, 0x2c, 0x57, 0x53, + 0x4f, 0x70, 0x65, 0x6e, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x24, 0x24, 0x28, + 0x27, 0x2e, 0x6e, 0x61, 0x76, 0x2d, 0x77, 0x73, 0x2d, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, + 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x27, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x27, 0x29, + 0x3b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x27, 0x2c, 0x20, 0x27, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x27, 0x20, + 0x2b, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x41, 0x70, 0x70, 0x57, 0x53, 0x43, 0x6f, 0x6e, 0x6e, 0x2e, 0x75, + 0x72, 0x6c, 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x7d, 0x2c, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x57, 0x72, 0x61, 0x70, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6e, 0x61, + 0x76, 0x29, 0x20, 0x7b, 0x24, 0x28, 0x27, 0x6e, 0x61, 0x76, 0x27, + 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, + 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, 0x2e, 0x4e, 0x61, + 0x76, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2e, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x69, 0x31, 0x38, 0x6e, 0x29, 0x3b, 0x7d, 0x2c, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, + 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x68, + 0x65, 0x6d, 0x65, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x2e, + 0x74, 0x68, 0x65, 0x6d, 0x65, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x57, 0x72, 0x61, 0x70, + 0x28, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x57, 0x53, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x28, 0x29, 0x3b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x29, 0x3b, + 0x7d, 0x7d, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x20, 0x3d, 0x20, 0x7b, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x24, + 0x24, 0x28, 0x27, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x74, 0x6f, + 0x67, 0x67, 0x6c, 0x65, 0x3d, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x5d, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, + 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x4f, 0x70, 0x74, 0x73, 0x28, + 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x69, 0x74, 0x65, + 0x6d, 0x2e, 0x6f, 0x6e, 0x62, 0x6c, 0x75, 0x72, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, + 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x4f, 0x70, 0x74, 0x73, 0x28, 0x65, 0x29, 0x3b, 0x7d, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x5b, 0x64, 0x61, + 0x74, 0x61, 0x2d, 0x70, 0x6c, 0x6f, 0x74, 0x5d, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, + 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, + 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, + 0x20, 0x7b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x2e, 0x72, 0x65, 0x64, 0x72, + 0x61, 0x77, 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, 0x65, 0x2e, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, + 0x27, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x5d, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, + 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, + 0x2e, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x28, 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x3b, 0x7d, 0x2e, 0x62, + 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x5b, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, + 0x5d, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, + 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, + 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x2e, + 0x73, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x28, 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x3b, 0x7d, 0x2e, 0x62, + 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x5b, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5d, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, + 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, + 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, + 0x20, 0x7b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x28, 0x65, 0x2e, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x7d, 0x2c, + 0x6f, 0x70, 0x65, 0x6e, 0x4f, 0x70, 0x74, 0x73, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x61, + 0x72, 0x67, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x61, 0x72, 0x67, 0x2e, + 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x74, 0x61, 0x72, 0x67, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, + 0x2e, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x28, 0x27, 0x6f, 0x70, + 0x65, 0x6e, 0x27, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x73, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x7d, 0x2c, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x4f, 0x70, 0x74, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, + 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x28, 0x27, 0x6f, 0x70, 0x65, 0x6e, 0x27, 0x29, 0x3b, + 0x69, 0x66, 0x20, 0x28, 0x65, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x20, 0x26, 0x26, + 0x20, 0x65, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, + 0x74, 0x61, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x27, 0x29, + 0x20, 0x21, 0x3d, 0x3d, 0x20, 0x27, 0x64, 0x72, 0x6f, 0x70, 0x64, + 0x6f, 0x77, 0x6e, 0x27, 0x29, 0x65, 0x2e, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x65, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x63, + 0x6c, 0x69, 0x63, 0x6b, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x73, 0x65, + 0x74, 0x50, 0x6c, 0x6f, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x75, 0x69, 0x2c, 0x20, 0x70, 0x72, 0x65, + 0x66, 0x73, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x28, + 0x28, 0x70, 0x72, 0x65, 0x66, 0x73, 0x20, 0x7c, 0x7c, 0x20, 0x7b, + 0x7d, 0x29, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x20, 0x7c, 0x7c, 0x20, + 0x7b, 0x7d, 0x29, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x20, 0x7c, 0x7c, 0x20, 0x75, 0x69, 0x2e, 0x70, 0x6c, + 0x6f, 0x74, 0x5b, 0x30, 0x5d, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x65, + 0x74, 0x72, 0x69, 0x63, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x70, 0x72, + 0x65, 0x66, 0x73, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, + 0x70, 0x6c, 0x6f, 0x74, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, + 0x2e, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x20, 0x7c, 0x7c, 0x20, + 0x75, 0x69, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x5b, 0x30, 0x5d, 0x2e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x3b, 0x75, + 0x69, 0x5b, 0x63, 0x68, 0x61, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x66, 0x6f, + 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x30, 0x2c, 0x20, 0x6c, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x75, 0x69, + 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6c, 0x65, 0x6e, 0x3b, + 0x20, 0x2b, 0x2b, 0x69, 0x29, 0x69, 0x66, 0x20, 0x28, 0x75, 0x69, + 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x5b, 0x69, 0x5d, 0x2e, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x3d, 0x20, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x29, 0x75, 0x69, 0x2e, 0x70, + 0x6c, 0x6f, 0x74, 0x5b, 0x69, 0x5d, 0x5b, 0x27, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x74, + 0x72, 0x75, 0x65, 0x3b, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x43, 0x6f, + 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x70, 0x72, 0x65, 0x66, + 0x73, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x28, 0x70, 0x72, 0x65, + 0x66, 0x73, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x20, 0x7c, 0x7c, 0x20, 0x7b, + 0x7d, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x6c, 0x65, 0x6e, 0x20, + 0x3d, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6c, 0x65, + 0x6e, 0x3b, 0x20, 0x2b, 0x2b, 0x69, 0x29, 0x69, 0x66, 0x20, 0x28, + 0x28, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x69, 0x5d, 0x2e, 0x6b, + 0x65, 0x79, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x73, 0x29, 0x20, 0x26, 0x26, 0x20, 0x63, 0x6f, 0x6c, 0x75, + 0x6d, 0x6e, 0x73, 0x5b, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x69, + 0x5d, 0x2e, 0x6b, 0x65, 0x79, 0x5d, 0x5b, 0x27, 0x68, 0x69, 0x64, + 0x65, 0x27, 0x5d, 0x29, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x69, + 0x5d, 0x5b, 0x27, 0x68, 0x69, 0x64, 0x65, 0x27, 0x5d, 0x20, 0x3d, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x7d, 0x2c, 0x73, 0x65, 0x74, + 0x43, 0x68, 0x61, 0x72, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x75, 0x69, 0x2c, 0x20, 0x70, 0x72, 0x65, + 0x66, 0x73, 0x29, 0x20, 0x7b, 0x75, 0x69, 0x5b, 0x27, 0x73, 0x68, + 0x6f, 0x77, 0x43, 0x68, 0x61, 0x72, 0x74, 0x27, 0x5d, 0x20, 0x3d, + 0x20, 0x70, 0x72, 0x65, 0x66, 0x73, 0x20, 0x26, 0x26, 0x20, 0x28, + 0x27, 0x63, 0x68, 0x61, 0x72, 0x74, 0x27, 0x20, 0x69, 0x6e, 0x20, + 0x70, 0x72, 0x65, 0x66, 0x73, 0x29, 0x20, 0x3f, 0x20, 0x70, 0x72, + 0x65, 0x66, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3a, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x7d, 0x2c, 0x73, 0x65, 0x74, + 0x4f, 0x70, 0x74, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, + 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, + 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x69, 0x66, 0x79, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, + 0x49, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x29, 0x2c, + 0x20, 0x70, 0x72, 0x65, 0x66, 0x73, 0x20, 0x3d, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, + 0x72, 0x65, 0x66, 0x73, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x68, + 0x61, 0x72, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x75, 0x69, 0x2c, 0x20, 0x70, 0x72, 0x65, 0x66, 0x73, + 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x50, + 0x6c, 0x6f, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x75, 0x69, 0x2c, 0x20, 0x70, 0x72, 0x65, 0x66, 0x73, + 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, + 0x6f, 0x6c, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x75, 0x69, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, + 0x70, 0x72, 0x65, 0x66, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x6d, 0x65, 0x72, 0x67, 0x65, + 0x28, 0x75, 0x69, 0x2c, 0x20, 0x7b, 0x27, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x27, 0x3a, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x69, 0x31, 0x38, 0x6e, 0x7d, 0x29, 0x3b, 0x7d, + 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4f, 0x70, 0x74, 0x73, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x24, 0x28, + 0x27, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x6f, 0x70, 0x74, + 0x73, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, + 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, 0x2e, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x73, 0x2e, 0x6f, 0x70, 0x74, 0x73, 0x2e, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x73, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x73, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x72, 0x65, 0x76, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, 0x23, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x2b, 0x20, 0x27, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x2e, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2d, 0x70, 0x72, 0x65, 0x76, 0x27, 0x29, 0x3b, 0x69, + 0x66, 0x20, 0x28, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x29, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, + 0x27, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x27, 0x29, + 0x3b, 0x7d, 0x2c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, + 0x72, 0x65, 0x76, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, + 0x23, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x70, 0x72, 0x65, + 0x76, 0x27, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x24, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x24, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64, + 0x64, 0x28, 0x27, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x27, 0x29, 0x3b, 0x7d, 0x2c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x4e, 0x65, 0x78, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x24, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x24, 0x28, + 0x27, 0x23, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x27, 0x20, 0x2b, + 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x20, + 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x61, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x6e, 0x65, + 0x78, 0x74, 0x27, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x24, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x24, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x27, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x27, 0x29, 0x3b, 0x7d, 0x2c, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, 0x78, 0x74, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, 0x23, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x2b, 0x20, 0x27, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x2e, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2d, 0x6e, 0x65, 0x78, 0x74, 0x27, 0x29, 0x3b, 0x69, + 0x66, 0x20, 0x28, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x29, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x27, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x27, 0x29, 0x3b, 0x7d, 0x2c, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, 0x72, 0x73, 0x74, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, 0x23, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x2e, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x2e, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x27, + 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x24, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x24, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x28, 0x27, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x27, 0x29, 0x3b, 0x7d, 0x2c, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x46, 0x69, 0x72, 0x73, 0x74, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x24, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, + 0x20, 0x24, 0x28, 0x27, 0x23, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, + 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, + 0x20, 0x27, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x69, 0x66, + 0x20, 0x28, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x29, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, + 0x73, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x27, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x27, 0x29, 0x3b, 0x7d, 0x2c, 0x65, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, 0x23, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x2b, 0x20, 0x27, 0x20, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x2e, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2d, 0x6c, 0x61, 0x73, 0x74, 0x27, 0x29, 0x3b, 0x69, + 0x66, 0x20, 0x28, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x29, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, + 0x27, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x27, 0x29, + 0x3b, 0x7d, 0x2c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4c, + 0x61, 0x73, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x24, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, + 0x23, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x6c, 0x61, 0x73, + 0x74, 0x27, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x24, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x24, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, 0x64, + 0x64, 0x28, 0x27, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x27, 0x29, 0x3b, 0x7d, 0x2c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x72, 0x65, + 0x76, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, + 0x78, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x46, + 0x69, 0x72, 0x73, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x4c, 0x61, 0x73, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x3b, 0x7d, 0x2c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x72, + 0x65, 0x76, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x4e, 0x65, 0x78, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x46, 0x69, 0x72, 0x73, 0x74, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x73, 0x74, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x7d, 0x2c, 0x68, 0x61, 0x73, + 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x75, 0x69, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x66, 0x6f, + 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, + 0x30, 0x2c, 0x20, 0x6c, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, + 0x69, 0x20, 0x3c, 0x20, 0x6c, 0x65, 0x6e, 0x3b, 0x20, 0x2b, 0x2b, + 0x69, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x64, 0x61, + 0x74, 0x61, 0x5b, 0x69, 0x5d, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x75, 0x69, + 0x5b, 0x27, 0x68, 0x61, 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, + 0x6d, 0x73, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, + 0x5b, 0x69, 0x5d, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x28, 0x75, 0x69, 0x5b, 0x27, 0x68, 0x61, + 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x27, 0x5d, + 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x29, 0x3b, 0x7d, 0x7d, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x3b, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, + 0x75, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x2c, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x68, + 0x61, 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x28, + 0x75, 0x69, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x61, + 0x74, 0x61, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x2e, 0x68, 0x61, + 0x73, 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x2e, 0x68, 0x61, 0x73, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x75, + 0x69, 0x29, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2c, 0x20, 0x75, 0x69, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x29, 0x20, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, + 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, + 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x3d, + 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x28, 0x27, 0x64, 0x69, 0x76, 0x27, 0x29, 0x3b, 0x62, 0x6f, + 0x78, 0x2e, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x27, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x3b, 0x62, 0x6f, 0x78, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, + 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, + 0x73, 0x2e, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x2e, 0x77, 0x72, + 0x61, 0x70, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, + 0x6c, 0x2e, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x28, 0x75, 0x69, 0x2c, + 0x20, 0x7b, 0x27, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x27, 0x3a, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x69, + 0x31, 0x38, 0x6e, 0x7d, 0x29, 0x29, 0x3b, 0x63, 0x6f, 0x6c, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, + 0x28, 0x62, 0x6f, 0x78, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3c, 0x3d, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, + 0x65, 0x66, 0x73, 0x28, 0x29, 0x2e, 0x70, 0x65, 0x72, 0x50, 0x61, + 0x67, 0x65, 0x29, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x54, 0x68, 0x65, 0x61, 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2c, 0x20, 0x75, 0x69, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x63, 0x6f, 0x6c, 0x3b, 0x7d, 0x2c, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x72, 0x6f, 0x77, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x65, 0x72, 0x52, 0x6f, + 0x77, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x5b, + 0x27, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x27, 0x5d, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, + 0x61, 0x6c, 0x27, 0x20, 0x3f, 0x20, 0x36, 0x20, 0x3a, 0x20, 0x31, + 0x32, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6c, 0x20, 0x3d, + 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x28, 0x27, 0x64, 0x69, 0x76, 0x27, 0x29, 0x3b, 0x63, 0x6f, + 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, + 0x2c, 0x20, 0x27, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x27, + 0x20, 0x2b, 0x20, 0x70, 0x65, 0x72, 0x52, 0x6f, 0x77, 0x20, 0x2b, + 0x20, 0x27, 0x20, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x72, 0x6f, 0x77, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x63, + 0x6f, 0x6c, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x63, 0x6f, 0x6c, 0x3b, 0x7d, 0x2c, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x52, 0x6f, 0x77, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x72, 0x6f, 0x77, 0x2c, 0x20, 0x69, + 0x64, 0x78, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x77, 0x72, + 0x61, 0x70, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, 0x2e, 0x77, 0x72, + 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x27, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, + 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x5b, 0x27, 0x6c, + 0x61, 0x79, 0x6f, 0x75, 0x74, 0x27, 0x5d, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, + 0x27, 0x20, 0x3f, 0x20, 0x32, 0x20, 0x3a, 0x20, 0x31, 0x3b, 0x69, + 0x66, 0x20, 0x28, 0x69, 0x64, 0x78, 0x20, 0x25, 0x20, 0x65, 0x76, + 0x65, 0x72, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b, + 0x72, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x64, 0x69, 0x76, + 0x27, 0x29, 0x3b, 0x72, 0x6f, 0x77, 0x2e, 0x73, 0x65, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x72, 0x6f, 0x77, + 0x27, 0x20, 0x2b, 0x20, 0x28, 0x65, 0x76, 0x65, 0x72, 0x79, 0x20, + 0x3d, 0x3d, 0x20, 0x32, 0x20, 0x3f, 0x20, 0x27, 0x20, 0x65, 0x71, + 0x75, 0x61, 0x6c, 0x27, 0x20, 0x3a, 0x20, 0x27, 0x27, 0x29, 0x29, + 0x3b, 0x77, 0x72, 0x61, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x72, 0x6f, 0x77, 0x29, + 0x3b, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x6f, + 0x77, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x73, 0x65, 0x74, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, + 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x29, 0x2c, 0x20, + 0x69, 0x64, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x72, 0x6f, + 0x77, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, + 0x23, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, + 0x69, 0x6c, 0x2e, 0x69, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x56, + 0x61, 0x6c, 0x69, 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6c, 0x20, + 0x3d, 0x20, 0x65, 0x6c, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x63, 0x6f, 0x6c, 0x2e, 0x72, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, + 0x65, 0x6c, 0x65, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x5b, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x29, + 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, + 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x29, 0x2c, 0x20, 0x69, + 0x64, 0x78, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x72, 0x6f, 0x77, + 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x20, 0x63, 0x6f, + 0x6c, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x24, 0x28, + 0x27, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x2d, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x73, 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, + 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x27, 0x27, 0x3b, 0x66, 0x6f, + 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x69, 0x29, 0x20, 0x7b, 0x69, + 0x66, 0x20, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x69, 0x73, 0x50, 0x61, 0x6e, + 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x29, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x3b, 0x72, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x77, + 0x28, 0x72, 0x6f, 0x77, 0x2c, 0x20, 0x69, 0x64, 0x78, 0x2b, 0x2b, + 0x29, 0x3b, 0x63, 0x6f, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, + 0x28, 0x72, 0x6f, 0x77, 0x29, 0x3b, 0x63, 0x6f, 0x6c, 0x20, 0x3d, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x5d, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x29, 0x3b, 0x7d, 0x7d, 0x2c, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x28, 0x29, + 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x7d, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, + 0x20, 0x3d, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x72, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x63, 0x61, + 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x20, 0x7b, 0x4f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x73, 0x28, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, + 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x29, 0x2e, 0x66, 0x6f, 0x72, + 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, + 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x69, 0x73, + 0x57, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x50, + 0x6f, 0x72, 0x74, 0x28, 0x24, 0x28, 0x27, 0x23, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, + 0x69, 0x66, 0x20, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x20, 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, + 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x3d, + 0x3d, 0x3d, 0x20, 0x27, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x27, 0x29, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, + 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, + 0x70, 0x70, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x5b, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x5d, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, 0x20, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x5b, 0x27, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x27, 0x5d, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x61, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x5b, 0x6b, 0x65, 0x79, 0x5d, 0x3b, + 0x20, 0x7d, 0x29, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x20, 0x3d, 0x20, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, + 0x69, 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x70, 0x6c, 0x6f, 0x74, + 0x27, 0x29, 0x3b, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x28, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, + 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x2e, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x20, 0x3f, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, 0x20, 0x3a, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x3b, 0x7d, 0x2c, 0x64, 0x72, 0x61, 0x77, 0x50, 0x6c, + 0x6f, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x70, + 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, + 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2c, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2c, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x73, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x20, 0x3d, + 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x73, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x20, 0x3d, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x2c, 0x73, 0x65, + 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x74, 0x61, 0x72, 0x67, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x61, 0x72, + 0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x61, 0x72, 0x67, + 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x27, 0x29, 0x3b, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, + 0x69, 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, + 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x70, 0x6c, 0x6f, 0x74, + 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x27, + 0x2c, 0x20, 0x74, 0x79, 0x70, 0x65, 0x29, 0x3b, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, + 0x65, 0x66, 0x73, 0x28, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x70, + 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, + 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, + 0x2b, 0x20, 0x27, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x27, 0x29, 0x3b, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x50, 0x6c, + 0x6f, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x70, + 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, + 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x3b, + 0x7d, 0x2c, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x74, 0x61, 0x72, 0x67, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3d, 0x20, + 0x74, 0x61, 0x72, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x73, 0x20, 0x3d, 0x20, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, + 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x2c, 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, + 0x70, 0x72, 0x65, 0x66, 0x73, 0x20, 0x26, 0x26, 0x20, 0x28, 0x27, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x70, + 0x72, 0x65, 0x66, 0x73, 0x29, 0x20, 0x3f, 0x20, 0x70, 0x72, 0x65, + 0x66, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3a, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x73, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, + 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, + 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x27, 0x2c, 0x20, 0x21, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, + 0x73, 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x2e, 0x72, 0x65, + 0x73, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x2e, 0x72, + 0x65, 0x73, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x3b, 0x7d, 0x2c, 0x68, 0x61, 0x73, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x72, 0x65, 0x66, 0x73, + 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2c, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x20, 0x3d, 0x20, 0x70, 0x72, 0x65, 0x66, 0x73, 0x20, 0x26, 0x26, + 0x20, 0x28, 0x27, 0x63, 0x68, 0x61, 0x72, 0x74, 0x27, 0x20, 0x69, + 0x6e, 0x20, 0x70, 0x72, 0x65, 0x66, 0x73, 0x29, 0x20, 0x3f, 0x20, + 0x70, 0x72, 0x65, 0x66, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x75, 0x69, 0x5b, + 0x27, 0x63, 0x68, 0x61, 0x72, 0x74, 0x27, 0x5d, 0x20, 0x3d, 0x20, + 0x75, 0x69, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x20, 0x26, 0x26, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x20, 0x26, 0x26, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, + 0x7d, 0x2c, 0x72, 0x65, 0x64, 0x72, 0x61, 0x77, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x74, 0x61, 0x72, 0x67, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x20, 0x3d, 0x20, 0x74, + 0x61, 0x72, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x70, 0x6c, 0x6f, 0x74, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x61, + 0x72, 0x67, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, + 0x6c, 0x55, 0x49, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x20, + 0x3d, 0x20, 0x75, 0x69, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x3b, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, + 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, + 0x50, 0x72, 0x65, 0x66, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x2e, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x27, 0x2c, 0x20, 0x70, 0x6c, + 0x6f, 0x74, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x78, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, + 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x70, 0x6c, 0x6f, + 0x74, 0x55, 0x49, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x78, 0x29, 0x20, + 0x7c, 0x7c, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x78, + 0x5d, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, + 0x20, 0x21, 0x3d, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x29, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x73, + 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, + 0x20, 0x27, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x27, 0x2c, 0x20, 0x70, + 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x78, 0x5d, 0x29, 0x3b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x50, 0x6c, 0x6f, + 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x70, 0x6c, + 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x78, 0x5d, 0x2c, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, + 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x7d, 0x7d, 0x2c, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6f, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x66, 0x6f, + 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x70, 0x72, 0x6f, 0x70, + 0x20, 0x69, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x6f, 0x5b, + 0x70, 0x72, 0x6f, 0x70, 0x5d, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, + 0x67, 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x28, 0x69, 0x74, + 0x65, 0x6d, 0x5b, 0x70, 0x72, 0x6f, 0x70, 0x5d, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x3b, 0x7d, 0x2c, 0x70, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x44, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, + 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x20, 0x2b, 0x2b, 0x69, 0x29, 0x6f, 0x75, 0x74, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, + 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x5b, 0x69, 0x5d, 0x29, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x3b, + 0x7d, 0x2c, 0x66, 0x69, 0x6e, 0x64, 0x55, 0x49, 0x49, 0x74, 0x65, + 0x6d, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, + 0x79, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, + 0x55, 0x49, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x6f, 0x20, 0x3d, 0x20, 0x7b, + 0x7d, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x20, 0x2b, 0x2b, 0x69, 0x29, 0x20, 0x7b, 0x69, 0x66, + 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x69, 0x5d, 0x2e, + 0x6b, 0x65, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x6b, 0x65, 0x79, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x5b, 0x69, 0x5d, 0x3b, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x7d, 0x2c, 0x67, 0x65, + 0x74, 0x58, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x61, 0x74, 0x75, 0x6d, + 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x61, 0x72, 0x72, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x69, + 0x66, 0x20, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6b, + 0x65, 0x79, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x27, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x5b, 0x6b, 0x65, 0x79, 0x5d, + 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x70, + 0x72, 0x6f, 0x70, 0x20, 0x69, 0x6e, 0x20, 0x6b, 0x65, 0x79, 0x29, + 0x61, 0x72, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x64, 0x61, + 0x74, 0x75, 0x6d, 0x5b, 0x6b, 0x65, 0x79, 0x5b, 0x70, 0x72, 0x6f, + 0x70, 0x5d, 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x72, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x27, + 0x20, 0x27, 0x29, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x41, 0x72, + 0x65, 0x61, 0x53, 0x70, 0x6c, 0x69, 0x6e, 0x65, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, + 0x20, 0x3d, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x27, + 0x64, 0x33, 0x27, 0x5d, 0x5b, 0x27, 0x79, 0x31, 0x27, 0x5d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3d, + 0x20, 0x41, 0x72, 0x65, 0x61, 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, + 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x29, 0x2e, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x28, 0x7b, 0x79, 0x30, 0x3a, + 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x27, 0x64, 0x33, + 0x27, 0x5d, 0x5b, 0x27, 0x79, 0x30, 0x27, 0x5d, 0x2e, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x2c, 0x79, 0x31, 0x3a, 0x20, 0x64, 0x75, 0x61, + 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, 0x3f, 0x20, 0x70, 0x6c, + 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x27, 0x64, 0x33, 0x27, 0x5d, 0x5b, + 0x27, 0x79, 0x31, 0x27, 0x5d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x20, 0x3a, 0x20, 0x27, 0x27, 0x7d, 0x29, 0x2e, 0x78, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, + 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x28, 0x28, 0x28, 0x70, 0x6c, + 0x6f, 0x74, 0x55, 0x49, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, + 0x2e, 0x64, 0x33, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, + 0x78, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x6b, 0x65, + 0x79, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x58, 0x4b, 0x65, 0x79, 0x28, + 0x64, 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x27, + 0x64, 0x33, 0x27, 0x5d, 0x5b, 0x27, 0x78, 0x27, 0x5d, 0x5b, 0x27, + 0x6b, 0x65, 0x79, 0x27, 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x64, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x7d, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x29, 0x2e, 0x79, 0x30, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x2b, 0x64, 0x5b, 0x70, 0x6c, 0x6f, 0x74, + 0x55, 0x49, 0x5b, 0x27, 0x64, 0x33, 0x27, 0x5d, 0x5b, 0x27, 0x79, + 0x30, 0x27, 0x5d, 0x5b, 0x27, 0x6b, 0x65, 0x79, 0x27, 0x5d, 0x5d, + 0x3b, 0x7d, 0x29, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x28, 0x24, + 0x28, 0x22, 0x23, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x22, 0x20, + 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x67, 0x65, + 0x74, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x74, 0x28, 0x29, 0x2e, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x2e, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x28, 0x31, 0x37, 0x35, 0x29, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x28, 0x7b, 0x78, 0x3a, 0x20, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x55, 0x49, 0x49, 0x74, + 0x65, 0x6d, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x27, + 0x64, 0x61, 0x74, 0x61, 0x27, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x7b, + 0x7d, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, + 0x20, 0x7c, 0x7c, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x79, 0x30, + 0x3a, 0x20, 0x28, 0x28, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2e, + 0x64, 0x33, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x79, + 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x79, 0x31, 0x3a, 0x20, 0x28, 0x28, + 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2e, 0x64, 0x33, 0x20, 0x7c, + 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x79, 0x31, 0x20, 0x7c, 0x7c, + 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x2c, 0x7d, 0x29, 0x2e, 0x6f, 0x70, 0x74, 0x73, 0x28, 0x70, 0x6c, + 0x6f, 0x74, 0x55, 0x49, 0x29, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, + 0x61, 0x78, 0x69, 0x73, 0x20, 0x26, 0x26, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2e, 0x79, 0x31, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x2b, 0x64, 0x5b, 0x70, 0x6c, 0x6f, + 0x74, 0x55, 0x49, 0x5b, 0x27, 0x64, 0x33, 0x27, 0x5d, 0x5b, 0x27, + 0x79, 0x31, 0x27, 0x5d, 0x5b, 0x27, 0x6b, 0x65, 0x79, 0x27, 0x5d, + 0x5d, 0x3b, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x2c, 0x67, 0x65, + 0x74, 0x56, 0x42, 0x61, 0x72, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2c, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, + 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, 0x3d, 0x20, + 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x27, 0x64, 0x33, 0x27, + 0x5d, 0x5b, 0x27, 0x79, 0x31, 0x27, 0x5d, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x42, 0x61, + 0x72, 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, 0x64, 0x75, 0x61, 0x6c, + 0x59, 0x61, 0x78, 0x69, 0x73, 0x29, 0x2e, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x28, 0x7b, 0x79, 0x30, 0x3a, 0x20, 0x70, 0x6c, 0x6f, + 0x74, 0x55, 0x49, 0x5b, 0x27, 0x64, 0x33, 0x27, 0x5d, 0x5b, 0x27, + 0x79, 0x30, 0x27, 0x5d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2c, + 0x79, 0x31, 0x3a, 0x20, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, + 0x69, 0x73, 0x20, 0x3f, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, + 0x5b, 0x27, 0x64, 0x33, 0x27, 0x5d, 0x5b, 0x27, 0x79, 0x31, 0x27, + 0x5d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x3a, 0x20, 0x27, + 0x27, 0x7d, 0x29, 0x2e, 0x78, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x69, 0x66, + 0x20, 0x28, 0x28, 0x28, 0x28, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, + 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x64, 0x33, 0x20, + 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x78, 0x20, 0x7c, 0x7c, + 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x6b, 0x65, 0x79, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, + 0x65, 0x74, 0x58, 0x4b, 0x65, 0x79, 0x28, 0x64, 0x2c, 0x20, 0x70, + 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x27, 0x64, 0x33, 0x27, 0x5d, + 0x5b, 0x27, 0x78, 0x27, 0x5d, 0x5b, 0x27, 0x6b, 0x65, 0x79, 0x27, + 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x2e, 0x79, 0x30, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x2b, 0x64, 0x5b, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, 0x27, + 0x64, 0x33, 0x27, 0x5d, 0x5b, 0x27, 0x79, 0x30, 0x27, 0x5d, 0x5b, + 0x27, 0x6b, 0x65, 0x79, 0x27, 0x5d, 0x5d, 0x3b, 0x7d, 0x29, 0x2e, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x28, 0x24, 0x28, 0x22, 0x23, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2d, 0x22, 0x20, 0x2b, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x42, 0x6f, 0x75, + 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x63, 0x74, 0x28, 0x29, 0x2e, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x29, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x28, 0x31, + 0x37, 0x35, 0x29, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, + 0x7b, 0x78, 0x3a, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, + 0x69, 0x6e, 0x64, 0x55, 0x49, 0x49, 0x74, 0x65, 0x6d, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x27, 0x64, 0x61, 0x74, 0x61, + 0x27, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x20, 0x7c, 0x7c, 0x20, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x79, 0x30, 0x3a, 0x20, 0x28, 0x28, + 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2e, 0x64, 0x33, 0x20, 0x7c, + 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x79, 0x30, 0x20, 0x7c, 0x7c, + 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x2c, 0x79, 0x31, 0x3a, 0x20, 0x28, 0x28, 0x70, 0x6c, 0x6f, 0x74, + 0x55, 0x49, 0x2e, 0x64, 0x33, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, + 0x29, 0x2e, 0x79, 0x31, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x7d, 0x29, 0x2e, + 0x6f, 0x70, 0x74, 0x73, 0x28, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, + 0x29, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, + 0x20, 0x26, 0x26, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x79, + 0x31, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x2b, 0x64, 0x5b, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x5b, + 0x27, 0x64, 0x33, 0x27, 0x5d, 0x5b, 0x27, 0x79, 0x31, 0x27, 0x5d, + 0x5b, 0x27, 0x6b, 0x65, 0x79, 0x27, 0x5d, 0x5d, 0x3b, 0x7d, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, + 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x75, 0x69, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x29, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x27, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x67, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, + 0x28, 0x29, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, + 0x20, 0x27, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x27, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x75, 0x69, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x5b, 0x30, 0x5d, + 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x54, 0x79, 0x70, 0x65, 0x3b, + 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x50, 0x6c, 0x6f, 0x74, 0x55, 0x49, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, + 0x29, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, + 0x27, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x2e, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x63, 0x27, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x75, 0x69, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x5b, 0x30, + 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x69, + 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x76, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x76, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, + 0x65, 0x20, 0x3d, 0x3d, 0x20, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x3b, 0x7d, 0x29, 0x5b, 0x30, 0x5d, 0x3b, 0x7d, 0x2c, 0x67, 0x65, + 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2c, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, + 0x6c, 0x3b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x29, 0x20, 0x7b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x61, + 0x72, 0x65, 0x61, 0x2d, 0x73, 0x70, 0x6c, 0x69, 0x6e, 0x65, 0x27, + 0x3a, 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x72, 0x65, 0x61, 0x53, + 0x70, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2c, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, + 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x62, 0x61, 0x72, 0x27, 0x3a, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x56, 0x42, 0x61, 0x72, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, + 0x49, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x3b, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x2c, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x43, 0x68, 0x61, 0x72, 0x74, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x64, 0x33, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x23, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x3e, 0x2e, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, + 0x2d, 0x77, 0x72, 0x61, 0x70, 0x27, 0x29, 0x2e, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x28, 0x29, 0x3b, 0x64, 0x33, 0x2e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x23, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x73, + 0x76, 0x67, 0x27, 0x29, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x28, 0x29, 0x3b, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x28, 0x22, 0x23, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x22, + 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x64, + 0x61, 0x74, 0x75, 0x6d, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x2e, + 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x63, 0x68, 0x61, 0x72, 0x74, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x22, 0x64, 0x69, + 0x76, 0x22, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x22, 0x2c, 0x20, 0x22, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x2d, + 0x77, 0x72, 0x61, 0x70, 0x22, 0x29, 0x3b, 0x7d, 0x2c, 0x61, 0x64, + 0x64, 0x43, 0x68, 0x61, 0x72, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x20, 0x3d, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, + 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x75, 0x69, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x20, 0x7c, 0x7c, + 0x20, 0x21, 0x75, 0x69, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x3b, 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x20, 0x3d, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x6c, 0x6f, + 0x74, 0x55, 0x49, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x75, 0x69, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2c, + 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, + 0x70, 0x6c, 0x6f, 0x74, 0x27, 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, + 0x55, 0x49, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, + 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x28, 0x63, 0x68, 0x61, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x70, 0x6c, + 0x6f, 0x74, 0x55, 0x49, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, + 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x68, + 0x61, 0x72, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x41, 0x70, 0x70, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x5b, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x20, 0x3d, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x75, 0x69, 0x29, 0x20, + 0x7b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x69, 0x29, + 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x75, 0x69, 0x2e, 0x68, + 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x61, 0x64, 0x64, 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x5b, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x29, 0x3b, 0x7d, 0x7d, 0x2c, 0x72, + 0x65, 0x73, 0x65, 0x74, 0x43, 0x68, 0x61, 0x72, 0x74, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x75, 0x69, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x69, 0x66, 0x20, + 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, + 0x74, 0x69, 0x6c, 0x2e, 0x69, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x3b, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, + 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x64, 0x64, + 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2c, 0x20, 0x75, 0x69, 0x29, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6c, + 0x6f, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x74, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x75, 0x62, 0x49, 0x74, + 0x65, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, + 0x67, 0x65, 0x74, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, + 0x20, 0x28, 0x73, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3f, 0x20, 0x73, 0x75, + 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x3a, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, + 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x29, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x29, 0x3b, 0x64, 0x33, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x22, 0x23, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2d, 0x22, 0x20, 0x2b, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x43, 0x68, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, + 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x29, 0x29, 0x2e, + 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x28, 0x24, 0x28, 0x22, 0x23, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2d, 0x22, 0x20, 0x2b, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x57, 0x69, 0x64, 0x74, 0x68, 0x29, 0x29, 0x3b, 0x7d, 0x2c, 0x72, + 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x74, + 0x65, 0x72, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2c, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x28, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2c, 0x20, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, + 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x7d, 0x2c, 0x72, + 0x65, 0x64, 0x72, 0x61, 0x77, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x74, + 0x65, 0x72, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2c, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x64, 0x33, 0x2e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x28, 0x22, 0x23, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2d, 0x22, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x28, 0x24, 0x28, 0x22, + 0x23, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x22, 0x20, 0x2b, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x57, 0x69, 0x64, 0x74, 0x68, 0x29, 0x29, 0x3b, 0x7d, + 0x29, 0x3b, 0x7d, 0x2c, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x73, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, + 0x28, 0x29, 0x29, 0x3b, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x29, 0x2e, + 0x6f, 0x6e, 0x28, 0x27, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x73, 0x27, 0x2c, 0x20, 0x64, 0x65, + 0x62, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x28, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x68, + 0x61, 0x72, 0x74, 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x20, 0x32, + 0x35, 0x30, 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x2e, + 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, + 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, + 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x73, 0x27, 0x2c, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, + 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x64, 0x72, 0x61, + 0x77, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x28, 0x29, 0x3b, 0x7d, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x29, 0x3b, 0x7d, 0x7d, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x63, 0x68, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, + 0x3a, 0x20, 0x7b, 0x7d, 0x2c, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x29, 0x20, 0x7b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2d, 0x6e, 0x65, 0x78, 0x74, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, + 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, + 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x27, + 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x65, + 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, + 0x28, 0x27, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x70, 0x72, + 0x65, 0x76, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, + 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, + 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x50, 0x61, 0x67, 0x65, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x3b, 0x7d, 0x2e, + 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, + 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2d, 0x66, 0x69, 0x72, 0x73, 0x74, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, + 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, + 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x3d, 0x20, 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x27, + 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x22, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, + 0x50, 0x41, 0x47, 0x45, 0x22, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, + 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, + 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2d, 0x6c, 0x61, 0x73, 0x74, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, + 0x29, 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, + 0x6c, 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3d, 0x20, + 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, + 0x20, 0x22, 0x4c, 0x41, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, + 0x22, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, + 0x27, 0x2e, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x74, 0x64, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, + 0x20, 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, + 0x69, 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x69, 0x66, + 0x20, 0x28, 0x21, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x67, + 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x28, 0x29, 0x29, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x28, 0x65, 0x2e, 0x63, 0x75, + 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, + 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x24, 0x24, 0x28, 0x27, + 0x2e, 0x72, 0x6f, 0x77, 0x2d, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, + 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x61, + 0x62, 0x6c, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, + 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x52, 0x6f, 0x77, + 0x28, 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x3b, 0x7d, 0x2e, 0x62, 0x69, + 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, 0x2e, + 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, + 0x3b, 0x24, 0x24, 0x28, 0x27, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x20, + 0x7b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x69, + 0x63, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x28, 0x65, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x3b, 0x7d, 0x2e, 0x62, + 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x7d, + 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x29, 0x3b, 0x7d, 0x2c, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x43, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x61, 0x72, 0x67, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x3d, 0x20, 0x74, 0x61, 0x72, 0x67, 0x2e, 0x67, 0x65, 0x74, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x27, + 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x20, 0x3d, 0x20, 0x74, 0x61, 0x72, 0x67, 0x2e, 0x67, 0x65, + 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, + 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x28, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, + 0x65, 0x66, 0x73, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, + 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x63, 0x6f, 0x6c, 0x75, + 0x6d, 0x6e, 0x73, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x3b, 0x69, + 0x66, 0x20, 0x28, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x20, 0x69, + 0x6e, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x29, 0x20, + 0x7b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x73, 0x5b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, + 0x5d, 0x3b, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, + 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x2c, 0x20, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x68, 0x69, 0x64, + 0x65, 0x27, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x65, 0x29, 0x3b, 0x7d, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, + 0x69, 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, + 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x63, 0x6f, 0x6c, 0x75, + 0x6d, 0x6e, 0x73, 0x27, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x73, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, + 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x54, 0x68, 0x65, 0x61, 0x64, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, + 0x49, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x3b, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, + 0x75, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x7d, 0x2c, 0x73, 0x6f, 0x72, 0x74, + 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, 0x6c, 0x65, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x20, 0x3d, 0x20, 0x65, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, + 0x61, 0x74, 0x61, 0x2d, 0x6b, 0x65, 0x79, 0x27, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x3d, 0x20, + 0x65, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x27, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3d, 0x20, 0x65, + 0x6c, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x27, 0x29, 0x3b, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x20, 0x3d, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x20, 0x3f, 0x20, + 0x27, 0x61, 0x73, 0x63, 0x27, 0x20, 0x3d, 0x3d, 0x20, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x20, 0x3f, 0x20, 0x27, 0x64, 0x65, 0x73, 0x63, + 0x27, 0x20, 0x3a, 0x20, 0x27, 0x61, 0x73, 0x63, 0x27, 0x20, 0x3a, + 0x20, 0x27, 0x61, 0x73, 0x63, 0x27, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x73, 0x6f, + 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2c, 0x20, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x73, 0x65, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, + 0x27, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x27, 0x2c, 0x20, 0x7b, 0x27, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x27, 0x3a, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x2c, 0x27, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x27, 0x3a, + 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2c, 0x7d, 0x29, 0x3b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, + 0x68, 0x65, 0x61, 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, + 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x75, 0x72, 0x50, 0x61, + 0x67, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x3b, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, + 0x61, 0x72, 0x74, 0x73, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, + 0x43, 0x68, 0x61, 0x72, 0x74, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x73, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x2c, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x7d, 0x2c, 0x67, 0x65, + 0x74, 0x44, 0x61, 0x74, 0x61, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, + 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, + 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x64, 0x61, + 0x74, 0x61, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x6e, 0x20, 0x3d, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6e, 0x3b, 0x20, 0x2b, + 0x2b, 0x69, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, + 0x2e, 0x68, 0x61, 0x73, 0x68, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x64, + 0x61, 0x74, 0x61, 0x5b, 0x69, 0x5d, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x6b, 0x65, 0x79, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x61, 0x5b, 0x69, + 0x5d, 0x3b, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x53, 0x75, + 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x44, 0x61, 0x74, 0x61, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x2c, 0x20, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, + 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x3b, 0x66, 0x6f, 0x72, + 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x78, 0x20, 0x69, 0x6e, 0x20, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, + 0x28, 0x21, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x68, 0x61, 0x73, + 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x28, 0x78, 0x29, 0x29, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x3b, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, + 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x5b, 0x78, 0x5d, 0x29, 0x3b, 0x7d, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x7d, 0x2c, 0x61, + 0x64, 0x64, 0x43, 0x68, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, + 0x44, 0x61, 0x74, 0x61, 0x42, 0x79, 0x4b, 0x65, 0x79, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x27, + 0x20, 0x2b, 0x20, 0x6b, 0x65, 0x79, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x64, 0x61, 0x74, 0x61, 0x20, 0x7c, 0x7c, 0x20, 0x21, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x29, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5b, 0x5d, 0x3b, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, + 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, + 0x61, 0x2c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2c, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x67, 0x65, 0x74, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, + 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, + 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, 0x20, 0x7b, 0x69, + 0x66, 0x20, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x27, 0x20, 0x2b, 0x20, + 0x6b, 0x65, 0x79, 0x29, 0x29, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x44, 0x61, 0x74, 0x61, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, + 0x5b, 0x6b, 0x65, 0x79, 0x5d, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x44, + 0x61, 0x74, 0x61, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x20, + 0x7c, 0x7c, 0x20, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x6b, + 0x65, 0x79, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x5b, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x5d, 0x29, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, + 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x64, 0x61, + 0x74, 0x61, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x75, 0x62, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x7d, 0x2c, 0x69, 0x73, 0x45, 0x78, + 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x65, 0x78, 0x70, + 0x61, 0x6e, 0x64, 0x65, 0x64, 0x2e, 0x27, 0x20, 0x2b, 0x20, 0x6b, + 0x65, 0x79, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, + 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x74, 0x68, + 0x29, 0x3b, 0x7d, 0x2c, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x45, + 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x65, 0x78, + 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x2e, 0x27, 0x20, 0x2b, 0x20, + 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x69, 0x73, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, + 0x65, 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x6b, + 0x65, 0x79, 0x29, 0x29, 0x20, 0x7b, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x5b, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x5d, 0x5b, 0x27, 0x65, 0x78, 0x70, 0x61, 0x6e, + 0x64, 0x65, 0x64, 0x27, 0x5d, 0x5b, 0x6b, 0x65, 0x79, 0x5d, 0x3b, + 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, + 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x74, 0x68, 0x2c, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x29, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x20, + 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x7d, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x3b, 0x7d, 0x2c, + 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x65, + 0x6c, 0x65, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x68, 0x69, + 0x64, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x65, + 0x6c, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, + 0x64, 0x65, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x20, 0x3d, 0x20, 0x72, 0x6f, 0x77, 0x2e, 0x67, 0x65, 0x74, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x27, + 0x29, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x3d, 0x20, 0x72, 0x6f, + 0x77, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6b, + 0x65, 0x79, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x6c, + 0x6f, 0x74, 0x55, 0x49, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x73, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x2e, + 0x6f, 0x70, 0x74, 0x73, 0x28, 0x29, 0x3b, 0x68, 0x69, 0x64, 0x65, + 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, + 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, + 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, + 0x74, 0x43, 0x75, 0x72, 0x50, 0x61, 0x67, 0x65, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x70, 0x6c, 0x6f, 0x74, 0x55, 0x49, 0x2e, 0x72, 0x65, 0x64, 0x72, + 0x61, 0x77, 0x4f, 0x6e, 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x68, 0x69, 0x64, 0x65, 0x29, 0x20, 0x7b, 0x64, 0x61, 0x74, + 0x61, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x72, 0x74, 0x44, + 0x61, 0x74, 0x61, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x64, + 0x64, 0x43, 0x68, 0x61, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x6b, 0x65, 0x79, 0x29, + 0x29, 0x3b, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x64, + 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x44, 0x61, 0x74, 0x61, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, + 0x20, 0x6b, 0x65, 0x79, 0x29, 0x29, 0x3b, 0x7d, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x73, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x50, 0x6c, 0x6f, 0x74, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x70, 0x6c, 0x6f, 0x74, + 0x55, 0x49, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x7d, + 0x2c, 0x67, 0x65, 0x74, 0x43, 0x75, 0x72, 0x50, 0x61, 0x67, 0x65, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x67, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, + 0x2e, 0x63, 0x75, 0x72, 0x50, 0x61, 0x67, 0x65, 0x27, 0x29, 0x20, + 0x7c, 0x7c, 0x20, 0x30, 0x3b, 0x7d, 0x2c, 0x70, 0x61, 0x67, 0x65, + 0x4f, 0x66, 0x66, 0x53, 0x65, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x28, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x43, + 0x75, 0x72, 0x50, 0x61, 0x67, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x20, 0x2d, 0x20, 0x31, 0x29, 0x20, 0x2a, 0x20, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, + 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x29, 0x2e, 0x70, 0x65, 0x72, + 0x50, 0x61, 0x67, 0x65, 0x29, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, + 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x61, 0x67, 0x65, 0x73, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x29, 0x20, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x64, 0x61, 0x74, 0x61, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x20, 0x2f, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, + 0x29, 0x2e, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x29, 0x3b, + 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x50, 0x61, 0x67, 0x65, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x67, 0x65, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x50, 0x61, 0x67, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x50, + 0x61, 0x67, 0x65, 0x73, 0x28, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, + 0x65, 0x6d, 0x73, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x70, 0x61, + 0x67, 0x65, 0x20, 0x3c, 0x20, 0x31, 0x29, 0x70, 0x61, 0x67, 0x65, + 0x20, 0x3d, 0x20, 0x31, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x70, 0x61, + 0x67, 0x65, 0x20, 0x3e, 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, + 0x61, 0x67, 0x65, 0x73, 0x29, 0x70, 0x61, 0x67, 0x65, 0x20, 0x3d, + 0x20, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x61, 0x67, 0x65, 0x73, + 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, + 0x74, 0x69, 0x6c, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, + 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x63, 0x75, 0x72, + 0x50, 0x61, 0x67, 0x65, 0x27, 0x2c, 0x20, 0x70, 0x61, 0x67, 0x65, + 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x61, 0x67, + 0x65, 0x4f, 0x66, 0x66, 0x53, 0x65, 0x74, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x6e, 0x64, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x2b, 0x20, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, + 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x29, 0x2e, 0x70, 0x65, + 0x72, 0x50, 0x61, 0x67, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x2c, 0x20, 0x65, 0x6e, 0x64, 0x29, 0x3b, 0x7d, 0x2c, 0x70, + 0x72, 0x65, 0x76, 0x50, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x75, + 0x72, 0x50, 0x61, 0x67, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x20, 0x2d, 0x20, 0x31, 0x3b, 0x7d, 0x2c, 0x6e, 0x65, 0x78, + 0x74, 0x50, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x75, 0x72, 0x50, + 0x61, 0x67, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, + 0x2b, 0x20, 0x31, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x4d, 0x65, + 0x74, 0x61, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x75, 0x69, 0x2c, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x7b, 0x69, 0x66, + 0x20, 0x28, 0x27, 0x6d, 0x65, 0x74, 0x61, 0x27, 0x20, 0x69, 0x6e, + 0x20, 0x75, 0x69, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5b, 0x75, 0x69, 0x2e, 0x6d, 0x65, + 0x74, 0x61, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x43, 0x65, 0x6c, 0x6c, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x75, 0x69, 0x2c, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x76, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x28, 0x75, 0x69, 0x2c, 0x20, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x61, 0x78, + 0x20, 0x3d, 0x20, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x7c, + 0x7c, 0x20, 0x7b, 0x7d, 0x29, 0x2e, 0x6d, 0x61, 0x78, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, 0x29, + 0x2e, 0x6d, 0x69, 0x6e, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x76, 0x74, + 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x75, 0x69, 0x2e, 0x6d, 0x65, + 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x20, 0x7c, 0x7c, 0x20, 0x75, + 0x69, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, + 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x75, 0x69, 0x2e, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7c, 0x7c, 0x20, 0x27, + 0x27, 0x3b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, + 0x20, 0x2b, 0x3d, 0x20, 0x75, 0x69, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x54, 0x79, 0x70, 0x65, 0x20, 0x21, 0x3d, 0x20, 0x27, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x27, 0x20, 0x3f, 0x20, 0x27, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x27, 0x20, 0x3a, + 0x20, 0x27, 0x27, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x7b, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, + 0x27, 0x3a, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, + 0x65, 0x2c, 0x27, 0x6d, 0x61, 0x78, 0x27, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3a, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x21, 0x3d, 0x20, + 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x3f, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, + 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x28, 0x6d, 0x61, 0x78, 0x2c, 0x20, 0x76, 0x74, 0x79, 0x70, + 0x65, 0x29, 0x20, 0x3a, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x27, + 0x6d, 0x69, 0x6e, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, + 0x20, 0x6d, 0x69, 0x6e, 0x20, 0x21, 0x3d, 0x20, 0x75, 0x6e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x20, 0x3f, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, + 0x2e, 0x66, 0x6d, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x6d, + 0x69, 0x6e, 0x2c, 0x20, 0x76, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, + 0x3a, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x27, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x27, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x76, 0x61, + 0x6c, 0x20, 0x21, 0x3d, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x65, 0x64, 0x20, 0x3f, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, + 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x76, 0x61, 0x6c, 0x2c, + 0x20, 0x76, 0x74, 0x79, 0x70, 0x65, 0x29, 0x20, 0x3a, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x27, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x27, + 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x75, 0x69, 0x2e, 0x6d, 0x65, + 0x74, 0x61, 0x2c, 0x27, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x3a, 0x20, 0x75, 0x69, 0x2e, 0x6d, 0x65, 0x74, + 0x61, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x7c, 0x7c, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x7d, 0x3b, 0x7d, 0x2c, 0x68, 0x69, 0x64, + 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x20, + 0x3d, 0x20, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, 0x73, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x7b, 0x7d, + 0x29, 0x2e, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x20, 0x7c, + 0x7c, 0x20, 0x7b, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x28, 0x28, 0x63, 0x6f, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x63, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x29, 0x20, 0x26, 0x26, 0x20, + 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x5b, 0x63, 0x6f, 0x6c, + 0x5d, 0x5b, 0x27, 0x68, 0x69, 0x64, 0x65, 0x27, 0x5d, 0x29, 0x3b, + 0x7d, 0x2c, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x28, 0x27, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, + 0x66, 0x73, 0x28, 0x29, 0x29, 0x20, 0x3f, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, + 0x65, 0x66, 0x73, 0x28, 0x29, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x3b, 0x7d, 0x2c, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x27, 0x61, 0x75, + 0x74, 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x27, 0x20, 0x69, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, 0x66, + 0x73, 0x28, 0x29, 0x29, 0x20, 0x3f, 0x20, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x65, + 0x66, 0x73, 0x28, 0x29, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, + 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x20, 0x3a, 0x20, + 0x74, 0x72, 0x75, 0x65, 0x3b, 0x7d, 0x2c, 0x68, 0x61, 0x73, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x75, 0x69, 0x29, 0x20, 0x7b, 0x75, + 0x69, 0x5b, 0x27, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x27, 0x5d, 0x20, + 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x68, 0x6f, 0x77, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, 0x29, 0x3b, 0x75, 0x69, + 0x5b, 0x27, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, 0x29, 0x3b, 0x7d, + 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, + 0x52, 0x6f, 0x77, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x75, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x6d, 0x65, + 0x74, 0x61, 0x27, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x20, + 0x3d, 0x20, 0x5b, 0x5d, 0x2c, 0x20, 0x75, 0x69, 0x49, 0x74, 0x65, + 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x75, 0x69, 0x2e, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, + 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x66, 0x6f, 0x72, + 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, + 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x75, 0x69, 0x49, 0x74, 0x65, + 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, + 0x2b, 0x2b, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, + 0x74, 0x65, 0x6d, 0x20, 0x3d, 0x20, 0x75, 0x69, 0x49, 0x74, 0x65, + 0x6d, 0x73, 0x5b, 0x69, 0x5d, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x68, 0x69, 0x64, 0x65, 0x43, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6b, 0x65, 0x79, 0x29, 0x29, 0x63, + 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x5b, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6b, 0x65, 0x79, + 0x5d, 0x3b, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x4d, + 0x65, 0x74, 0x61, 0x43, 0x65, 0x6c, 0x6c, 0x28, 0x69, 0x74, 0x65, + 0x6d, 0x2c, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x29, 0x3b, + 0x7d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x6e, 0x65, + 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, + 0x6c, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x6d, + 0x65, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, + 0x7b, 0x72, 0x6f, 0x77, 0x3a, 0x20, 0x5b, 0x7b, 0x27, 0x68, 0x61, + 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x27, 0x3a, + 0x20, 0x75, 0x69, 0x2e, 0x68, 0x61, 0x73, 0x53, 0x75, 0x62, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x27, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x27, 0x3a, 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x7d, 0x5d, 0x7d, + 0x29, 0x3b, 0x7d, 0x2c, 0x69, 0x74, 0x65, 0x72, 0x55, 0x49, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, + 0x20, 0x75, 0x69, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5b, 0x5d, + 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c, 0x20, 0x75, + 0x69, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x20, 0x2b, 0x2b, 0x69, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x75, 0x69, 0x49, 0x74, 0x65, 0x6d, 0x20, 0x3d, + 0x20, 0x75, 0x69, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x69, 0x5d, + 0x3b, 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x68, + 0x69, 0x64, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x49, 0x74, 0x65, + 0x6d, 0x2e, 0x6b, 0x65, 0x79, 0x29, 0x29, 0x63, 0x6f, 0x6e, 0x74, + 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x20, 0x3d, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x75, 0x69, 0x49, + 0x74, 0x65, 0x6d, 0x2e, 0x6b, 0x65, 0x79, 0x5d, 0x3b, 0x69, 0x66, + 0x20, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x20, + 0x26, 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x63, + 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x20, 0x3d, 0x3d, 0x20, + 0x27, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 0x74, 0x20, 0x3d, + 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x49, 0x74, 0x65, + 0x6d, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, + 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x72, 0x65, 0x74, 0x29, 0x20, + 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x65, + 0x74, 0x29, 0x3b, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x65, 0x6c, 0x6c, 0x3a, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x2c, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x3d, + 0x20, 0x75, 0x69, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, + 0x6d, 0x65, 0x20, 0x7c, 0x7c, 0x20, 0x27, 0x27, 0x3b, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x2b, 0x3d, 0x20, + 0x75, 0x69, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, + 0x20, 0x21, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x27, 0x20, 0x3f, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x27, 0x20, 0x3a, 0x20, 0x27, 0x27, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x27, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x27, 0x3a, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x2c, 0x27, 0x70, + 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x27, 0x3a, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, + 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x2c, 0x27, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x27, 0x3a, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, + 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x67, + 0x65, 0x74, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x28, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x29, 0x2c, 0x20, 0x75, 0x69, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x54, 0x79, 0x70, 0x65, 0x29, 0x7d, 0x3b, 0x7d, 0x2c, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x52, 0x6f, 0x77, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, + 0x63, 0x6b, 0x2c, 0x20, 0x75, 0x69, 0x2c, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x49, 0x74, 0x65, 0x6d, 0x2c, 0x20, 0x69, 0x64, 0x78, 0x2c, + 0x20, 0x73, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x2c, 0x20, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x2c, 0x20, 0x65, 0x78, + 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x50, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x21, 0x73, 0x75, 0x62, + 0x49, 0x74, 0x65, 0x6d, 0x20, 0x26, 0x26, 0x20, 0x69, 0x64, 0x78, + 0x20, 0x25, 0x20, 0x32, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x20, + 0x3f, 0x20, 0x27, 0x73, 0x68, 0x61, 0x64, 0x65, 0x64, 0x27, 0x20, + 0x3a, 0x20, 0x27, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x73, + 0x68, 0x61, 0x64, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x20, 0x3d, + 0x20, 0x28, 0x28, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, + 0x20, 0x25, 0x20, 0x32, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x20, + 0x3f, 0x20, 0x27, 0x73, 0x68, 0x61, 0x64, 0x65, 0x64, 0x27, 0x20, + 0x3a, 0x20, 0x27, 0x27, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x7b, 0x27, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x27, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x27, 0x69, 0x64, 0x78, 0x27, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x21, 0x73, 0x75, + 0x62, 0x49, 0x74, 0x65, 0x6d, 0x20, 0x26, 0x26, 0x20, 0x28, 0x53, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x28, 0x69, 0x64, 0x78, 0x20, + 0x2b, 0x20, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x70, 0x61, 0x67, 0x65, 0x4f, 0x66, 0x66, 0x53, 0x65, 0x74, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x29, 0x2c, 0x27, + 0x6b, 0x65, 0x79, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3a, 0x20, 0x21, 0x73, 0x75, 0x62, 0x49, 0x74, 0x65, + 0x6d, 0x20, 0x3f, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x68, 0x61, 0x73, 0x68, + 0x43, 0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, + 0x65, 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x3a, 0x20, + 0x27, 0x27, 0x2c, 0x27, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, + 0x64, 0x27, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x21, 0x73, 0x75, + 0x62, 0x49, 0x74, 0x65, 0x6d, 0x20, 0x26, 0x26, 0x20, 0x65, 0x78, + 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x2c, 0x27, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x27, 0x20, 0x20, 0x20, 0x20, 0x3a, + 0x20, 0x73, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x20, 0x3f, 0x20, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x49, 0x64, 0x29, 0x20, 0x3a, 0x20, 0x27, 0x27, 0x2c, + 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x27, + 0x20, 0x20, 0x20, 0x3a, 0x20, 0x73, 0x75, 0x62, 0x49, 0x74, 0x65, + 0x6d, 0x20, 0x3f, 0x20, 0x27, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x20, + 0x27, 0x20, 0x2b, 0x20, 0x73, 0x68, 0x61, 0x64, 0x65, 0x43, 0x68, + 0x69, 0x6c, 0x64, 0x20, 0x3a, 0x20, 0x27, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x27, 0x20, 0x2b, 0x20, 0x73, 0x68, 0x61, 0x64, + 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x27, 0x68, 0x61, + 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x27, 0x20, + 0x3a, 0x20, 0x75, 0x69, 0x2e, 0x68, 0x61, 0x73, 0x53, 0x75, 0x62, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x27, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x20, 0x3f, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, + 0x74, 0x65, 0x6d, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3a, 0x20, 0x30, 0x2c, 0x27, + 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3a, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, + 0x6b, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x2c, 0x7d, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x52, 0x6f, 0x77, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x72, 0x6f, 0x77, 0x73, 0x2c, + 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x2c, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2c, + 0x20, 0x73, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x2c, 0x20, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x29, 0x20, 0x7b, 0x73, + 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x20, 0x3d, 0x20, 0x73, 0x75, + 0x62, 0x49, 0x74, 0x65, 0x6d, 0x20, 0x7c, 0x7c, 0x20, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, 0x74, + 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x26, 0x26, 0x20, + 0x75, 0x69, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x29, 0x20, 0x7b, 0x72, 0x6f, 0x77, 0x73, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x63, 0x65, 0x6c, 0x6c, + 0x73, 0x3a, 0x20, 0x5b, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, + 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x27, 0x2c, 0x63, 0x6f, 0x6c, + 0x73, 0x70, 0x61, 0x6e, 0x3a, 0x20, 0x75, 0x69, 0x2e, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, + 0x2b, 0x20, 0x31, 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x20, + 0x27, 0x4e, 0x6f, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x6f, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2e, 0x27, 0x7d, 0x5d, 0x7d, 0x29, 0x3b, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x63, 0x62, 0x20, 0x3d, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, + 0x3c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x20, 0x2b, 0x2b, + 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x49, 0x74, 0x65, 0x6d, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x69, 0x5d, 0x2c, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x6e, 0x75, 0x6c, 0x6c, + 0x2c, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x20, + 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x73, 0x77, 0x69, + 0x74, 0x63, 0x68, 0x28, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x7b, + 0x63, 0x61, 0x73, 0x65, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x27, 0x3a, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x3b, 0x63, 0x65, 0x6c, + 0x6c, 0x63, 0x62, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x27, 0x63, 0x6f, 0x6c, 0x73, 0x70, + 0x61, 0x6e, 0x27, 0x3a, 0x20, 0x75, 0x69, 0x2e, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x27, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x27, 0x3a, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x7d, 0x3b, 0x7d, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x64, 0x61, 0x74, + 0x61, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, + 0x6d, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x3b, 0x63, 0x65, 0x6c, 0x6c, + 0x63, 0x62, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x74, 0x65, 0x72, 0x55, 0x49, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x2e, + 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x2e, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, + 0x74, 0x65, 0x6d, 0x2c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, + 0x65, 0x74, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x65, 0x6c, + 0x6c, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x29, 0x3b, 0x7d, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, + 0x64, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, + 0x45, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, + 0x29, 0x3b, 0x72, 0x6f, 0x77, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x52, 0x6f, 0x77, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, + 0x20, 0x63, 0x65, 0x6c, 0x6c, 0x63, 0x62, 0x2c, 0x20, 0x75, 0x69, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x2c, + 0x20, 0x69, 0x2c, 0x20, 0x73, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, + 0x2c, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x2c, + 0x20, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x29, 0x29, + 0x3b, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, + 0x65, 0x6d, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x26, 0x26, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x2e, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x20, 0x26, 0x26, 0x20, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, + 0x64, 0x29, 0x20, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x52, 0x6f, 0x77, 0x73, 0x28, 0x72, 0x6f, + 0x77, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x75, 0x69, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, + 0x6d, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x2c, 0x20, 0x69, 0x2c, 0x20, 0x65, 0x78, 0x70, 0x61, + 0x6e, 0x64, 0x65, 0x64, 0x29, 0x3b, 0x7d, 0x7d, 0x7d, 0x2c, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x6f, + 0x77, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, + 0x69, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x2c, 0x20, 0x70, 0x61, 0x67, 0x65, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, + 0x24, 0x28, 0x27, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x27, + 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, + 0x27, 0x20, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, 0x61, 0x27, 0x29, 0x3b, 0x69, + 0x66, 0x20, 0x28, 0x21, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x29, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x64, 0x61, 0x74, 0x61, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x67, 0x65, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, + 0x65, 0x6d, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x67, 0x65, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x20, 0x3d, 0x20, + 0x5b, 0x5d, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x52, 0x6f, 0x77, 0x73, 0x28, 0x72, 0x6f, 0x77, + 0x73, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, + 0x69, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x72, 0x6f, 0x77, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3d, 0x3d, 0x20, + 0x30, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, + 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, 0x2e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x7b, 0x72, 0x6f, + 0x77, 0x73, 0x3a, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x7d, 0x29, 0x3b, + 0x7d, 0x2c, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x50, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x70, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x29, 0x20, 0x7b, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x73, 0x2e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x70, 0x61, 0x67, 0x65, 0x20, 0x3e, 0x3d, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x50, + 0x61, 0x67, 0x65, 0x73, 0x28, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, + 0x65, 0x6d, 0x73, 0x29, 0x29, 0x20, 0x7b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x73, + 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x65, 0x78, + 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x61, 0x6e, 0x65, + 0x6c, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4c, + 0x61, 0x73, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, + 0x7d, 0x69, 0x66, 0x20, 0x28, 0x70, 0x61, 0x67, 0x65, 0x20, 0x3c, + 0x3d, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x2e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x72, 0x65, 0x76, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x61, 0x6e, 0x65, 0x6c, + 0x73, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x46, 0x69, + 0x72, 0x73, 0x74, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, + 0x7d, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x70, 0x61, 0x67, 0x65, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x3d, + 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, + 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, + 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x70, 0x61, + 0x67, 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x22, 0x4c, 0x41, 0x53, + 0x54, 0x5f, 0x50, 0x41, 0x47, 0x45, 0x22, 0x29, 0x20, 0x7b, 0x70, + 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x67, 0x65, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x61, 0x67, + 0x65, 0x73, 0x28, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x29, 0x3b, 0x7d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, + 0x66, 0x20, 0x28, 0x70, 0x61, 0x67, 0x65, 0x20, 0x3d, 0x3d, 0x3d, + 0x20, 0x22, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x50, 0x41, 0x47, + 0x45, 0x22, 0x29, 0x20, 0x7b, 0x70, 0x61, 0x67, 0x65, 0x20, 0x3d, + 0x20, 0x31, 0x3b, 0x7d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x6f, + 0x67, 0x67, 0x6c, 0x65, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x70, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, + 0x6f, 0x77, 0x73, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x75, 0x69, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x49, 0x74, 0x65, + 0x6d, 0x73, 0x2c, 0x20, 0x70, 0x61, 0x67, 0x65, 0x29, 0x3b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x28, + 0x29, 0x3b, 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x46, + 0x75, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, + 0x69, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, + 0x49, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2c, 0x20, 0x70, + 0x61, 0x67, 0x65, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x27, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x27, 0x29, 0x29, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x4d, 0x65, 0x74, 0x61, + 0x52, 0x6f, 0x77, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, + 0x75, 0x69, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, + 0x27, 0x29, 0x29, 0x20, 0x7b, 0x70, 0x61, 0x67, 0x65, 0x20, 0x3d, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x75, + 0x72, 0x50, 0x61, 0x67, 0x65, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x50, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x70, 0x61, + 0x67, 0x65, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x61, + 0x74, 0x61, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x6f, 0x77, + 0x73, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x2c, 0x20, 0x70, 0x61, 0x67, 0x65, 0x29, 0x3b, 0x7d, 0x7d, 0x2c, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x69, 0x6e, 0x20, 0x75, 0x69, 0x29, 0x20, 0x7b, 0x69, 0x66, + 0x20, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x69, 0x73, 0x50, 0x61, 0x6e, 0x65, + 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x21, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x28, 0x29, 0x29, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, + 0x3b, 0x69, 0x66, 0x20, 0x28, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x20, + 0x7c, 0x7c, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x69, 0x73, 0x57, 0x69, 0x74, + 0x68, 0x69, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x50, 0x6f, 0x72, 0x74, + 0x28, 0x24, 0x28, 0x27, 0x23, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, + 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, + 0x29, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x3b, 0x7d, 0x7d, 0x2c, 0x73, + 0x6f, 0x72, 0x74, 0x32, 0x54, 0x70, 0x6c, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x75, 0x69, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x20, 0x3d, + 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x28, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x69, 0x66, 0x79, 0x28, 0x75, 0x69, 0x29, 0x29, 0x2c, 0x20, + 0x6f, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x73, 0x6f, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x27, 0x29, + 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, + 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x20, 0x6c, 0x65, 0x6e, 0x20, 0x3d, + 0x20, 0x75, 0x69, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x20, 0x69, 0x20, 0x3c, 0x20, 0x6c, 0x65, 0x6e, 0x3b, 0x20, 0x2b, + 0x2b, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x74, + 0x65, 0x6d, 0x20, 0x3d, 0x20, 0x75, 0x69, 0x43, 0x6c, 0x6f, 0x6e, + 0x65, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x5b, 0x69, 0x5d, 0x3b, + 0x69, 0x66, 0x20, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x68, 0x69, + 0x64, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6b, + 0x65, 0x79, 0x29, 0x29, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, + 0x65, 0x3b, 0x69, 0x74, 0x65, 0x6d, 0x5b, 0x27, 0x73, 0x6f, 0x72, + 0x74, 0x27, 0x5d, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x3b, 0x69, 0x66, 0x20, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x2e, 0x6b, + 0x65, 0x79, 0x20, 0x3d, 0x3d, 0x20, 0x73, 0x6f, 0x72, 0x74, 0x2e, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x26, 0x26, 0x20, 0x73, 0x6f, + 0x72, 0x74, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x29, 0x20, 0x7b, + 0x69, 0x74, 0x65, 0x6d, 0x5b, 0x27, 0x73, 0x6f, 0x72, 0x74, 0x27, + 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x69, 0x74, + 0x65, 0x6d, 0x5b, 0x73, 0x6f, 0x72, 0x74, 0x2e, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, + 0x61, 0x73, 0x65, 0x28, 0x29, 0x5d, 0x20, 0x3d, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x3b, 0x7d, 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x69, 0x74, 0x65, 0x6d, 0x29, 0x3b, 0x7d, 0x75, 0x69, + 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x2e, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x20, 0x3d, 0x20, 0x6f, 0x75, 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x75, 0x69, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x3b, + 0x7d, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, 0x68, 0x65, + 0x61, 0x64, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, + 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x24, 0x74, 0x68, + 0x65, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x3e, 0x74, 0x68, 0x65, + 0x61, 0x64, 0x27, 0x29, 0x2c, 0x20, 0x24, 0x63, 0x6f, 0x6c, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x20, 0x3d, 0x20, 0x24, 0x28, 0x27, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x27, 0x20, 0x2b, 0x20, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x3e, 0x63, 0x6f, + 0x6c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x27, 0x29, 0x3b, 0x69, 0x66, + 0x20, 0x28, 0x24, 0x74, 0x68, 0x65, 0x61, 0x64, 0x20, 0x26, 0x26, + 0x20, 0x24, 0x63, 0x6f, 0x6c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, + 0x26, 0x26, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x68, 0x6f, + 0x77, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, 0x29, 0x29, 0x20, + 0x7b, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x73, 0x6f, 0x72, 0x74, 0x32, 0x54, 0x70, 0x6c, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x75, 0x69, 0x29, 0x3b, 0x24, 0x74, + 0x68, 0x65, 0x61, 0x64, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, + 0x54, 0x4d, 0x4c, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x75, 0x69, + 0x29, 0x3b, 0x24, 0x63, 0x6f, 0x6c, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x20, + 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x41, 0x70, 0x70, 0x54, 0x70, 0x6c, 0x73, 0x2e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6c, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x75, 0x69, + 0x29, 0x3b, 0x7d, 0x7d, 0x2c, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, 0x66, 0x61, 0x6c, 0x73, 0x65, + 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x28, 0x74, 0x72, 0x75, 0x65, 0x29, + 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x28, 0x29, 0x3b, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x28, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x29, 0x2e, + 0x6f, 0x6e, 0x28, 0x27, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x27, 0x2c, 0x20, 0x64, 0x65, + 0x62, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x28, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x20, 0x32, + 0x35, 0x30, 0x2c, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x2e, + 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, + 0x3b, 0x7d, 0x2c, 0x7d, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x20, 0x3d, 0x20, 0x7b, 0x68, + 0x61, 0x73, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x3a, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x2c, 0x74, 0x70, 0x6c, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x70, 0x6c, 0x29, + 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x48, 0x6f, + 0x67, 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x28, 0x74, 0x70, 0x6c, 0x29, 0x3b, 0x7d, 0x2c, 0x73, 0x65, 0x74, + 0x54, 0x70, 0x6c, 0x73, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x54, 0x70, + 0x6c, 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x27, 0x4e, 0x61, 0x76, 0x27, + 0x3a, 0x20, 0x7b, 0x27, 0x77, 0x72, 0x61, 0x70, 0x27, 0x3a, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x70, 0x6c, 0x28, 0x24, 0x28, + 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, 0x6e, 0x61, 0x76, 0x2d, 0x77, + 0x72, 0x61, 0x70, 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, + 0x48, 0x54, 0x4d, 0x4c, 0x29, 0x2c, 0x27, 0x6d, 0x65, 0x6e, 0x75, + 0x27, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x70, 0x6c, + 0x28, 0x24, 0x28, 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, 0x6e, 0x61, + 0x76, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x27, 0x29, 0x2e, 0x69, 0x6e, + 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x29, 0x2c, 0x27, 0x6f, + 0x70, 0x74, 0x73, 0x27, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x74, 0x70, 0x6c, 0x28, 0x24, 0x28, 0x27, 0x23, 0x74, 0x70, 0x6c, + 0x2d, 0x6e, 0x61, 0x76, 0x2d, 0x6f, 0x70, 0x74, 0x73, 0x27, 0x29, + 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x29, + 0x2c, 0x7d, 0x2c, 0x27, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x73, 0x27, + 0x3a, 0x20, 0x7b, 0x27, 0x77, 0x72, 0x61, 0x70, 0x27, 0x3a, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x70, 0x6c, 0x28, 0x24, 0x28, + 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, + 0x4c, 0x29, 0x2c, 0x27, 0x6f, 0x70, 0x74, 0x73, 0x27, 0x3a, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x70, 0x6c, 0x28, 0x24, 0x28, + 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x2d, 0x6f, 0x70, 0x74, 0x73, 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, + 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x29, 0x2c, 0x7d, 0x2c, 0x27, + 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x27, 0x3a, 0x20, 0x7b, + 0x27, 0x77, 0x72, 0x61, 0x70, 0x27, 0x3a, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x74, 0x70, 0x6c, 0x28, 0x24, 0x28, 0x27, 0x23, 0x74, + 0x70, 0x6c, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x27, + 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, + 0x29, 0x2c, 0x27, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x27, 0x3a, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x70, 0x6c, 0x28, 0x24, 0x28, + 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x61, 0x6c, 0x2d, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x27, 0x29, 0x2e, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x29, 0x2c, + 0x7d, 0x2c, 0x27, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x27, 0x3a, + 0x20, 0x7b, 0x27, 0x63, 0x6f, 0x6c, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x27, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x70, 0x6c, + 0x28, 0x24, 0x28, 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x6f, 0x6c, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, + 0x4d, 0x4c, 0x29, 0x2c, 0x27, 0x68, 0x65, 0x61, 0x64, 0x27, 0x3a, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x70, 0x6c, 0x28, 0x24, + 0x28, 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x74, 0x68, 0x65, 0x61, 0x64, 0x27, 0x29, 0x2e, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x29, 0x2c, 0x27, + 0x6d, 0x65, 0x74, 0x61, 0x27, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x74, 0x70, 0x6c, 0x28, 0x24, 0x28, 0x27, 0x23, 0x74, 0x70, + 0x6c, 0x2d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x6f, 0x77, + 0x2d, 0x6d, 0x65, 0x74, 0x61, 0x27, 0x29, 0x2e, 0x69, 0x6e, 0x6e, + 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x29, 0x2c, 0x27, 0x64, 0x61, + 0x74, 0x61, 0x27, 0x3a, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, + 0x70, 0x6c, 0x28, 0x24, 0x28, 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x6f, 0x77, 0x27, 0x29, + 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x29, + 0x2c, 0x7d, 0x2c, 0x7d, 0x3b, 0x7d, 0x2c, 0x73, 0x6f, 0x72, 0x74, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6f, 0x2c, 0x20, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x66, + 0x20, 0x3d, 0x20, 0x6f, 0x5b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5d, + 0x3b, 0x69, 0x66, 0x20, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x69, 0x73, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x66, 0x29, 0x20, 0x26, 0x26, + 0x20, 0x28, 0x66, 0x20, 0x21, 0x3d, 0x3d, 0x20, 0x6e, 0x75, 0x6c, + 0x6c, 0x29, 0x29, 0x66, 0x20, 0x3d, 0x20, 0x6f, 0x5b, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x5d, 0x2e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x3b, 0x7d, 0x2c, + 0x73, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x2c, + 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, + 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, + 0x74, 0x61, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x3b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, + 0x74, 0x61, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x61, 0x2c, 0x20, 0x62, + 0x29, 0x20, 0x7b, 0x61, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x28, + 0x61, 0x2c, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x29, 0x3b, 0x62, + 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x6f, 0x72, + 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x28, 0x62, 0x2c, 0x20, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x74, + 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x61, 0x20, 0x3d, 0x3d, 0x3d, + 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x27, 0x20, 0x26, + 0x26, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x62, 0x20, + 0x3d, 0x3d, 0x3d, 0x20, 0x27, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x27, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x27, 0x61, + 0x73, 0x63, 0x27, 0x20, 0x3d, 0x3d, 0x20, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x20, 0x3f, 0x20, 0x61, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x28, 0x62, 0x29, + 0x20, 0x3a, 0x20, 0x62, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, + 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x28, 0x61, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x20, 0x27, 0x61, 0x73, + 0x63, 0x27, 0x20, 0x3d, 0x3d, 0x20, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x20, 0x3f, 0x20, 0x61, 0x20, 0x2d, 0x20, 0x62, 0x20, 0x3a, 0x20, + 0x62, 0x20, 0x2d, 0x20, 0x61, 0x3b, 0x7d, 0x2e, 0x62, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x7d, 0x2c, + 0x73, 0x65, 0x74, 0x49, 0x6e, 0x69, 0x74, 0x53, 0x6f, 0x72, 0x74, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x69, 0x20, + 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x55, 0x49, 0x28, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x69, + 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x69, + 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x56, 0x61, 0x6c, 0x69, 0x64, + 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x29, 0x29, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x73, 0x65, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x2c, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2b, 0x20, + 0x27, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x27, 0x2c, 0x20, 0x75, 0x69, + 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x5d, 0x2e, 0x73, 0x6f, 0x72, + 0x74, 0x29, 0x3b, 0x7d, 0x7d, 0x2c, 0x76, 0x65, 0x72, 0x69, 0x66, + 0x79, 0x53, 0x6f, 0x72, 0x74, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x75, 0x69, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x61, 0x6e, + 0x65, 0x6c, 0x55, 0x49, 0x28, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x20, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, + 0x69, 0x6e, 0x20, 0x75, 0x69, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, + 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, + 0x74, 0x69, 0x6c, 0x2e, 0x69, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, + 0x56, 0x61, 0x6c, 0x69, 0x64, 0x28, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x29, 0x29, 0x63, 0x6f, 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x73, 0x6f, 0x72, 0x74, 0x20, 0x3d, 0x20, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, + 0x69, 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x28, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, + 0x70, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x2e, 0x73, 0x6f, 0x72, 0x74, + 0x27, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x4a, 0x53, 0x4f, 0x4e, + 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79, 0x28, + 0x73, 0x6f, 0x72, 0x74, 0x29, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x4a, + 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, + 0x66, 0x79, 0x28, 0x75, 0x69, 0x5b, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x5d, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x29, 0x29, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x73, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2c, 0x20, 0x73, 0x6f, 0x72, 0x74, 0x2e, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x2c, 0x20, 0x73, 0x6f, 0x72, 0x74, 0x2e, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x29, 0x3b, 0x7d, 0x7d, 0x2c, 0x69, + 0x6e, 0x69, 0x74, 0x44, 0x6f, 0x6d, 0x3a, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x24, + 0x28, 0x27, 0x6e, 0x61, 0x76, 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x28, 0x27, 0x68, 0x69, 0x64, 0x65, 0x27, 0x29, 0x3b, + 0x24, 0x28, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x27, 0x29, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, + 0x69, 0x73, 0x74, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, + 0x27, 0x68, 0x69, 0x64, 0x65, 0x27, 0x29, 0x3b, 0x24, 0x28, 0x27, + 0x2e, 0x73, 0x70, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x27, 0x29, 0x2e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, + 0x64, 0x64, 0x28, 0x27, 0x68, 0x69, 0x64, 0x65, 0x27, 0x29, 0x3b, + 0x69, 0x66, 0x20, 0x28, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x50, 0x72, 0x65, 0x66, 0x73, 0x5b, + 0x27, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x27, 0x5d, 0x20, 0x3d, + 0x3d, 0x20, 0x27, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, + 0x61, 0x6c, 0x27, 0x29, 0x20, 0x7b, 0x24, 0x28, 0x27, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x27, 0x29, 0x2e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x61, + 0x64, 0x64, 0x28, 0x27, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x27, 0x29, 0x3b, + 0x24, 0x28, 0x27, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x27, 0x29, 0x2e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x72, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x27, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x27, 0x29, 0x3b, 0x7d, 0x7d, 0x2c, + 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x3a, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x68, 0x61, 0x73, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x6f, 0x72, 0x74, + 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, + 0x74, 0x73, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x73, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x43, + 0x68, 0x61, 0x72, 0x74, 0x73, 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x28, 0x29, 0x3b, 0x7d, 0x2c, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x49, 0x6e, 0x69, + 0x74, 0x53, 0x6f, 0x72, 0x74, 0x28, 0x29, 0x3b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x70, 0x6c, 0x73, 0x28, 0x29, + 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x4e, + 0x61, 0x76, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, + 0x7a, 0x65, 0x28, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x6e, 0x69, 0x74, 0x44, 0x6f, 0x6d, 0x28, 0x29, 0x3b, 0x47, 0x6f, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x4f, 0x76, 0x65, 0x72, + 0x61, 0x6c, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x73, 0x2e, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x3b, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x73, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x43, 0x68, 0x61, 0x72, 0x74, 0x73, + 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, + 0x28, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x2e, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x3b, 0x7d, + 0x2c, 0x7d, 0x3b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x27, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, + 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x20, 0x3d, 0x3d, 0x3d, 0x20, 0x27, 0x68, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x27, 0x29, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x68, 0x61, 0x73, 0x46, + 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, + 0x65, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x20, 0x3d, 0x3d, + 0x3d, 0x20, 0x27, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x27, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x68, 0x61, 0x73, 0x46, + 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x68, 0x61, + 0x73, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x68, 0x61, + 0x73, 0x46, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x72, + 0x75, 0x65, 0x3b, 0x68, 0x61, 0x73, 0x46, 0x6f, 0x63, 0x75, 0x73, + 0x20, 0x7c, 0x7c, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x44, 0x61, 0x74, 0x61, 0x28, 0x29, 0x3b, 0x7d, 0x7d, 0x29, + 0x3b, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6f, 0x6e, 0x6c, + 0x6f, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x47, 0x6f, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, + 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x7b, 0x27, 0x69, 0x31, 0x38, + 0x6e, 0x27, 0x3a, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, + 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x69, 0x31, 0x38, 0x6e, 0x2c, 0x27, + 0x75, 0x69, 0x44, 0x61, 0x74, 0x61, 0x27, 0x3a, 0x20, 0x77, 0x69, + 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x2c, 0x27, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x44, 0x61, 0x74, 0x61, 0x27, 0x3a, 0x20, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6a, 0x73, 0x6f, 0x6e, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x27, 0x77, 0x73, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x27, 0x3a, 0x20, + 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7c, 0x7c, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x27, 0x70, 0x72, 0x65, 0x66, 0x73, 0x27, + 0x3a, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x74, + 0x6d, 0x6c, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x73, 0x20, 0x7c, 0x7c, + 0x20, 0x7b, 0x7d, 0x2c, 0x7d, 0x29, 0x3b, 0x47, 0x6f, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x69, 0x6e, + 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x28, 0x29, 0x3b, + 0x7d, 0x3b, 0x7d, 0x28, 0x29, 0x29, 0x3b, 0x00 +}; + +const int app_js_length = 39696; diff --git a/goaccess++/src/base64.c b/goaccess++/src/base64.c new file mode 100644 index 0000000..698235e --- /dev/null +++ b/goaccess++/src/base64.c @@ -0,0 +1,80 @@ +/** + * base64.c -- A basic base64 encode implementation + * _______ _______ __ __ + * / ____/ | / / ___/____ _____/ /_____ / /_ + * / / __ | | /| / /\__ \/ __ \/ ___/ //_/ _ \/ __/ + * / /_/ / | |/ |/ /___/ / /_/ / /__/ ,< / __/ /_ + * \____/ |__/|__//____/\____/\___/_/|_|\___/\__/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <stdlib.h> +#include <string.h> + +#include "base64.h" + +/* Encodes the given data with base64.. + * + * On success, the encoded nul-terminated data, as a string is returned. */ +char * +base64_encode (const void *buf, size_t size) +{ + static const char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + char *str = (char *) malloc ((size + 3) * 4 / 3 + 1); + + char *p = str; + const unsigned char *q = (const unsigned char *) buf; + size_t i = 0; + + while (i < size) { + int c = q[i++]; + c *= 256; + if (i < size) + c += q[i]; + i++; + + c *= 256; + if (i < size) + c += q[i]; + i++; + + *p++ = base64[(c & 0x00fc0000) >> 18]; + *p++ = base64[(c & 0x0003f000) >> 12]; + + if (i > size + 1) + *p++ = '='; + else + *p++ = base64[(c & 0x00000fc0) >> 6]; + + if (i > size) + *p++ = '='; + else + *p++ = base64[c & 0x0000003f]; + } + + *p = 0; + + return str; +} diff --git a/goaccess++/src/base64.h b/goaccess++/src/base64.h new file mode 100644 index 0000000..7f36936 --- /dev/null +++ b/goaccess++/src/base64.h @@ -0,0 +1,37 @@ +/** + * _______ _______ __ __ + * / ____/ | / / ___/____ _____/ /_____ / /_ + * / / __ | | /| / /\__ \/ __ \/ ___/ //_/ _ \/ __/ + * / /_/ / | |/ |/ /___/ / /_/ / /__/ ,< / __/ /_ + * \____/ |__/|__//____/\____/\___/_/|_|\___/\__/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BASE64_H_INCLUDED +#define BASE64_H_INCLUDED + +#include <stddef.h> + +char *base64_encode (const void *buf, size_t size); + +#endif // for #ifndef BASE64_H diff --git a/goaccess++/src/base64.o b/goaccess++/src/base64.o new file mode 100644 index 0000000..0088ffa Binary files /dev/null and b/goaccess++/src/base64.o differ diff --git a/goaccess++/src/bin2c.c b/goaccess++/src/bin2c.c new file mode 100644 index 0000000..bc635f8 --- /dev/null +++ b/goaccess++/src/bin2c.c @@ -0,0 +1,117 @@ +/* + * This is bin2c program, which allows you to convert binary file to + * C language array, for use as embedded resource, for instance you can + * embed graphics or audio file directly into your program. + * This is public domain software, use it on your own risk. + * Contact Serge Fukanchik at fuxx@mail.ru if you have any questions. + * + * Some modifications were made by Gwilym Kuiper (kuiper.gwilym@gmail.com) + * I have decided not to change the licence. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +#ifdef USE_BZ2 +#include <bzlib.h> +#endif + +int +main (int argc, char *argv[]) +{ + char *buf; + char *ident; + unsigned int i, file_size, need_comma; + FILE *f_input, *f_output; + +#ifdef USE_BZ2 + int status; + char *bz2_buf; + unsigned int uncompressed_size, bz2_size; +#endif + + if (argc < 4) { + fprintf (stderr, "Usage: %s binary_file output_file array_name\n", argv[0]); + return -1; + } + + f_input = fopen (argv[1], "rb"); + if (f_input == NULL) { + fprintf (stderr, "%s: can't open %s for reading\n", argv[0], argv[1]); + return -1; + } + // Get the file length + fseek (f_input, 0, SEEK_END); + file_size = ftell (f_input); + fseek (f_input, 0, SEEK_SET); + file_size++; + + if ((buf = malloc (file_size)) == NULL) { + fprintf (stderr, "Unable to malloc bin2c.c buffer\n"); + fclose (f_input); + return -1; + } + + fread (buf, file_size, 1, f_input); + fclose (f_input); + +#ifdef USE_BZ2 + // allocate for bz2. + bz2_size = ((file_size) * 1.01) + 600; // as per the documentation + + if ((bz2_buf = malloc (bz2_size)) == NULL) { + fprintf (stderr, "Unable to malloc bin2c.c buffer\n"); + free (buf); + return -1; + } + // compress the data + status = + BZ2_bzBuffToBuffCompress (bz2_buf, &bz2_size, buf, file_size, 9, 1, 0); + if (status != BZ_OK) { + fprintf (stderr, "Failed to compress data: error %i\n", status); + free (buf); + free (bz2_buf); + return -1; + } + // and be very lazy + free (buf); + uncompressed_size = file_size; + file_size = bz2_size; + buf = bz2_buf; +#endif + + f_output = fopen (argv[2], "w"); + if (f_output == NULL) { + fprintf (stderr, "%s: can't open %s for writing\n", argv[0], argv[1]); + free (buf); + return -1; + } + + ident = argv[3]; + need_comma = 0; + + fprintf (f_output, "const char %s[%u] = {", ident, file_size); + for (i = 0; i < file_size; ++i) { + if (need_comma) + fprintf (f_output, ", "); + else + need_comma = 1; + if ((i % 11) == 0) + fprintf (f_output, "\n\t"); + fprintf (f_output, "0x%.2x", buf[i] & 0xff); + } + fprintf (f_output, "\n};\n\n"); + fprintf (f_output, "const int %s_length = %u;\n", ident, file_size); + +#ifdef USE_BZ2 + fprintf (f_output, "const int %s_length_uncompressed = %u;\n", ident, + uncompressed_size); +#endif + + fclose (f_output); + free (buf); + + return 0; +} diff --git a/goaccess++/src/bin2c.o b/goaccess++/src/bin2c.o new file mode 100644 index 0000000..506493a Binary files /dev/null and b/goaccess++/src/bin2c.o differ diff --git a/goaccess++/src/bootstrapcss.h b/goaccess++/src/bootstrapcss.h new file mode 100644 index 0000000..53092fa --- /dev/null +++ b/goaccess++/src/bootstrapcss.h @@ -0,0 +1,4696 @@ +const char bootstrap_css[51609] = { + 0x2f, 0x2a, 0x21, 0x20, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, + 0x67, 0x65, 0x74, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, + 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, + 0x6d, 0x69, 0x7a, 0x65, 0x2f, 0x3f, 0x69, 0x64, 0x3d, 0x66, 0x38, + 0x61, 0x62, 0x63, 0x30, 0x38, 0x63, 0x38, 0x38, 0x38, 0x61, 0x66, + 0x38, 0x39, 0x62, 0x32, 0x65, 0x64, 0x38, 0x63, 0x64, 0x36, 0x34, + 0x66, 0x34, 0x38, 0x61, 0x31, 0x66, 0x65, 0x33, 0x20, 0x2a, 0x2f, + 0x68, 0x74, 0x6d, 0x6c, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, + 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x73, 0x61, 0x6e, 0x73, 0x2d, + 0x73, 0x65, 0x72, 0x69, 0x66, 0x3b, 0x2d, 0x6d, 0x73, 0x2d, 0x74, + 0x65, 0x78, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x61, 0x64, + 0x6a, 0x75, 0x73, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x2d, + 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x2d, 0x61, 0x64, 0x6a, 0x75, 0x73, + 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x62, 0x6f, 0x64, 0x79, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x7d, 0x61, + 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2c, 0x61, 0x73, 0x69, 0x64, + 0x65, 0x2c, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x2c, 0x66, + 0x69, 0x67, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x66, + 0x69, 0x67, 0x75, 0x72, 0x65, 0x2c, 0x66, 0x6f, 0x6f, 0x74, 0x65, + 0x72, 0x2c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2c, 0x68, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x2c, 0x6d, 0x61, 0x69, 0x6e, 0x2c, 0x6d, + 0x65, 0x6e, 0x75, 0x2c, 0x6e, 0x61, 0x76, 0x2c, 0x73, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, + 0x79, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x7d, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x2c, + 0x63, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x2c, 0x70, 0x72, 0x6f, 0x67, + 0x72, 0x65, 0x73, 0x73, 0x2c, 0x76, 0x69, 0x64, 0x65, 0x6f, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x76, + 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x62, 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x7d, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x3a, 0x6e, 0x6f, 0x74, 0x28, + 0x5b, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x73, 0x5d, 0x29, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, + 0x6e, 0x65, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x30, + 0x7d, 0x5b, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x5d, 0x2c, 0x74, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x7b, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x61, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x7d, 0x61, 0x3a, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x61, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x7b, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x3a, + 0x30, 0x7d, 0x61, 0x62, 0x62, 0x72, 0x5b, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x5d, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, + 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x64, + 0x6f, 0x74, 0x74, 0x65, 0x64, 0x7d, 0x62, 0x2c, 0x73, 0x74, 0x72, + 0x6f, 0x6e, 0x67, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x7d, 0x64, + 0x66, 0x6e, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x3a, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x63, 0x7d, 0x68, + 0x31, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x32, 0x65, 0x6d, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x3a, 0x30, 0x2e, 0x36, 0x37, 0x65, 0x6d, 0x20, 0x30, 0x7d, 0x6d, + 0x61, 0x72, 0x6b, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x3a, 0x23, 0x66, 0x66, 0x30, 0x3b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x30, 0x30, 0x30, 0x7d, 0x73, 0x6d, + 0x61, 0x6c, 0x6c, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x38, 0x30, 0x25, 0x7d, 0x73, 0x75, 0x62, 0x2c, + 0x73, 0x75, 0x70, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x37, 0x35, 0x25, 0x3b, 0x6c, 0x69, 0x6e, 0x65, + 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x30, 0x3b, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x62, + 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x7d, 0x73, 0x75, 0x70, + 0x7b, 0x74, 0x6f, 0x70, 0x3a, 0x2d, 0x30, 0x2e, 0x35, 0x65, 0x6d, + 0x7d, 0x73, 0x75, 0x62, 0x7b, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, + 0x3a, 0x2d, 0x30, 0x2e, 0x32, 0x35, 0x65, 0x6d, 0x7d, 0x69, 0x6d, + 0x67, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x30, 0x7d, + 0x73, 0x76, 0x67, 0x3a, 0x6e, 0x6f, 0x74, 0x28, 0x3a, 0x72, 0x6f, + 0x6f, 0x74, 0x29, 0x7b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, + 0x77, 0x3a, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x7d, 0x66, 0x69, + 0x67, 0x75, 0x72, 0x65, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x3a, 0x31, 0x65, 0x6d, 0x20, 0x34, 0x30, 0x70, 0x78, 0x7d, 0x68, + 0x72, 0x7b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, + 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x3b, + 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, + 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, + 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x30, 0x7d, 0x70, 0x72, 0x65, 0x7b, 0x6f, 0x76, + 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x61, 0x75, 0x74, 0x6f, + 0x7d, 0x63, 0x6f, 0x64, 0x65, 0x2c, 0x6b, 0x62, 0x64, 0x2c, 0x70, + 0x72, 0x65, 0x2c, 0x73, 0x61, 0x6d, 0x70, 0x7b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x6d, 0x6f, + 0x6e, 0x6f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x20, 0x6d, 0x6f, + 0x6e, 0x6f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x65, 0x6d, 0x7d, + 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x2c, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x2c, 0x6f, 0x70, 0x74, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2c, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2c, 0x74, 0x65, 0x78, 0x74, + 0x61, 0x72, 0x65, 0x61, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x3b, 0x66, 0x6f, 0x6e, + 0x74, 0x3a, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x3b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x7d, 0x62, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x7b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, + 0x77, 0x3a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x7d, 0x62, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, + 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x2c, 0x68, 0x74, 0x6d, 0x6c, + 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x5d, 0x2c, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x72, 0x65, 0x73, 0x65, 0x74, 0x22, 0x5d, 0x2c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, + 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x5d, 0x7b, 0x2d, 0x77, 0x65, + 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, + 0x61, 0x6e, 0x63, 0x65, 0x3a, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x3b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x7d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2c, + 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x7b, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x7d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x3a, 0x3a, + 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2d, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x3a, 0x3a, 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x3a, 0x30, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3a, 0x30, 0x7d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x7b, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x7d, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x63, 0x68, + 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x5d, 0x2c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x72, + 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, 0x7b, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, + 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x62, 0x6f, 0x78, 0x3b, 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x30, 0x7d, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x22, 0x5d, 0x3a, 0x3a, 0x2d, 0x77, 0x65, + 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x2d, + 0x73, 0x70, 0x69, 0x6e, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x5d, 0x3a, + 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x6f, 0x75, + 0x74, 0x65, 0x72, 0x2d, 0x73, 0x70, 0x69, 0x6e, 0x2d, 0x62, 0x75, + 0x74, 0x74, 0x6f, 0x6e, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x22, 0x5d, 0x7b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, + 0x74, 0x2d, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, 0x63, + 0x65, 0x3a, 0x74, 0x65, 0x78, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x2d, + 0x6d, 0x6f, 0x7a, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, + 0x69, 0x6e, 0x67, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, + 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x7d, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x65, 0x61, 0x72, + 0x63, 0x68, 0x22, 0x5d, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, + 0x69, 0x74, 0x2d, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2d, 0x63, + 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x5d, + 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x7b, 0x2d, 0x77, 0x65, 0x62, 0x6b, + 0x69, 0x74, 0x2d, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, 0x6e, + 0x63, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x65, 0x74, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x63, 0x30, 0x63, 0x30, 0x63, 0x30, 0x3b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x20, 0x32, 0x70, 0x78, 0x3b, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x30, 0x2e, 0x33, + 0x35, 0x65, 0x6d, 0x20, 0x30, 0x2e, 0x36, 0x32, 0x35, 0x65, 0x6d, + 0x20, 0x30, 0x2e, 0x37, 0x35, 0x65, 0x6d, 0x7d, 0x6c, 0x65, 0x67, + 0x65, 0x6e, 0x64, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, + 0x30, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x30, + 0x7d, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x7b, 0x6f, + 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x61, 0x75, 0x74, + 0x6f, 0x7d, 0x6f, 0x70, 0x74, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x7b, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x7d, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6c, 0x61, 0x70, 0x73, 0x65, 0x3a, 0x63, 0x6f, 0x6c, 0x6c, 0x61, + 0x70, 0x73, 0x65, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x30, 0x7d, 0x74, + 0x64, 0x2c, 0x74, 0x68, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x3a, 0x30, 0x7d, 0x2f, 0x2a, 0x21, 0x20, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x3a, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, + 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, + 0x6d, 0x2f, 0x68, 0x35, 0x62, 0x70, 0x2f, 0x68, 0x74, 0x6d, 0x6c, + 0x35, 0x2d, 0x62, 0x6f, 0x69, 0x6c, 0x65, 0x72, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x63, 0x73, 0x73, + 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x63, 0x73, 0x73, 0x20, 0x2a, + 0x2f, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x7b, 0x2a, 0x2c, 0x2a, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x2c, 0x2a, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3a, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x30, 0x30, 0x30, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x6e, 0x6f, + 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, + 0x6e, 0x74, 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x3b, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x6e, 0x6f, + 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, + 0x6e, 0x74, 0x7d, 0x61, 0x2c, 0x61, 0x3a, 0x76, 0x69, 0x73, 0x69, + 0x74, 0x65, 0x64, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x65, + 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x75, 0x6e, + 0x64, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x65, 0x7d, 0x61, 0x5b, 0x68, + 0x72, 0x65, 0x66, 0x5d, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x7b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x20, 0x28, + 0x22, 0x20, 0x61, 0x74, 0x74, 0x72, 0x28, 0x68, 0x72, 0x65, 0x66, + 0x29, 0x20, 0x22, 0x29, 0x22, 0x7d, 0x61, 0x62, 0x62, 0x72, 0x5b, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x5d, 0x3a, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x20, 0x28, 0x22, 0x20, 0x61, 0x74, 0x74, 0x72, 0x28, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x29, 0x20, 0x22, 0x29, 0x22, 0x7d, 0x61, 0x5b, + 0x68, 0x72, 0x65, 0x66, 0x5e, 0x3d, 0x22, 0x23, 0x22, 0x5d, 0x3a, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x61, 0x5b, 0x68, 0x72, 0x65, + 0x66, 0x5e, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3a, 0x22, 0x5d, 0x3a, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x22, 0x7d, 0x70, 0x72, 0x65, 0x2c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x71, 0x75, 0x6f, 0x74, 0x65, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, + 0x20, 0x23, 0x39, 0x39, 0x39, 0x3b, 0x70, 0x61, 0x67, 0x65, 0x2d, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x2d, 0x69, 0x6e, 0x73, 0x69, 0x64, + 0x65, 0x3a, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x7d, 0x74, 0x68, 0x65, + 0x61, 0x64, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x7d, 0x74, 0x72, 0x2c, + 0x69, 0x6d, 0x67, 0x7b, 0x70, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x2d, 0x69, 0x6e, 0x73, 0x69, 0x64, 0x65, 0x3a, + 0x61, 0x76, 0x6f, 0x69, 0x64, 0x7d, 0x69, 0x6d, 0x67, 0x7b, 0x6d, + 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x30, + 0x30, 0x25, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, + 0x6e, 0x74, 0x7d, 0x70, 0x2c, 0x68, 0x32, 0x2c, 0x68, 0x33, 0x7b, + 0x6f, 0x72, 0x70, 0x68, 0x61, 0x6e, 0x73, 0x3a, 0x33, 0x3b, 0x77, + 0x69, 0x64, 0x6f, 0x77, 0x73, 0x3a, 0x33, 0x7d, 0x68, 0x32, 0x2c, + 0x68, 0x33, 0x7b, 0x70, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x3a, 0x61, 0x76, + 0x6f, 0x69, 0x64, 0x7d, 0x2e, 0x6e, 0x61, 0x76, 0x62, 0x61, 0x72, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, + 0x6e, 0x65, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x3e, 0x2e, 0x63, 0x61, + 0x72, 0x65, 0x74, 0x2c, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x75, 0x70, + 0x3e, 0x2e, 0x62, 0x74, 0x6e, 0x3e, 0x2e, 0x63, 0x61, 0x72, 0x65, + 0x74, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, + 0x70, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x30, 0x30, + 0x30, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x23, 0x30, 0x30, 0x30, 0x7d, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x3a, 0x63, + 0x6f, 0x6c, 0x6c, 0x61, 0x70, 0x73, 0x65, 0x20, 0x21, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x74, 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x66, 0x66, 0x66, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, + 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x64, 0x7b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, + 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x64, 0x64, 0x64, 0x20, + 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, + 0x7d, 0x2a, 0x7b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, + 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x78, 0x3b, + 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, + 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, + 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x62, 0x6f, 0x78, 0x7d, 0x2a, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x2c, 0x2a, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x7b, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, + 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x2d, 0x6d, 0x6f, + 0x7a, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, + 0x67, 0x3a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, + 0x78, 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, + 0x67, 0x3a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, + 0x78, 0x7d, 0x68, 0x74, 0x6d, 0x6c, 0x7b, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x74, 0x61, 0x70, + 0x2d, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x72, 0x67, 0x62, 0x61, 0x28, + 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x29, 0x7d, 0x62, 0x6f, + 0x64, 0x79, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, + 0x69, 0x6c, 0x79, 0x3a, 0x22, 0x48, 0x65, 0x6c, 0x76, 0x65, 0x74, + 0x69, 0x63, 0x61, 0x20, 0x4e, 0x65, 0x75, 0x65, 0x22, 0x2c, 0x48, + 0x65, 0x6c, 0x76, 0x65, 0x74, 0x69, 0x63, 0x61, 0x2c, 0x41, 0x72, + 0x69, 0x61, 0x6c, 0x2c, 0x73, 0x61, 0x6e, 0x73, 0x2d, 0x73, 0x65, + 0x72, 0x69, 0x66, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x31, 0x34, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, + 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, + 0x34, 0x32, 0x38, 0x35, 0x37, 0x31, 0x34, 0x33, 0x3b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x33, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x2c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x2c, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2c, 0x74, 0x65, 0x78, 0x74, + 0x61, 0x72, 0x65, 0x61, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, + 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x69, 0x6e, 0x68, 0x65, 0x72, + 0x69, 0x74, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x3b, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x7d, 0x61, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x37, 0x61, 0x62, + 0x37, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, + 0x7d, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x32, 0x33, 0x35, 0x32, 0x37, 0x63, 0x3b, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x6c, 0x69, 0x6e, + 0x65, 0x7d, 0x61, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x6f, + 0x75, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x3a, 0x35, 0x70, 0x78, 0x20, + 0x61, 0x75, 0x74, 0x6f, 0x20, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, + 0x74, 0x2d, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2d, 0x72, 0x69, 0x6e, + 0x67, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x6f, 0x75, 0x74, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x3a, 0x2d, 0x32, 0x70, 0x78, 0x7d, 0x66, 0x69, 0x67, 0x75, 0x72, + 0x65, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x7d, + 0x69, 0x6d, 0x67, 0x7b, 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, + 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6d, 0x69, 0x64, + 0x64, 0x6c, 0x65, 0x7d, 0x2e, 0x69, 0x6d, 0x67, 0x2d, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x7b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x3b, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x31, 0x30, 0x30, 0x25, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x69, 0x6d, 0x67, 0x2d, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, + 0x36, 0x70, 0x78, 0x7d, 0x2e, 0x69, 0x6d, 0x67, 0x2d, 0x74, 0x68, + 0x75, 0x6d, 0x62, 0x6e, 0x61, 0x69, 0x6c, 0x7b, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x34, 0x70, 0x78, 0x3b, 0x6c, 0x69, + 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, + 0x2e, 0x34, 0x32, 0x38, 0x35, 0x37, 0x31, 0x34, 0x33, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x64, 0x64, 0x64, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, + 0x73, 0x3a, 0x34, 0x70, 0x78, 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, + 0x69, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x61, 0x6c, 0x6c, 0x20, 0x2e, 0x32, 0x73, 0x20, + 0x65, 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x2d, 0x6f, 0x75, 0x74, + 0x3b, 0x2d, 0x6f, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x6c, 0x6c, 0x20, 0x2e, 0x32, 0x73, + 0x20, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x2d, 0x6f, 0x75, + 0x74, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x61, 0x6c, 0x6c, 0x20, 0x2e, 0x32, 0x73, 0x20, 0x65, + 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x2d, 0x6f, 0x75, 0x74, 0x3b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x6d, + 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x30, + 0x30, 0x25, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x61, + 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x69, 0x6d, 0x67, 0x2d, 0x63, 0x69, + 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x35, 0x30, 0x25, + 0x7d, 0x68, 0x72, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, + 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3a, 0x30, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x23, 0x65, 0x65, 0x65, 0x7d, 0x2e, 0x73, 0x72, + 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, + 0x65, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x70, 0x78, + 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x70, 0x78, + 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x2d, 0x31, 0x70, + 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x30, + 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x68, + 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x63, 0x6c, 0x69, 0x70, 0x3a, + 0x72, 0x65, 0x63, 0x74, 0x28, 0x30, 0x2c, 0x20, 0x30, 0x2c, 0x20, + 0x30, 0x2c, 0x20, 0x30, 0x29, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3a, 0x30, 0x7d, 0x2e, 0x73, 0x72, 0x2d, 0x6f, 0x6e, 0x6c, + 0x79, 0x2d, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x73, 0x72, + 0x2d, 0x6f, 0x6e, 0x6c, 0x79, 0x2d, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x3a, 0x30, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, + 0x77, 0x3a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x3b, 0x63, + 0x6c, 0x69, 0x70, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x5b, 0x72, + 0x6f, 0x6c, 0x65, 0x3d, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x22, 0x5d, 0x7b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x7d, 0x68, 0x31, 0x2c, 0x68, + 0x32, 0x2c, 0x68, 0x33, 0x2c, 0x68, 0x34, 0x2c, 0x68, 0x35, 0x2c, + 0x68, 0x36, 0x2c, 0x2e, 0x68, 0x31, 0x2c, 0x2e, 0x68, 0x32, 0x2c, + 0x2e, 0x68, 0x33, 0x2c, 0x2e, 0x68, 0x34, 0x2c, 0x2e, 0x68, 0x35, + 0x2c, 0x2e, 0x68, 0x36, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, + 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x69, 0x6e, 0x68, 0x65, 0x72, + 0x69, 0x74, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x35, 0x30, 0x30, 0x3b, 0x6c, 0x69, 0x6e, + 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, + 0x31, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x69, 0x6e, 0x68, + 0x65, 0x72, 0x69, 0x74, 0x7d, 0x68, 0x31, 0x20, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x68, 0x32, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x2c, 0x68, 0x33, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, + 0x34, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x35, 0x20, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x36, 0x20, 0x73, 0x6d, + 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x31, 0x20, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x32, 0x20, 0x73, 0x6d, 0x61, 0x6c, + 0x6c, 0x2c, 0x2e, 0x68, 0x33, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x2c, 0x2e, 0x68, 0x34, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, + 0x2e, 0x68, 0x35, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, + 0x68, 0x36, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x31, + 0x20, 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x32, 0x20, + 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x33, 0x20, 0x2e, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x34, 0x20, 0x2e, 0x73, + 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x35, 0x20, 0x2e, 0x73, 0x6d, + 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x36, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x31, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x32, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x33, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x34, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x35, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x36, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x31, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x37, + 0x37, 0x37, 0x7d, 0x68, 0x31, 0x2c, 0x2e, 0x68, 0x31, 0x2c, 0x68, + 0x32, 0x2c, 0x2e, 0x68, 0x32, 0x2c, 0x68, 0x33, 0x2c, 0x2e, 0x68, + 0x33, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, + 0x70, 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, + 0x30, 0x70, 0x78, 0x7d, 0x68, 0x31, 0x20, 0x73, 0x6d, 0x61, 0x6c, + 0x6c, 0x2c, 0x2e, 0x68, 0x31, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x2c, 0x68, 0x32, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, + 0x68, 0x32, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x33, + 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x33, 0x20, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x31, 0x20, 0x2e, 0x73, + 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x31, 0x20, 0x2e, 0x73, + 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x32, 0x20, 0x2e, 0x73, 0x6d, + 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x32, 0x20, 0x2e, 0x73, 0x6d, + 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x33, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x33, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x36, 0x35, 0x25, 0x7d, 0x68, 0x34, 0x2c, 0x2e, 0x68, + 0x34, 0x2c, 0x68, 0x35, 0x2c, 0x2e, 0x68, 0x35, 0x2c, 0x68, 0x36, + 0x2c, 0x2e, 0x68, 0x36, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x7d, 0x68, 0x34, 0x20, 0x73, + 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x34, 0x20, 0x73, 0x6d, + 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x35, 0x20, 0x73, 0x6d, 0x61, 0x6c, + 0x6c, 0x2c, 0x2e, 0x68, 0x35, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x2c, 0x68, 0x36, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, + 0x68, 0x36, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x34, + 0x20, 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x34, + 0x20, 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x35, 0x20, + 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x35, 0x20, + 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x68, 0x36, 0x20, 0x2e, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x68, 0x36, 0x20, 0x2e, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, + 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x68, 0x31, + 0x2c, 0x2e, 0x68, 0x31, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x33, 0x36, 0x70, 0x78, 0x7d, 0x68, 0x32, + 0x2c, 0x2e, 0x68, 0x32, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x33, 0x30, 0x70, 0x78, 0x7d, 0x68, 0x33, + 0x2c, 0x2e, 0x68, 0x33, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x32, 0x34, 0x70, 0x78, 0x7d, 0x68, 0x34, + 0x2c, 0x2e, 0x68, 0x34, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x38, 0x70, 0x78, 0x7d, 0x68, 0x35, + 0x2c, 0x2e, 0x68, 0x35, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x34, 0x70, 0x78, 0x7d, 0x68, 0x36, + 0x2c, 0x2e, 0x68, 0x36, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x32, 0x70, 0x78, 0x7d, 0x70, 0x7b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x20, 0x30, 0x20, + 0x31, 0x30, 0x70, 0x78, 0x7d, 0x2e, 0x6c, 0x65, 0x61, 0x64, 0x7b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x36, 0x70, 0x78, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x33, 0x30, 0x30, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x34, 0x7d, + 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, + 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, + 0x78, 0x29, 0x7b, 0x2e, 0x6c, 0x65, 0x61, 0x64, 0x7b, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x32, 0x31, 0x70, + 0x78, 0x7d, 0x7d, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x2c, 0x2e, 0x73, + 0x6d, 0x61, 0x6c, 0x6c, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x38, 0x35, 0x25, 0x7d, 0x6d, 0x61, 0x72, + 0x6b, 0x2c, 0x2e, 0x6d, 0x61, 0x72, 0x6b, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x63, 0x66, 0x38, 0x65, 0x33, 0x3b, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x2e, 0x32, 0x65, + 0x6d, 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x7d, 0x2e, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x7b, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x6a, 0x75, 0x73, 0x74, + 0x69, 0x66, 0x79, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, + 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x6e, 0x6f, 0x77, 0x72, + 0x61, 0x70, 0x7b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x3a, 0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, 0x7d, + 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x6c, 0x6f, 0x77, 0x65, 0x72, + 0x63, 0x61, 0x73, 0x65, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x6c, 0x6f, + 0x77, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x7d, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x75, 0x70, 0x70, 0x65, 0x72, 0x63, 0x61, 0x73, + 0x65, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x75, 0x70, 0x70, 0x65, 0x72, + 0x63, 0x61, 0x73, 0x65, 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x7b, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x3a, 0x63, 0x61, 0x70, 0x69, 0x74, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x6d, + 0x75, 0x74, 0x65, 0x64, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x37, 0x37, 0x37, 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x37, 0x61, 0x62, 0x37, 0x7d, + 0x61, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, + 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x38, 0x36, 0x30, 0x39, 0x30, + 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x33, 0x63, 0x37, 0x36, 0x33, 0x64, 0x7d, 0x61, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x2e, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x66, + 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x32, 0x62, 0x35, 0x34, 0x32, 0x63, 0x7d, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x31, 0x37, 0x30, 0x38, 0x66, 0x7d, + 0x61, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, + 0x34, 0x35, 0x32, 0x36, 0x39, 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x38, 0x61, 0x36, 0x64, 0x33, 0x62, + 0x7d, 0x61, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x61, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x36, 0x36, 0x35, 0x31, 0x32, + 0x63, 0x7d, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x61, 0x39, 0x34, 0x34, 0x34, 0x32, 0x7d, 0x61, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x38, + 0x34, 0x33, 0x35, 0x33, 0x34, 0x7d, 0x2e, 0x62, 0x67, 0x2d, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x33, 0x33, 0x37, 0x61, 0x62, 0x37, 0x7d, 0x61, + 0x2e, 0x62, 0x67, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x2e, 0x62, 0x67, + 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x32, 0x38, 0x36, 0x30, 0x39, 0x30, 0x7d, 0x2e, 0x62, 0x67, 0x2d, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x66, 0x66, 0x30, 0x64, 0x38, 0x7d, + 0x61, 0x2e, 0x62, 0x67, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x2e, 0x62, + 0x67, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x66, + 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x63, 0x31, 0x65, 0x32, 0x62, 0x33, 0x7d, 0x2e, 0x62, 0x67, + 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x64, 0x39, 0x65, 0x64, 0x66, 0x37, 0x7d, 0x61, 0x2e, + 0x62, 0x67, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x2c, 0x61, 0x2e, 0x62, 0x67, 0x2d, 0x69, 0x6e, 0x66, + 0x6f, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x66, 0x64, 0x39, 0x65, 0x65, 0x7d, + 0x2e, 0x62, 0x67, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x63, 0x66, + 0x38, 0x65, 0x33, 0x7d, 0x61, 0x2e, 0x62, 0x67, 0x2d, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x2c, 0x61, 0x2e, 0x62, 0x67, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x37, 0x65, 0x63, 0x62, 0x35, + 0x7d, 0x2e, 0x62, 0x67, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x32, 0x64, + 0x65, 0x64, 0x65, 0x7d, 0x61, 0x2e, 0x62, 0x67, 0x2d, 0x64, 0x61, + 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x61, 0x2e, 0x62, 0x67, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x65, 0x34, 0x62, 0x39, 0x62, 0x39, 0x7d, 0x2e, + 0x70, 0x61, 0x67, 0x65, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x62, 0x6f, + 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x39, 0x70, 0x78, 0x3b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x34, 0x30, 0x70, 0x78, 0x20, 0x30, + 0x20, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, 0x70, + 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x65, 0x65, + 0x65, 0x7d, 0x75, 0x6c, 0x2c, 0x6f, 0x6c, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x3b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x7d, 0x75, 0x6c, 0x20, 0x75, + 0x6c, 0x2c, 0x6f, 0x6c, 0x20, 0x75, 0x6c, 0x2c, 0x75, 0x6c, 0x20, + 0x6f, 0x6c, 0x2c, 0x6f, 0x6c, 0x20, 0x6f, 0x6c, 0x7b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, + 0x3a, 0x30, 0x7d, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x2d, 0x75, 0x6e, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x64, 0x7b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x3b, + 0x6c, 0x69, 0x73, 0x74, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x7b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x3b, + 0x6c, 0x69, 0x73, 0x74, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x2d, 0x35, 0x70, 0x78, 0x7d, + 0x2e, 0x6c, 0x69, 0x73, 0x74, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, + 0x65, 0x3e, 0x6c, 0x69, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x70, 0x78, 0x3b, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x35, 0x70, 0x78, 0x7d, 0x64, 0x6c, 0x7b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x3b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x32, 0x30, 0x70, 0x78, 0x7d, 0x64, 0x74, 0x2c, + 0x64, 0x64, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x34, 0x32, 0x38, 0x35, 0x37, + 0x31, 0x34, 0x33, 0x7d, 0x64, 0x74, 0x7b, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, + 0x64, 0x7d, 0x64, 0x64, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x7d, 0x40, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x7b, + 0x2e, 0x64, 0x6c, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, + 0x74, 0x61, 0x6c, 0x20, 0x64, 0x74, 0x7b, 0x66, 0x6c, 0x6f, 0x61, + 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x31, 0x36, 0x30, 0x70, 0x78, 0x3b, 0x63, 0x6c, 0x65, + 0x61, 0x72, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, + 0x3a, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, + 0x65, 0x6c, 0x6c, 0x69, 0x70, 0x73, 0x69, 0x73, 0x3b, 0x77, 0x68, + 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x6e, + 0x6f, 0x77, 0x72, 0x61, 0x70, 0x7d, 0x2e, 0x64, 0x6c, 0x2d, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x64, + 0x64, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x31, 0x38, 0x30, 0x70, 0x78, 0x7d, 0x7d, 0x61, + 0x62, 0x62, 0x72, 0x5b, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x5d, 0x2c, + 0x61, 0x62, 0x62, 0x72, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x61, 0x6c, 0x2d, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x5d, 0x7b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, + 0x68, 0x65, 0x6c, 0x70, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, 0x70, 0x78, + 0x20, 0x64, 0x6f, 0x74, 0x74, 0x65, 0x64, 0x20, 0x23, 0x37, 0x37, + 0x37, 0x7d, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x69, + 0x73, 0x6d, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x39, 0x30, 0x25, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x75, + 0x70, 0x70, 0x65, 0x72, 0x63, 0x61, 0x73, 0x65, 0x7d, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x7b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x20, + 0x32, 0x30, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x3a, 0x30, 0x20, 0x30, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x37, + 0x2e, 0x35, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x65, 0x65, 0x65, 0x7d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x20, 0x70, + 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x2c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, + 0x20, 0x75, 0x6c, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x2c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, + 0x6f, 0x74, 0x65, 0x20, 0x6f, 0x6c, 0x3a, 0x6c, 0x61, 0x73, 0x74, + 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x7b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x30, + 0x7d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, + 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x2c, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x20, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x2c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, + 0x74, 0x65, 0x20, 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x7b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x38, 0x30, 0x25, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x34, 0x32, 0x38, + 0x35, 0x37, 0x31, 0x34, 0x33, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x37, 0x37, 0x37, 0x7d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x71, 0x75, 0x6f, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, + 0x72, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x20, 0x73, 0x6d, + 0x61, 0x6c, 0x6c, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x20, + 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, + 0x27, 0x5c, 0x32, 0x30, 0x31, 0x34, 0x20, 0x5c, 0x30, 0x30, 0x41, + 0x30, 0x27, 0x7d, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, + 0x6f, 0x74, 0x65, 0x2d, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x2c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, + 0x2e, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x31, 0x35, 0x70, 0x78, 0x3b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x30, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x35, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x23, 0x65, 0x65, 0x65, 0x3b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x3b, + 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x7d, 0x2e, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2d, 0x72, 0x65, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x3a, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2e, 0x70, 0x75, 0x6c, 0x6c, + 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x66, 0x6f, 0x6f, 0x74, + 0x65, 0x72, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x2e, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2d, + 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x20, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2e, 0x70, + 0x75, 0x6c, 0x6c, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x73, + 0x6d, 0x61, 0x6c, 0x6c, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x2c, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, + 0x65, 0x2d, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x20, 0x2e, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x2c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, + 0x65, 0x2e, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x27, 0x27, 0x7d, 0x2e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2d, 0x72, 0x65, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x3a, 0x61, + 0x66, 0x74, 0x65, 0x72, 0x2c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x71, + 0x75, 0x6f, 0x74, 0x65, 0x2e, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, + 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2d, 0x72, 0x65, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3a, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2e, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2d, 0x72, 0x65, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x20, 0x2e, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x2e, 0x70, 0x75, 0x6c, 0x6c, + 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x2e, 0x73, 0x6d, 0x61, + 0x6c, 0x6c, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x7b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x27, 0x5c, 0x30, 0x30, 0x41, + 0x30, 0x20, 0x5c, 0x32, 0x30, 0x31, 0x34, 0x27, 0x7d, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x32, 0x30, + 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x3a, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x31, 0x2e, 0x34, 0x32, 0x38, 0x35, 0x37, 0x31, 0x34, 0x33, 0x7d, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x7b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x61, 0x75, 0x74, + 0x6f, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x31, 0x35, 0x70, 0x78, 0x3b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x31, 0x35, 0x70, 0x78, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x7b, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x37, 0x35, 0x30, 0x70, 0x78, 0x7d, 0x7d, + 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, + 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, 0x39, 0x32, 0x70, + 0x78, 0x29, 0x7b, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, 0x37, + 0x30, 0x70, 0x78, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x31, 0x32, 0x30, 0x30, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x7b, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x31, 0x31, 0x37, 0x30, 0x70, 0x78, 0x7d, + 0x7d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x7b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x61, 0x75, + 0x74, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x31, 0x35, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x35, 0x70, + 0x78, 0x7d, 0x2e, 0x72, 0x6f, 0x77, 0x7b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x2d, 0x31, 0x35, + 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x2d, 0x31, 0x35, 0x70, 0x78, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x31, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x31, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x32, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x32, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x32, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x32, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x33, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x33, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x33, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x33, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x34, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x34, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x34, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x34, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x35, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x35, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x35, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x35, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x36, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x36, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x36, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x36, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x37, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x37, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x37, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x37, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x38, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x38, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x38, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x38, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x39, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x39, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x39, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x39, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x31, 0x30, 0x2c, + 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x30, + 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x31, + 0x30, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, + 0x31, 0x30, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x31, 0x31, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, + 0x6d, 0x2d, 0x31, 0x31, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x31, 0x31, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6c, 0x67, 0x2d, 0x31, 0x31, 0x2c, 0x20, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x31, 0x32, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x32, 0x2c, 0x20, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x31, 0x32, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, 0x32, 0x7b, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b, 0x6d, 0x69, 0x6e, 0x2d, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x70, 0x78, 0x3b, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x31, 0x35, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, + 0x35, 0x70, 0x78, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x31, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x32, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x33, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x34, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x35, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x36, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x37, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x38, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x39, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x31, 0x30, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, + 0x73, 0x2d, 0x31, 0x31, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x31, 0x32, 0x7b, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x31, 0x32, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x31, 0x31, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, + 0x31, 0x30, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x38, 0x33, + 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x39, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x38, 0x7b, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, + 0x73, 0x2d, 0x37, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x35, + 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x36, 0x7b, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x35, 0x7b, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x34, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x33, + 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x32, 0x35, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x32, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x78, 0x73, 0x2d, 0x31, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, + 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x32, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x31, + 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x39, 0x31, 0x2e, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x31, 0x30, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x38, 0x33, + 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x6c, + 0x6c, 0x2d, 0x39, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x37, + 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x38, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x37, 0x7b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x35, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, + 0x73, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x36, 0x7b, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x35, + 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x34, 0x31, 0x2e, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x34, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x33, 0x2e, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x6c, 0x6c, + 0x2d, 0x33, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x32, 0x35, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, + 0x75, 0x6c, 0x6c, 0x2d, 0x32, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x30, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, 0x32, + 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x73, + 0x68, 0x2d, 0x31, 0x31, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x39, + 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, + 0x73, 0x68, 0x2d, 0x31, 0x30, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, + 0x75, 0x73, 0x68, 0x2d, 0x39, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x38, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x37, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x35, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x36, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x35, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x34, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x33, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x32, + 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, + 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x78, 0x73, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x30, 0x7b, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x2d, 0x31, 0x32, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x2d, 0x31, 0x31, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x39, 0x31, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x2d, 0x31, 0x30, 0x7b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x38, 0x33, 0x2e, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x2d, 0x39, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x2d, 0x38, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x2d, 0x37, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x35, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x36, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x35, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, + 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x34, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x33, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x32, 0x35, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x32, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x36, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x2d, 0x31, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x78, 0x73, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x2d, 0x30, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x30, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x32, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x33, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x34, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x35, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x36, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x37, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x38, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x39, 0x2c, 0x20, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x30, 0x2c, 0x20, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x31, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x32, 0x7b, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x32, 0x7b, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x31, 0x7b, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x30, 0x7b, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, + 0x6d, 0x2d, 0x39, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, + 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, + 0x38, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x36, 0x36, 0x2e, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x37, 0x7b, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x35, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x73, 0x6d, 0x2d, 0x36, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, + 0x2d, 0x35, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x34, 0x31, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x34, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x73, 0x6d, 0x2d, 0x33, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, + 0x6d, 0x2d, 0x32, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, + 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x31, 0x7b, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x32, + 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, + 0x6c, 0x6c, 0x2d, 0x31, 0x31, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x30, 0x7b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, + 0x6d, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x39, 0x7b, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x38, + 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x37, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x35, 0x38, 0x2e, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x6c, 0x6c, + 0x2d, 0x36, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x35, 0x30, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, + 0x75, 0x6c, 0x6c, 0x2d, 0x35, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x34, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, + 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x33, 0x7b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x32, 0x7b, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, + 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x30, + 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, + 0x73, 0x68, 0x2d, 0x31, 0x32, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, + 0x6d, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, 0x31, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, 0x30, 0x7b, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x39, 0x7b, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, + 0x38, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, + 0x37, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x38, 0x2e, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, + 0x36, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x30, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x73, + 0x68, 0x2d, 0x35, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x34, 0x31, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x73, + 0x68, 0x2d, 0x34, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x33, 0x33, + 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, 0x73, + 0x68, 0x2d, 0x33, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x32, 0x35, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, + 0x75, 0x73, 0x68, 0x2d, 0x32, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, + 0x75, 0x73, 0x68, 0x2d, 0x31, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x70, 0x75, + 0x73, 0x68, 0x2d, 0x30, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x61, + 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, + 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x31, 0x32, 0x7b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x73, 0x6d, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x31, + 0x31, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, + 0x6d, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x31, 0x30, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, + 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x39, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, + 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x38, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x36, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x37, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x38, + 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x2d, 0x36, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x30, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x2d, 0x35, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x34, 0x31, 0x2e, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x2d, 0x34, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x73, 0x6d, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, + 0x33, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x73, 0x6d, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, + 0x32, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, + 0x6d, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x31, 0x7b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x73, 0x6d, 0x2d, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x30, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x7d, + 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, + 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, 0x39, 0x32, + 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x31, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x32, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x33, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x34, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x35, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x36, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x37, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x38, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x39, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x31, 0x30, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, + 0x64, 0x2d, 0x31, 0x31, 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x31, 0x32, 0x7b, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x31, 0x32, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x31, 0x31, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, + 0x31, 0x30, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x38, 0x33, + 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x39, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x38, 0x7b, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, + 0x64, 0x2d, 0x37, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x35, + 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x36, 0x7b, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x35, 0x7b, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x34, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x33, + 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x32, 0x35, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x32, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6d, 0x64, 0x2d, 0x31, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, + 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x32, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x31, + 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x39, 0x31, 0x2e, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x31, 0x30, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x38, 0x33, + 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x6c, + 0x6c, 0x2d, 0x39, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x37, + 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x38, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x37, 0x7b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x35, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, + 0x64, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x36, 0x7b, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x35, + 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x34, 0x31, 0x2e, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x34, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x33, 0x2e, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x6c, 0x6c, + 0x2d, 0x33, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x32, 0x35, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, + 0x75, 0x6c, 0x6c, 0x2d, 0x32, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x30, 0x7b, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, 0x32, + 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x73, + 0x68, 0x2d, 0x31, 0x31, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x39, + 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, + 0x73, 0x68, 0x2d, 0x31, 0x30, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, + 0x75, 0x73, 0x68, 0x2d, 0x39, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x38, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x37, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x35, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x36, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x35, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x34, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x33, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x32, + 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, + 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6d, 0x64, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x30, 0x7b, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x2d, 0x31, 0x32, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x2d, 0x31, 0x31, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x39, 0x31, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x2d, 0x31, 0x30, 0x7b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x38, 0x33, 0x2e, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x2d, 0x39, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x2d, 0x38, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x2d, 0x37, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x35, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x36, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x35, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, + 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x34, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x33, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x32, 0x35, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x32, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x36, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x2d, 0x31, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x2d, 0x30, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x30, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x31, 0x32, 0x30, 0x30, 0x70, 0x78, 0x29, 0x7b, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x32, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x33, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x34, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x35, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x36, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x37, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x38, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x39, 0x2c, 0x20, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, 0x30, 0x2c, + 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, 0x31, + 0x2c, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, + 0x32, 0x7b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, + 0x74, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, + 0x32, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, + 0x31, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, 0x31, 0x2e, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x31, 0x30, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6c, 0x67, 0x2d, 0x39, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, + 0x67, 0x2d, 0x38, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x36, + 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x37, 0x7b, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x35, 0x38, 0x2e, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x36, 0x7b, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6c, 0x67, 0x2d, 0x35, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x34, + 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x33, 0x33, 0x2e, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x33, 0x7b, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6c, 0x67, 0x2d, 0x32, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, + 0x31, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x38, 0x2e, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x31, 0x32, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x30, + 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, + 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x31, 0x7b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, + 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x31, 0x30, 0x7b, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x39, 0x7b, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, + 0x2d, 0x38, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x36, 0x36, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x6c, + 0x6c, 0x2d, 0x37, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x35, + 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, + 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, + 0x6c, 0x6c, 0x2d, 0x36, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x35, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, + 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x35, 0x7b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, + 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x34, 0x7b, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x33, 0x7b, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x32, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x36, 0x2e, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, + 0x2d, 0x31, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x38, 0x2e, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, + 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x6c, 0x6c, + 0x2d, 0x30, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x61, 0x75, + 0x74, 0x6f, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, + 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, 0x32, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, 0x31, + 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, + 0x30, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x38, 0x33, 0x2e, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, + 0x39, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x37, 0x35, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x73, + 0x68, 0x2d, 0x38, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x36, 0x36, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x73, + 0x68, 0x2d, 0x37, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x38, + 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, 0x75, 0x73, + 0x68, 0x2d, 0x36, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x30, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, + 0x75, 0x73, 0x68, 0x2d, 0x35, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x34, 0x31, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, + 0x75, 0x73, 0x68, 0x2d, 0x34, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x33, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x70, + 0x75, 0x73, 0x68, 0x2d, 0x33, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, + 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x32, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, + 0x2d, 0x70, 0x75, 0x73, 0x68, 0x2d, 0x31, 0x7b, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, + 0x70, 0x75, 0x73, 0x68, 0x2d, 0x30, 0x7b, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x31, + 0x32, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x6f, + 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x2d, 0x31, 0x31, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x39, 0x31, 0x2e, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, + 0x31, 0x30, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x38, 0x33, 0x2e, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x39, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x37, 0x35, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, + 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x38, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, + 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x37, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x35, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x36, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x35, 0x30, + 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x35, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x34, 0x31, + 0x2e, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, + 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x2d, 0x34, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x33, 0x33, 0x2e, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x2d, 0x33, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x32, 0x35, 0x25, 0x7d, 0x2e, 0x63, + 0x6f, 0x6c, 0x2d, 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x2d, 0x32, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x36, 0x2e, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x37, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, + 0x2d, 0x6c, 0x67, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, + 0x31, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x38, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x25, 0x7d, 0x2e, 0x63, 0x6f, 0x6c, 0x2d, 0x6c, 0x67, + 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2d, 0x30, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x30, 0x7d, 0x7d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x7d, 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x74, + 0x6f, 0x70, 0x3a, 0x38, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, + 0x38, 0x70, 0x78, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x37, 0x37, 0x37, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x7d, 0x74, 0x68, + 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, + 0x25, 0x3b, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x32, 0x30, + 0x70, 0x78, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, + 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, + 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x7b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x3a, 0x38, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, + 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, + 0x34, 0x32, 0x38, 0x35, 0x37, 0x31, 0x34, 0x33, 0x3b, 0x76, 0x65, + 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x3a, 0x74, 0x6f, 0x70, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x64, 0x64, 0x64, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x7b, 0x76, 0x65, 0x72, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x32, + 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x64, + 0x64, 0x64, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x63, + 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2b, 0x74, 0x68, 0x65, 0x61, + 0x64, 0x3e, 0x74, 0x72, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x63, 0x6f, 0x6c, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x2b, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, + 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3a, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x74, 0x72, 0x3a, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x63, 0x61, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2b, 0x74, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x74, 0x64, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x63, 0x6f, 0x6c, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x2b, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, + 0x72, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3a, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x74, 0x72, + 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x3e, 0x74, 0x64, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x7d, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2b, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x32, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x23, 0x64, 0x64, 0x64, 0x7d, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x64, + 0x65, 0x6e, 0x73, 0x65, 0x64, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x65, 0x6e, 0x73, 0x65, + 0x64, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, + 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, + 0x6f, 0x6e, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x64, 0x3e, 0x74, 0x66, + 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x65, + 0x6e, 0x73, 0x65, 0x64, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x63, 0x6f, 0x6e, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x64, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, + 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x6f, + 0x6e, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x64, 0x3e, 0x74, 0x66, 0x6f, + 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x7b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x35, 0x70, 0x78, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, + 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, + 0x64, 0x64, 0x64, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, + 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x7b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x23, 0x64, 0x64, 0x64, 0x7d, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, + 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, + 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x68, 0x65, 0x61, + 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x32, 0x70, 0x78, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x70, + 0x65, 0x64, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, + 0x3a, 0x6e, 0x74, 0x68, 0x2d, 0x6f, 0x66, 0x2d, 0x74, 0x79, 0x70, + 0x65, 0x28, 0x6f, 0x64, 0x64, 0x29, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x66, 0x39, 0x66, 0x39, 0x66, 0x39, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x66, 0x35, 0x66, 0x35, 0x66, 0x35, 0x7d, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x63, 0x6f, 0x6c, 0x5b, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x2a, 0x3d, 0x22, 0x63, 0x6f, 0x6c, 0x2d, 0x22, 0x5d, 0x7b, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x74, + 0x61, 0x74, 0x69, 0x63, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x7d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, + 0x64, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2a, 0x3d, 0x22, 0x63, + 0x6f, 0x6c, 0x2d, 0x22, 0x5d, 0x2c, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x74, 0x68, 0x5b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2a, 0x3d, + 0x22, 0x63, 0x6f, 0x6c, 0x2d, 0x22, 0x5d, 0x7b, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x3b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, + 0x3e, 0x74, 0x64, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, + 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x74, 0x72, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, + 0x74, 0x72, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x74, + 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x74, 0x68, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, + 0x3e, 0x74, 0x72, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, + 0x74, 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, + 0x35, 0x66, 0x35, 0x66, 0x35, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, + 0x74, 0x68, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, + 0x72, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x3e, 0x74, 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x65, 0x38, 0x65, 0x38, 0x65, 0x38, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, + 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, + 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, + 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2e, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, + 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, + 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3e, 0x74, 0x64, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x2e, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3e, 0x74, 0x64, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, + 0x64, 0x3e, 0x74, 0x72, 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3e, 0x74, 0x68, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, + 0x3e, 0x74, 0x72, 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x3e, 0x74, 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x64, 0x66, 0x66, 0x30, 0x64, 0x38, 0x7d, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, + 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0x74, 0x72, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x2e, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, + 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x30, + 0x65, 0x39, 0x63, 0x36, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, + 0x64, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, + 0x3e, 0x74, 0x64, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, + 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, + 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x69, 0x6e, 0x66, + 0x6f, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x69, + 0x6e, 0x66, 0x6f, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, + 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x2e, + 0x69, 0x6e, 0x66, 0x6f, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, + 0x72, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x3e, 0x74, 0x64, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, + 0x3e, 0x74, 0x72, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x3e, 0x74, 0x64, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x74, 0x72, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x3e, + 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x69, 0x6e, 0x66, + 0x6f, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x2e, 0x69, + 0x6e, 0x66, 0x6f, 0x3e, 0x74, 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x64, 0x39, 0x65, 0x64, 0x66, 0x37, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, + 0x64, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x3e, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x69, 0x6e, + 0x66, 0x6f, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x68, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x63, 0x34, 0x65, + 0x33, 0x66, 0x33, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, + 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, + 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, + 0x3e, 0x74, 0x68, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x74, 0x72, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3e, 0x74, 0x64, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, + 0x74, 0x3e, 0x74, 0x72, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x2e, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3e, 0x74, 0x68, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x3e, 0x74, 0x72, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x2e, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3e, 0x74, 0x68, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x63, 0x66, 0x38, 0x65, 0x33, + 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, + 0x3e, 0x74, 0x64, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, + 0x72, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x3e, 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, + 0x2e, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x3e, 0x74, 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x66, 0x61, 0x66, 0x32, 0x63, 0x63, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x64, 0x61, 0x6e, 0x67, + 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, + 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, + 0x3e, 0x74, 0x64, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, 0x61, + 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x64, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, + 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, 0x65, + 0x61, 0x64, 0x3e, 0x74, 0x72, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, + 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x64, + 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, + 0x74, 0x72, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3e, 0x74, + 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x2e, 0x64, 0x61, 0x6e, 0x67, + 0x65, 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x2e, + 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, + 0x3e, 0x74, 0x72, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3e, + 0x74, 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, + 0x32, 0x64, 0x65, 0x64, 0x65, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2e, 0x64, 0x61, + 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, + 0x74, 0x68, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, + 0x79, 0x3e, 0x74, 0x72, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x74, 0x64, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x3e, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, + 0x72, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, + 0x72, 0x2e, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x3e, 0x74, 0x68, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x65, 0x62, 0x63, 0x63, 0x63, 0x63, 0x7d, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x69, 0x76, 0x65, 0x7b, 0x6f, 0x76, 0x65, 0x72, 0x66, + 0x6c, 0x6f, 0x77, 0x2d, 0x78, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x3b, + 0x6d, 0x69, 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x30, 0x2e, 0x30, 0x31, 0x25, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x61, 0x6e, + 0x64, 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x37, 0x36, 0x37, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x69, 0x76, 0x65, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x31, 0x30, 0x30, 0x25, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, 0x35, 0x70, + 0x78, 0x3b, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2d, + 0x79, 0x3a, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x2d, 0x6d, + 0x73, 0x2d, 0x6f, 0x76, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x2d, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3a, 0x2d, 0x6d, 0x73, 0x2d, 0x61, + 0x75, 0x74, 0x6f, 0x68, 0x69, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x73, + 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x23, 0x64, 0x64, 0x64, 0x7d, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x3a, 0x30, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, + 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x68, + 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, + 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, + 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, + 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, + 0x3e, 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x74, 0x66, 0x6f, 0x6f, + 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x7b, 0x77, 0x68, 0x69, + 0x74, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x6e, 0x6f, + 0x77, 0x72, 0x61, 0x70, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, + 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3a, 0x30, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, + 0x74, 0x72, 0x3e, 0x74, 0x68, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, + 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, + 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x62, 0x6f, + 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x3a, 0x66, 0x69, + 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, + 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, + 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x65, 0x64, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, + 0x3e, 0x74, 0x64, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, + 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x3a, 0x66, 0x69, 0x72, 0x73, + 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x66, + 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x3a, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x7b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x30, 0x7d, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x3e, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, + 0x72, 0x3e, 0x74, 0x68, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, + 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, + 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x3a, 0x6c, 0x61, 0x73, 0x74, + 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, + 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x66, 0x6f, + 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x68, 0x3a, 0x6c, 0x61, + 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2c, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, + 0x68, 0x65, 0x61, 0x64, 0x3e, 0x74, 0x72, 0x3e, 0x74, 0x64, 0x3a, + 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x2c, + 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, + 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3e, 0x74, + 0x64, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x65, 0x64, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, + 0x3e, 0x74, 0x64, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x30, 0x7d, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, 0x74, 0x62, + 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3a, 0x6c, 0x61, 0x73, 0x74, + 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x74, 0x68, 0x2c, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x3e, + 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, 0x72, 0x3a, 0x6c, 0x61, + 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x74, 0x68, + 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, + 0x64, 0x3e, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x74, 0x72, 0x3a, + 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, + 0x74, 0x64, 0x2c, 0x2e, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x3e, 0x2e, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x65, 0x64, 0x3e, 0x74, 0x66, 0x6f, 0x6f, 0x74, 0x3e, 0x74, + 0x72, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x3e, 0x74, 0x64, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x30, 0x7d, 0x7d, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x7b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x30, 0x3b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x3a, 0x30, 0x3b, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x30, 0x7d, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, + 0x30, 0x30, 0x25, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3a, 0x30, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, + 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x32, + 0x31, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, + 0x74, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, + 0x33, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x30, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, + 0x64, 0x20, 0x23, 0x65, 0x35, 0x65, 0x35, 0x65, 0x35, 0x7d, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x3b, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, + 0x35, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x7d, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x5d, 0x7b, 0x2d, 0x77, + 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, + 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, + 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x78, 0x3b, + 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x3a, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x78, 0x7d, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, 0x2c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x5d, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x34, 0x70, 0x78, 0x20, 0x30, + 0x20, 0x30, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, + 0x6f, 0x70, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x5c, 0x39, 0x3b, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x7d, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, + 0x65, 0x22, 0x5d, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7d, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x22, 0x5d, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x5b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x65, 0x5d, 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5b, 0x73, + 0x69, 0x7a, 0x65, 0x5d, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x66, 0x69, 0x6c, 0x65, + 0x22, 0x5d, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x72, + 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, + 0x22, 0x5d, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x6f, 0x75, + 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x3a, 0x35, 0x70, 0x78, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x20, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, + 0x2d, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2d, 0x72, 0x69, 0x6e, 0x67, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x6f, 0x75, 0x74, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3a, + 0x2d, 0x32, 0x70, 0x78, 0x7d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x37, 0x70, 0x78, 0x3b, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x34, 0x70, + 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x34, 0x32, 0x38, 0x35, 0x37, 0x31, + 0x34, 0x33, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x35, + 0x35, 0x35, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x34, 0x70, 0x78, 0x3b, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x36, 0x70, 0x78, 0x20, + 0x31, 0x32, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, + 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x34, 0x70, 0x78, 0x3b, 0x6c, 0x69, + 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, + 0x2e, 0x34, 0x32, 0x38, 0x35, 0x37, 0x31, 0x34, 0x33, 0x3b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x35, 0x35, 0x35, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x63, 0x63, 0x63, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, + 0x73, 0x3a, 0x34, 0x70, 0x78, 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, + 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, + 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, + 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, + 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x30, + 0x37, 0x35, 0x29, 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, + 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, 0x65, 0x74, 0x20, 0x30, + 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, 0x78, 0x20, 0x72, 0x67, + 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, + 0x30, 0x37, 0x35, 0x29, 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, + 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, + 0x2d, 0x6f, 0x75, 0x74, 0x20, 0x2e, 0x31, 0x35, 0x73, 0x2c, 0x20, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, + 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x65, 0x61, 0x73, + 0x65, 0x2d, 0x69, 0x6e, 0x2d, 0x6f, 0x75, 0x74, 0x20, 0x2e, 0x31, + 0x35, 0x73, 0x3b, 0x2d, 0x6f, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x65, 0x61, 0x73, + 0x65, 0x2d, 0x69, 0x6e, 0x2d, 0x6f, 0x75, 0x74, 0x20, 0x2e, 0x31, + 0x35, 0x73, 0x2c, 0x20, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, + 0x64, 0x6f, 0x77, 0x20, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, + 0x2d, 0x6f, 0x75, 0x74, 0x20, 0x2e, 0x31, 0x35, 0x73, 0x3b, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x20, 0x65, 0x61, 0x73, 0x65, 0x2d, 0x69, 0x6e, 0x2d, 0x6f, 0x75, + 0x74, 0x20, 0x2e, 0x31, 0x35, 0x73, 0x2c, 0x20, 0x62, 0x6f, 0x78, + 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x20, 0x65, 0x61, 0x73, + 0x65, 0x2d, 0x69, 0x6e, 0x2d, 0x6f, 0x75, 0x74, 0x20, 0x2e, 0x31, + 0x35, 0x73, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x36, 0x36, 0x61, 0x66, 0x65, 0x39, 0x3b, + 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x3a, 0x30, 0x3b, 0x2d, + 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, + 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, 0x65, + 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, 0x78, + 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, + 0x2c, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x2c, 0x20, 0x30, 0x20, 0x30, + 0x20, 0x38, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x31, + 0x30, 0x32, 0x2c, 0x20, 0x31, 0x37, 0x35, 0x2c, 0x20, 0x32, 0x33, + 0x33, 0x2c, 0x20, 0x30, 0x2e, 0x36, 0x29, 0x3b, 0x62, 0x6f, 0x78, + 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, + 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, + 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x2c, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x2c, 0x20, 0x30, 0x20, + 0x30, 0x20, 0x38, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, + 0x31, 0x30, 0x32, 0x2c, 0x20, 0x31, 0x37, 0x35, 0x2c, 0x20, 0x32, + 0x33, 0x33, 0x2c, 0x20, 0x30, 0x2e, 0x36, 0x29, 0x7d, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x3a, 0x3a, 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x39, 0x39, 0x39, 0x3b, 0x6f, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x3a, 0x31, 0x7d, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x2d, + 0x6d, 0x73, 0x2d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x39, 0x39, 0x39, 0x7d, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x3a, 0x3a, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x70, 0x6c, 0x61, 0x63, 0x65, + 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x39, 0x39, 0x39, 0x7d, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x3a, + 0x2d, 0x6d, 0x73, 0x2d, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x7b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x30, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2c, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5b, 0x72, + 0x65, 0x61, 0x64, 0x6f, 0x6e, 0x6c, 0x79, 0x5d, 0x2c, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, 0x65, 0x65, 0x3b, 0x6f, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x31, 0x7d, 0x2e, 0x66, 0x6f, + 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5b, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2c, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x7b, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x6e, 0x6f, 0x74, 0x2d, 0x61, + 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x7d, 0x74, 0x65, 0x78, 0x74, + 0x61, 0x72, 0x65, 0x61, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x7b, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x73, 0x65, + 0x61, 0x72, 0x63, 0x68, 0x22, 0x5d, 0x7b, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x61, 0x70, 0x70, 0x65, 0x61, 0x72, 0x61, + 0x6e, 0x63, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x40, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x20, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x2d, 0x77, 0x65, 0x62, 0x6b, + 0x69, 0x74, 0x2d, 0x6d, 0x69, 0x6e, 0x2d, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x2d, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x2d, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x3a, 0x30, 0x29, 0x7b, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x64, 0x61, 0x74, + 0x65, 0x22, 0x5d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x69, 0x6d, 0x65, + 0x22, 0x5d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x64, 0x61, 0x74, 0x65, 0x74, + 0x69, 0x6d, 0x65, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x5d, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x5d, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x33, 0x34, 0x70, 0x78, 0x7d, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x64, + 0x61, 0x74, 0x65, 0x22, 0x5d, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x2d, 0x73, 0x6d, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x5d, + 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x73, 0x6d, 0x2c, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x64, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x22, 0x5d, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x2d, 0x73, 0x6d, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x22, + 0x5d, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x73, 0x6d, 0x2c, + 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x64, 0x61, 0x74, 0x65, 0x22, + 0x5d, 0x2c, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x69, 0x6d, + 0x65, 0x22, 0x5d, 0x2c, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x64, + 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, 0x65, 0x2d, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x22, 0x5d, 0x2c, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x5d, 0x7b, 0x6c, 0x69, 0x6e, + 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x30, + 0x70, 0x78, 0x7d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x64, 0x61, 0x74, 0x65, 0x22, 0x5d, 0x2e, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x6c, 0x67, 0x2c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x69, 0x6d, 0x65, 0x22, 0x5d, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x2d, 0x6c, 0x67, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x64, 0x61, 0x74, 0x65, 0x74, 0x69, + 0x6d, 0x65, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x5d, 0x2e, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x6c, 0x67, 0x2c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x6d, + 0x6f, 0x6e, 0x74, 0x68, 0x22, 0x5d, 0x2e, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x2d, 0x6c, 0x67, 0x2c, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x6c, 0x67, 0x20, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x64, 0x61, 0x74, 0x65, 0x22, 0x5d, 0x2c, 0x2e, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x6c, 0x67, + 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x5d, 0x2c, 0x2e, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, + 0x6c, 0x67, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x64, 0x61, 0x74, 0x65, 0x74, 0x69, 0x6d, + 0x65, 0x2d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x22, 0x5d, 0x2c, 0x2e, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x2d, 0x6c, 0x67, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x22, + 0x5d, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x34, 0x36, 0x70, 0x78, 0x7d, 0x7d, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3a, 0x31, 0x35, 0x70, 0x78, 0x7d, 0x2e, 0x72, 0x61, 0x64, + 0x69, 0x6f, 0x2c, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, + 0x78, 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, + 0x3a, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, 0x30, + 0x70, 0x78, 0x7d, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x20, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x2c, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x62, 0x6f, 0x78, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7b, 0x6d, + 0x69, 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x32, + 0x30, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x32, 0x30, 0x70, 0x78, 0x3b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x30, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x3b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x7d, 0x2e, 0x72, 0x61, 0x64, 0x69, + 0x6f, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, 0x2c, + 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2d, 0x69, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, + 0x2c, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x5d, + 0x2c, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x5d, 0x7b, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x62, 0x73, 0x6f, 0x6c, + 0x75, 0x74, 0x65, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x2d, 0x32, 0x30, 0x70, 0x78, 0x3b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, + 0x34, 0x70, 0x78, 0x20, 0x5c, 0x39, 0x7d, 0x2e, 0x72, 0x61, 0x64, + 0x69, 0x6f, 0x2b, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2c, 0x2e, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2b, 0x2e, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x2d, 0x35, 0x70, + 0x78, 0x7d, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x62, 0x6f, 0x78, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x7b, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, + 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x32, 0x30, 0x70, + 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, + 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x30, 0x3b, 0x76, 0x65, 0x72, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, + 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x3b, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x6e, 0x6f, 0x72, + 0x6d, 0x61, 0x6c, 0x3b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x7d, 0x2e, 0x72, 0x61, + 0x64, 0x69, 0x6f, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2b, + 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2d, 0x69, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x2c, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, + 0x78, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2b, 0x2e, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2d, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, + 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x30, 0x70, 0x78, + 0x7d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, 0x5b, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x5d, 0x5b, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2c, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x72, + 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, 0x2e, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x2c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x62, 0x6f, 0x78, 0x22, 0x5d, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, + 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, + 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, 0x2c, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x5d, 0x7b, 0x63, 0x75, 0x72, + 0x73, 0x6f, 0x72, 0x3a, 0x6e, 0x6f, 0x74, 0x2d, 0x61, 0x6c, 0x6c, + 0x6f, 0x77, 0x65, 0x64, 0x7d, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, + 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2c, 0x2e, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x62, 0x6f, 0x78, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2c, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x72, 0x61, 0x64, + 0x69, 0x6f, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, + 0x65, 0x7b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x6e, 0x6f, + 0x74, 0x2d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x7d, 0x2e, + 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2c, 0x2e, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, + 0x72, 0x61, 0x64, 0x69, 0x6f, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x7b, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x6e, + 0x6f, 0x74, 0x2d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x7d, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x7b, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x6f, 0x70, 0x3a, + 0x37, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x37, 0x70, 0x78, + 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x3a, 0x30, 0x3b, 0x6d, 0x69, 0x6e, 0x2d, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x34, 0x70, 0x78, 0x7d, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x2e, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x6c, 0x67, 0x2c, 0x2e, 0x66, 0x6f, + 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, + 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x2e, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x2d, 0x73, 0x6d, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x3b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x30, 0x7d, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x73, + 0x6d, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x30, + 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x35, 0x70, 0x78, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x32, 0x70, + 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x35, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x33, + 0x70, 0x78, 0x7d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2e, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x73, 0x6d, 0x7b, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x33, 0x30, 0x70, 0x78, 0x3b, 0x6c, 0x69, + 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, + 0x30, 0x70, 0x78, 0x7d, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, + 0x61, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x73, 0x6d, 0x2c, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5b, 0x6d, 0x75, 0x6c, 0x74, + 0x69, 0x70, 0x6c, 0x65, 0x5d, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x2d, 0x73, 0x6d, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x30, 0x70, + 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x35, + 0x70, 0x78, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x32, 0x70, 0x78, + 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x31, 0x2e, 0x35, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x33, 0x70, + 0x78, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x33, 0x30, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x30, 0x70, 0x78, 0x7d, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x2d, 0x73, 0x6d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, + 0x61, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x5b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, + 0x65, 0x5d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x7b, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x30, 0x70, 0x78, 0x3b, 0x6d, + 0x69, 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, + 0x32, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3a, 0x36, 0x70, 0x78, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x32, + 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x35, 0x7d, 0x2e, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x2d, 0x6c, 0x67, 0x7b, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x34, 0x36, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, + 0x36, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x31, 0x38, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, + 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, + 0x36, 0x70, 0x78, 0x7d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2e, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x6c, 0x67, 0x7b, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x34, 0x36, 0x70, 0x78, 0x3b, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x34, 0x36, 0x70, 0x78, 0x7d, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, + 0x65, 0x61, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x6c, 0x67, + 0x2c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x5b, 0x6d, 0x75, 0x6c, + 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5d, 0x2e, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x2d, 0x6c, 0x67, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x6c, 0x67, 0x20, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x34, 0x36, + 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, + 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x38, + 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x36, 0x70, 0x78, 0x7d, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, + 0x6c, 0x67, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x34, 0x36, 0x70, + 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x34, 0x36, 0x70, 0x78, 0x7d, 0x2e, 0x66, 0x6f, + 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x6c, 0x67, + 0x20, 0x74, 0x65, 0x78, 0x74, 0x61, 0x72, 0x65, 0x61, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x2d, 0x6c, 0x67, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x5b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x70, 0x6c, 0x65, 0x5d, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x61, 0x75, + 0x74, 0x6f, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x2d, 0x6c, 0x67, 0x20, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x73, + 0x74, 0x61, 0x74, 0x69, 0x63, 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x34, 0x36, 0x70, 0x78, 0x3b, 0x6d, 0x69, 0x6e, 0x2d, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x38, 0x70, 0x78, + 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x31, + 0x70, 0x78, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x38, 0x70, 0x78, + 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x31, 0x2e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, + 0x7d, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, + 0x61, 0x63, 0x6b, 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x7d, + 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, + 0x63, 0x6b, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x34, 0x32, + 0x2e, 0x35, 0x70, 0x78, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, 0x65, + 0x64, 0x62, 0x61, 0x63, 0x6b, 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x61, 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, + 0x65, 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x3b, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x30, 0x3b, 0x7a, 0x2d, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x3a, 0x32, 0x3b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x33, 0x34, 0x70, 0x78, 0x3b, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x33, 0x34, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, + 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x34, + 0x70, 0x78, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x2d, 0x6c, 0x67, 0x2b, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, + 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x2c, 0x2e, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x6c, + 0x67, 0x2b, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, + 0x63, 0x6b, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x2d, 0x6c, 0x67, 0x20, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2b, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x7b, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x34, 0x36, 0x70, 0x78, 0x3b, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x34, 0x36, 0x70, 0x78, + 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x34, 0x36, 0x70, 0x78, 0x7d, 0x2e, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x2d, 0x73, 0x6d, 0x2b, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, + 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x2c, 0x2e, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x73, 0x6d, + 0x2b, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, + 0x6b, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x2d, 0x73, 0x6d, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2b, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x7b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x33, 0x30, 0x70, 0x78, 0x3b, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x30, 0x70, 0x78, 0x3b, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x33, 0x30, 0x70, 0x78, 0x7d, 0x2e, 0x68, 0x61, 0x73, 0x2d, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x2e, 0x68, 0x65, + 0x6c, 0x70, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x2e, 0x68, + 0x61, 0x73, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, + 0x6f, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x20, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, + 0x6f, 0x78, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, + 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x68, 0x61, + 0x73, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x2e, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x72, 0x61, 0x64, 0x69, + 0x6f, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2c, 0x2e, 0x68, 0x61, + 0x73, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, + 0x78, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x33, 0x63, 0x37, 0x36, 0x33, 0x64, 0x7d, 0x2e, 0x68, 0x61, 0x73, + 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x63, 0x37, 0x36, 0x33, 0x64, 0x3b, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, + 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, + 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, + 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x3b, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, + 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, + 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, + 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x7d, 0x2e, + 0x68, 0x61, 0x73, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x32, 0x62, 0x35, 0x34, 0x32, 0x63, 0x3b, 0x2d, 0x77, + 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, + 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, 0x65, 0x74, + 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, 0x78, 0x20, + 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x2c, 0x30, 0x20, 0x30, 0x20, + 0x36, 0x70, 0x78, 0x20, 0x23, 0x36, 0x37, 0x62, 0x31, 0x36, 0x38, + 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x3a, 0x69, 0x6e, 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, + 0x78, 0x20, 0x31, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, + 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, + 0x29, 0x2c, 0x30, 0x20, 0x30, 0x20, 0x36, 0x70, 0x78, 0x20, 0x23, + 0x36, 0x37, 0x62, 0x31, 0x36, 0x38, 0x7d, 0x2e, 0x68, 0x61, 0x73, + 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x2e, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, + 0x61, 0x64, 0x64, 0x6f, 0x6e, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x33, 0x63, 0x37, 0x36, 0x33, 0x64, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x33, 0x63, 0x37, 0x36, 0x33, 0x64, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x66, 0x66, 0x30, 0x64, 0x38, 0x7d, + 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, + 0x63, 0x6b, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, + 0x63, 0x37, 0x36, 0x33, 0x64, 0x7d, 0x2e, 0x68, 0x61, 0x73, 0x2d, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x2e, 0x68, 0x65, + 0x6c, 0x70, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x2e, 0x68, + 0x61, 0x73, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, + 0x6f, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x20, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, + 0x6f, 0x78, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, + 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x68, 0x61, + 0x73, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x2e, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x61, 0x64, 0x69, + 0x6f, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2c, 0x2e, 0x68, 0x61, + 0x73, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, + 0x78, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x38, 0x61, 0x36, 0x64, 0x33, 0x62, 0x7d, 0x2e, 0x68, 0x61, 0x73, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x38, 0x61, 0x36, 0x64, 0x33, 0x62, 0x3b, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, + 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, + 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, + 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x3b, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, + 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, + 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, + 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x7d, 0x2e, + 0x68, 0x61, 0x73, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x36, 0x36, 0x35, 0x31, 0x32, 0x63, 0x3b, 0x2d, 0x77, + 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, + 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, 0x65, 0x74, + 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, 0x78, 0x20, + 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x2c, 0x30, 0x20, 0x30, 0x20, + 0x36, 0x70, 0x78, 0x20, 0x23, 0x63, 0x30, 0x61, 0x31, 0x36, 0x62, + 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x3a, 0x69, 0x6e, 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, + 0x78, 0x20, 0x31, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, + 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, + 0x29, 0x2c, 0x30, 0x20, 0x30, 0x20, 0x36, 0x70, 0x78, 0x20, 0x23, + 0x63, 0x30, 0x61, 0x31, 0x36, 0x62, 0x7d, 0x2e, 0x68, 0x61, 0x73, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x2e, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, + 0x61, 0x64, 0x64, 0x6f, 0x6e, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x38, 0x61, 0x36, 0x64, 0x33, 0x62, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x38, 0x61, 0x36, 0x64, 0x33, 0x62, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x63, 0x66, 0x38, 0x65, 0x33, 0x7d, + 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, + 0x63, 0x6b, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x38, + 0x61, 0x36, 0x64, 0x33, 0x62, 0x7d, 0x2e, 0x68, 0x61, 0x73, 0x2d, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, 0x68, 0x65, 0x6c, 0x70, + 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x2e, 0x68, 0x61, 0x73, + 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2c, + 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, + 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2c, 0x2e, 0x68, 0x61, 0x73, + 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, + 0x6f, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x68, + 0x61, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2d, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x20, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, + 0x6f, 0x78, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2c, 0x2e, 0x68, + 0x61, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x72, 0x61, + 0x64, 0x69, 0x6f, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x2d, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x62, 0x6f, 0x78, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x61, 0x39, 0x34, 0x34, 0x34, 0x32, 0x7d, 0x2e, 0x68, + 0x61, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x39, 0x34, 0x34, 0x34, 0x32, 0x3b, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, + 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, + 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, + 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x3b, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, + 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, + 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, + 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x7d, 0x2e, + 0x68, 0x61, 0x73, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x38, 0x34, 0x33, 0x35, 0x33, 0x34, 0x3b, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, + 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, 0x73, 0x65, 0x74, 0x20, 0x30, + 0x20, 0x31, 0x70, 0x78, 0x20, 0x31, 0x70, 0x78, 0x20, 0x72, 0x67, + 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, + 0x30, 0x37, 0x35, 0x29, 0x2c, 0x30, 0x20, 0x30, 0x20, 0x36, 0x70, + 0x78, 0x20, 0x23, 0x63, 0x65, 0x38, 0x34, 0x38, 0x33, 0x3b, 0x62, + 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, + 0x6e, 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x31, 0x70, 0x78, 0x20, + 0x31, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, + 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x30, 0x37, 0x35, 0x29, 0x2c, + 0x30, 0x20, 0x30, 0x20, 0x36, 0x70, 0x78, 0x20, 0x23, 0x63, 0x65, + 0x38, 0x34, 0x38, 0x33, 0x7d, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x61, 0x64, 0x64, 0x6f, + 0x6e, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x39, + 0x34, 0x34, 0x34, 0x32, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x39, 0x34, + 0x34, 0x34, 0x32, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x66, 0x32, 0x64, 0x65, 0x64, 0x65, 0x7d, 0x2e, 0x68, 0x61, 0x73, + 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, + 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x39, 0x34, 0x34, 0x34, 0x32, 0x7d, + 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, + 0x63, 0x6b, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7e, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x7b, 0x74, + 0x6f, 0x70, 0x3a, 0x32, 0x35, 0x70, 0x78, 0x7d, 0x2e, 0x68, 0x61, + 0x73, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x20, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x73, 0x72, 0x2d, 0x6f, 0x6e, + 0x6c, 0x79, 0x7e, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, 0x65, 0x64, 0x62, + 0x61, 0x63, 0x6b, 0x7b, 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x7d, 0x2e, + 0x68, 0x65, 0x6c, 0x70, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, + 0x6f, 0x70, 0x3a, 0x35, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x37, 0x33, 0x37, 0x33, 0x37, 0x33, 0x7d, 0x40, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x7b, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, + 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x3a, 0x30, 0x3b, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6d, + 0x69, 0x64, 0x64, 0x6c, 0x65, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x66, 0x6f, + 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x76, + 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x7d, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x2d, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7d, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3b, 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6d, 0x69, 0x64, 0x64, 0x6c, + 0x65, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x2e, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x61, 0x64, 0x64, + 0x6f, 0x6e, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, + 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x2e, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x62, 0x74, + 0x6e, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x7b, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, + 0x2e, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x2d, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x3e, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x30, 0x3b, 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, + 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6d, 0x69, + 0x64, 0x64, 0x6c, 0x65, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x72, 0x61, 0x64, + 0x69, 0x6f, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x62, 0x6f, 0x78, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, + 0x6f, 0x70, 0x3a, 0x30, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x30, 0x3b, 0x76, + 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x3a, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x7d, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x20, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x62, 0x6f, 0x78, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7b, 0x70, + 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, 0x74, + 0x3a, 0x30, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, + 0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x22, 0x5d, 0x2c, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, + 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x5d, + 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x7d, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, + 0x65, 0x20, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x66, 0x65, 0x65, 0x64, + 0x62, 0x61, 0x63, 0x6b, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, 0x65, + 0x64, 0x62, 0x61, 0x63, 0x6b, 0x7b, 0x74, 0x6f, 0x70, 0x3a, 0x30, + 0x7d, 0x7d, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x2e, 0x72, 0x61, + 0x64, 0x69, 0x6f, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x2e, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x2c, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, + 0x74, 0x61, 0x6c, 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, + 0x6c, 0x20, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, + 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x3b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3a, 0x30, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x37, 0x70, 0x78, 0x7d, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, + 0x74, 0x61, 0x6c, 0x20, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x6f, 0x2c, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x2e, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x62, 0x6f, 0x78, 0x7b, 0x6d, 0x69, 0x6e, 0x2d, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x32, 0x37, 0x70, 0x78, 0x7d, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, + 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x2d, 0x31, 0x35, 0x70, + 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x2d, 0x31, 0x35, 0x70, 0x78, 0x7d, 0x40, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, + 0x29, 0x7b, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x68, 0x6f, 0x72, + 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x30, + 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x6f, + 0x70, 0x3a, 0x37, 0x70, 0x78, 0x7d, 0x7d, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, + 0x6c, 0x20, 0x2e, 0x68, 0x61, 0x73, 0x2d, 0x66, 0x65, 0x65, 0x64, + 0x62, 0x61, 0x63, 0x6b, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, + 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x66, 0x65, 0x65, + 0x64, 0x62, 0x61, 0x63, 0x6b, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x31, 0x35, 0x70, 0x78, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, + 0x74, 0x61, 0x6c, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x2d, 0x6c, 0x67, 0x20, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x6f, + 0x70, 0x3a, 0x31, 0x31, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x38, 0x70, 0x78, 0x7d, + 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, + 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, 0x38, + 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x2d, + 0x73, 0x6d, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, + 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x36, 0x70, 0x78, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x32, 0x70, 0x78, 0x7d, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3a, 0x30, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x76, 0x65, 0x72, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x3a, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x3b, 0x2d, 0x6d, 0x73, + 0x2d, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2d, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x6d, 0x61, 0x6e, 0x69, 0x70, 0x75, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2d, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6d, 0x61, 0x6e, 0x69, + 0x70, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x63, 0x75, + 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, + 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x77, 0x68, + 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x6e, + 0x6f, 0x77, 0x72, 0x61, 0x70, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3a, 0x36, 0x70, 0x78, 0x20, 0x31, 0x32, 0x70, 0x78, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x34, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x34, 0x32, 0x38, + 0x35, 0x37, 0x31, 0x34, 0x33, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x34, 0x70, + 0x78, 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x75, + 0x73, 0x65, 0x72, 0x2d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, 0x75, + 0x73, 0x65, 0x72, 0x2d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x2d, 0x6d, 0x73, 0x2d, 0x75, 0x73, + 0x65, 0x72, 0x2d, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3a, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x2d, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, + 0x62, 0x74, 0x6e, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2e, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x66, + 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x6e, + 0x65, 0x3a, 0x35, 0x70, 0x78, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x20, + 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2d, 0x72, 0x69, 0x6e, 0x67, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3b, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x2d, + 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3a, 0x2d, 0x32, 0x70, 0x78, + 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x33, + 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x7b, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x3a, 0x30, + 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, + 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, + 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, 0x6e, + 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x33, 0x70, 0x78, 0x20, 0x35, + 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, + 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x31, 0x32, 0x35, 0x29, 0x3b, 0x62, + 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x69, + 0x6e, 0x73, 0x65, 0x74, 0x20, 0x30, 0x20, 0x33, 0x70, 0x78, 0x20, + 0x35, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, + 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x31, 0x32, 0x35, 0x29, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2c, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x7b, 0x63, 0x75, + 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x6e, 0x6f, 0x74, 0x2d, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x3b, 0x6f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x3a, 0x2e, 0x36, 0x35, 0x3b, 0x66, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x3a, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x28, 0x6f, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x3d, 0x36, 0x35, 0x29, 0x3b, 0x2d, + 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, + 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, + 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x61, 0x2e, 0x62, 0x74, 0x6e, + 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2c, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x61, 0x2e, 0x62, 0x74, + 0x6e, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, + 0x33, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, + 0x66, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x63, 0x63, 0x63, 0x7d, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, + 0x33, 0x33, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, + 0x36, 0x65, 0x36, 0x65, 0x36, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x38, 0x63, + 0x38, 0x63, 0x38, 0x63, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, + 0x33, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, 0x36, + 0x65, 0x36, 0x65, 0x36, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x64, 0x61, + 0x64, 0x61, 0x64, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, + 0x33, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, 0x36, + 0x65, 0x36, 0x65, 0x36, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x64, 0x61, + 0x64, 0x61, 0x64, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, + 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, + 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x33, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x34, 0x64, 0x34, 0x64, 0x34, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x38, 0x63, 0x38, 0x63, 0x38, 0x63, 0x7d, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, + 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, + 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, + 0x74, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2e, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x63, + 0x63, 0x63, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x20, 0x2e, 0x62, 0x61, 0x64, 0x67, 0x65, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, + 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x33, + 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, + 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, + 0x33, 0x37, 0x61, 0x62, 0x37, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x65, + 0x36, 0x64, 0x61, 0x34, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x38, 0x36, 0x30, 0x39, + 0x30, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x31, 0x32, 0x32, 0x62, 0x34, 0x30, + 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x38, 0x36, 0x30, 0x39, 0x30, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x30, 0x34, 0x64, 0x37, 0x34, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x38, 0x36, 0x30, 0x39, 0x30, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x30, 0x34, 0x64, 0x37, 0x34, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, + 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x2e, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x32, 0x30, 0x34, 0x64, 0x37, 0x34, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x31, + 0x32, 0x32, 0x62, 0x34, 0x30, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x3a, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x6e, + 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, + 0x69, 0x6d, 0x61, 0x72, 0x79, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, + 0x6d, 0x61, 0x72, 0x79, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, 0x72, 0x69, 0x6d, + 0x61, 0x72, 0x79, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x5d, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x66, 0x69, + 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x2e, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, + 0x33, 0x37, 0x61, 0x62, 0x37, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x65, + 0x36, 0x64, 0x61, 0x34, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x70, + 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x20, 0x2e, 0x62, 0x61, 0x64, + 0x67, 0x65, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, + 0x33, 0x37, 0x61, 0x62, 0x37, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x35, 0x63, 0x62, 0x38, 0x35, 0x63, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x34, 0x63, 0x61, 0x65, 0x34, 0x63, 0x7d, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x34, 0x34, 0x39, 0x64, 0x34, 0x34, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, + 0x35, 0x35, 0x36, 0x32, 0x35, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, + 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x34, + 0x34, 0x39, 0x64, 0x34, 0x34, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x39, + 0x38, 0x34, 0x33, 0x39, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, + 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, + 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x34, + 0x34, 0x39, 0x64, 0x34, 0x34, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x39, + 0x38, 0x34, 0x33, 0x39, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, + 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x39, 0x38, 0x34, 0x33, 0x39, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x35, 0x35, 0x36, 0x32, 0x35, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5b, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2e, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x35, 0x63, 0x62, 0x38, 0x35, 0x63, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x34, 0x63, 0x61, 0x65, 0x34, 0x63, 0x7d, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x20, 0x2e, 0x62, 0x61, 0x64, 0x67, 0x65, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x35, 0x63, 0x62, 0x38, 0x35, 0x63, 0x3b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x35, 0x62, 0x63, 0x30, 0x64, + 0x65, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x34, 0x36, 0x62, 0x38, 0x64, 0x61, + 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x31, 0x62, 0x30, + 0x64, 0x35, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x31, 0x62, 0x36, 0x64, 0x38, + 0x35, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x33, 0x31, 0x62, 0x30, 0x64, 0x35, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x32, 0x36, 0x39, 0x61, 0x62, 0x63, 0x7d, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, + 0x66, 0x6f, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, + 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x31, 0x62, 0x30, 0x64, 0x35, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x36, 0x39, 0x61, 0x62, 0x63, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, + 0x6f, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, + 0x66, 0x6f, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x66, + 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, + 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, + 0x6e, 0x66, 0x6f, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x36, 0x39, 0x61, 0x62, + 0x63, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x31, 0x62, 0x36, 0x64, 0x38, 0x35, + 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x3a, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, + 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, + 0x66, 0x6f, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, + 0x6e, 0x66, 0x6f, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, + 0x6f, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2e, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x5b, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2e, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, + 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, + 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x2e, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x35, 0x62, 0x63, 0x30, 0x64, 0x65, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x34, 0x36, 0x62, 0x38, 0x64, 0x61, 0x7d, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x2e, 0x62, 0x61, 0x64, + 0x67, 0x65, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x35, + 0x62, 0x63, 0x30, 0x64, 0x65, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x30, 0x61, 0x64, 0x34, 0x65, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x65, 0x65, 0x61, 0x32, 0x33, 0x36, 0x7d, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x65, 0x63, 0x39, 0x37, 0x31, 0x66, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x39, + 0x38, 0x35, 0x66, 0x30, 0x64, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, + 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, + 0x63, 0x39, 0x37, 0x31, 0x66, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x35, + 0x38, 0x35, 0x31, 0x32, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, + 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, + 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, + 0x63, 0x39, 0x37, 0x31, 0x66, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x35, + 0x38, 0x35, 0x31, 0x32, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, + 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x35, 0x38, 0x35, 0x31, 0x32, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x39, 0x38, 0x35, 0x66, 0x30, 0x64, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x6f, 0x70, 0x65, + 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, + 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x5b, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2e, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x30, 0x61, 0x64, 0x34, 0x65, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x65, 0x65, 0x61, 0x32, 0x33, 0x36, 0x7d, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, + 0x20, 0x2e, 0x62, 0x61, 0x64, 0x67, 0x65, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x30, 0x61, 0x64, 0x34, 0x65, 0x3b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, + 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x39, 0x35, + 0x33, 0x34, 0x66, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x34, 0x33, 0x66, + 0x33, 0x61, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2e, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x63, 0x39, 0x33, 0x30, 0x32, 0x63, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x37, 0x36, 0x31, 0x63, 0x31, 0x39, 0x7d, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x63, 0x39, 0x33, 0x30, 0x32, 0x63, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x61, + 0x63, 0x32, 0x39, 0x32, 0x35, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, + 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x63, 0x39, 0x33, + 0x30, 0x32, 0x63, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x63, 0x32, 0x39, + 0x32, 0x35, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x6f, + 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, + 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, + 0x65, 0x72, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x63, 0x32, 0x39, 0x32, 0x35, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x37, 0x36, 0x31, 0x63, 0x31, 0x39, 0x7d, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x3a, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x3e, + 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, + 0x61, 0x6e, 0x67, 0x65, 0x72, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2e, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x2e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, + 0x6e, 0x67, 0x65, 0x72, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x5d, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x3a, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x5b, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2e, 0x66, 0x6f, 0x63, + 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x64, 0x39, 0x35, 0x33, 0x34, 0x66, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x64, 0x34, 0x33, 0x66, 0x33, 0x61, 0x7d, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x2e, + 0x62, 0x61, 0x64, 0x67, 0x65, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x64, 0x39, 0x35, 0x33, 0x34, 0x66, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x7d, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x37, 0x61, 0x62, 0x37, 0x3b, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, + 0x30, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, + 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, + 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x2c, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, + 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, + 0x61, 0x64, 0x6f, 0x77, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x2c, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, + 0x6b, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, + 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x66, + 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x23, 0x32, 0x33, 0x35, 0x32, 0x37, 0x63, 0x3b, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x6c, 0x69, 0x6e, 0x65, + 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x7d, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x5b, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x2c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x2c, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x6c, 0x69, 0x6e, + 0x6b, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5d, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x65, 0x74, 0x5b, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x5d, 0x20, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x6c, 0x69, + 0x6e, 0x6b, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x37, 0x37, 0x37, 0x3b, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x6c, 0x67, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, 0x36, 0x70, 0x78, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x38, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x33, 0x33, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x36, 0x70, 0x78, + 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x6d, 0x7b, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x35, 0x70, 0x78, 0x20, 0x31, + 0x30, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, + 0x7a, 0x65, 0x3a, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, + 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, + 0x35, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x3a, 0x33, 0x70, 0x78, 0x7d, 0x2e, 0x62, + 0x74, 0x6e, 0x2d, 0x78, 0x73, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x35, 0x70, 0x78, 0x3b, + 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, + 0x32, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x35, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, + 0x3a, 0x33, 0x70, 0x78, 0x7d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2b, 0x2e, 0x62, 0x74, + 0x6e, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x35, 0x70, 0x78, + 0x7d, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x73, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x22, 0x5d, 0x2e, + 0x62, 0x74, 0x6e, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, + 0x72, 0x65, 0x73, 0x65, 0x74, 0x22, 0x5d, 0x2e, 0x62, 0x74, 0x6e, + 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x69, 0x6e, 0x70, 0x75, + 0x74, 0x5b, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x62, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x22, 0x5d, 0x2e, 0x62, 0x74, 0x6e, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x31, 0x30, 0x30, 0x25, 0x7d, 0x2e, 0x63, 0x61, 0x72, 0x65, 0x74, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x30, 0x3b, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x30, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x32, 0x70, 0x78, 0x3b, + 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x3a, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, + 0x34, 0x70, 0x78, 0x20, 0x64, 0x61, 0x73, 0x68, 0x65, 0x64, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, + 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x5c, + 0x39, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, + 0x69, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x34, 0x70, 0x78, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x75, + 0x70, 0x2c, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, + 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x7d, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x6f, 0x75, + 0x74, 0x6c, 0x69, 0x6e, 0x65, 0x3a, 0x30, 0x7d, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, + 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x61, + 0x62, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x3b, 0x74, 0x6f, 0x70, + 0x3a, 0x31, 0x30, 0x30, 0x25, 0x3b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x30, 0x3b, 0x7a, 0x2d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x31, + 0x30, 0x30, 0x30, 0x3b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x66, 0x6c, 0x6f, 0x61, 0x74, + 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x6d, 0x69, 0x6e, 0x2d, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x36, 0x30, 0x70, 0x78, 0x3b, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x35, 0x70, 0x78, + 0x20, 0x30, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, 0x32, + 0x70, 0x78, 0x20, 0x30, 0x20, 0x30, 0x3b, 0x6c, 0x69, 0x73, 0x74, + 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x31, 0x34, 0x70, 0x78, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x23, 0x63, 0x63, 0x63, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, + 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, + 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x31, 0x35, 0x29, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x3a, 0x34, 0x70, 0x78, 0x3b, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, + 0x64, 0x6f, 0x77, 0x3a, 0x30, 0x20, 0x36, 0x70, 0x78, 0x20, 0x31, + 0x32, 0x70, 0x78, 0x20, 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, + 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2e, 0x31, 0x37, 0x35, 0x29, 0x3b, + 0x62, 0x6f, 0x78, 0x2d, 0x73, 0x68, 0x61, 0x64, 0x6f, 0x77, 0x3a, + 0x30, 0x20, 0x36, 0x70, 0x78, 0x20, 0x31, 0x32, 0x70, 0x78, 0x20, + 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x2e, 0x31, 0x37, 0x35, 0x29, 0x3b, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6c, 0x69, 0x70, 0x3a, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x62, 0x6f, 0x78, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6c, 0x69, 0x70, 0x3a, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x2d, 0x62, 0x6f, 0x78, 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, + 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x2e, 0x70, 0x75, + 0x6c, 0x6c, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x7b, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x30, 0x3b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, + 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x20, 0x2e, 0x64, + 0x69, 0x76, 0x69, 0x64, 0x65, 0x72, 0x7b, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x31, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x3a, 0x39, 0x70, 0x78, 0x20, 0x30, 0x3b, 0x6f, 0x76, + 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x68, 0x69, 0x64, 0x64, + 0x65, 0x6e, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, + 0x35, 0x65, 0x35, 0x65, 0x35, 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x6c, + 0x69, 0x3e, 0x61, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x3a, 0x33, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, + 0x78, 0x3b, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x3a, 0x62, 0x6f, 0x74, + 0x68, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x31, 0x2e, 0x34, 0x32, 0x38, 0x35, 0x37, 0x31, 0x34, 0x33, 0x3b, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x33, 0x3b, + 0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x3a, 0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, 0x7d, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, + 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x2c, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, + 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x66, + 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, + 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6e, + 0x6f, 0x6e, 0x65, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x32, 0x36, 0x32, 0x36, 0x32, 0x36, 0x3b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x66, 0x35, 0x66, 0x35, 0x66, 0x35, 0x7d, 0x2e, + 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, + 0x6e, 0x75, 0x3e, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, + 0x61, 0x2c, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x3e, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, + 0x65, 0x6e, 0x75, 0x3e, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x3e, 0x61, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x74, 0x65, + 0x78, 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x6f, 0x75, 0x74, + 0x6c, 0x69, 0x6e, 0x65, 0x3a, 0x30, 0x3b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x33, 0x33, 0x37, 0x61, 0x62, 0x37, 0x7d, 0x2e, + 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, + 0x6e, 0x75, 0x3e, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x3e, 0x61, 0x2c, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x37, 0x37, 0x37, 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x3a, 0x68, 0x6f, + 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x3e, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x65, + 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6e, 0x6f, + 0x6e, 0x65, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x69, + 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3a, 0x70, 0x72, 0x6f, 0x67, 0x69, + 0x64, 0x3a, 0x44, 0x58, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x4d, 0x69, 0x63, + 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x67, 0x72, 0x61, 0x64, + 0x69, 0x65, 0x6e, 0x74, 0x28, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x20, 0x3d, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x29, 0x3b, + 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x6e, 0x6f, 0x74, 0x2d, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x7d, 0x2e, 0x6f, 0x70, + 0x65, 0x6e, 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, + 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7d, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x3e, 0x61, 0x7b, 0x6f, 0x75, 0x74, 0x6c, + 0x69, 0x6e, 0x65, 0x3a, 0x30, 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x61, + 0x75, 0x74, 0x6f, 0x3b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x30, + 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, + 0x6d, 0x65, 0x6e, 0x75, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x7b, 0x6c, + 0x65, 0x66, 0x74, 0x3a, 0x30, 0x3b, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x3b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3a, 0x33, 0x70, 0x78, 0x20, 0x32, 0x30, 0x70, 0x78, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x32, + 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x34, 0x32, 0x38, 0x35, 0x37, + 0x31, 0x34, 0x33, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x37, 0x37, 0x37, 0x3b, 0x77, 0x68, 0x69, 0x74, 0x65, 0x2d, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x3a, 0x6e, 0x6f, 0x77, 0x72, 0x61, 0x70, + 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, + 0x62, 0x61, 0x63, 0x6b, 0x64, 0x72, 0x6f, 0x70, 0x7b, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x66, 0x69, 0x78, 0x65, + 0x64, 0x3b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x3b, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x30, 0x3b, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3a, 0x30, 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x3b, 0x7a, + 0x2d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x39, 0x39, 0x30, 0x7d, + 0x2e, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3e, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, + 0x6d, 0x65, 0x6e, 0x75, 0x7b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x30, 0x3b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, + 0x7d, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x75, 0x70, 0x20, 0x2e, 0x63, + 0x61, 0x72, 0x65, 0x74, 0x2c, 0x2e, 0x6e, 0x61, 0x76, 0x62, 0x61, + 0x72, 0x2d, 0x66, 0x69, 0x78, 0x65, 0x64, 0x2d, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x20, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, + 0x77, 0x6e, 0x20, 0x2e, 0x63, 0x61, 0x72, 0x65, 0x74, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x30, + 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x3a, 0x34, 0x70, 0x78, 0x20, 0x64, 0x61, 0x73, + 0x68, 0x65, 0x64, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x34, 0x70, 0x78, 0x20, + 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x5c, 0x39, 0x3b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x22, 0x7d, 0x2e, 0x64, + 0x72, 0x6f, 0x70, 0x75, 0x70, 0x20, 0x2e, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x2c, 0x2e, + 0x6e, 0x61, 0x76, 0x62, 0x61, 0x72, 0x2d, 0x66, 0x69, 0x78, 0x65, + 0x64, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x2e, 0x64, + 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x20, 0x2e, 0x64, 0x72, + 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, + 0x7b, 0x74, 0x6f, 0x70, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x62, + 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, 0x30, 0x30, 0x25, 0x3b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x32, 0x70, 0x78, 0x7d, 0x40, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x7b, 0x2e, + 0x6e, 0x61, 0x76, 0x62, 0x61, 0x72, 0x2d, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x30, 0x7d, 0x2e, 0x6e, 0x61, 0x76, 0x62, 0x61, 0x72, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x2e, 0x64, 0x72, 0x6f, 0x70, 0x64, + 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x3b, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x7d, 0x7d, + 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x30, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x3a, + 0x32, 0x30, 0x70, 0x78, 0x20, 0x30, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x34, + 0x70, 0x78, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x7d, + 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x73, + 0x70, 0x61, 0x6e, 0x7b, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x3b, + 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x6c, 0x65, 0x66, 0x74, 0x3b, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x36, 0x70, 0x78, + 0x20, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, 0x2d, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x34, 0x32, + 0x38, 0x35, 0x37, 0x31, 0x34, 0x33, 0x3b, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x33, 0x33, 0x37, 0x61, 0x62, 0x37, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, + 0x6c, 0x69, 0x64, 0x20, 0x23, 0x64, 0x64, 0x64, 0x3b, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x2d, + 0x31, 0x70, 0x78, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3a, 0x66, 0x69, 0x72, + 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x61, 0x2c, + 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3e, 0x6c, 0x69, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x7b, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x30, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, + 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x72, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x34, 0x70, 0x78, 0x3b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, + 0x34, 0x70, 0x78, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3a, 0x6c, 0x61, 0x73, + 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x61, 0x2c, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, + 0x6c, 0x69, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, + 0x73, 0x3a, 0x34, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x34, 0x70, 0x78, + 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, 0x61, + 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x6c, 0x69, 0x3e, + 0x73, 0x70, 0x61, 0x6e, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, + 0x7a, 0x2d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x32, 0x3b, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x33, 0x35, 0x32, 0x37, + 0x63, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, 0x65, + 0x65, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x64, 0x64, 0x7d, 0x2e, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x61, 0x2c, 0x2e, 0x70, + 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x73, 0x70, 0x61, 0x6e, + 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3e, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x61, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x3a, 0x68, + 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x3e, 0x61, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, + 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3e, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x73, 0x70, + 0x61, 0x6e, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x7a, 0x2d, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x33, 0x3b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, 0x3b, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, 0x37, 0x61, 0x62, 0x37, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x33, 0x33, 0x37, 0x61, 0x62, 0x37, 0x3b, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x64, 0x65, 0x66, 0x61, 0x75, + 0x6c, 0x74, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x2c, 0x2e, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x73, 0x70, 0x61, + 0x6e, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x73, 0x70, 0x61, + 0x6e, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x2c, 0x2e, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x2c, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, + 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, + 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x2e, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x3e, 0x61, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x37, 0x37, 0x37, 0x3b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x66, 0x66, 0x66, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x64, 0x64, 0x3b, + 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x6e, 0x6f, 0x74, 0x2d, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x7d, 0x2e, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6c, 0x67, + 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6c, 0x67, 0x3e, 0x6c, + 0x69, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x7b, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x3a, 0x31, 0x30, 0x70, 0x78, 0x20, 0x31, 0x36, + 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x31, 0x38, 0x70, 0x78, 0x3b, 0x6c, 0x69, 0x6e, 0x65, + 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x31, 0x2e, 0x33, + 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x7d, 0x2e, 0x70, 0x61, 0x67, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6c, 0x67, 0x3e, + 0x6c, 0x69, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x3e, 0x61, 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6c, 0x67, 0x3e, 0x6c, + 0x69, 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x7b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, + 0x3a, 0x36, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x72, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x36, 0x70, 0x78, 0x7d, 0x2e, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, + 0x6c, 0x67, 0x3e, 0x6c, 0x69, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x3e, 0x61, 0x2c, 0x2e, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6c, 0x67, + 0x3e, 0x6c, 0x69, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x7b, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, + 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x72, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x3a, 0x36, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x36, 0x70, + 0x78, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2d, 0x73, 0x6d, 0x3e, 0x6c, 0x69, 0x3e, 0x61, 0x2c, + 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2d, 0x73, 0x6d, 0x3e, 0x6c, 0x69, 0x3e, 0x73, 0x70, 0x61, 0x6e, + 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x35, 0x70, + 0x78, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x66, 0x6f, 0x6e, 0x74, + 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x31, 0x32, 0x70, 0x78, 0x3b, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x31, 0x2e, 0x35, 0x7d, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x6d, 0x3e, 0x6c, 0x69, + 0x3a, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x3e, 0x61, 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x6d, 0x3e, 0x6c, 0x69, 0x3a, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x33, + 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, + 0x6f, 0x70, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x72, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x3a, 0x33, 0x70, 0x78, 0x7d, 0x2e, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x6d, + 0x3e, 0x6c, 0x69, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x3e, 0x61, 0x2c, 0x2e, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x73, 0x6d, 0x3e, 0x6c, + 0x69, 0x3a, 0x6c, 0x61, 0x73, 0x74, 0x2d, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x3e, 0x73, 0x70, 0x61, 0x6e, 0x7b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, + 0x3a, 0x33, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, + 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x33, 0x70, 0x78, 0x7d, + 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x3b, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x2e, 0x32, 0x65, + 0x6d, 0x20, 0x2e, 0x36, 0x65, 0x6d, 0x20, 0x2e, 0x33, 0x65, 0x6d, + 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x37, 0x35, 0x25, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, 0x6c, 0x64, 0x3b, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x31, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, + 0x66, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x3a, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x77, 0x68, + 0x69, 0x74, 0x65, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, 0x6e, + 0x6f, 0x77, 0x72, 0x61, 0x70, 0x3b, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x2d, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x62, + 0x61, 0x73, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x3b, 0x62, 0x6f, 0x72, + 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, + 0x2e, 0x32, 0x35, 0x65, 0x6d, 0x7d, 0x61, 0x2e, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x61, 0x2e, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, + 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x66, 0x66, + 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x64, 0x65, 0x63, 0x6f, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, + 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x3a, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3a, + 0x65, 0x6d, 0x70, 0x74, 0x79, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x7d, 0x2e, 0x62, 0x74, + 0x6e, 0x20, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7b, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x76, 0x65, 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x2d, 0x31, + 0x70, 0x78, 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x64, + 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x7b, 0x62, 0x61, 0x63, 0x6b, + 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x23, 0x37, 0x37, 0x37, 0x7d, 0x2e, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x2d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5b, + 0x68, 0x72, 0x65, 0x66, 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x2c, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x5b, 0x68, 0x72, 0x65, 0x66, 0x5d, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x35, 0x65, 0x35, 0x65, 0x35, 0x65, 0x7d, 0x2e, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, + 0x79, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x33, + 0x37, 0x61, 0x62, 0x37, 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, 0x72, 0x79, 0x5b, 0x68, 0x72, + 0x65, 0x66, 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x70, 0x72, 0x69, 0x6d, 0x61, + 0x72, 0x79, 0x5b, 0x68, 0x72, 0x65, 0x66, 0x5d, 0x3a, 0x66, 0x6f, + 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x32, 0x38, 0x36, 0x30, 0x39, 0x30, 0x7d, 0x2e, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x35, 0x63, 0x62, 0x38, + 0x35, 0x63, 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5b, 0x68, 0x72, 0x65, 0x66, + 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5b, 0x68, 0x72, 0x65, 0x66, 0x5d, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x34, 0x34, + 0x39, 0x64, 0x34, 0x34, 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x35, 0x62, 0x63, 0x30, 0x64, 0x65, 0x7d, 0x2e, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x5b, 0x68, + 0x72, 0x65, 0x66, 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, + 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x5b, 0x68, 0x72, 0x65, 0x66, 0x5d, 0x3a, 0x66, 0x6f, 0x63, 0x75, + 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x31, + 0x62, 0x30, 0x64, 0x35, 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x7b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x30, 0x61, 0x64, 0x34, 0x65, + 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x5b, 0x68, 0x72, 0x65, 0x66, 0x5d, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x2c, 0x2e, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x5b, 0x68, + 0x72, 0x65, 0x66, 0x5d, 0x3a, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, 0x63, 0x39, 0x37, + 0x31, 0x66, 0x7d, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x64, + 0x61, 0x6e, 0x67, 0x65, 0x72, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x64, 0x39, 0x35, 0x33, 0x34, 0x66, 0x7d, 0x2e, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x5b, 0x68, 0x72, 0x65, 0x66, 0x5d, 0x3a, 0x68, 0x6f, 0x76, 0x65, + 0x72, 0x2c, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2d, 0x64, 0x61, + 0x6e, 0x67, 0x65, 0x72, 0x5b, 0x68, 0x72, 0x65, 0x66, 0x5d, 0x3a, + 0x66, 0x6f, 0x63, 0x75, 0x73, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x63, 0x39, 0x33, 0x30, 0x32, 0x63, 0x7d, 0x2e, 0x61, + 0x6c, 0x65, 0x72, 0x74, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x3a, 0x31, 0x35, 0x70, 0x78, 0x3b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x32, + 0x30, 0x70, 0x78, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, + 0x31, 0x70, 0x78, 0x20, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x20, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x3a, 0x34, 0x70, 0x78, 0x7d, 0x2e, 0x61, 0x6c, 0x65, + 0x72, 0x74, 0x20, 0x68, 0x34, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x30, 0x3b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x69, 0x74, 0x7d, + 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x20, 0x2e, 0x61, 0x6c, 0x65, + 0x72, 0x74, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x7b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x6f, + 0x6c, 0x64, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x3e, 0x70, + 0x2c, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x3e, 0x75, 0x6c, 0x7b, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3a, 0x30, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, + 0x3e, 0x70, 0x2b, 0x70, 0x7b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x35, 0x70, 0x78, 0x7d, 0x2e, 0x61, + 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x64, 0x69, 0x73, 0x6d, 0x69, 0x73, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x2e, 0x61, 0x6c, 0x65, 0x72, + 0x74, 0x2d, 0x64, 0x69, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x62, + 0x6c, 0x65, 0x7b, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2d, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x33, 0x35, 0x70, 0x78, 0x7d, + 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x64, 0x69, 0x73, 0x6d, + 0x69, 0x73, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x2e, 0x63, 0x6c, + 0x6f, 0x73, 0x65, 0x2c, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, + 0x64, 0x69, 0x73, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x20, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x7b, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x3b, 0x74, 0x6f, 0x70, 0x3a, 0x2d, 0x32, 0x70, + 0x78, 0x3b, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x2d, 0x32, 0x31, + 0x70, 0x78, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x69, 0x6e, + 0x68, 0x65, 0x72, 0x69, 0x74, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, + 0x74, 0x2d, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x7b, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x66, 0x66, 0x30, 0x64, + 0x38, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x36, 0x65, 0x39, 0x63, 0x36, + 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, 0x63, 0x37, + 0x36, 0x33, 0x64, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x68, 0x72, 0x7b, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x63, 0x39, 0x65, 0x32, + 0x62, 0x33, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x2e, 0x61, 0x6c, 0x65, + 0x72, 0x74, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x7b, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x23, 0x32, 0x62, 0x35, 0x34, 0x32, 0x63, 0x7d, + 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x69, 0x6e, 0x66, 0x6f, + 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x64, 0x39, 0x65, + 0x64, 0x66, 0x37, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x62, 0x63, 0x65, 0x38, + 0x66, 0x31, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x33, + 0x31, 0x37, 0x30, 0x38, 0x66, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, + 0x74, 0x2d, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x68, 0x72, 0x7b, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x61, 0x36, 0x65, 0x31, 0x65, + 0x63, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x69, 0x6e, + 0x66, 0x6f, 0x20, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x6c, + 0x69, 0x6e, 0x6b, 0x7b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x32, 0x34, 0x35, 0x32, 0x36, 0x39, 0x7d, 0x2e, 0x61, 0x6c, 0x65, + 0x72, 0x74, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x7b, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x63, 0x66, 0x38, + 0x65, 0x33, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x61, 0x65, 0x62, 0x63, + 0x63, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x38, 0x61, + 0x36, 0x64, 0x33, 0x62, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, + 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x72, + 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x74, 0x6f, 0x70, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x66, 0x37, 0x65, + 0x31, 0x62, 0x35, 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, + 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x2e, 0x61, 0x6c, + 0x65, 0x72, 0x74, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x7b, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x36, 0x36, 0x35, 0x31, 0x32, 0x63, + 0x7d, 0x2e, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x64, 0x61, 0x6e, + 0x67, 0x65, 0x72, 0x7b, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x66, 0x32, 0x64, 0x65, 0x64, 0x65, 0x3b, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x65, + 0x62, 0x63, 0x63, 0x64, 0x31, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x23, 0x61, 0x39, 0x34, 0x34, 0x34, 0x32, 0x7d, 0x2e, 0x61, + 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, + 0x20, 0x68, 0x72, 0x7b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x74, 0x6f, 0x70, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, + 0x65, 0x34, 0x62, 0x39, 0x63, 0x30, 0x7d, 0x2e, 0x61, 0x6c, 0x65, + 0x72, 0x74, 0x2d, 0x64, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x20, 0x2e, + 0x61, 0x6c, 0x65, 0x72, 0x74, 0x2d, 0x6c, 0x69, 0x6e, 0x6b, 0x7b, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x23, 0x38, 0x34, 0x33, 0x35, + 0x33, 0x34, 0x7d, 0x2e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, + 0x78, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x2e, 0x63, + 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, 0x3a, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x6c, 0x2d, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x64, 0x64, 0x3a, 0x62, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x2e, 0x64, 0x6c, 0x2d, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x64, + 0x64, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2d, 0x66, + 0x6c, 0x75, 0x69, 0x64, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x3a, 0x61, 0x66, 0x74, 0x65, + 0x72, 0x2c, 0x2e, 0x72, 0x6f, 0x77, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x2c, 0x2e, 0x72, 0x6f, 0x77, 0x3a, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x68, 0x6f, + 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x3a, 0x62, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, + 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x7b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x20, 0x22, 0x3b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x7d, 0x2e, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, 0x78, 0x3a, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x2e, 0x64, 0x6c, 0x2d, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x64, + 0x64, 0x3a, 0x61, 0x66, 0x74, 0x65, 0x72, 0x2c, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x3a, 0x61, 0x66, 0x74, + 0x65, 0x72, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x2d, 0x66, 0x6c, 0x75, 0x69, 0x64, 0x3a, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x2c, 0x2e, 0x72, 0x6f, 0x77, 0x3a, 0x61, 0x66, + 0x74, 0x65, 0x72, 0x2c, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x20, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x3a, + 0x61, 0x66, 0x74, 0x65, 0x72, 0x7b, 0x63, 0x6c, 0x65, 0x61, 0x72, + 0x3a, 0x62, 0x6f, 0x74, 0x68, 0x7d, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, + 0x74, 0x3a, 0x61, 0x75, 0x74, 0x6f, 0x3b, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x61, 0x75, + 0x74, 0x6f, 0x7d, 0x2e, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x7b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x2e, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x7b, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3a, + 0x6c, 0x65, 0x66, 0x74, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x2e, 0x68, 0x69, 0x64, 0x65, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x2e, 0x73, 0x68, 0x6f, 0x77, 0x7b, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, + 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, + 0x2e, 0x69, 0x6e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x7b, + 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x3a, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x7d, 0x2e, 0x74, 0x65, 0x78, + 0x74, 0x2d, 0x68, 0x69, 0x64, 0x65, 0x7b, 0x66, 0x6f, 0x6e, 0x74, + 0x3a, 0x30, 0x2f, 0x30, 0x20, 0x61, 0x3b, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x73, 0x68, 0x61, + 0x64, 0x6f, 0x77, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x30, 0x7d, 0x2e, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x2e, 0x61, 0x66, 0x66, 0x69, 0x78, 0x7b, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x66, 0x69, 0x78, 0x65, + 0x64, 0x7d, 0x40, 0x2d, 0x6d, 0x73, 0x2d, 0x76, 0x69, 0x65, 0x77, + 0x70, 0x6f, 0x72, 0x74, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x7d, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, + 0x78, 0x73, 0x2c, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x2d, 0x73, 0x6d, 0x2c, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x6d, 0x64, 0x2c, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x6c, 0x65, 0x2d, 0x6c, 0x67, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x2e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x78, 0x73, 0x2d, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2c, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x78, 0x73, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x2c, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x78, + 0x73, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x2c, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x73, 0x6d, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x73, 0x6d, + 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x73, 0x6d, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6d, 0x64, + 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x2e, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6d, 0x64, 0x2d, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x2c, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x6d, 0x64, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2c, 0x2e, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6c, 0x67, 0x2d, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2c, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x2d, 0x6c, 0x67, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2c, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6c, 0x67, + 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x37, 0x36, 0x37, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x78, 0x73, 0x7b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x7d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x2d, 0x78, 0x73, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x21, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x74, + 0x72, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x78, + 0x73, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x6f, 0x77, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x74, 0x68, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x78, 0x73, + 0x2c, 0x74, 0x64, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x2d, 0x78, 0x73, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6c, 0x6c, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, + 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, + 0x37, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x6c, 0x65, 0x2d, 0x78, 0x73, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x37, 0x36, 0x37, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x78, 0x73, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, 0x37, 0x70, 0x78, + 0x29, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, + 0x78, 0x73, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x39, 0x39, 0x31, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x73, 0x6d, 0x7b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x7d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x2d, 0x73, 0x6d, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x21, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x74, + 0x72, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x73, + 0x6d, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x6f, 0x77, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x74, 0x68, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x73, 0x6d, + 0x2c, 0x74, 0x64, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x2d, 0x73, 0x6d, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6c, 0x6c, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, + 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, + 0x38, 0x70, 0x78, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x6d, + 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, 0x39, + 0x31, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x6c, 0x65, 0x2d, 0x73, 0x6d, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x39, 0x39, 0x31, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x73, 0x6d, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, + 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, 0x39, 0x31, 0x70, 0x78, + 0x29, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, + 0x73, 0x6d, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, + 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x39, 0x39, 0x32, 0x70, 0x78, 0x29, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x31, 0x31, 0x39, 0x39, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, + 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6d, 0x64, 0x7b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6d, 0x64, 0x7b, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, + 0x74, 0x72, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, + 0x6d, 0x64, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x6f, 0x77, 0x20, 0x21, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x74, + 0x68, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6d, + 0x64, 0x2c, 0x74, 0x64, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x6d, 0x64, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6c, + 0x6c, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, + 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, + 0x39, 0x32, 0x70, 0x78, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, + 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, + 0x31, 0x39, 0x39, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6d, 0x64, 0x2d, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x39, 0x39, 0x32, 0x70, 0x78, 0x29, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x31, 0x31, 0x39, 0x39, 0x70, 0x78, 0x29, 0x7b, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6d, 0x64, + 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x7b, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, + 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, 0x39, + 0x32, 0x70, 0x78, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, 0x6d, + 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x31, + 0x39, 0x39, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x2d, 0x6d, 0x64, 0x2d, 0x69, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, 0x6e, + 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, + 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x32, 0x30, 0x30, 0x70, 0x78, + 0x29, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, + 0x6c, 0x67, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6c, 0x67, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x6e, 0x74, 0x7d, 0x74, 0x72, 0x2e, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x2d, 0x6c, 0x67, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, + 0x6f, 0x77, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, + 0x6e, 0x74, 0x7d, 0x74, 0x68, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x6c, 0x65, 0x2d, 0x6c, 0x67, 0x2c, 0x74, 0x64, 0x2e, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6c, 0x67, 0x7b, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, + 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, + 0x74, 0x68, 0x3a, 0x31, 0x32, 0x30, 0x30, 0x70, 0x78, 0x29, 0x7b, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6c, 0x67, + 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x21, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, + 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, + 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x32, 0x30, 0x30, + 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x6c, 0x67, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, + 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, + 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3a, 0x31, 0x32, 0x30, 0x30, 0x70, 0x78, 0x29, 0x7b, 0x2e, + 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x6c, 0x67, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, + 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, + 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, + 0x37, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x68, 0x69, 0x64, 0x64, 0x65, + 0x6e, 0x2d, 0x78, 0x73, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, + 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, + 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, + 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x37, 0x36, 0x38, 0x70, 0x78, 0x29, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x28, 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x3a, 0x39, 0x39, 0x31, 0x70, 0x78, 0x29, 0x7b, + 0x2e, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, 0x73, 0x6d, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, + 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x39, + 0x39, 0x32, 0x70, 0x78, 0x29, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x28, + 0x6d, 0x61, 0x78, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, + 0x31, 0x39, 0x39, 0x70, 0x78, 0x29, 0x7b, 0x2e, 0x68, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x2d, 0x6d, 0x64, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x28, 0x6d, 0x69, 0x6e, 0x2d, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x31, 0x32, 0x30, 0x30, 0x70, + 0x78, 0x29, 0x7b, 0x2e, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, + 0x6c, 0x67, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, + 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x2e, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x7b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, + 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, + 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, + 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x21, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x7b, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, + 0x74, 0x72, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x3a, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x6f, + 0x77, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x74, 0x68, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2c, 0x74, 0x64, 0x2e, + 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x70, 0x72, 0x69, + 0x6e, 0x74, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6c, 0x6c, 0x20, + 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, + 0x7d, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x70, + 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x2e, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, + 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x7b, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x40, 0x6d, + 0x65, 0x64, 0x69, 0x61, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x7b, + 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x2d, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, + 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, + 0x6c, 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x69, 0x6e, + 0x6c, 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7b, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x6e, 0x6f, 0x6e, + 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, + 0x74, 0x7d, 0x40, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x7b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x2d, 0x69, 0x6e, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x7b, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x69, 0x6e, 0x6c, 0x69, + 0x6e, 0x65, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x21, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x40, + 0x6d, 0x65, 0x64, 0x69, 0x61, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, + 0x7b, 0x2e, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, 0x70, 0x72, + 0x69, 0x6e, 0x74, 0x7b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x20, 0x21, 0x69, 0x6d, 0x70, 0x6f, + 0x72, 0x74, 0x61, 0x6e, 0x74, 0x7d, 0x7d, 0x00 +}; + +const int bootstrap_css_length = 51609; diff --git a/goaccess++/src/browsers.c b/goaccess++/src/browsers.c new file mode 100644 index 0000000..3985b33 --- /dev/null +++ b/goaccess++/src/browsers.c @@ -0,0 +1,522 @@ +/** + 6 browsers.c -- functions for dealing with browsers + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stddef.h> + +#include "browsers.h" + +#include "error.h" +#include "settings.h" +#include "util.h" +#include "xmalloc.h" + +/* ###NOTE: The size of the list is proportional to the run time, + * which makes this pretty slow */ + +static char ***browsers_hash = NULL; + +/* {"search string", "belongs to"} */ +static const char *browsers[][2] = { + /* Game systems: most of them are based of major browsers, + * thus they need to go before. */ + {"Xbox One", "Game Systems"}, + {"Xbox", "Game Systems"}, + {"PlayStation", "Game Systems"}, + {"NintendoBrowser", "Game Systems"}, + {"Valve Steam", "Game Systems"}, + {"Origin", "Game Systems"}, + {"Raptr", "Game Systems"}, + + /* Based on Internet Explorer */ + {"America Online Browser", "Others"}, + {"Avant Browser", "Others"}, + /* Internet Explorer */ + {"IEMobile", "MSIE"}, + {"MSIE", "MSIE"}, + /* IE11 */ + {"Trident/7.0", "MSIE"}, + /* Microsoft Edge */ + {"Edge", "MSIE"}, + + /* Opera */ + {"Opera Mini", "Opera"}, + {"Opera Mobi", "Opera"}, + {"Opera", "Opera"}, + {"OPR", "Opera"}, + {"OPiOS", "Opera"}, + {"Coast", "Opera"}, + + /* Others */ + {"Homebrew", "Others"}, + {"APT-HTTP", "Others"}, + {"Apt-Cacher", "Others"}, + {"Chef Client", "Others"}, + {"Huawei", "Others"}, + {"HUAWEI", "Others"}, + {"BlackBerry", "Others"}, + {"BrowserX", "Others"}, + {"Dalvik", "Others"}, + {"Dillo", "Others"}, + {"ELinks", "Others"}, + {"Epiphany", "Others"}, + {"Firebird", "Others"}, + {"Galeon", "Others"}, + {"google-cloud-sdk", "Others"}, + {"GranParadiso", "Others"}, + {"IBrowse", "Others"}, + {"K-Meleon", "Others"}, + {"Kazehakase", "Others"}, + {"Konqueror", "Others"}, + {"Links", "Others"}, + {"Lynx", "Others"}, + {"Midori", "Others"}, + {"Minefield", "Others"}, + {"Mosaic", "Others"}, + {"Netscape", "Others"}, + {"SeaMonkey", "Others"}, + {"UCBrowser", "Others"}, + {"Wget", "Others"}, + {"libfetch", "Others"}, + {"check_http", "Others"}, + {"Go-http-client", "Others"}, + {"curl", "Others"}, + {"midori", "Others"}, + {"w3m", "Others"}, + {"MicroMessenger", "Others"}, + {"Apache", "Others"}, + {"JOSM", "Others"}, + + /* Feed-reader-as-a-service */ + {"AppleNewsBot", "Feeds"}, + {"Bloglines", "Feeds"}, + {"Digg Feed Fetcher", "Feeds"}, + {"Feedbin", "Feeds"}, + {"FeedHQ", "Feeds"}, + {"Feedly", "Feeds"}, + {"Flipboard", "Feeds"}, + {"Netvibes", "Feeds"}, + {"NewsBlur", "Feeds"}, + {"PinRSS", "Feeds"}, + {"WordPress.com Reader", "Feeds"}, + {"YandexBlogs", "Feeds"}, + + /* Google crawlers (some based on Chrome, + * therefore up on the list) */ + {"AdsBot-Google", "Crawlers"}, + {"AppEngine-Google", "Crawlers"}, + {"Mediapartners-Google", "Crawlers"}, + {"Google", "Crawlers"}, + {"WhatsApp", "Crawlers"}, + + /* Based on Firefox */ + {"Camino", "Others"}, + /* Rebranded Firefox but is really unmodified + * Firefox (Debian trademark policy) */ + {"Iceweasel", "Firefox"}, + {"Firefox", "Firefox"}, + + /* Based on Chromium */ + {"Vivaldi", "Others"}, + {"YaBrowser", "Others"}, + {"Flock", "Others"}, + /* Chrome has to go before Safari */ + {"HeadlessChrome", "Chrome"}, + {"Chrome", "Chrome"}, + {"CriOS", "Chrome"}, + + /* Crawlers/Bots (Possible Safari based) */ + {"AppleBot", "Crawlers"}, + {"Twitter", "Crawlers"}, + + {"Safari", "Safari"}, + + /* Crawlers/Bots */ + {"Sogou", "Crawlers"}, + {"Java", "Crawlers"}, + {"Jakarta Commons-HttpClient", "Crawlers"}, + {"netEstate", "Crawlers"}, + {"PiplBot", "Crawlers"}, + {"IstellaBot", "Crawlers"}, + {"heritrix", "Crawlers"}, + {"PagesInventory", "Crawlers"}, + {"rogerbot", "Crawlers"}, + {"fastbot", "Crawlers"}, + {"yacybot", "Crawlers"}, + {"PycURL", "Crawlers"}, + {"PHP", "Crawlers"}, + {"AndroidDownloadManager", "Crawlers"}, + {"Embedly", "Crawlers"}, + {"ruby", "Crawlers"}, + {"Ruby", "Crawlers"}, + {"python", "Crawlers"}, + {"Python", "Crawlers"}, + {"LinkedIn", "Crawlers"}, + {"Microsoft-WebDAV", "Crawlers"}, + + /* Podcast fetchers */ + {"Downcast", "Podcasts"}, + {"gPodder", "Podcasts"}, + {"Instacast", "Podcasts"}, + {"iTunes", "Podcasts"}, + {"Miro", "Podcasts"}, + {"Pocket Casts", "Podcasts"}, + {"BashPodder", "Podcasts"}, + + /* Feed reader clients */ + {"Akregator", "Feeds"}, + {"Apple-PubSub", "Feeds"}, + {"com.apple.Safari.WebFeedParser", "Feeds"}, + {"FeedDemon", "Feeds"}, + {"Feedy", "Feeds"}, + {"Liferea", "Feeds"}, + {"NetNewsWire", "Feeds"}, + {"RSSOwl", "Feeds"}, + {"Thunderbird", "Feeds"}, + + {"Pingdom.com", "Uptime"}, + {"jetmon", "Uptime"}, + {"NodeUptime", "Uptime"}, + {"NewRelicPinger", "Uptime"}, + {"StatusCake", "Uptime"}, + {"internetVista", "Uptime"}, + {"Server Density Service Monitoring v2", "Uptime"}, + + {"Mozilla", "Others"} +}; + +/* Free all browser entries from our array of key/value pairs. */ +void +free_browsers_hash (void) +{ + size_t i; + int j; + + for (i = 0; i < ARRAY_SIZE (browsers); ++i) { + free (browsers_hash[i][0]); + free (browsers_hash[i][1]); + free (browsers_hash[i]); + } + free (browsers_hash); + + + for (j = 0; j < conf.browsers_hash_idx; ++j) { + free (conf.user_browsers_hash[j][0]); + free (conf.user_browsers_hash[j][1]); + free (conf.user_browsers_hash[j]); + } + if (conf.browsers_file) { + free (conf.user_browsers_hash); + } +} + +static int +is_dup (char ***list, int len, const char *browser) +{ + int i; + /* check for dups */ + for (i = 0; i < len; ++i) { + if (strcmp (browser, list[i][0]) == 0) + return 1; + } + return 0; +} + +/* Set a browser/type pair into our multidimensional array of browsers. + * + * On duplicate functions returns void. + * Otherwise memory is mallo'd for our array entry. */ +static void +set_browser (char ***list, int idx, const char *browser, const char *type) +{ + list[idx] = xcalloc (2, sizeof (char *)); + list[idx][0] = xstrdup (browser); + list[idx][1] = xstrdup (type); +} + +/* Parse the key/value pair from the browser list file. */ +static void +parse_browser_token (char ***list, char *line, int n) +{ + char *val; + size_t idx = 0; + + /* key */ + idx = strcspn (line, "\t"); + if (strlen (line) == idx) + FATAL ("Malformed browser name at line: %d", n); + + line[idx] = '\0'; + + /* value */ + val = line + (idx + 1); + idx = strspn (val, "\t"); + if (strlen (val) == idx) + FATAL ("Malformed browser category at line: %d", n); + val = val + idx; + val = trim_str (val); + + if (is_dup (list, conf.browsers_hash_idx, line)) { + LOG_INVALID (("Duplicate browser entry: %s", line)); + return; + } + + set_browser (list, conf.browsers_hash_idx, line, val); + conf.browsers_hash_idx++; +} + +/* Parse our default array of browsers and put them on our hash including those + * from the custom parsed browsers file. + * + * On error functions returns void. + * Otherwise browser entries are put into the hash. */ +void +parse_browsers_file (void) +{ + char line[MAX_LINE_BROWSERS + 1]; + FILE *file; + int n = 0; + size_t i, len = ARRAY_SIZE (browsers); + + browsers_hash = xmalloc (ARRAY_SIZE (browsers) * sizeof (char **)); + /* load hash from the browser's array (default) */ + for (i = 0; i < len; ++i) { + set_browser (browsers_hash, i, browsers[i][0], browsers[i][1]); + } + + if (!conf.browsers_file) + return; + + /* could not open browsers file */ + if ((file = fopen (conf.browsers_file, "r")) == NULL) + FATAL ("Unable to open browser's file: %s", strerror (errno)); + + conf.user_browsers_hash = xmalloc (MAX_CUSTOM_BROWSERS * sizeof (char **)); + /* load hash from the user's given browsers file */ + while (fgets (line, sizeof line, file) != NULL) { + while (line[0] == ' ' || line[0] == '\t') + memmove (line, line + 1, strlen (line)); + n++; + + if (line[0] == '\n' || line[0] == '\r' || line[0] == '#') + continue; + if (conf.browsers_hash_idx >= MAX_CUSTOM_BROWSERS) + FATAL ("Maximum number of custom browsers has been reached"); + parse_browser_token (conf.user_browsers_hash, line, n); + } + fclose (file); +} + +/* Determine if the user-agent is a crawler. + * + * On error or is not a crawler, 0 is returned. + * If it is a crawler, 1 is returned . */ +int +is_crawler (const char *agent) +{ + char type[BROWSER_TYPE_LEN]; + char *browser, *a; + + if (agent == NULL || *agent == '\0') + return 0; + + if ((a = xstrdup (agent), browser = verify_browser (a, type)) != NULL) + free (browser); + free (a); + + return strcmp (type, "Crawlers") == 0 ? 1 : 0; +} + +/* Return the Opera 15 and beyond. + * + * On success, the opera string and version is returned. */ +static char * +parse_opera (char *token) +{ + char *val = xmalloc (snprintf (NULL, 0, "Opera%s", token) + 1); + sprintf (val, "Opera%s", token); + + return val; +} + +/* Given the original user agent string, and a partial crawler match, iterate + * back until the next delimiter is found and return occurrence. + * + * On error when attempting to extract crawler, NULL is returned. + * If a possible crawler string is matched, then possible bot is returned . */ +static char * +parse_crawler (char *str, char *match, char *type) +{ + char *ptr = NULL; + int found = 0; + + while (match != str) { + match--; + if (*match == ' ' || *match == '+') { + found = 1; + break; + } + } + + /* same addr */ + if (match == str) + return NULL; + + /* account for the previous +|space */ + if (found) + match++; + + if ((ptr = strpbrk (match, "; "))) + *ptr = '\0'; + /* empty string after parsing it */ + if (*match == '\0') + return NULL; + + xstrncpy (type, "Crawlers", BROWSER_TYPE_LEN); + + return xstrdup (match); +} + +/* If the following string matches are found within user agent, then it's + * highly likely it's a possible crawler. + * Note that this could certainly return false positives. + * + * If no occurrences are found, NULL is returned. + * If an occurrence is found, a pointer to the match is returned . */ +static char * +check_http_crawler (const char *str) +{ + char *match = NULL; + + /* e.g., compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm */ + if ((match = strstr (str, "; +http"))) + return match; + /* compatible; UptimeRobot/2.0; http://www.uptimerobot.com/ */ + if ((match = strstr (str, "; http"))) + return match; + /* Slack-ImgProxy (+https://api.slack.com/robots) */ + if ((match = strstr (str, " (+http"))) + return match; + /* TurnitinBot/3.0 (http://www.turnitin.com/robot/crawlerinfo.html) */ + if ((match = strstr (str, " (http"))) + return match; + /* w3c e.g., (compatible;+Googlebot/2.1;++http://www.google.com/bot.html) */ + if ((match = strstr (str, ";++http"))) + return match; + return NULL; +} + +/* Parse the given user agent match and extract the browser string. + * + * If no match, the original match is returned. + * Otherwise the parsed browser is returned. */ +static char * +parse_browser (char *match, char *type, int i, char ***hash) +{ + char *b = NULL, *ptr = NULL, *slh = NULL; + size_t cnt = 0, space = 0; + + /* Check if there are spaces in the token string, that way strpbrk + * does not stop at the first space within the token string */ + if ((cnt = count_matches (hash[i][0], ' ')) && (b = match)) { + while (space++ < cnt && (b = strchr (b, ' '))) + b++; + } else + b = match; + + xstrncpy (type, hash[i][1], BROWSER_TYPE_LEN); + /* Internet Explorer 11 */ + if (strstr (match, "rv:11") && strstr (match, "Trident/7.0")) { + return alloc_string ("MSIE/11.0"); + } + /* Opera +15 uses OPR/# */ + if (strstr (match, "OPR") != NULL && (slh = strrchr (match, '/'))) { + return parse_opera (slh); + } + /* Opera has the version number at the end */ + if (strstr (match, "Opera") && (slh = strrchr (match, '/')) && match < slh) { + memmove (match + 5, slh, strlen (slh) + 1); + } + /* IE Old */ + if (strstr (match, "MSIE") != NULL) { + if ((ptr = strpbrk (match, ";)-")) != NULL) + *ptr = '\0'; + match = char_replace (match, ' ', '/'); + } + /* all others */ + else if ((ptr = strpbrk (b, ";) ")) != NULL) { + *ptr = '\0'; + } + + return alloc_string (match); +} + +/* Given a user agent, determine the browser used. + * + * ###NOTE: The size of the list is proportional to the run time, + * which makes this pretty slow + * + * On error, NULL is returned. + * On success, a malloc'd string containing the browser is returned. */ +char * +verify_browser (char *str, char *type) +{ + char *match = NULL, *token = NULL; + int i = 0; + size_t j = 0; + + if (str == NULL || *str == '\0') + return NULL; + + /* check user's list */ + for (i = 0; i < conf.browsers_hash_idx; ++i) { + if ((match = strstr (str, conf.user_browsers_hash[i][0])) == NULL) + continue; + return parse_browser (match, type, i, conf.user_browsers_hash); + } + + if ((match = check_http_crawler (str)) && + (token = parse_crawler (str, match, type))) + return token; + + /* fallback to default browser list */ + for (j = 0; j < ARRAY_SIZE (browsers); ++j) { + if ((match = strstr (str, browsers_hash[j][0])) == NULL) + continue; + return parse_browser (match, type, j, browsers_hash); + } + + xstrncpy (type, "Unknown", BROWSER_TYPE_LEN); + + return alloc_string ("Unknown"); +} diff --git a/goaccess++/src/browsers.h b/goaccess++/src/browsers.h new file mode 100644 index 0000000..959999b --- /dev/null +++ b/goaccess++/src/browsers.h @@ -0,0 +1,49 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef BROWSERS_H_INCLUDED +#define BROWSERS_H_INCLUDED + +#define BROWSER_TYPE_LEN 13 +#define MAX_LINE_BROWSERS 128 +#define MAX_CUSTOM_BROWSERS 256 + +/* Each Browser contains the number of hits and the Browser's type */ +typedef struct GBrowser_ +{ + char browser_type[BROWSER_TYPE_LEN]; + int hits; +} GBrowser; + +char *verify_browser (char *str, char *browser_type); +int is_crawler (const char *agent); +void free_browsers_hash (void); +void parse_browsers_file (void); + +#endif diff --git a/goaccess++/src/browsers.o b/goaccess++/src/browsers.o new file mode 100644 index 0000000..59e5840 Binary files /dev/null and b/goaccess++/src/browsers.o differ diff --git a/goaccess++/src/chartsjs.h b/goaccess++/src/chartsjs.h new file mode 100644 index 0000000..1f201e1 --- /dev/null +++ b/goaccess++/src/chartsjs.h @@ -0,0 +1,1861 @@ +const char charts_js[20421] = { + 0x2f, 0x2a, 0x2a, 0x2a, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x5f, 0x5f, + 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5f, 0x5f, + 0x5f, 0x2a, 0x20, 0x20, 0x20, 0x2f, 0x20, 0x5f, 0x5f, 0x5f, 0x5f, + 0x2f, 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x2f, 0x20, 0x20, 0x20, 0x7c, + 0x20, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, + 0x5f, 0x5f, 0x5f, 0x20, 0x20, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, + 0x5f, 0x5f, 0x5f, 0x5f, 0x2a, 0x20, 0x20, 0x2f, 0x20, 0x2f, 0x20, + 0x5f, 0x5f, 0x2f, 0x20, 0x5f, 0x5f, 0x20, 0x5c, 0x2f, 0x20, 0x2f, + 0x7c, 0x20, 0x7c, 0x2f, 0x20, 0x5f, 0x5f, 0x5f, 0x2f, 0x20, 0x5f, + 0x5f, 0x5f, 0x2f, 0x20, 0x5f, 0x20, 0x5c, 0x2f, 0x20, 0x5f, 0x5f, + 0x5f, 0x2f, 0x20, 0x5f, 0x5f, 0x5f, 0x2f, 0x2a, 0x20, 0x2f, 0x20, + 0x2f, 0x5f, 0x2f, 0x20, 0x2f, 0x20, 0x2f, 0x5f, 0x2f, 0x20, 0x2f, + 0x20, 0x5f, 0x5f, 0x5f, 0x20, 0x2f, 0x20, 0x2f, 0x5f, 0x5f, 0x2f, + 0x20, 0x2f, 0x5f, 0x5f, 0x2f, 0x20, 0x20, 0x5f, 0x5f, 0x28, 0x5f, + 0x5f, 0x20, 0x20, 0x7c, 0x5f, 0x5f, 0x20, 0x20, 0x29, 0x2a, 0x20, + 0x5c, 0x5f, 0x5f, 0x5f, 0x5f, 0x2f, 0x5c, 0x5f, 0x5f, 0x5f, 0x5f, + 0x2f, 0x5f, 0x2f, 0x20, 0x20, 0x7c, 0x5f, 0x5c, 0x5f, 0x5f, 0x5f, + 0x2f, 0x5c, 0x5f, 0x5f, 0x5f, 0x2f, 0x5c, 0x5f, 0x5f, 0x5f, 0x2f, + 0x5f, 0x5f, 0x5f, 0x5f, 0x2f, 0x5f, 0x5f, 0x5f, 0x5f, 0x2f, 0x2a, + 0x2a, 0x20, 0x54, 0x68, 0x65, 0x20, 0x4d, 0x49, 0x54, 0x20, 0x4c, + 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x28, 0x4d, 0x49, 0x54, + 0x29, 0x2a, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30, 0x30, 0x39, 0x2d, + 0x32, 0x30, 0x31, 0x38, 0x20, 0x47, 0x65, 0x72, 0x61, 0x72, 0x64, + 0x6f, 0x20, 0x4f, 0x72, 0x65, 0x6c, 0x6c, 0x61, 0x6e, 0x61, 0x20, + 0x3c, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x40, 0x20, 0x67, 0x6f, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x69, 0x6f, 0x3e, 0x2a, + 0x2f, 0x27, 0x75, 0x73, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x63, + 0x74, 0x27, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x28, 0x74, + 0x65, 0x78, 0x74, 0x2c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, + 0x20, 0x7b, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x65, 0x61, 0x63, 0x68, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2c, 0x20, + 0x24, 0x64, 0x33, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x20, 0x3d, + 0x20, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x67, 0x77, 0x20, 0x3d, 0x20, 0x24, 0x64, 0x33, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x29, + 0x2e, 0x67, 0x65, 0x74, 0x42, 0x42, 0x6f, 0x78, 0x28, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x67, 0x77, 0x2e, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x29, 0x20, 0x2f, 0x20, 0x32, 0x29, 0x20, 0x2a, 0x20, 0x2d, 0x31, + 0x3b, 0x69, 0x66, 0x20, 0x28, 0x27, 0x73, 0x76, 0x67, 0x27, 0x20, + 0x3d, 0x3d, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x20, 0x7b, 0x24, + 0x64, 0x33, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x77, 0x69, 0x64, 0x74, 0x68, 0x27, 0x2c, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x78, 0x29, 0x3b, 0x7d, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x24, 0x64, 0x33, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, + 0x28, 0x27, 0x73, 0x76, 0x67, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x3b, + 0x7d, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x77, 0x72, 0x61, 0x70, + 0x2d, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x77, 0x69, 0x64, 0x74, 0x68, 0x27, 0x2c, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x78, 0x29, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x3b, 0x7d, 0x2e, 0x62, + 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, + 0x7d, 0x7d, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x41, 0x72, 0x65, 0x61, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x28, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x70, 0x74, 0x73, + 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6d, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x7b, 0x74, 0x6f, + 0x70, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x32, 0x30, 0x2c, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x20, 0x3a, 0x20, 0x35, 0x30, 0x2c, + 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x3a, 0x20, 0x34, 0x30, + 0x2c, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x35, + 0x30, 0x2c, 0x7d, 0x2c, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, + 0x3d, 0x20, 0x31, 0x37, 0x30, 0x2c, 0x6e, 0x54, 0x69, 0x63, 0x6b, + 0x73, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x2c, 0x70, 0x61, 0x64, 0x64, + 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x2c, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x37, 0x36, 0x30, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x20, 0x3d, + 0x20, 0x7b, 0x20, 0x78, 0x3a, 0x20, 0x27, 0x55, 0x6e, 0x6e, 0x61, + 0x6d, 0x65, 0x64, 0x27, 0x2c, 0x20, 0x79, 0x30, 0x3a, 0x20, 0x27, + 0x55, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x27, 0x2c, 0x20, 0x79, + 0x31, 0x3a, 0x20, 0x27, 0x55, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x64, + 0x27, 0x20, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x20, 0x78, 0x3a, 0x20, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x20, 0x79, 0x30, 0x3a, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x20, 0x79, 0x31, 0x3a, 0x20, 0x6e, 0x75, + 0x6c, 0x6c, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x78, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x5b, 0x30, 0x5d, 0x3b, 0x7d, + 0x2c, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x30, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, + 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, + 0x5b, 0x31, 0x5d, 0x3b, 0x7d, 0x2c, 0x79, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x31, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x64, 0x5b, 0x32, 0x5d, 0x3b, 0x7d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x20, + 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x28, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x20, + 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x28, 0x29, 0x2e, 0x6e, 0x69, + 0x63, 0x65, 0x28, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x79, 0x53, + 0x63, 0x61, 0x6c, 0x65, 0x31, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x61, + 0x72, 0x28, 0x29, 0x2e, 0x6e, 0x69, 0x63, 0x65, 0x28, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x78, 0x41, 0x78, 0x69, 0x73, 0x20, 0x3d, + 0x20, 0x64, 0x33, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, 0x78, 0x69, + 0x73, 0x28, 0x29, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x78, + 0x53, 0x63, 0x61, 0x6c, 0x65, 0x29, 0x2e, 0x6f, 0x72, 0x69, 0x65, + 0x6e, 0x74, 0x28, 0x27, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x27, + 0x29, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x64, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x78, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x28, 0x64, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x2e, 0x78, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x64, 0x3b, 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x79, 0x41, 0x78, 0x69, 0x73, 0x30, 0x20, 0x3d, 0x20, 0x64, 0x33, + 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x28, 0x29, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x79, 0x53, 0x63, 0x61, + 0x6c, 0x65, 0x30, 0x29, 0x2e, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, + 0x28, 0x27, 0x6c, 0x65, 0x66, 0x74, 0x27, 0x29, 0x2e, 0x74, 0x69, + 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x33, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x27, 0x2e, 0x32, 0x73, + 0x27, 0x29, 0x28, 0x64, 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x79, 0x41, 0x78, 0x69, 0x73, 0x31, 0x20, 0x3d, 0x20, + 0x64, 0x33, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, 0x78, 0x69, 0x73, + 0x28, 0x29, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x79, 0x53, + 0x63, 0x61, 0x6c, 0x65, 0x31, 0x29, 0x2e, 0x6f, 0x72, 0x69, 0x65, + 0x6e, 0x74, 0x28, 0x27, 0x72, 0x69, 0x67, 0x68, 0x74, 0x27, 0x29, + 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x64, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x2e, 0x79, 0x31, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x28, 0x64, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x2e, 0x79, 0x31, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x64, 0x33, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x28, 0x27, 0x2e, 0x32, 0x73, 0x27, 0x29, 0x28, 0x64, 0x29, + 0x3b, 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x78, 0x47, 0x72, + 0x69, 0x64, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x76, 0x67, + 0x2e, 0x61, 0x78, 0x69, 0x73, 0x28, 0x29, 0x2e, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x28, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x29, 0x2e, + 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x62, 0x6f, 0x74, + 0x74, 0x6f, 0x6d, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x79, + 0x47, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, + 0x76, 0x67, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x28, 0x29, 0x2e, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x28, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, + 0x30, 0x29, 0x2e, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x28, 0x27, + 0x6c, 0x65, 0x66, 0x74, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x61, 0x72, 0x65, 0x61, 0x30, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, + 0x73, 0x76, 0x67, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x28, 0x29, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, + 0x28, 0x27, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x27, + 0x29, 0x2e, 0x78, 0x28, 0x58, 0x29, 0x2e, 0x79, 0x28, 0x59, 0x30, + 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x72, 0x65, 0x61, 0x31, + 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, + 0x72, 0x65, 0x61, 0x28, 0x29, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x27, 0x63, 0x61, 0x72, + 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x27, 0x29, 0x2e, 0x78, 0x28, 0x58, + 0x29, 0x2e, 0x79, 0x28, 0x59, 0x31, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x30, 0x20, 0x3d, 0x20, 0x64, 0x33, + 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x29, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, + 0x65, 0x28, 0x27, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, + 0x27, 0x29, 0x2e, 0x78, 0x28, 0x58, 0x29, 0x2e, 0x79, 0x28, 0x59, + 0x30, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x69, 0x6e, 0x65, + 0x31, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x76, 0x67, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x28, 0x29, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x27, 0x63, 0x61, + 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x27, 0x29, 0x2e, 0x78, 0x28, + 0x58, 0x29, 0x2e, 0x79, 0x28, 0x59, 0x31, 0x29, 0x3b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x58, 0x28, 0x64, 0x29, + 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, 0x53, + 0x63, 0x61, 0x6c, 0x65, 0x28, 0x64, 0x5b, 0x30, 0x5d, 0x29, 0x3b, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x59, + 0x30, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x28, 0x64, + 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x59, 0x31, 0x28, 0x64, 0x29, 0x20, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, 0x53, 0x63, 0x61, + 0x6c, 0x65, 0x31, 0x28, 0x64, 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, + 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2d, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2e, 0x6c, 0x65, 0x66, + 0x74, 0x20, 0x2d, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2e, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, + 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x2d, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2e, 0x74, 0x6f, 0x70, 0x20, 0x2d, 0x20, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2e, 0x62, 0x6f, 0x74, 0x74, + 0x6f, 0x6d, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x67, 0x65, 0x74, 0x58, 0x54, 0x69, 0x63, 0x6b, 0x73, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x20, 0x3c, 0x20, 0x6e, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, 0x53, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x33, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x30, 0x2c, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, + 0x2f, 0x20, 0x6e, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x29, 0x29, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x5b, 0x64, 0x5d, 0x3b, + 0x7d, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x67, 0x65, 0x74, 0x59, 0x54, 0x69, 0x63, 0x6b, 0x73, + 0x28, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x3d, 0x20, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x64, 0x33, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x64, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x5b, 0x31, 0x5d, 0x20, 0x2f, 0x20, 0x6e, 0x54, + 0x69, 0x63, 0x6b, 0x73, 0x29, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x70, 0x44, 0x61, + 0x74, 0x61, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x5f, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x64, 0x61, 0x74, 0x75, 0x6d, 0x20, 0x3d, 0x20, 0x5b, 0x78, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x64, + 0x61, 0x74, 0x61, 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x2c, + 0x20, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x30, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x64, 0x2c, + 0x20, 0x69, 0x29, 0x5d, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, + 0x78, 0x69, 0x73, 0x20, 0x26, 0x26, 0x20, 0x64, 0x61, 0x74, 0x75, + 0x6d, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x79, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x31, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x64, 0x61, + 0x74, 0x61, 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x75, + 0x6d, 0x3b, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, + 0x69, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x5f, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x28, 0x64, 0x2c, 0x20, 0x69, + 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, + 0x63, 0x61, 0x6c, 0x65, 0x73, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, + 0x20, 0x7b, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6d, + 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x64, 0x5b, 0x30, 0x5d, 0x3b, 0x7d, 0x29, 0x29, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, + 0x28, 0x5b, 0x30, 0x2c, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x57, + 0x28, 0x29, 0x5d, 0x2c, 0x20, 0x31, 0x29, 0x3b, 0x79, 0x53, 0x63, + 0x61, 0x6c, 0x65, 0x30, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x28, 0x5b, 0x30, 0x2c, 0x20, 0x64, 0x33, 0x2e, 0x6d, 0x61, 0x78, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x5b, 0x31, 0x5d, 0x3b, + 0x7d, 0x29, 0x5d, 0x29, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, + 0x5b, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x2c, 0x20, + 0x30, 0x5d, 0x29, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, + 0x69, 0x73, 0x20, 0x26, 0x26, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, + 0x65, 0x31, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x5b, + 0x30, 0x2c, 0x20, 0x64, 0x33, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x64, + 0x61, 0x74, 0x61, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x64, 0x5b, 0x32, 0x5d, 0x3b, 0x7d, 0x29, + 0x5d, 0x29, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x5b, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x2c, 0x20, 0x30, 0x5d, + 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, + 0x69, 0x74, 0x79, 0x28, 0x65, 0x6c, 0x65, 0x2c, 0x20, 0x6f, 0x70, + 0x29, 0x20, 0x7b, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x28, 0x65, 0x6c, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x2e, 0x27, 0x20, 0x2b, + 0x20, 0x28, 0x65, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, + 0x74, 0x61, 0x2d, 0x79, 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, 0x20, + 0x3d, 0x3d, 0x20, 0x27, 0x79, 0x30, 0x27, 0x20, 0x3f, 0x20, 0x27, + 0x79, 0x31, 0x27, 0x20, 0x3a, 0x20, 0x27, 0x79, 0x30, 0x27, 0x29, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x27, 0x2c, 0x20, 0x6f, 0x70, 0x29, 0x3b, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x74, + 0x4c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x28, 0x73, 0x76, 0x67, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x72, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x76, 0x67, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, + 0x27, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, 0x6e, + 0x64, 0x2e, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x28, 0x5b, 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, 0x3b, 0x72, 0x65, + 0x63, 0x74, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x72, 0x65, 0x63, + 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x6c, 0x65, 0x67, + 0x65, 0x6e, 0x64, 0x20, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x79, 0x61, + 0x78, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x79, 0x30, 0x27, 0x29, + 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, + 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, + 0x27, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x30, 0x2e, + 0x31, 0x27, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x6f, 0x6e, 0x28, + 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x65, 0x61, 0x76, 0x65, + 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x74, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x6e, 0x75, 0x6c, + 0x6c, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, 0x28, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x20, 0x2d, 0x20, 0x31, 0x35, 0x29, 0x29, 0x3b, 0x72, + 0x65, 0x63, 0x74, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, + 0x27, 0x2c, 0x20, 0x28, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2f, + 0x20, 0x32, 0x29, 0x20, 0x2d, 0x20, 0x31, 0x30, 0x30, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x76, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, + 0x6c, 0x6c, 0x28, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x6c, 0x65, + 0x67, 0x65, 0x6e, 0x64, 0x2e, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x28, 0x5b, 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, + 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, + 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, + 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x20, 0x79, 0x30, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x79, 0x61, 0x78, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x79, + 0x30, 0x27, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, + 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, + 0x69, 0x29, 0x20, 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, + 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x20, 0x27, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, + 0x3a, 0x30, 0x2e, 0x31, 0x27, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, + 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x65, + 0x61, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, + 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, + 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, 0x28, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x2d, 0x20, 0x36, 0x29, 0x29, + 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, + 0x27, 0x78, 0x27, 0x2c, 0x20, 0x28, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x20, 0x2f, 0x20, 0x32, 0x29, 0x20, 0x2d, 0x20, 0x38, 0x35, 0x29, + 0x2e, 0x74, 0x65, 0x78, 0x74, 0x28, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x2e, 0x79, 0x30, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x29, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x20, + 0x3d, 0x20, 0x73, 0x76, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x72, 0x65, 0x63, 0x74, 0x2e, + 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x2e, 0x79, 0x31, 0x27, 0x29, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, 0x6e, 0x75, 0x6c, 0x6c, + 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, + 0x28, 0x27, 0x72, 0x65, 0x63, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, + 0x20, 0x27, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x20, 0x79, 0x31, + 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x64, 0x61, + 0x74, 0x61, 0x2d, 0x79, 0x61, 0x78, 0x69, 0x73, 0x27, 0x2c, 0x20, + 0x27, 0x79, 0x31, 0x27, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, + 0x6f, 0x75, 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, + 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, + 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x20, 0x27, 0x6f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x3a, 0x30, 0x2e, 0x31, 0x27, 0x29, 0x3b, 0x20, 0x7d, + 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x6c, 0x65, 0x61, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, + 0x29, 0x20, 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x20, 0x7d, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, + 0x28, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x2d, 0x20, 0x31, + 0x35, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x28, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x20, 0x2f, 0x20, 0x32, 0x29, 0x29, 0x3b, 0x74, + 0x65, 0x78, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x76, 0x67, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x2e, + 0x79, 0x31, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, + 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, 0x3b, 0x74, 0x65, 0x78, 0x74, + 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x74, 0x65, 0x78, 0x74, 0x27, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x6c, 0x65, 0x67, 0x65, 0x6e, + 0x64, 0x20, 0x79, 0x31, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x79, 0x61, 0x78, 0x69, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x79, 0x31, 0x27, 0x29, 0x2e, 0x6f, + 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, + 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x27, 0x6f, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x30, 0x2e, 0x31, 0x27, + 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, + 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x27, 0x2c, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x74, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, + 0x79, 0x27, 0x2c, 0x20, 0x28, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x20, 0x2d, 0x20, 0x36, 0x29, 0x29, 0x3b, 0x74, 0x65, 0x78, 0x74, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, + 0x28, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2f, 0x20, 0x32, 0x29, + 0x20, 0x2b, 0x20, 0x31, 0x35, 0x29, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x28, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x79, 0x31, 0x29, + 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x73, 0x65, 0x74, 0x41, 0x78, 0x69, 0x73, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x28, 0x73, 0x76, 0x67, 0x29, 0x20, 0x7b, 0x73, 0x76, + 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, + 0x28, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x61, 0x78, 0x69, 0x73, + 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x79, 0x30, 0x27, 0x29, + 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, 0x6e, 0x75, 0x6c, 0x6c, + 0x5d, 0x29, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x74, 0x65, 0x78, + 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x61, 0x78, 0x69, + 0x73, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x79, 0x30, 0x27, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, + 0x20, 0x31, 0x30, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, + 0x78, 0x27, 0x2c, 0x20, 0x35, 0x33, 0x29, 0x2e, 0x74, 0x65, 0x78, + 0x74, 0x28, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x79, 0x30, + 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x64, 0x75, 0x61, 0x6c, + 0x59, 0x61, 0x78, 0x69, 0x73, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x45, 0x6e, 0x74, 0x65, + 0x72, 0x20, 0x3d, 0x20, 0x73, 0x76, 0x67, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x74, 0x65, 0x78, + 0x74, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x2d, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x2e, 0x79, 0x31, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x28, 0x5b, 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, 0x3b, 0x74, 0x45, + 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, + 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x74, + 0x65, 0x78, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, + 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x61, + 0x78, 0x69, 0x73, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x79, + 0x31, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, + 0x27, 0x2c, 0x20, 0x31, 0x30, 0x29, 0x2e, 0x74, 0x65, 0x78, 0x74, + 0x28, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x79, 0x31, 0x29, + 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, + 0x26, 0x26, 0x20, 0x74, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x20, 0x2d, 0x20, 0x32, 0x35, 0x29, 0x3b, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x53, 0x6b, 0x65, 0x6c, 0x65, 0x74, 0x6f, + 0x6e, 0x28, 0x73, 0x76, 0x67, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x73, + 0x76, 0x67, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x73, 0x76, 0x67, + 0x27, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, + 0x67, 0x27, 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x30, 0x20, 0x79, 0x30, 0x27, 0x29, 0x3b, 0x64, + 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, 0x26, 0x26, + 0x20, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, + 0x20, 0x27, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x6c, 0x69, 0x6e, 0x65, + 0x31, 0x20, 0x79, 0x31, 0x27, 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, + 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, + 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x61, 0x72, 0x65, + 0x61, 0x20, 0x61, 0x72, 0x65, 0x61, 0x30, 0x20, 0x79, 0x30, 0x27, + 0x29, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, + 0x20, 0x26, 0x26, 0x20, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x61, 0x72, 0x65, 0x61, 0x20, 0x61, + 0x72, 0x65, 0x61, 0x31, 0x20, 0x79, 0x31, 0x27, 0x29, 0x3b, 0x67, + 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x20, 0x79, 0x30, 0x27, 0x29, + 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, + 0x26, 0x26, 0x20, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x27, 0x2c, 0x20, 0x27, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x20, + 0x79, 0x31, 0x27, 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x78, 0x20, 0x67, 0x72, 0x69, + 0x64, 0x27, 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x79, 0x20, 0x67, 0x72, 0x69, 0x64, + 0x27, 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x27, 0x2c, 0x20, 0x27, 0x78, 0x20, 0x61, 0x78, 0x69, 0x73, 0x27, + 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, + 0x2c, 0x20, 0x27, 0x79, 0x30, 0x20, 0x61, 0x78, 0x69, 0x73, 0x27, + 0x29, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, + 0x20, 0x26, 0x26, 0x20, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x79, 0x31, 0x20, 0x61, 0x78, 0x69, + 0x73, 0x27, 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x72, 0x65, 0x63, 0x74, 0x73, 0x27, + 0x29, 0x3b, 0x73, 0x65, 0x74, 0x41, 0x78, 0x69, 0x73, 0x4c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x28, 0x73, 0x76, 0x67, 0x29, 0x3b, 0x73, + 0x65, 0x74, 0x4c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x28, 0x73, 0x76, 0x67, 0x29, 0x3b, 0x67, 0x45, + 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, + 0x28, 0x27, 0x6c, 0x69, 0x6e, 0x65, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x79, 0x32, 0x27, 0x2c, 0x20, 0x69, 0x6e, + 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x79, 0x31, 0x27, 0x2c, 0x20, 0x30, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x27, 0x2c, 0x20, 0x27, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, + 0x6f, 0x72, 0x27, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, + 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x64, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x2e, 0x67, + 0x65, 0x74, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x4c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x28, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x4c, 0x69, 0x6e, 0x65, + 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x6c, + 0x69, 0x6e, 0x65, 0x2c, 0x20, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x61, 0x74, 0x68, 0x20, + 0x3d, 0x20, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x27, 0x67, 0x2e, 0x27, 0x20, 0x2b, 0x20, 0x63, 0x4e, 0x61, 0x6d, + 0x65, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, + 0x6c, 0x28, 0x27, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x27, 0x20, 0x2b, + 0x20, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x28, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x5d, 0x29, 0x3b, 0x70, + 0x61, 0x74, 0x68, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x73, 0x76, + 0x67, 0x3a, 0x70, 0x61, 0x74, 0x68, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x64, 0x27, 0x2c, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x63, 0x4e, 0x61, 0x6d, 0x65, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x73, 0x74, 0x72, + 0x6f, 0x6b, 0x65, 0x2d, 0x64, 0x61, 0x73, 0x68, 0x61, 0x72, 0x72, + 0x61, 0x79, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x70, 0x6c, 0x20, 0x3d, 0x20, 0x70, 0x61, 0x74, 0x68, 0x4c, + 0x65, 0x6e, 0x28, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x6c, 0x20, 0x2b, 0x20, 0x27, + 0x20, 0x27, 0x20, 0x2b, 0x20, 0x70, 0x6c, 0x3b, 0x7d, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x73, 0x74, 0x72, 0x6f, 0x6b, + 0x65, 0x2d, 0x64, 0x61, 0x73, 0x68, 0x6f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x70, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x28, + 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x70, 0x61, + 0x74, 0x68, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x64, 0x27, + 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x29, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x73, 0x74, 0x72, 0x6f, 0x6b, 0x65, + 0x2d, 0x64, 0x61, 0x73, 0x68, 0x61, 0x72, 0x72, 0x61, 0x79, 0x27, + 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x64, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x6c, + 0x20, 0x3d, 0x20, 0x70, 0x61, 0x74, 0x68, 0x4c, 0x65, 0x6e, 0x28, + 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x70, 0x6c, 0x20, 0x2b, 0x20, 0x27, 0x20, 0x27, 0x20, + 0x2b, 0x20, 0x70, 0x6c, 0x3b, 0x7d, 0x29, 0x2e, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x32, 0x30, 0x30, 0x30, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x73, 0x74, 0x72, 0x6f, + 0x6b, 0x65, 0x2d, 0x64, 0x61, 0x73, 0x68, 0x6f, 0x66, 0x66, 0x73, + 0x65, 0x74, 0x27, 0x2c, 0x20, 0x30, 0x29, 0x3b, 0x70, 0x61, 0x74, + 0x68, 0x2e, 0x65, 0x78, 0x69, 0x74, 0x28, 0x29, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x41, 0x72, + 0x65, 0x61, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, + 0x20, 0x63, 0x62, 0x2c, 0x20, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x29, + 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x72, 0x65, 0x61, 0x20, + 0x3d, 0x20, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x27, 0x67, 0x2e, 0x27, 0x20, 0x2b, 0x20, 0x63, 0x4e, 0x61, 0x6d, + 0x65, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, + 0x6c, 0x28, 0x27, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x27, 0x20, 0x2b, + 0x20, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x28, 0x5b, 0x64, 0x61, 0x74, 0x61, 0x5d, 0x29, 0x3b, 0x61, + 0x72, 0x65, 0x61, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x73, 0x76, + 0x67, 0x3a, 0x70, 0x61, 0x74, 0x68, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, + 0x20, 0x63, 0x4e, 0x61, 0x6d, 0x65, 0x29, 0x3b, 0x61, 0x72, 0x65, + 0x61, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x64, 0x27, 0x2c, + 0x20, 0x63, 0x62, 0x29, 0x3b, 0x61, 0x72, 0x65, 0x61, 0x2e, 0x65, + 0x78, 0x69, 0x74, 0x28, 0x29, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x28, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x41, 0x72, 0x65, 0x61, 0x4c, + 0x69, 0x6e, 0x65, 0x73, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x29, 0x20, 0x7b, 0x61, 0x64, 0x64, 0x41, 0x72, 0x65, 0x61, + 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x61, + 0x72, 0x65, 0x61, 0x30, 0x2e, 0x79, 0x30, 0x28, 0x79, 0x53, 0x63, + 0x61, 0x6c, 0x65, 0x30, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, + 0x29, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x20, 0x27, 0x61, 0x72, 0x65, + 0x61, 0x30, 0x27, 0x29, 0x3b, 0x61, 0x64, 0x64, 0x4c, 0x69, 0x6e, + 0x65, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, + 0x6c, 0x69, 0x6e, 0x65, 0x30, 0x2c, 0x20, 0x27, 0x6c, 0x69, 0x6e, + 0x65, 0x30, 0x27, 0x29, 0x3b, 0x61, 0x64, 0x64, 0x41, 0x72, 0x65, + 0x61, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, + 0x61, 0x72, 0x65, 0x61, 0x31, 0x2e, 0x79, 0x31, 0x28, 0x79, 0x53, + 0x63, 0x61, 0x6c, 0x65, 0x31, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x28, 0x29, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x20, 0x27, 0x61, 0x72, + 0x65, 0x61, 0x31, 0x27, 0x29, 0x3b, 0x61, 0x64, 0x64, 0x4c, 0x69, + 0x6e, 0x65, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x31, 0x2c, 0x20, 0x27, 0x6c, 0x69, + 0x6e, 0x65, 0x31, 0x27, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3e, 0x20, 0x31, 0x30, 0x30, + 0x20, 0x3f, 0x20, 0x31, 0x20, 0x3a, 0x20, 0x32, 0x2e, 0x35, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x20, + 0x3d, 0x20, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x27, 0x67, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x79, + 0x30, 0x27, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, + 0x6c, 0x6c, 0x28, 0x27, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x73, 0x76, + 0x67, 0x3a, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x72, 0x27, 0x2c, 0x20, 0x72, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x27, 0x29, 0x3b, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, + 0x78, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, + 0x64, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x79, 0x27, 0x2c, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, + 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, + 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x28, 0x64, 0x5b, 0x31, 0x5d, + 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x3b, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x73, 0x2e, 0x65, 0x78, 0x69, 0x74, 0x28, 0x29, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x28, 0x27, 0x67, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x73, 0x2e, 0x79, 0x31, 0x27, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x63, 0x69, 0x72, 0x63, + 0x6c, 0x65, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x27, 0x29, 0x2e, + 0x64, 0x61, 0x74, 0x61, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, + 0x27, 0x73, 0x76, 0x67, 0x3a, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, + 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x72, 0x27, + 0x2c, 0x20, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, + 0x2c, 0x20, 0x27, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x27, 0x29, 0x3b, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x63, 0x78, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, 0x53, 0x63, 0x61, + 0x6c, 0x65, 0x28, 0x64, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x20, 0x7d, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x79, 0x27, + 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x64, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x31, 0x28, 0x64, + 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x3b, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x2e, 0x65, 0x78, 0x69, 0x74, 0x28, 0x29, + 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x3b, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, + 0x64, 0x41, 0x78, 0x69, 0x73, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x78, 0x54, + 0x69, 0x63, 0x6b, 0x73, 0x20, 0x3d, 0x20, 0x67, 0x65, 0x74, 0x58, + 0x54, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x69, 0x63, 0x6b, 0x44, 0x69, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x3d, 0x20, 0x78, 0x54, + 0x69, 0x63, 0x6b, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x20, 0x3e, 0x20, 0x31, 0x20, 0x3f, 0x20, 0x28, 0x78, 0x53, 0x63, + 0x61, 0x6c, 0x65, 0x28, 0x78, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x5b, + 0x31, 0x5d, 0x29, 0x20, 0x2d, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, + 0x65, 0x28, 0x78, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x5b, 0x30, 0x5d, + 0x29, 0x29, 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x57, + 0x28, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x57, 0x20, 0x3d, 0x20, 0x74, 0x69, 0x63, 0x6b, 0x44, 0x69, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x2d, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3b, 0x67, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, 0x78, 0x2e, 0x61, 0x78, 0x69, + 0x73, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x27, 0x2c, 0x20, + 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, + 0x30, 0x2c, 0x27, 0x20, 0x2b, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, + 0x65, 0x30, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x29, 0x5b, + 0x30, 0x5d, 0x20, 0x2b, 0x20, 0x27, 0x29, 0x27, 0x29, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x78, 0x41, 0x78, 0x69, 0x73, 0x2e, 0x74, + 0x69, 0x63, 0x6b, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x28, 0x78, + 0x54, 0x69, 0x63, 0x6b, 0x73, 0x29, 0x29, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x2e, 0x74, 0x69, + 0x63, 0x6b, 0x20, 0x74, 0x65, 0x78, 0x74, 0x22, 0x29, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, + 0x65, 0x2c, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x57, 0x20, 0x3e, + 0x20, 0x30, 0x20, 0x3f, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x57, + 0x20, 0x3a, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, + 0x29, 0x3b, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x27, 0x2e, 0x79, 0x30, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, + 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x79, 0x41, 0x78, 0x69, 0x73, + 0x30, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x28, 0x67, 0x65, 0x74, 0x59, 0x54, 0x69, 0x63, 0x6b, 0x73, + 0x28, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x29, 0x29, 0x29, + 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x64, 0x75, 0x61, 0x6c, 0x59, + 0x61, 0x78, 0x69, 0x73, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x3b, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, + 0x2e, 0x79, 0x31, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x27, 0x2c, 0x20, 0x27, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x27, 0x20, 0x2b, 0x20, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, 0x20, 0x2b, 0x20, + 0x27, 0x2c, 0x20, 0x30, 0x29, 0x27, 0x29, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x79, 0x41, 0x78, 0x69, 0x73, 0x31, 0x2e, 0x74, 0x69, + 0x63, 0x6b, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x28, 0x67, 0x65, + 0x74, 0x59, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x79, 0x53, 0x63, + 0x61, 0x6c, 0x65, 0x31, 0x29, 0x29, 0x29, 0x3b, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x47, + 0x72, 0x69, 0x64, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x20, 0x7b, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x28, 0x27, 0x2e, 0x78, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x27, 0x2c, 0x20, 0x27, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x30, 0x2c, 0x27, + 0x20, 0x2b, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x29, 0x5b, 0x30, 0x5d, 0x20, + 0x2b, 0x20, 0x27, 0x29, 0x27, 0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x78, 0x47, 0x72, 0x69, 0x64, 0x2e, 0x74, 0x69, 0x63, 0x6b, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x28, 0x67, 0x65, 0x74, 0x58, + 0x54, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, + 0x29, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x28, + 0x2d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x2c, 0x20, + 0x30, 0x2c, 0x20, 0x30, 0x29, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x27, 0x27, 0x29, 0x29, 0x3b, + 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, + 0x79, 0x2e, 0x67, 0x72, 0x69, 0x64, 0x27, 0x29, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x79, 0x47, 0x72, 0x69, 0x64, 0x2e, 0x74, 0x69, + 0x63, 0x6b, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x28, 0x67, 0x65, + 0x74, 0x59, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x79, 0x53, 0x63, + 0x61, 0x6c, 0x65, 0x30, 0x29, 0x29, 0x2e, 0x74, 0x69, 0x63, 0x6b, + 0x53, 0x69, 0x7a, 0x65, 0x28, 0x2d, 0x69, 0x6e, 0x6e, 0x65, 0x72, + 0x57, 0x28, 0x29, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x29, 0x2e, + 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, + 0x27, 0x27, 0x29, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, + 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x28, 0x64, 0x61, 0x74, 0x61, + 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, + 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x73, 0x6c, 0x69, + 0x63, 0x65, 0x28, 0x30, 0x29, 0x3b, 0x64, 0x5b, 0x30, 0x5d, 0x20, + 0x3d, 0x20, 0x28, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x78, + 0x29, 0x20, 0x3f, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x28, 0x64, 0x5b, 0x30, 0x5d, 0x2c, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x78, 0x29, 0x20, 0x3a, + 0x20, 0x64, 0x5b, 0x30, 0x5d, 0x3b, 0x64, 0x5b, 0x31, 0x5d, 0x20, + 0x3d, 0x20, 0x28, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x79, + 0x30, 0x29, 0x20, 0x3f, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x64, 0x5b, 0x31, 0x5d, 0x2c, + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x79, 0x30, 0x29, + 0x20, 0x3a, 0x20, 0x64, 0x33, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x28, 0x27, 0x2c, 0x27, 0x29, 0x28, 0x64, 0x5b, 0x31, 0x5d, + 0x29, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, + 0x20, 0x26, 0x26, 0x20, 0x28, 0x64, 0x5b, 0x32, 0x5d, 0x20, 0x3d, + 0x20, 0x28, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x79, 0x31, + 0x29, 0x20, 0x3f, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x28, 0x64, 0x5b, 0x32, 0x5d, 0x2c, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x79, 0x31, 0x29, 0x20, + 0x3a, 0x20, 0x64, 0x33, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x28, 0x27, 0x2c, 0x27, 0x29, 0x28, 0x64, 0x5b, 0x32, 0x5d, 0x29, + 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, + 0x69, 0x70, 0x27, 0x29, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x28, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x48, 0x6f, 0x67, + 0x61, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x28, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x29, 0x2e, 0x72, + 0x65, 0x6e, 0x64, 0x65, 0x72, 0x28, 0x7b, 0x27, 0x64, 0x61, 0x74, + 0x61, 0x27, 0x3a, 0x20, 0x64, 0x7d, 0x29, 0x3b, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6f, 0x75, 0x73, + 0x65, 0x6f, 0x76, 0x65, 0x72, 0x28, 0x5f, 0x73, 0x65, 0x6c, 0x66, + 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x69, 0x64, 0x78, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x6f, 0x6c, + 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x28, 0x27, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, + 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x27, + 0x29, 0x3b, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x2e, 0x68, + 0x74, 0x6d, 0x6c, 0x28, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, + 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x28, 0x64, 0x61, 0x74, 0x61, + 0x2c, 0x20, 0x69, 0x64, 0x78, 0x29, 0x29, 0x2e, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x28, 0x27, 0x6c, 0x65, 0x66, 0x74, 0x27, 0x2c, 0x20, + 0x28, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x64, 0x61, 0x74, + 0x61, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x20, 0x2b, 0x20, 0x27, 0x70, + 0x78, 0x27, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x27, + 0x74, 0x6f, 0x70, 0x27, 0x2c, 0x20, 0x20, 0x28, 0x64, 0x33, 0x2e, + 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x28, 0x5f, 0x73, 0x65, 0x6c, 0x66, + 0x29, 0x5b, 0x31, 0x5d, 0x20, 0x2b, 0x20, 0x31, 0x30, 0x29, 0x20, + 0x2b, 0x20, 0x27, 0x70, 0x78, 0x27, 0x29, 0x2e, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x28, 0x27, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, + 0x27, 0x2c, 0x20, 0x27, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x27, 0x29, + 0x3b, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x6c, 0x69, 0x6e, + 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, + 0x27, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x27, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x27, 0x2c, 0x20, 0x27, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x27, 0x2c, 0x20, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x65, 0x28, 0x27, 0x20, 0x2b, 0x20, 0x78, 0x53, 0x63, 0x61, + 0x6c, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x5b, 0x30, 0x5d, 0x29, + 0x20, 0x2b, 0x20, 0x27, 0x2c, 0x27, 0x20, 0x2b, 0x20, 0x30, 0x20, + 0x2b, 0x20, 0x27, 0x29, 0x27, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x6f, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x2d, + 0x77, 0x72, 0x61, 0x70, 0x27, 0x29, 0x3b, 0x74, 0x6f, 0x6f, 0x6c, + 0x74, 0x69, 0x70, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x27, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x27, 0x2c, 0x20, 0x27, + 0x6e, 0x6f, 0x6e, 0x65, 0x27, 0x29, 0x3b, 0x67, 0x2e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x6c, 0x69, 0x6e, 0x65, 0x2e, + 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x27, 0x29, + 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x27, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x27, 0x2c, 0x20, 0x27, 0x6e, 0x6f, 0x6e, + 0x65, 0x27, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x52, 0x65, 0x63, 0x74, 0x73, + 0x28, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, + 0x20, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x77, 0x20, 0x3d, 0x20, 0x28, 0x69, 0x6e, + 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, 0x20, 0x2f, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 0x63, 0x74, 0x73, 0x20, 0x3d, + 0x20, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, + 0x67, 0x2e, 0x72, 0x65, 0x63, 0x74, 0x73, 0x27, 0x29, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x72, + 0x65, 0x63, 0x74, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, + 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x73, + 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x73, 0x76, 0x67, 0x3a, 0x72, + 0x65, 0x63, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, + 0x27, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x27, 0x2c, 0x20, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, + 0x20, 0x27, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x27, 0x29, 0x3b, 0x72, + 0x65, 0x63, 0x74, 0x73, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x27, 0x2c, 0x20, 0x64, 0x33, 0x2e, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x6f, 0x72, 0x28, 0x77, 0x29, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, + 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x28, 0x77, 0x20, 0x2a, 0x20, 0x69, 0x29, 0x3b, + 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, + 0x27, 0x2c, 0x20, 0x30, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, + 0x6f, 0x75, 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, + 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x6f, 0x76, 0x65, 0x72, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, + 0x64, 0x2c, 0x20, 0x69, 0x29, 0x3b, 0x7d, 0x29, 0x2e, 0x6f, 0x6e, + 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x65, 0x61, 0x76, + 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x6d, + 0x6f, 0x75, 0x73, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x29, 0x3b, + 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x73, 0x2e, 0x65, 0x78, + 0x69, 0x74, 0x28, 0x29, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x28, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x28, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, 0x7b, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x65, 0x61, 0x63, + 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x64, 0x61, 0x74, + 0x61, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x70, 0x44, 0x61, 0x74, 0x61, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x73, 0x28, 0x64, 0x61, + 0x74, 0x61, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x76, 0x67, + 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x73, 0x76, 0x67, + 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, 0x64, 0x61, + 0x74, 0x61, 0x5d, 0x29, 0x3b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x53, 0x6b, 0x65, 0x6c, 0x65, 0x74, 0x6f, 0x6e, 0x28, 0x73, 0x76, + 0x67, 0x29, 0x3b, 0x73, 0x76, 0x67, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x7b, 0x27, 0x77, 0x69, 0x64, 0x74, 0x68, 0x27, 0x3a, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x27, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x27, 0x3a, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x67, 0x20, 0x3d, 0x20, + 0x73, 0x76, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x27, 0x2c, + 0x20, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, + 0x28, 0x27, 0x20, 0x2b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2e, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x2b, 0x20, 0x27, 0x2c, 0x27, + 0x20, 0x2b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2e, 0x74, + 0x6f, 0x70, 0x20, 0x2b, 0x20, 0x27, 0x29, 0x27, 0x29, 0x3b, 0x61, + 0x64, 0x64, 0x47, 0x72, 0x69, 0x64, 0x28, 0x67, 0x2c, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x29, 0x3b, 0x61, 0x64, 0x64, 0x41, 0x72, 0x65, + 0x61, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x28, 0x67, 0x2c, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x29, 0x3b, 0x61, 0x64, 0x64, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x3b, 0x61, 0x64, 0x64, 0x41, 0x78, 0x69, 0x73, 0x28, 0x67, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x61, 0x64, 0x64, + 0x52, 0x65, 0x63, 0x74, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x2c, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x7d, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2e, 0x6f, 0x70, 0x74, 0x73, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, + 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, + 0x70, 0x74, 0x73, 0x3b, 0x6f, 0x70, 0x74, 0x73, 0x20, 0x3d, 0x20, + 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, + 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x3b, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x5f, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3b, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x3b, 0x7d, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, 0x20, 0x7b, 0x69, + 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x61, 0x72, 0x67, + 0x69, 0x6e, 0x3b, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x3d, + 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, + 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, + 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x5f, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, + 0x3b, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x78, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, + 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3b, 0x78, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x79, 0x30, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, + 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x30, 0x3b, 0x79, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, + 0x7d, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x79, 0x31, 0x20, + 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x5f, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x3b, 0x79, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x20, 0x3d, 0x20, 0x5f, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x3b, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x61, 0x72, 0x43, 0x68, 0x61, + 0x72, 0x74, 0x28, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, + 0x73, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x70, 0x74, + 0x73, 0x20, 0x3d, 0x20, 0x7b, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x7b, 0x74, + 0x6f, 0x70, 0x20, 0x20, 0x20, 0x20, 0x3a, 0x20, 0x32, 0x30, 0x2c, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x20, 0x3a, 0x20, 0x35, 0x30, + 0x2c, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x20, 0x3a, 0x20, 0x34, + 0x30, 0x2c, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x20, 0x20, 0x3a, 0x20, + 0x35, 0x30, 0x2c, 0x7d, 0x2c, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x20, 0x3d, 0x20, 0x31, 0x37, 0x30, 0x2c, 0x6e, 0x54, 0x69, 0x63, + 0x6b, 0x73, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x2c, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x2c, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x37, 0x36, 0x30, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x20, + 0x3d, 0x20, 0x7b, 0x20, 0x78, 0x3a, 0x20, 0x27, 0x55, 0x6e, 0x6e, + 0x61, 0x6d, 0x65, 0x64, 0x27, 0x2c, 0x20, 0x79, 0x30, 0x3a, 0x20, + 0x27, 0x55, 0x6e, 0x6e, 0x61, 0x6d, 0x65, 0x64, 0x27, 0x2c, 0x20, + 0x79, 0x31, 0x3a, 0x20, 0x27, 0x55, 0x6e, 0x6e, 0x61, 0x6d, 0x65, + 0x64, 0x27, 0x20, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x7b, 0x20, 0x78, 0x3a, + 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x20, 0x79, 0x30, 0x3a, 0x20, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x20, 0x79, 0x31, 0x3a, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x78, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x5b, 0x30, 0x5d, 0x3b, + 0x7d, 0x2c, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x30, 0x20, 0x3d, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x64, 0x5b, 0x31, 0x5d, 0x3b, 0x7d, 0x2c, 0x79, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x31, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x5b, 0x32, 0x5d, 0x3b, 0x7d, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, + 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x28, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, + 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x28, 0x29, 0x2e, 0x6e, + 0x69, 0x63, 0x65, 0x28, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x79, + 0x53, 0x63, 0x61, 0x6c, 0x65, 0x31, 0x20, 0x3d, 0x20, 0x64, 0x33, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x61, 0x72, 0x28, 0x29, 0x2e, 0x6e, 0x69, 0x63, 0x65, 0x28, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x78, 0x41, 0x78, 0x69, 0x73, 0x20, + 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, 0x78, + 0x69, 0x73, 0x28, 0x29, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, + 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x29, 0x2e, 0x6f, 0x72, 0x69, + 0x65, 0x6e, 0x74, 0x28, 0x27, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, + 0x27, 0x29, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x78, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x28, 0x64, 0x2c, 0x20, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x2e, 0x78, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x64, 0x3b, 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x79, 0x41, 0x78, 0x69, 0x73, 0x30, 0x20, 0x3d, 0x20, 0x64, + 0x33, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x28, + 0x29, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x79, 0x53, 0x63, + 0x61, 0x6c, 0x65, 0x30, 0x29, 0x2e, 0x6f, 0x72, 0x69, 0x65, 0x6e, + 0x74, 0x28, 0x27, 0x6c, 0x65, 0x66, 0x74, 0x27, 0x29, 0x2e, 0x74, + 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, + 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x33, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x27, 0x2e, 0x32, + 0x73, 0x27, 0x29, 0x28, 0x64, 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x79, 0x41, 0x78, 0x69, 0x73, 0x31, 0x20, 0x3d, + 0x20, 0x64, 0x33, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, 0x78, 0x69, + 0x73, 0x28, 0x29, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x79, + 0x53, 0x63, 0x61, 0x6c, 0x65, 0x31, 0x29, 0x2e, 0x6f, 0x72, 0x69, + 0x65, 0x6e, 0x74, 0x28, 0x27, 0x72, 0x69, 0x67, 0x68, 0x74, 0x27, + 0x29, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x64, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x79, 0x31, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x2e, 0x55, 0x74, 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x28, 0x64, 0x2c, 0x20, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x2e, 0x79, 0x31, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x64, 0x33, 0x2e, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x28, 0x27, 0x2e, 0x32, 0x73, 0x27, 0x29, 0x28, 0x64, + 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x78, 0x47, + 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x76, + 0x67, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x28, 0x29, 0x2e, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x28, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x29, + 0x2e, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x28, 0x27, 0x62, 0x6f, + 0x74, 0x74, 0x6f, 0x6d, 0x27, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x79, 0x47, 0x72, 0x69, 0x64, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, + 0x73, 0x76, 0x67, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x28, 0x29, 0x2e, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x79, 0x53, 0x63, 0x61, 0x6c, + 0x65, 0x30, 0x29, 0x2e, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x28, + 0x27, 0x6c, 0x65, 0x66, 0x74, 0x27, 0x29, 0x3b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, + 0x57, 0x28, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2d, 0x20, 0x6d, 0x61, + 0x72, 0x67, 0x69, 0x6e, 0x2e, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x2d, + 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2e, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x20, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x2d, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2e, 0x74, 0x6f, 0x70, 0x20, 0x2d, 0x20, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2e, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3b, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, + 0x65, 0x74, 0x58, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x64, 0x61, + 0x74, 0x61, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3c, + 0x20, 0x6e, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x33, 0x2e, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x28, 0x30, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x20, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x2f, 0x20, 0x6e, + 0x54, 0x69, 0x63, 0x6b, 0x73, 0x29, 0x29, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x28, 0x29, 0x5b, 0x64, 0x5d, 0x3b, 0x7d, 0x29, 0x3b, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, + 0x65, 0x74, 0x59, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x3d, 0x20, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x33, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x63, 0x65, 0x69, 0x6c, 0x28, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x5b, 0x31, 0x5d, 0x20, 0x2f, 0x20, 0x6e, 0x54, 0x69, 0x63, 0x6b, + 0x73, 0x29, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x70, 0x44, 0x61, 0x74, 0x61, 0x28, + 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x5f, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, + 0x69, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x74, + 0x75, 0x6d, 0x20, 0x3d, 0x20, 0x5b, 0x78, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x64, 0x61, 0x74, 0x61, + 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x2c, 0x20, 0x79, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x30, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x69, 0x29, + 0x5d, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, + 0x20, 0x26, 0x26, 0x20, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, + 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c, + 0x20, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x75, 0x6d, 0x3b, 0x7d, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x64, 0x61, + 0x74, 0x75, 0x6d, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x3b, 0x7d, + 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x61, 0x6c, + 0x65, 0x73, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x78, + 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, + 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x64, + 0x5b, 0x30, 0x5d, 0x3b, 0x7d, 0x29, 0x29, 0x2e, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x28, 0x5b, 0x30, 0x2c, + 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, 0x5d, 0x2c, + 0x20, 0x30, 0x2e, 0x31, 0x29, 0x3b, 0x79, 0x53, 0x63, 0x61, 0x6c, + 0x65, 0x30, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x5b, + 0x30, 0x2c, 0x20, 0x64, 0x33, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x64, + 0x61, 0x74, 0x61, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x64, 0x5b, 0x31, 0x5d, 0x3b, 0x7d, 0x29, + 0x5d, 0x29, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x5b, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x2c, 0x20, 0x30, 0x5d, + 0x29, 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, + 0x20, 0x26, 0x26, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x31, + 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x5b, 0x30, 0x2c, + 0x20, 0x64, 0x33, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x64, 0x61, 0x74, + 0x61, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x64, 0x5b, 0x32, 0x5d, 0x3b, 0x7d, 0x29, 0x5d, 0x29, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x5b, 0x69, 0x6e, 0x6e, + 0x65, 0x72, 0x48, 0x28, 0x29, 0x2c, 0x20, 0x30, 0x5d, 0x29, 0x3b, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x79, 0x28, 0x65, 0x6c, 0x65, 0x2c, 0x20, 0x6f, 0x70, 0x29, 0x20, + 0x7b, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x65, 0x6c, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x2e, 0x27, 0x20, 0x2b, 0x20, 0x28, + 0x65, 0x6c, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x79, 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, 0x20, 0x3d, 0x3d, + 0x20, 0x27, 0x79, 0x30, 0x27, 0x20, 0x3f, 0x20, 0x27, 0x79, 0x31, + 0x27, 0x20, 0x3a, 0x20, 0x27, 0x79, 0x30, 0x27, 0x29, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x27, 0x2c, 0x20, 0x6f, 0x70, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x74, 0x4c, 0x65, + 0x67, 0x65, 0x6e, 0x64, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x28, + 0x73, 0x76, 0x67, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x76, 0x67, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x72, + 0x65, 0x63, 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x2e, + 0x79, 0x30, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, + 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x63, 0x74, + 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x72, 0x65, 0x63, 0x74, 0x27, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x6c, 0x65, 0x67, 0x65, 0x6e, + 0x64, 0x20, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x79, 0x61, 0x78, 0x69, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x6f, + 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, + 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x27, 0x6f, + 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x30, 0x2e, 0x31, 0x27, + 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, + 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x27, 0x2c, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, + 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x74, 0x6f, 0x67, + 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, + 0x79, 0x27, 0x2c, 0x20, 0x28, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x20, 0x2d, 0x20, 0x31, 0x35, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x63, + 0x74, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, + 0x20, 0x28, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2f, 0x20, 0x32, + 0x29, 0x20, 0x2d, 0x20, 0x31, 0x30, 0x30, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x65, 0x78, 0x74, 0x20, 0x3d, 0x20, 0x73, 0x76, + 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, + 0x28, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, + 0x6e, 0x64, 0x2e, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, + 0x61, 0x28, 0x5b, 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, 0x3b, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x74, 0x65, + 0x78, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x6c, 0x65, + 0x67, 0x65, 0x6e, 0x64, 0x20, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x79, + 0x61, 0x78, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x79, 0x30, 0x27, + 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, + 0x20, 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, + 0x61, 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, + 0x20, 0x27, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x3a, 0x30, + 0x2e, 0x31, 0x27, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x6f, 0x6e, + 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x65, 0x61, 0x76, + 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, + 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, + 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x6e, 0x75, + 0x6c, 0x6c, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, 0x28, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x20, 0x2d, 0x20, 0x36, 0x29, 0x29, 0x3b, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, + 0x27, 0x2c, 0x20, 0x28, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x2f, + 0x20, 0x32, 0x29, 0x20, 0x2d, 0x20, 0x38, 0x35, 0x29, 0x2e, 0x74, + 0x65, 0x78, 0x74, 0x28, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, + 0x79, 0x30, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x64, 0x75, + 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x20, 0x3d, 0x20, + 0x73, 0x76, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, + 0x6c, 0x6c, 0x28, 0x27, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x6c, 0x65, + 0x67, 0x65, 0x6e, 0x64, 0x2e, 0x79, 0x31, 0x27, 0x29, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x28, 0x5b, 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, + 0x3b, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, + 0x72, 0x65, 0x63, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, + 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x20, 0x79, 0x31, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x79, 0x61, 0x78, 0x69, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x79, + 0x31, 0x27, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, + 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, + 0x69, 0x29, 0x20, 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, + 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x20, 0x27, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, + 0x3a, 0x30, 0x2e, 0x31, 0x27, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, + 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x65, + 0x61, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, + 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, + 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, 0x28, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x2d, 0x20, 0x31, 0x35, 0x29, + 0x29, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x28, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x20, 0x2f, 0x20, 0x32, 0x29, 0x29, 0x3b, 0x74, 0x65, 0x78, + 0x74, 0x20, 0x3d, 0x20, 0x73, 0x76, 0x67, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x74, 0x65, 0x78, + 0x74, 0x2e, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x2e, 0x79, 0x31, + 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, 0x6e, 0x75, + 0x6c, 0x6c, 0x5d, 0x29, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x28, 0x27, 0x74, 0x65, 0x78, 0x74, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x27, 0x2c, 0x20, 0x27, 0x6c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x20, + 0x79, 0x31, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x79, 0x61, 0x78, 0x69, 0x73, 0x27, + 0x2c, 0x20, 0x27, 0x79, 0x31, 0x27, 0x29, 0x2e, 0x6f, 0x6e, 0x28, + 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x27, + 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x74, 0x6f, + 0x67, 0x67, 0x6c, 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x20, 0x27, 0x6f, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x3a, 0x30, 0x2e, 0x31, 0x27, 0x29, 0x3b, + 0x20, 0x7d, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, + 0x73, 0x65, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, + 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x4f, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x20, + 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, + 0x2c, 0x20, 0x28, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x2d, + 0x20, 0x36, 0x29, 0x29, 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x28, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x20, 0x2f, 0x20, 0x32, 0x29, 0x20, 0x2b, + 0x20, 0x31, 0x35, 0x29, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x28, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x79, 0x31, 0x29, 0x3b, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x65, + 0x74, 0x41, 0x78, 0x69, 0x73, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x28, 0x73, 0x76, 0x67, 0x29, 0x20, 0x7b, 0x73, 0x76, 0x67, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, + 0x74, 0x65, 0x78, 0x74, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x2d, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x28, 0x5b, 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, + 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x74, 0x65, 0x78, 0x74, 0x27, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x61, 0x78, 0x69, 0x73, 0x2d, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x79, 0x30, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, 0x31, + 0x30, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, 0x27, + 0x2c, 0x20, 0x35, 0x33, 0x29, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x28, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x79, 0x30, 0x29, 0x3b, + 0x69, 0x66, 0x20, 0x28, 0x21, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, + 0x78, 0x69, 0x73, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, + 0x3d, 0x20, 0x73, 0x76, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x74, 0x65, 0x78, 0x74, 0x2e, + 0x61, 0x78, 0x69, 0x73, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x2e, + 0x79, 0x31, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, + 0x6e, 0x75, 0x6c, 0x6c, 0x5d, 0x29, 0x3b, 0x74, 0x45, 0x6e, 0x74, + 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, + 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x74, 0x65, 0x78, + 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, 0x61, 0x78, 0x69, + 0x73, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x79, 0x31, 0x27, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, + 0x20, 0x31, 0x30, 0x29, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x28, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x79, 0x31, 0x29, 0x3b, 0x64, + 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, 0x26, 0x26, + 0x20, 0x74, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x20, 0x2d, 0x20, 0x32, 0x35, 0x29, 0x3b, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x53, 0x6b, 0x65, 0x6c, 0x65, 0x74, 0x6f, 0x6e, 0x28, + 0x73, 0x76, 0x67, 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x67, + 0x45, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x73, 0x76, 0x67, + 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x73, 0x76, 0x67, 0x27, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, + 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, + 0x2c, 0x20, 0x27, 0x78, 0x20, 0x67, 0x72, 0x69, 0x64, 0x27, 0x29, + 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, + 0x20, 0x27, 0x79, 0x20, 0x67, 0x72, 0x69, 0x64, 0x27, 0x29, 0x3b, + 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, + 0x27, 0x78, 0x20, 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, 0x3b, 0x67, + 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, 0x20, 0x27, + 0x79, 0x30, 0x20, 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, 0x3b, 0x64, + 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, 0x26, 0x26, + 0x20, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, + 0x20, 0x27, 0x79, 0x31, 0x20, 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, + 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, + 0x20, 0x27, 0x62, 0x61, 0x72, 0x73, 0x20, 0x79, 0x30, 0x27, 0x29, + 0x3b, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, + 0x26, 0x26, 0x20, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x27, 0x2c, 0x20, 0x27, 0x62, 0x61, 0x72, 0x73, 0x20, 0x79, 0x31, + 0x27, 0x29, 0x3b, 0x67, 0x45, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x27, 0x2c, 0x20, 0x27, 0x72, 0x65, 0x63, 0x74, 0x73, 0x27, 0x29, + 0x3b, 0x73, 0x65, 0x74, 0x41, 0x78, 0x69, 0x73, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x28, 0x73, 0x76, 0x67, 0x29, 0x3b, 0x73, 0x65, + 0x74, 0x4c, 0x65, 0x67, 0x65, 0x6e, 0x64, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x28, 0x73, 0x76, 0x67, 0x29, 0x3b, 0x67, 0x45, 0x6e, + 0x74, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, + 0x27, 0x6c, 0x69, 0x6e, 0x65, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x79, 0x32, 0x27, 0x2c, 0x20, 0x69, 0x6e, 0x6e, + 0x65, 0x72, 0x48, 0x28, 0x29, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x79, 0x31, 0x27, 0x2c, 0x20, 0x30, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, + 0x2c, 0x20, 0x27, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, + 0x72, 0x27, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x42, 0x61, 0x72, 0x73, 0x28, + 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x62, 0x61, 0x72, 0x73, 0x20, 0x3d, 0x20, 0x67, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x67, 0x2e, + 0x62, 0x61, 0x72, 0x73, 0x2e, 0x79, 0x30, 0x27, 0x29, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, 0x72, + 0x65, 0x63, 0x74, 0x2e, 0x62, 0x61, 0x72, 0x27, 0x29, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x62, + 0x61, 0x72, 0x73, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x73, 0x76, + 0x67, 0x3a, 0x72, 0x65, 0x63, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x27, 0x2c, + 0x20, 0x27, 0x62, 0x61, 0x72, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x27, 0x2c, + 0x20, 0x30, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, + 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, + 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x42, 0x61, 0x6e, 0x64, 0x28, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x3b, + 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, + 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, + 0x65, 0x28, 0x64, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x20, 0x7d, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, + 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, + 0x3b, 0x20, 0x7d, 0x29, 0x3b, 0x62, 0x61, 0x72, 0x73, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x77, 0x69, 0x64, 0x74, 0x68, 0x27, + 0x2c, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, 0x28, 0x29, 0x20, 0x2f, + 0x20, 0x32, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, + 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x64, + 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x2e, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, + 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x20, + 0x2f, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x30, 0x30, 0x3b, 0x20, + 0x7d, 0x29, 0x2e, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x35, 0x30, 0x30, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, + 0x27, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x27, 0x2c, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, + 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x20, + 0x2d, 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x28, 0x64, + 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, + 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x28, 0x64, 0x5b, 0x31, + 0x5d, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x3b, 0x62, 0x61, 0x72, 0x73, + 0x2e, 0x65, 0x78, 0x69, 0x74, 0x28, 0x29, 0x2e, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x28, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, 0x21, + 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x29, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x62, 0x61, 0x72, 0x73, 0x20, + 0x3d, 0x20, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x27, 0x67, 0x2e, 0x62, 0x61, 0x72, 0x73, 0x2e, 0x79, 0x31, 0x27, + 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, + 0x28, 0x27, 0x72, 0x65, 0x63, 0x74, 0x2e, 0x62, 0x61, 0x72, 0x27, + 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x3b, 0x62, 0x61, 0x72, 0x73, 0x2e, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, + 0x27, 0x73, 0x76, 0x67, 0x3a, 0x72, 0x65, 0x63, 0x74, 0x27, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x62, 0x61, 0x72, 0x27, 0x29, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x27, 0x2c, 0x20, 0x30, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x77, 0x69, 0x64, 0x74, 0x68, 0x27, 0x2c, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, + 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, 0x28, 0x29, 0x20, 0x2f, + 0x20, 0x32, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x78, 0x53, 0x63, 0x61, + 0x6c, 0x65, 0x28, 0x64, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, + 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x42, 0x61, 0x6e, 0x64, 0x28, 0x29, 0x20, 0x2f, 0x20, 0x32, + 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, + 0x27, 0x79, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x6e, 0x6e, + 0x65, 0x72, 0x48, 0x28, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x3b, 0x62, + 0x61, 0x72, 0x73, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x27, 0x2c, 0x20, 0x78, 0x53, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, + 0x64, 0x28, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x78, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x29, 0x20, 0x7b, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x78, 0x53, + 0x63, 0x61, 0x6c, 0x65, 0x28, 0x64, 0x5b, 0x30, 0x5d, 0x29, 0x20, + 0x2b, 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, 0x28, 0x29, 0x20, 0x2f, + 0x20, 0x32, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x2e, 0x64, + 0x65, 0x6c, 0x61, 0x79, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x20, 0x2f, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x20, 0x2a, 0x20, 0x31, 0x30, 0x30, 0x30, 0x3b, 0x20, 0x7d, + 0x29, 0x2e, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x35, 0x30, 0x30, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x27, 0x2c, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, + 0x69, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x20, 0x2d, + 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x31, 0x28, 0x64, 0x5b, + 0x32, 0x5d, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, + 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, + 0x53, 0x63, 0x61, 0x6c, 0x65, 0x31, 0x28, 0x64, 0x5b, 0x32, 0x5d, + 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x3b, 0x62, 0x61, 0x72, 0x73, 0x2e, + 0x65, 0x78, 0x69, 0x74, 0x28, 0x29, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x28, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x41, 0x78, 0x69, 0x73, + 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x78, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x20, + 0x3d, 0x20, 0x67, 0x65, 0x74, 0x58, 0x54, 0x69, 0x63, 0x6b, 0x73, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x69, 0x63, 0x6b, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x3d, 0x20, 0x78, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x20, 0x3e, 0x20, 0x31, 0x20, + 0x3f, 0x20, 0x28, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x78, + 0x54, 0x69, 0x63, 0x6b, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x20, 0x2d, + 0x20, 0x78, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x78, 0x54, 0x69, + 0x63, 0x6b, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x20, 0x3a, 0x20, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x57, 0x20, 0x3d, 0x20, + 0x74, 0x69, 0x63, 0x6b, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x20, 0x2d, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3b, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, + 0x2e, 0x78, 0x2e, 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x27, 0x2c, 0x20, 0x27, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x30, 0x2c, 0x27, 0x20, 0x2b, + 0x20, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x28, 0x29, 0x5b, 0x30, 0x5d, 0x20, 0x2b, 0x20, + 0x27, 0x29, 0x27, 0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x78, + 0x41, 0x78, 0x69, 0x73, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x28, 0x78, 0x54, 0x69, 0x63, 0x6b, 0x73, + 0x29, 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, + 0x6c, 0x28, 0x22, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x20, 0x74, 0x65, + 0x78, 0x74, 0x22, 0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, + 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x2c, 0x20, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x57, 0x20, 0x3e, 0x20, 0x30, 0x20, 0x3f, 0x20, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x57, 0x20, 0x3a, 0x20, 0x69, 0x6e, + 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, 0x29, 0x3b, 0x67, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, 0x79, 0x30, 0x2e, + 0x61, 0x78, 0x69, 0x73, 0x27, 0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x79, 0x41, 0x78, 0x69, 0x73, 0x30, 0x2e, 0x74, 0x69, 0x63, + 0x6b, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x28, 0x67, 0x65, 0x74, + 0x59, 0x54, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x79, 0x53, 0x63, 0x61, + 0x6c, 0x65, 0x30, 0x29, 0x29, 0x29, 0x3b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x64, 0x75, 0x61, 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x67, 0x2e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, 0x79, 0x31, 0x2e, 0x61, + 0x78, 0x69, 0x73, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, + 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x27, + 0x2c, 0x20, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, + 0x65, 0x28, 0x27, 0x20, 0x2b, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, + 0x57, 0x28, 0x29, 0x20, 0x2b, 0x20, 0x27, 0x2c, 0x20, 0x30, 0x29, + 0x27, 0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x79, 0x41, 0x78, + 0x69, 0x73, 0x31, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x28, 0x67, 0x65, 0x74, 0x59, 0x54, 0x69, 0x63, + 0x6b, 0x73, 0x28, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x31, 0x29, + 0x29, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x61, 0x64, 0x64, 0x47, 0x72, 0x69, 0x64, 0x28, 0x67, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, 0x67, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, 0x78, 0x2e, + 0x67, 0x72, 0x69, 0x64, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x27, 0x2c, 0x20, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x65, 0x28, 0x30, 0x2c, 0x27, 0x20, 0x2b, 0x20, 0x79, 0x53, + 0x63, 0x61, 0x6c, 0x65, 0x30, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x28, 0x29, 0x5b, 0x30, 0x5d, 0x20, 0x2b, 0x20, 0x27, 0x29, 0x27, + 0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x78, 0x47, 0x72, 0x69, + 0x64, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x28, 0x67, 0x65, 0x74, 0x58, 0x54, 0x69, 0x63, 0x6b, 0x73, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x29, 0x2e, 0x74, 0x69, 0x63, + 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x28, 0x2d, 0x69, 0x6e, 0x6e, 0x65, + 0x72, 0x48, 0x28, 0x29, 0x2c, 0x20, 0x30, 0x2c, 0x20, 0x30, 0x29, + 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x28, 0x27, 0x27, 0x29, 0x29, 0x3b, 0x67, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, 0x79, 0x2e, 0x67, 0x72, 0x69, + 0x64, 0x27, 0x29, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x79, 0x47, + 0x72, 0x69, 0x64, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x28, 0x67, 0x65, 0x74, 0x59, 0x54, 0x69, 0x63, + 0x6b, 0x73, 0x28, 0x79, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x30, 0x29, + 0x29, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x28, + 0x2d, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, 0x2c, 0x20, + 0x30, 0x2c, 0x20, 0x30, 0x29, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x27, 0x27, 0x29, 0x29, 0x3b, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x74, 0x69, + 0x70, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x69, 0x29, 0x20, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x20, 0x3d, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x29, + 0x3b, 0x64, 0x5b, 0x30, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x78, 0x29, 0x20, 0x3f, 0x20, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, + 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, + 0x64, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x2e, 0x78, 0x29, 0x20, 0x3a, 0x20, 0x64, 0x5b, 0x30, 0x5d, + 0x3b, 0x64, 0x5b, 0x31, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x79, 0x30, 0x29, 0x20, 0x3f, 0x20, + 0x47, 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, + 0x69, 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x28, 0x64, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x2e, 0x79, 0x30, 0x29, 0x20, 0x3a, 0x20, 0x64, 0x33, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x27, 0x2c, 0x27, + 0x29, 0x28, 0x64, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x64, 0x75, 0x61, + 0x6c, 0x59, 0x61, 0x78, 0x69, 0x73, 0x20, 0x26, 0x26, 0x20, 0x28, + 0x64, 0x5b, 0x32, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x2e, 0x79, 0x31, 0x29, 0x20, 0x3f, 0x20, 0x47, + 0x6f, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2e, 0x55, 0x74, 0x69, + 0x6c, 0x2e, 0x66, 0x6d, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, + 0x64, 0x5b, 0x32, 0x5d, 0x2c, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x2e, 0x79, 0x31, 0x29, 0x20, 0x3a, 0x20, 0x64, 0x33, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x27, 0x2c, 0x27, 0x29, + 0x28, 0x64, 0x5b, 0x32, 0x5d, 0x29, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x3d, + 0x20, 0x64, 0x33, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x27, 0x23, 0x74, 0x70, 0x6c, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x27, 0x29, 0x2e, + 0x68, 0x74, 0x6d, 0x6c, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x48, 0x6f, 0x67, 0x61, 0x6e, 0x2e, 0x63, 0x6f, + 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x28, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x29, 0x2e, 0x72, 0x65, 0x6e, 0x64, 0x65, 0x72, + 0x28, 0x7b, 0x27, 0x64, 0x61, 0x74, 0x61, 0x27, 0x3a, 0x20, 0x64, + 0x7d, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6f, 0x76, 0x65, 0x72, + 0x28, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x2c, 0x20, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2c, 0x20, 0x69, 0x64, 0x78, 0x29, 0x20, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x3d, 0x20, 0x78, 0x53, + 0x63, 0x61, 0x6c, 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x5b, 0x30, + 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x78, 0x53, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, + 0x28, 0x29, 0x20, 0x2f, 0x20, 0x32, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x3d, 0x20, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x2d, + 0x77, 0x72, 0x61, 0x70, 0x27, 0x29, 0x3b, 0x74, 0x6f, 0x6f, 0x6c, + 0x74, 0x69, 0x70, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x28, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c, 0x20, 0x69, 0x64, 0x78, 0x29, + 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x27, 0x6c, 0x65, + 0x66, 0x74, 0x27, 0x2c, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x2b, + 0x20, 0x27, 0x70, 0x78, 0x27, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x28, 0x27, 0x74, 0x6f, 0x70, 0x27, 0x2c, 0x20, 0x20, 0x28, + 0x64, 0x33, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x28, 0x5f, 0x73, + 0x65, 0x6c, 0x66, 0x29, 0x5b, 0x31, 0x5d, 0x20, 0x2b, 0x20, 0x31, + 0x30, 0x29, 0x20, 0x2b, 0x20, 0x27, 0x70, 0x78, 0x27, 0x29, 0x2e, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x27, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x27, 0x2c, 0x20, 0x27, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x27, 0x29, 0x3b, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, + 0x6c, 0x69, 0x6e, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, + 0x74, 0x6f, 0x72, 0x27, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x28, 0x27, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x27, 0x2c, + 0x20, 0x27, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x27, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x27, 0x2c, 0x20, 0x27, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x27, 0x20, 0x2b, 0x20, 0x6c, + 0x65, 0x66, 0x74, 0x20, 0x2b, 0x20, 0x27, 0x2c, 0x27, 0x20, 0x2b, + 0x20, 0x30, 0x20, 0x2b, 0x20, 0x27, 0x29, 0x27, 0x29, 0x3b, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6f, + 0x75, 0x73, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x29, 0x20, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, + 0x20, 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x2e, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, + 0x69, 0x70, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x27, 0x29, 0x3b, 0x74, + 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x28, 0x27, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x27, + 0x2c, 0x20, 0x27, 0x6e, 0x6f, 0x6e, 0x65, 0x27, 0x29, 0x3b, 0x67, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x27, 0x6c, 0x69, + 0x6e, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x69, 0x63, 0x61, 0x74, 0x6f, + 0x72, 0x27, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x27, + 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x27, 0x2c, 0x20, 0x27, + 0x6e, 0x6f, 0x6e, 0x65, 0x27, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x64, 0x64, 0x52, 0x65, + 0x63, 0x74, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x20, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x77, 0x20, 0x3d, 0x20, + 0x28, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x57, 0x28, 0x29, 0x20, 0x2f, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x65, 0x63, 0x74, + 0x73, 0x20, 0x3d, 0x20, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x28, 0x27, 0x67, 0x2e, 0x72, 0x65, 0x63, 0x74, 0x73, 0x27, + 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, + 0x28, 0x27, 0x72, 0x65, 0x63, 0x74, 0x27, 0x29, 0x2e, 0x64, 0x61, + 0x74, 0x61, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x72, 0x65, + 0x63, 0x74, 0x73, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x27, 0x73, 0x76, + 0x67, 0x3a, 0x72, 0x65, 0x63, 0x74, 0x27, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x27, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x27, + 0x2c, 0x20, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x28, 0x29, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x27, 0x2c, 0x20, 0x27, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x27, + 0x29, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x73, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x77, 0x69, 0x64, 0x74, 0x68, 0x27, 0x2c, 0x20, + 0x64, 0x33, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x6f, 0x72, 0x28, + 0x77, 0x29, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x27, 0x78, + 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x77, 0x20, 0x2a, 0x20, + 0x69, 0x29, 0x3b, 0x20, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x27, 0x79, 0x27, 0x2c, 0x20, 0x30, 0x29, 0x2e, 0x6f, 0x6e, + 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x20, 0x7b, 0x6d, 0x6f, + 0x75, 0x73, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x2c, 0x20, 0x64, 0x2c, 0x20, 0x69, 0x29, 0x3b, 0x7d, 0x29, + 0x2e, 0x6f, 0x6e, 0x28, 0x27, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6c, + 0x65, 0x61, 0x76, 0x65, 0x27, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x2c, 0x20, 0x69, 0x29, + 0x20, 0x7b, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6f, 0x75, 0x74, 0x28, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, + 0x67, 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x63, 0x74, 0x73, + 0x2e, 0x65, 0x78, 0x69, 0x74, 0x28, 0x29, 0x2e, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x28, 0x29, 0x3b, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x28, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x29, 0x20, + 0x7b, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x65, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x20, 0x7b, + 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x70, 0x44, + 0x61, 0x74, 0x61, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x73, + 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x76, 0x67, 0x20, 0x3d, 0x20, 0x64, 0x33, 0x2e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x27, + 0x73, 0x76, 0x67, 0x27, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, + 0x5b, 0x64, 0x61, 0x74, 0x61, 0x5d, 0x29, 0x3b, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x53, 0x6b, 0x65, 0x6c, 0x65, 0x74, 0x6f, 0x6e, + 0x28, 0x73, 0x76, 0x67, 0x29, 0x3b, 0x73, 0x76, 0x67, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x7b, 0x27, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x27, 0x3a, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x27, 0x68, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x27, 0x3a, 0x20, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x67, + 0x20, 0x3d, 0x20, 0x73, 0x76, 0x67, 0x2e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x28, 0x27, 0x67, 0x27, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, + 0x6d, 0x27, 0x2c, 0x20, 0x27, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, + 0x61, 0x74, 0x65, 0x28, 0x27, 0x20, 0x2b, 0x20, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x2e, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x2b, 0x20, + 0x27, 0x2c, 0x27, 0x20, 0x2b, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2e, 0x74, 0x6f, 0x70, 0x20, 0x2b, 0x20, 0x27, 0x29, 0x27, + 0x29, 0x3b, 0x61, 0x64, 0x64, 0x47, 0x72, 0x69, 0x64, 0x28, 0x67, + 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x61, 0x64, 0x64, + 0x41, 0x78, 0x69, 0x73, 0x28, 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x29, 0x3b, 0x61, 0x64, 0x64, 0x42, 0x61, 0x72, 0x73, 0x28, + 0x67, 0x2c, 0x20, 0x64, 0x61, 0x74, 0x61, 0x29, 0x3b, 0x61, 0x64, + 0x64, 0x52, 0x65, 0x63, 0x74, 0x73, 0x28, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x67, 0x2c, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x29, 0x3b, 0x7d, 0x29, 0x3b, 0x7d, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x2e, 0x6f, 0x70, 0x74, 0x73, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, + 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6f, 0x70, 0x74, 0x73, 0x3b, 0x6f, 0x70, 0x74, 0x73, 0x20, 0x3d, + 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x3d, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, + 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x3b, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x28, 0x5f, 0x29, 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, + 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x3b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x20, 0x3d, 0x20, 0x5f, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x3b, 0x7d, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, 0x20, 0x7b, 0x69, + 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x20, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x5f, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2e, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, 0x20, + 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x2e, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, 0x20, 0x7b, + 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x3b, 0x78, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x20, + 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2e, 0x79, 0x30, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, 0x20, 0x7b, + 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, + 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x30, 0x3b, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x30, 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, 0x3b, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2e, 0x79, 0x31, 0x20, 0x3d, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x5f, 0x29, + 0x20, 0x7b, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x31, 0x3b, 0x79, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x31, 0x20, 0x3d, 0x20, 0x5f, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3b, 0x7d, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x3b, 0x7d, 0x00 +}; + +const int charts_js_length = 20421; diff --git a/goaccess++/src/color.c b/goaccess++/src/color.c new file mode 100644 index 0000000..dbc7ff6 --- /dev/null +++ b/goaccess++/src/color.c @@ -0,0 +1,840 @@ +/** + * color.c -- functions related to custom color + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> + +#include "color.h" + +#include "error.h" +#include "gslist.h" +#include "util.h" +#include "xmalloc.h" + +static GSLList *color_list = NULL; +static GSLList *pair_list = NULL; + +/* *INDENT-OFF* */ +static GEnum CSTM_COLORS[] = { + {"COLOR_MTRC_HITS" , COLOR_MTRC_HITS}, + {"COLOR_MTRC_VISITORS" , COLOR_MTRC_VISITORS}, + {"COLOR_MTRC_HITS_PERC" , COLOR_MTRC_HITS_PERC}, + {"COLOR_MTRC_VISITORS_PERC" , COLOR_MTRC_VISITORS_PERC}, + {"COLOR_MTRC_BW" , COLOR_MTRC_BW}, + {"COLOR_MTRC_AVGTS" , COLOR_MTRC_AVGTS}, + {"COLOR_MTRC_CUMTS" , COLOR_MTRC_CUMTS}, + {"COLOR_MTRC_MAXTS" , COLOR_MTRC_MAXTS}, + {"COLOR_MTRC_PROT" , COLOR_MTRC_PROT}, + {"COLOR_MTRC_MTHD" , COLOR_MTRC_MTHD}, + {"COLOR_MTRC_DATA" , COLOR_MTRC_DATA}, + {"COLOR_MTRC_HITS_PERC_MAX" , COLOR_MTRC_HITS_PERC_MAX}, + {"COLOR_MTRC_VISITORS_PERC_MAX" , COLOR_MTRC_VISITORS_PERC_MAX}, + {"COLOR_PANEL_COLS" , COLOR_PANEL_COLS}, + {"COLOR_BARS" , COLOR_BARS}, + {"COLOR_ERROR" , COLOR_ERROR}, + {"COLOR_SELECTED" , COLOR_SELECTED}, + {"COLOR_PANEL_ACTIVE" , COLOR_PANEL_ACTIVE}, + {"COLOR_PANEL_HEADER" , COLOR_PANEL_HEADER}, + {"COLOR_PANEL_DESC" , COLOR_PANEL_DESC}, + {"COLOR_OVERALL_LBLS" , COLOR_OVERALL_LBLS}, + {"COLOR_OVERALL_VALS" , COLOR_OVERALL_VALS}, + {"COLOR_OVERALL_PATH" , COLOR_OVERALL_PATH}, + {"COLOR_ACTIVE_LABEL" , COLOR_ACTIVE_LABEL}, + {"COLOR_BG" , COLOR_BG}, + {"COLOR_DEFAULT" , COLOR_DEFAULT}, + {"COLOR_PROGRESS" , COLOR_PROGRESS}, +}; + +static const char *colors256_mono[] = { + "COLOR_MTRC_HITS color7:color-1", + "COLOR_MTRC_VISITORS color8:color-1", + "COLOR_MTRC_DATA color7:color-1", + "COLOR_MTRC_BW color8:color-1", + "COLOR_MTRC_AVGTS color8:color-1", + "COLOR_MTRC_CUMTS color8:color-1", + "COLOR_MTRC_MAXTS color8:color-1", + "COLOR_MTRC_PROT color8:color-1", + "COLOR_MTRC_MTHD color7:color-1", + "COLOR_MTRC_HITS_PERC color0:color-1 bold", + "COLOR_MTRC_HITS_PERC color1:color-1 bold VISITORS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold OS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold BROWSERS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold VISIT_TIMES", + "COLOR_MTRC_HITS_PERC_MAX color0:color-1 bold", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold VISITORS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold OS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold BROWSERS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold VISIT_TIMES", + "COLOR_MTRC_VISITORS_PERC color0:color-1 bold", + "COLOR_MTRC_VISITORS_PERC_MAX color0:color-1 bold", + "COLOR_PANEL_COLS color7:color-1", + "COLOR_BARS color7:color-1", + "COLOR_ERROR color7:color1", + "COLOR_SELECTED color7:color8", + "COLOR_PANEL_ACTIVE color0:color3", + "COLOR_PANEL_HEADER color0:color7", + "COLOR_PANEL_DESC color7:color-1", + "COLOR_OVERALL_LBLS color7:color-1 bold", + "COLOR_OVERALL_VALS color6:color-1 bold", + "COLOR_OVERALL_PATH color3:color-1", + "COLOR_ACTIVE_LABEL color4:color7", + "COLOR_BG color7:color-1", + "COLOR_DEFAULT color7:color-1", + "COLOR_PROGRESS color0:color6", +}; + +static const char *colors256_green[] = { + "COLOR_MTRC_HITS color7:color-1", + "COLOR_MTRC_VISITORS color8:color-1", + "COLOR_MTRC_DATA color7:color-1", + "COLOR_MTRC_BW color8:color-1", + "COLOR_MTRC_AVGTS color8:color-1", + "COLOR_MTRC_CUMTS color8:color-1", + "COLOR_MTRC_MAXTS color8:color-1", + "COLOR_MTRC_PROT color8:color-1", + "COLOR_MTRC_MTHD color7:color-1", + "COLOR_MTRC_HITS_PERC color0:color-1 bold", + "COLOR_MTRC_HITS_PERC color1:color-1 bold VISITORS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold OS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold BROWSERS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold VISIT_TIMES", + "COLOR_MTRC_HITS_PERC_MAX color0:color-1 bold", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold VISITORS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold OS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold BROWSERS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold VISIT_TIMES", + "COLOR_MTRC_VISITORS_PERC color0:color-1 bold", + "COLOR_MTRC_VISITORS_PERC_MAX color0:color-1 bold", + "COLOR_PANEL_COLS color7:color-1", + "COLOR_BARS color7:color-1", + "COLOR_ERROR color7:color1", + "COLOR_SELECTED color7:color8", + "COLOR_PANEL_ACTIVE color0:color3", + "COLOR_PANEL_HEADER color0:color35", + "COLOR_PANEL_DESC color7:color-1", + "COLOR_OVERALL_LBLS color7:color-1 bold", + "COLOR_OVERALL_VALS color6:color-1 bold", + "COLOR_OVERALL_PATH color3:color-1", + "COLOR_ACTIVE_LABEL color7:color35", + "COLOR_BG color7:color-1", + "COLOR_DEFAULT color7:color-1", + "COLOR_PROGRESS color0:color6", +}; + +static const char *colors256_monokai[] = { + "COLOR_MTRC_HITS color197:color-1", + "COLOR_MTRC_VISITORS color148:color-1", + "COLOR_MTRC_DATA color7:color-1", + "COLOR_MTRC_BW color81:color-1", + "COLOR_MTRC_AVGTS color247:color-1", + "COLOR_MTRC_CUMTS color95:color-1", + "COLOR_MTRC_MAXTS color186:color-1", + "COLOR_MTRC_PROT color141:color-1", + "COLOR_MTRC_MTHD color81:color-1", + "COLOR_MTRC_HITS_PERC color186:color-1", + "COLOR_MTRC_HITS_PERC color186:color-1 VISITORS", + "COLOR_MTRC_HITS_PERC color186:color-1 OS", + "COLOR_MTRC_HITS_PERC color186:color-1 BROWSERS", + "COLOR_MTRC_HITS_PERC color186:color-1 VISIT_TIMES", + "COLOR_MTRC_HITS_PERC_MAX color208:color-1", + "COLOR_MTRC_HITS_PERC_MAX color208:color-1 VISITORS", + "COLOR_MTRC_HITS_PERC_MAX color208:color-1 OS", + "COLOR_MTRC_HITS_PERC_MAX color208:color-1 BROWSERS", + "COLOR_MTRC_HITS_PERC_MAX color208:color-1 VISIT_TIMES", + "COLOR_MTRC_VISITORS_PERC color187:color-1", + "COLOR_MTRC_VISITORS_PERC_MAX color208:color-1", + "COLOR_PANEL_COLS color242:color-1", + "COLOR_BARS color186:color-1", + "COLOR_ERROR color231:color197", + "COLOR_SELECTED color0:color215", + "COLOR_PANEL_ACTIVE color7:color240", + "COLOR_PANEL_HEADER color7:color237", + "COLOR_PANEL_DESC color242:color-1", + "COLOR_OVERALL_LBLS color251:color-1", + "COLOR_OVERALL_VALS color148:color-1", + "COLOR_OVERALL_PATH color186:color-1", + "COLOR_ACTIVE_LABEL color7:color237", + "COLOR_BG color7:color-1", + "COLOR_DEFAULT color7:color-1", + "COLOR_PROGRESS color7:color141", +}; + +static const char *colors8_mono[] = { + "COLOR_MTRC_HITS color7:color-1", + "COLOR_MTRC_VISITORS color0:color-1 bold", + "COLOR_MTRC_DATA color7:color-1", + "COLOR_MTRC_BW color0:color-1 bold", + "COLOR_MTRC_AVGTS color0:color-1 bold", + "COLOR_MTRC_CUMTS color0:color-1 bold", + "COLOR_MTRC_MAXTS color0:color-1 bold", + "COLOR_MTRC_PROT color0:color-1 bold", + "COLOR_MTRC_MTHD color7:color-1 ", + "COLOR_MTRC_HITS_PERC color0:color-1 bold", + "COLOR_MTRC_HITS_PERC color1:color-1 bold VISITORS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold OS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold BROWSERS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold VISIT_TIMES", + "COLOR_MTRC_HITS_PERC_MAX color0:color-1 bold", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold VISITORS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold OS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold BROWSERS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold VISIT_TIMES", + "COLOR_MTRC_VISITORS_PERC color0:color-1 bold", + "COLOR_MTRC_VISITORS_PERC_MAX color0:color-1 bold", + "COLOR_PANEL_COLS color7:color-1", + "COLOR_BARS color7:color-1", + "COLOR_ERROR color7:color1", + "COLOR_SELECTED color0:color7", + "COLOR_PANEL_ACTIVE color0:color3", + "COLOR_PANEL_HEADER color0:color7", + "COLOR_PANEL_DESC color7:color-1", + "COLOR_OVERALL_LBLS color7:color-1 bold", + "COLOR_OVERALL_VALS color6:color-1", + "COLOR_OVERALL_PATH color3:color-1", + "COLOR_ACTIVE_LABEL color4:color7", + "COLOR_BG color7:color-1", + "COLOR_DEFAULT color7:color-1", + "COLOR_PROGRESS color0:color6", +}; + +static const char *colors8_green[] = { + "COLOR_MTRC_HITS color7:color-1", + "COLOR_MTRC_VISITORS color0:color-1 bold", + "COLOR_MTRC_DATA color7:color-1", + "COLOR_MTRC_BW color0:color-1 bold", + "COLOR_MTRC_AVGTS color0:color-1 bold", + "COLOR_MTRC_CUMTS color0:color-1 bold", + "COLOR_MTRC_MAXTS color0:color-1 bold", + "COLOR_MTRC_PROT color0:color-1 bold", + "COLOR_MTRC_MTHD color7:color-1 ", + "COLOR_MTRC_HITS_PERC color0:color-1 bold", + "COLOR_MTRC_HITS_PERC color1:color-1 bold VISITORS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold OS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold BROWSERS", + "COLOR_MTRC_HITS_PERC color1:color-1 bold VISIT_TIMES", + "COLOR_MTRC_HITS_PERC_MAX color0:color-1 bold", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold VISITORS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold OS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold BROWSERS", + "COLOR_MTRC_HITS_PERC_MAX color3:color-1 bold VISIT_TIMES", + "COLOR_MTRC_VISITORS_PERC color0:color-1 bold", + "COLOR_MTRC_VISITORS_PERC_MAX color0:color-1 bold", + "COLOR_PANEL_COLS color7:color-1", + "COLOR_BARS color2:color-1", + "COLOR_ERROR color7:color1", + "COLOR_SELECTED color0:color7", + "COLOR_PANEL_ACTIVE color0:color3", + "COLOR_PANEL_HEADER color0:color2", + "COLOR_PANEL_DESC color7:color-1", + "COLOR_OVERALL_LBLS color7:color-1 bold", + "COLOR_OVERALL_VALS color6:color-1", + "COLOR_OVERALL_PATH color3:color-1", + "COLOR_ACTIVE_LABEL color0:color2", + "COLOR_BG color7:color-1", + "COLOR_DEFAULT color7:color-1", + "COLOR_PROGRESS color0:color6", +}; + +static const char *nocolors[] = { + "COLOR_MTRC_HITS color0:color-1", + "COLOR_MTRC_VISITORS color0:color-1", + "COLOR_MTRC_DATA color0:color-1", + "COLOR_MTRC_BW color0:color-1", + "COLOR_MTRC_AVGTS color0:color-1", + "COLOR_MTRC_CUMTS color0:color-1", + "COLOR_MTRC_MAXTS color0:color-1", + "COLOR_MTRC_PROT color0:color-1", + "COLOR_MTRC_MTHD color0:color-1", + "COLOR_MTRC_HITS_PERC color0:color-1", + "COLOR_MTRC_HITS_PERC_MAX color0:color-1", + "COLOR_MTRC_VISITORS_PERC color0:color-1", + "COLOR_MTRC_VISITORS_PERC_MAX color0:color-1", + "COLOR_PANEL_COLS color0:color-1", + "COLOR_BARS color0:color-1", + "COLOR_ERROR color0:color-1", + "COLOR_SELECTED color0:color-1 reverse", + "COLOR_PANEL_ACTIVE color0:color-1 reverse", + "COLOR_PANEL_HEADER color0:color-1 reverse", + "COLOR_PANEL_DESC color0:color-1", + "COLOR_OVERALL_LBLS color0:color-1", + "COLOR_OVERALL_VALS color0:color-1", + "COLOR_OVERALL_PATH color0:color-1", + "COLOR_ACTIVE_LABEL color0:color-1 reverse", + "COLOR_BG color0:color-1", + "COLOR_DEFAULT color0:color-1", + "COLOR_PROGRESS color0:color-1 reverse", +}; + +/* *INDENT-ON* */ + +/* Allocate memory for color elements */ +static GColors * +new_gcolors (void) +{ + GColors *color = xcalloc (1, sizeof (GColors)); + color->module = -1; + + return color; +} + +/* Allocate memory for a color element properties */ +static GColorPair * +new_gcolorpair (void) +{ + GColorPair *pair = xcalloc (1, sizeof (GColorPair)); + /* Must be between 2 and COLOR_PAIRS-1. + * Starts at 2 since COLOR_NORMAL has already been set */ + pair->idx = 2; + + return pair; +} + +/* Free malloc'd memory for color elements */ +void +free_color_lists (void) +{ + if (pair_list) + list_remove_nodes (pair_list); + if (color_list) + list_remove_nodes (color_list); + color_list = NULL; + pair_list = NULL; +} + +/* Set a default color - COLOR_NORMAL, this will be used if + * no colors are supported by the terminal */ +void +set_normal_color (void) +{ + GColorPair *pair = new_gcolorpair (); + GColors *color = new_gcolors (); + + pair->idx = 1; + pair->fg = COLOR_WHITE; + pair->bg = -1; + + color->pair = pair; + color->item = COLOR_NORMAL; + + pair_list = list_create (pair); + color_list = list_create (color); + + init_pair (pair->idx, pair->fg, pair->bg); +} + +/* Get color properties for COLOR_OVERALL_LBLS */ +GColors * +color_overall_lbls (void) +{ + return get_color (COLOR_OVERALL_LBLS); +} + +/* Get color properties for COLOR_OVERALL_VALS */ +GColors * +color_overall_vals (void) +{ + return get_color (COLOR_OVERALL_VALS); +} + +/* Get color properties for COLOR_OVERALL_PATH */ +GColors * +color_overall_path (void) +{ + return get_color (COLOR_OVERALL_PATH); +} + +/* Get color properties for COLOR_PANEL_HEADER */ +GColors * +color_panel_header (void) +{ + return get_color (COLOR_PANEL_HEADER); +} + +/* Get color properties for COLOR_PANEL_DESC */ +GColors * +color_panel_desc (void) +{ + return get_color (COLOR_PANEL_DESC); +} + +/* Get color properties for COLOR_PANEL_ACTIVE*/ +GColors * +color_panel_active (void) +{ + return get_color (COLOR_PANEL_ACTIVE); +} + +/* Get color properties for COLOR_SELECTED */ +GColors * +color_selected (void) +{ + return get_color (COLOR_SELECTED); +} + +/* Get color properties for COLOR_PROGRESS */ +GColors * +color_progress (void) +{ + return get_color (COLOR_PROGRESS); +} + +/* Get color properties for COLOR_DEFAULT */ +GColors * +color_default (void) +{ + return get_color (COLOR_DEFAULT); +} + +/* Get color properties for COLOR_ERROR */ +GColors * +color_error (void) +{ + return get_color (COLOR_ERROR); +} + +/* Get the enumerated color given its equivalent color string. + * + * On error, -1 is returned. + * On success, the enumerated color is returned. */ +static int +get_color_item_enum (const char *str) +{ + return str2enum (CSTM_COLORS, ARRAY_SIZE (CSTM_COLORS), str); +} + +/* Extract color number from the given config string. + * + * On error, -2 is returned. If color is greater than max colors, it aborts. + * On success, the color number is returned. */ +static int +extract_color (char *color) +{ + char *sEnd; + int col = 0; + + if (strncasecmp (color, "color", 5) != 0) + return -2; + + color += 5; + col = strtol (color, &sEnd, 10); + if (color == sEnd || *sEnd != '\0' || errno == ERANGE) + return -2; + /* ensure used color is supported by the terminal */ + if (col > COLORS) + FATAL ("Terminal doesn't support color: %d - max colors: %d", col, COLORS); + + return col; +} + +/* Assign the background and foreground color number from the given + * config string to GColorPair. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +static int +parse_bg_fg_color (GColorPair * pair, const char *value) +{ + char bgcolor[COLOR_STR_LEN] = "", fgcolor[COLOR_STR_LEN] = ""; + int ret = 0; + + if (sscanf (value, "%8[^:]:%8[^ ]", fgcolor, bgcolor) != 2) + return 1; + + if ((pair->bg = extract_color (bgcolor)) == -2) + ret = 1; + + if ((pair->fg = extract_color (fgcolor)) == -2) + ret = 1; + + return ret; +} + +/* Assign color attributes from the given config string to GColors. */ +static void +locate_attr_color (GColors * color, const char *attr) +{ + if (strstr (attr, "bold")) + color->attr |= A_BOLD; + if (strstr (attr, "underline")) + color->attr |= A_UNDERLINE; + if (strstr (attr, "normal")) + color->attr |= A_NORMAL; + if (strstr (attr, "reverse")) + color->attr |= A_REVERSE; + if (strstr (attr, "standout")) + color->attr |= A_REVERSE; + if (strstr (attr, "blink")) + color->attr |= A_BLINK; +} + +/* Parse color attributes from the given config string. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +static int +parse_attr_color (GColors * color, const char *value) +{ + char *line, *ptr, *start; + int ret = 0; + + line = xstrdup (value); + + start = strchr (line, ' '); + if ((!start) || (!*(start + 1))) { + LOG_DEBUG (("attempted to parse color attr: %s\n", value)); + goto clean; + } + + start++; + while (1) { + if ((ptr = strpbrk (start, ", ")) != NULL) + *ptr = 0; + locate_attr_color (color, start); + if (ptr == NULL) + break; + start = ptr + 1; + } + +clean: + free (line); + + return ret; +} + +/* Parse color module from the given config string. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +static int +parse_module_color (GColors * color, const char *value) +{ + char *line = xstrdup (value), *p; + + p = strrchr (line, ' '); + if (!p || !*(p + 1)) { + LOG_DEBUG (("attempted to parse color module: %s\n", value)); + goto clean; + } + + if ((color->module = get_module_enum (p + 1)) == -1) + LOG_DEBUG (("attempted to parse color module: %s\n", value)); + +clean: + free (line); + + return 0; +} + +/* Find a color by item and module attributes on the list of already + * parsed colors. + * + * If color exists, 1 is returned. + * If color does not exist, 1 is returned. */ +static int +find_color_in_list (void *data, void *color) +{ + GColors *new_color = color; + GColors *old_color = data; + + if (old_color->item != new_color->item) + return 0; + if (old_color->module != new_color->module) + return 0; + return 1; +} + +/* Find a color by foreground and background attributes on the list of + * already parsed colors. + * + * If color exists, 1 is returned. + * If color does not exist, 1 is returned. */ +static int +find_pair_in_list (void *data, void *color) +{ + GColorPair *new_color = color; + GColorPair *old_color = data; + + if (old_color->fg != new_color->fg) + return 0; + if (old_color->bg != new_color->bg) + return 0; + return 1; +} + +/* Compare a color item (GColorItem) that has no module with the given needle + * item. + * + * If the items match and with no module, 1 is returned. + * If condition is not satisfied, 0 is returned. */ +static int +find_color_item_in_list (void *data, void *needle) +{ + GColors *color = data; + GColorItem *item = needle; + + return color->item == (GColorItem) (*(int *) item) && color->module == -1; +} + +/* Compare a color item (GColorItem) and module with the given needle item. + * + * If the items match and with no module, 1 is returned. + * If condition is not satisfied, 0 is returned. */ +static int +find_color_item_module_in_list (void *data, void *needle) +{ + GColors *color = data; + GColors *item = needle; + + return color->item == item->item && color->module == item->module; +} + +/* Get color item properties given an item (enumerated). + * + * On error, it aborts. + * On success, the color item properties are returned, or NULL if no match + * found. */ +GColors * +get_color (GColorItem item) +{ + GColorItem normal = COLOR_NORMAL; + GSLList *match = NULL; + + if ((match = list_find (color_list, find_color_item_in_list, &item))) + return (GColors *) match->data; + + if ((match = list_find (color_list, find_color_item_in_list, &normal))) + return (GColors *) match->data; + + /* should not get here */ + FATAL ("Unable to find color item %d", item); +} + +/* Get color item properties given an item (enumerated) and its module. + * + * On error, it aborts. + * On success, the color item properties are returned, or NULL if no match + * found. */ +GColors * +get_color_by_item_module (GColorItem item, GModule module) +{ + GColors *needle = new_gcolors (), *color = NULL; + GSLList *match = NULL; + + needle->module = module; + needle->item = item; + + /* find color for specific item/module pair */ + if ((match = list_find (color_list, find_color_item_module_in_list, needle))) + color = match->data; + + /* attempt to find color by item (fallback) */ + if (!color) + color = get_color (item); + free (needle); + + return color; +} + +/* Parse a color definition line from the config file. + * + * On error, it aborts. + * On success, the color properties are assigned */ +static void +parse_color_line (GColorPair * pair, GColors * color, char *line) +{ + char *val; + int item = 0; + size_t idx; + + /* key */ + idx = strcspn (line, " \t"); + if (strlen (line) == idx) + FATAL ("Malformed color key at line: %s", line); + + line[idx] = '\0'; + if ((item = get_color_item_enum (line)) == -1) + FATAL ("Unable to find color key: %s", line); + + /* value */ + val = line + (idx + 1); + idx = strspn (val, " \t"); + if (strlen (val) == idx) + FATAL ("Malformed color value at line: %s", line); + val = val + idx; + + /* get background/foreground color */ + if (parse_bg_fg_color (pair, val) == 1) + FATAL ("Invalid bg/fg color pairs at: %s %s", line, val); + + if (parse_attr_color (color, val) == 1) + FATAL ("Invalid color attrs at: %s %s", line, val); + + if (parse_module_color (color, val) == 1) + FATAL ("Invalid color module at: %s %s", line, val); + + color->item = item; +} + +/* Attempt to prepend the given color on our color linked list. + * + * On error, or if color already exists, the given color is freed. + * On success, or if not color found, store color properties */ +static void +prepend_color (GColors ** color) +{ + GSLList *match = NULL; + + /* create a list of colors if one does not exist */ + if (color_list == NULL) { + color_list = list_create (*color); + } + /* attempt to find the given color data type (by item and attributes) in + * our color list */ + else if ((match = list_find (color_list, find_color_in_list, *color))) { + /* if found, free the recently malloc'd color data type and use + * existing color */ + free (*color); + *color = NULL; + } else { + /* not a dup, so insert the new color in our color list */ + color_list = list_insert_prepend (color_list, *color); + } +} + +/* Parse a color definition line from the config file and store it on a signle + * linked-list. + * + * On error, it aborts. + * On success, the color properties are stored */ +static void +parse_color (char *line) +{ + GSLList *match = NULL; + GColors *color = NULL; + GColorPair *pair = NULL; + + color = new_gcolors (); + pair = new_gcolorpair (); + + /* extract a color pair and color attributes from the given config line */ + parse_color_line (pair, color, line); + + /* create a pair color list if one doesn't exist */ + if (pair_list == NULL) { + pair_list = list_create (pair); + } + /* attempt to find the given color pair in our pair list */ + else if ((match = list_find (pair_list, find_pair_in_list, pair))) { + /* pair found, use new pair and free existing one */ + free (pair); + pair = (GColorPair *) match->data; + } + /* pair not found, use it then */ + else { + pair->idx += list_count (pair_list); + pair_list = list_insert_prepend (pair_list, pair); + } + /* set color pair */ + color->pair = pair; + prepend_color (&color); + + /* if no color pair was found, then we init the color pair */ + if (!match && color) + init_pair (color->pair->idx, color->pair->fg, color->pair->bg); + + free (line); +} + +/* Iterate over all color definitions in the config file. + * + * On error, it aborts. + * On success, the color properties are parsed and stored */ +static void +parse_colors (const char *colors[], size_t n) +{ + char *line; + size_t i; + + for (i = 0; i < n; ++i) { + line = strdup (colors[i]); + /* did not find a valid format */ + if (strchr (line, ':') == NULL) { + free (line); + continue; + } + parse_color (line); + } +} + +/* Use default color definitions if necessary. */ +static void +add_default_colors (void) +{ + /* no colors */ + if (COLORS < 8) + parse_colors (nocolors, ARRAY_SIZE (nocolors)); + + /* 256 colors, and no color scheme set or set to monokai */ + if (COLORS == 256 && (!conf.color_scheme || conf.color_scheme == MONOKAI)) + parse_colors (colors256_monokai, ARRAY_SIZE (colors256_monokai)); + /* otherwise use 16 colors scheme */ + else if (COLORS > 16) { + if (conf.color_scheme == STD_GREEN) + parse_colors (colors256_green, ARRAY_SIZE (colors256_green)); + else + parse_colors (colors256_mono, ARRAY_SIZE (colors256_mono)); + } + + /* 8 colors */ + if (COLORS >= 8 && COLORS <= 16) { + if (conf.color_scheme == STD_GREEN) + parse_colors (colors8_green, ARRAY_SIZE (colors8_green)); + else + parse_colors (colors8_mono, ARRAY_SIZE (colors8_mono)); + } +} + +/* Entry point to parse color definitions or use default colors */ +void +set_colors (int force) +{ + errno = 0; + if (conf.color_idx > 0 && !force) + parse_colors (conf.colors, conf.color_idx); + else + add_default_colors (); +} diff --git a/goaccess++/src/color.h b/goaccess++/src/color.h new file mode 100644 index 0000000..5f54354 --- /dev/null +++ b/goaccess++/src/color.h @@ -0,0 +1,113 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef COLOR_H_INCLUDED +#define COLOR_H_INCLUDED + +#define COLOR_STR_LEN 9 + +/* Color Items/Fields */ +typedef enum CSTM_COLORS +{ + COLOR_NORMAL, + COLOR_MTRC_HITS, + COLOR_MTRC_VISITORS, + COLOR_MTRC_DATA, + COLOR_MTRC_BW, + COLOR_MTRC_AVGTS, + COLOR_MTRC_CUMTS, + COLOR_MTRC_MAXTS, + COLOR_MTRC_PROT, + COLOR_MTRC_MTHD, + COLOR_MTRC_HITS_PERC, + COLOR_MTRC_HITS_PERC_MAX, + COLOR_MTRC_VISITORS_PERC, + COLOR_MTRC_VISITORS_PERC_MAX, + COLOR_PANEL_COLS, + COLOR_BARS, + COLOR_ERROR, + COLOR_SELECTED, + COLOR_PANEL_ACTIVE, + COLOR_PANEL_HEADER, + COLOR_PANEL_DESC, + COLOR_OVERALL_LBLS, + COLOR_OVERALL_VALS, + COLOR_OVERALL_PATH, + COLOR_ACTIVE_LABEL, + COLOR_BG, + COLOR_DEFAULT, + COLOR_PROGRESS, +} GColorItem; + +/* Default Color Schemes */ +typedef enum SCHEMES +{ + NO_COLOR, + MONOCHROME, + STD_GREEN, + MONOKAI, +} GShemes; + +#include "commons.h" + +/* Each color properties */ +typedef struct GColorPair_ +{ + short idx; /* color pair index identifier */ + short fg; /* foreground color */ + short bg; /* background color */ +} GColorPair; + +/* Color */ +typedef struct GColors_ +{ + GColorItem item; /* screen item */ + GColorPair *pair; /* color pair */ + int attr; /* color attributes, e.g., bold */ + short module; /* panel */ +} GColors; + +GColors *color_default (void); +GColors *color_error (void); +GColors *color_overall_lbls (void); +GColors *color_overall_path (void); +GColors *color_overall_vals (void); +GColors *color_panel_active (void); +GColors *color_panel_desc (void); +GColors *color_panel_header (void); +GColors *color_progress (void); +GColors *color_selected (void); +GColors *get_color_by_item_module (GColorItem item, GModule module); +GColors *get_color (GColorItem item); +GColors *get_color_normal (void); +void free_color_lists (void); +void set_colors (int force); +void set_normal_color (void); + +#endif // for #ifndef COLOR_H diff --git a/goaccess++/src/color.o b/goaccess++/src/color.o new file mode 100644 index 0000000..a37de4a Binary files /dev/null and b/goaccess++/src/color.o differ diff --git a/goaccess++/src/commons.c b/goaccess++/src/commons.c new file mode 100644 index 0000000..cc7d45d --- /dev/null +++ b/goaccess++/src/commons.c @@ -0,0 +1,504 @@ +/** + * commons.c -- holds different data types + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include "commons.h" + +#include "error.h" +#include "labels.h" +#include "settings.h" +#include "util.h" +#include "xmalloc.h" + +/* processing time */ +time_t end_proc; +time_t timestamp; +time_t start_proc; + +/* list of available modules/panels */ +int module_list[TOTAL_MODULES] = {[0 ... TOTAL_MODULES - 1] = -1 }; + +/* Get number of items per panel to parse. + * + * The number of items per panel is returned. */ +int +get_max_choices (void) +{ + char *csv = NULL, *json = NULL, *html = NULL; + int max = MAX_CHOICES; + + /* no max choices, return defaults */ + if (conf.max_items <= 0) + return conf.real_time_html ? MAX_CHOICES_RT : MAX_CHOICES; + + /* TERM */ + if (!conf.output_stdout) + return conf.max_items > MAX_CHOICES ? MAX_CHOICES : conf.max_items; + + /* REAL-TIME STDOUT */ + /* real time HTML, display max rt choices */ + if (conf.real_time_html) + return conf.max_items > MAX_CHOICES_RT ? MAX_CHOICES_RT : conf.max_items; + + /* STDOUT */ + /* CSV - allow n amount of choices */ + if (find_output_type (&csv, "csv", 1) == 0) + max = conf.max_items; + /* JSON - allow n amount of choices */ + if (find_output_type (&json, "json", 1) == 0 && conf.max_items > 0) + max = conf.max_items; + /* HTML - takes priority on cases where multiple outputs were given. Note that + * we check either for an .html extension or we assume not extension was passed + * via -o and therefore we are redirecting the output to a file. */ + if (find_output_type (&html, "html", 1) == 0 || conf.output_format_idx == 0) + max = conf.max_items > MAX_CHOICES ? MAX_CHOICES : conf.max_items; + + free (csv); + free (html); + free (json); + + return max; +} + +/* Calculate a percentage. + * + * The percentage is returned. */ +float +get_percentage (unsigned long long total, unsigned long long hit) +{ + return (total == 0 ? 0 : (((float) hit) / total) * 100); +} + +/* Display the storage being used. */ +void +display_storage (void) +{ +#ifdef TCB_BTREE + fprintf (stdout, "%s\n", BUILT_WITH_TCBTREE); +#elif TCB_MEMHASH + fprintf (stdout, "%s\n", BUILT_WITH_TCMEMHASH); +#else + fprintf (stdout, "%s\n", BUILT_WITH_DEFHASH); +#endif +} + +/* Display the path of the default configuration file when `-p` is not used */ +void +display_default_config_file (void) +{ + char *path = get_config_file_path (); + + if (!path) { + fprintf (stdout, "%s\n", ERR_NODEF_CONF_FILE); + fprintf (stdout, "%s `-p /path/goaccess.conf`\n", ERR_NODEF_CONF_FILE_DESC); + } else { + fprintf (stdout, "%s\n", path); + free (path); + } +} + +/* Display the current version. */ +void +display_version (void) +{ + fprintf (stdout, "GoAccess - %s.\n", GO_VERSION); + fprintf (stdout, "%s: http://goaccess.io\n", INFO_MORE_INFO); + fprintf (stdout, "Copyright (C) 2009-2016 by Gerardo Orellana\n"); + fprintf (stdout, "\nBuild configure arguments:\n"); +#ifdef DEBUG + fprintf (stdout, " --enable-debug\n"); +#endif +#ifdef HAVE_NCURSESW_NCURSES_H + fprintf (stdout, " --enable-utf8\n"); +#endif +#ifdef HAVE_LIBGEOIP + fprintf (stdout, " --enable-geoip=legacy\n"); +#endif +#ifdef HAVE_LIBMAXMINDDB + fprintf (stdout, " --enable-geoip=mmdb\n"); +#endif +#ifdef TCB_MEMHASH + fprintf (stdout, " --enable-tcb=memhash\n"); +#endif +#ifdef TCB_BTREE + fprintf (stdout, " --enable-tcb=btree\n"); +#endif +#if defined(TCB_MEMHASH) || defined(TCB_BTREE) +#ifndef HAVE_ZLIB + fprintf (stdout, " --disable-zlib\n"); +#endif +#ifndef HAVE_BZ2 + fprintf (stdout, " --disable-bzip\n"); +#endif +#endif +#ifdef WITH_GETLINE + fprintf (stdout, " --with-getline\n"); +#endif +#ifdef HAVE_LIBSSL + fprintf (stdout, " --with-openssl\n"); +#endif +} + +/* Get the enumerated value given a string. + * + * On error, -1 is returned. + * On success, the enumerated module value is returned. */ +int +str2enum (const GEnum map[], int len, const char *str) +{ + int i; + + for (i = 0; i < len; ++i) { + if (!strcmp (str, map[i].str)) + return map[i].idx; + } + + return -1; +} + +/* Get the enumerated module value given a module string. + * + * On error, -1 is returned. + * On success, the enumerated module value is returned. */ +int +get_module_enum (const char *str) +{ + /* *INDENT-OFF* */ + /* String modules to enumerated modules */ + GEnum enum_modules[] = { + {"VISITORS" , VISITORS} , + {"REQUESTS" , REQUESTS} , + {"REQUESTS_STATIC" , REQUESTS_STATIC} , + {"NOT_FOUND" , NOT_FOUND} , + {"HOSTS" , HOSTS} , + {"OS" , OS} , + {"BROWSERS" , BROWSERS} , + {"VISIT_TIMES" , VISIT_TIMES} , + {"VIRTUAL_HOSTS" , VIRTUAL_HOSTS} , + {"REFERRERS" , REFERRERS} , + {"REFERRING_SITES" , REFERRING_SITES} , + {"KEYPHRASES" , KEYPHRASES} , + {"STATUS_CODES" , STATUS_CODES} , + {"REMOTE_USER" , REMOTE_USER} , +#ifdef HAVE_GEOLOCATION + {"GEO_LOCATION" , GEO_LOCATION} , +#endif + }; + /* *INDENT-ON* */ + + return str2enum (enum_modules, ARRAY_SIZE (enum_modules), str); +} + +/* Instantiate a new GAgents structure. + * + * On success, the newly malloc'd structure is returned. */ +GAgents * +new_gagents (void) +{ + GAgents *agents = xmalloc (sizeof (GAgents)); + memset (agents, 0, sizeof *agents); + + return agents; +} + +/* Instantiate a new GAgentItem structure. + * + * On success, the newly malloc'd structure is returned. */ +GAgentItem * +new_gagent_item (uint32_t size) +{ + GAgentItem *item = xcalloc (size, sizeof (GAgentItem)); + + return item; +} + +/* Clean the array of agents. */ +void +free_agents_array (GAgents * agents) +{ + int i; + + if (agents == NULL) + return; + + /* clean stuff up */ + for (i = 0; i < agents->size; ++i) + free (agents->items[i].agent); + if (agents->items) + free (agents->items); + free (agents); +} + +/* Determine if the given date format is a timestamp. + * + * On error, 0 is returned. + * On success, 1 is returned. */ +int +has_timestamp (const char *fmt) +{ + if (strcmp ("%s", fmt) == 0 || strcmp ("%f", fmt) == 0) + return 1; + return 0; +} + +/* Determine if the given module is set to be enabled. + * + * If enabled, 1 is returned, else 0 is returned. */ +int +enable_panel (GModule mod) +{ + int i, module; + + for (i = 0; i < conf.enable_panel_idx; ++i) { + if ((module = get_module_enum (conf.enable_panels[i])) == -1) + continue; + if (mod == (unsigned int) module) { + return 1; + } + } + + return 0; +} + +/* Determine if the given module is set to be ignored. + * + * If ignored, 1 is returned, else 0 is returned. */ +int +ignore_panel (GModule mod) +{ + int i, module; + + for (i = 0; i < conf.ignore_panel_idx; ++i) { + if ((module = get_module_enum (conf.ignore_panels[i])) == -1) + continue; + if (mod == (unsigned int) module) { + return 1; + } + } + + return 0; +} + +/* Get the number of available modules/panels. + * + * The number of modules available is returned. */ +uint32_t +get_num_modules (void) +{ + size_t idx = 0; + uint32_t num = 0; + + FOREACH_MODULE (idx, module_list) { + num++; + } + + return num; +} + +/* Get the index from the module_list given a module. + * + * If the module is not within the array, -1 is returned. + * If the module is within the array, the index is returned. */ +int +get_module_index (int module) +{ + size_t idx = 0; + + FOREACH_MODULE (idx, module_list) { + if (module_list[idx] == module) + return idx; + } + + return -1; +} + +/* Remove the given module from the module_list array. + * + * If the module is not within the array, 1 is returned. + * If the module is within the array, it is removed from the array and + * 0 is returned. */ +int +remove_module (GModule module) +{ + int idx = get_module_index (module); + if (idx == -1) + return 1; + + if (idx < TOTAL_MODULES - 1) + memmove (&module_list[idx], &module_list[idx + 1], + ((TOTAL_MODULES - 1) - idx) * sizeof (module_list[0])); + module_list[TOTAL_MODULES - 1] = -1; + + return 0; +} + +/* Find the next module given the current module. + * + * The next available module in the array is returned. */ +int +get_next_module (GModule module) +{ + int next = get_module_index (module) + 1; + + if (next == TOTAL_MODULES || module_list[next] == -1) + return module_list[0]; + + return module_list[next]; +} + +/* Find the previous module given the current module. + * + * The previous available module in the array is returned. */ +int +get_prev_module (GModule module) +{ + int i; + int next = get_module_index (module) - 1; + + if (next >= 0 && module_list[next] != -1) + return module_list[next]; + + for (i = TOTAL_MODULES - 1; i >= 0; i--) { + if (module_list[i] != -1) { + return module_list[i]; + } + } + + return 0; +} + +/* Perform some additional tasks to panels before they are being + * parsed. + * + * Note: This overwrites --enable-panel since it assumes there's + * truly nothing to do with the panel */ +void +verify_panels (void) +{ + int ignore_panel_idx = conf.ignore_panel_idx; + + /* Remove virtual host panel if no '%v' within log format */ + if (!conf.log_format) + return; + + if (!strstr (conf.log_format, "%v") && ignore_panel_idx < TOTAL_MODULES) { + if (str_inarray ("VIRTUAL_HOSTS", conf.ignore_panels, ignore_panel_idx) < 0) + remove_module (VIRTUAL_HOSTS); + } + if (!strstr (conf.log_format, "%e") && ignore_panel_idx < TOTAL_MODULES) { + if (str_inarray ("REMOTE_USER", conf.ignore_panels, ignore_panel_idx) < 0) + remove_module (REMOTE_USER); + } +} + +/* Build an array of available modules (ignores listed panels). + * + * If there are no modules enabled, 0 is returned. + * On success, the first enabled module is returned. */ +int +init_modules (void) +{ + GModule module; + int i; + + /* init - terminating with -1 */ + for (module = 0; module < TOTAL_MODULES; ++module) + module_list[module] = -1; + + for (i = 0, module = 0; module < TOTAL_MODULES; ++module) { + if (!ignore_panel (module) || enable_panel (module)) { + module_list[i++] = module; + } + } + + return module_list[0] > -1 ? module_list[0] : 0; +} + +/* Get the logs size. + * + * If log was piped (from stdin), 0 is returned. + * On success, it adds up all log sizes and its value is returned. + * if --log-size was specified, it will be returned explicitly */ +intmax_t +get_log_sizes (void) +{ + int i; + off_t size = 0; + + /* --log-size */ + if (conf.log_size > 0) + return (intmax_t) conf.log_size; + + for (i = 0; i < conf.filenames_idx; ++i) { + if (conf.filenames[i][0] == '-' && conf.filenames[i][1] == '\0') + size += 0; + else + size += file_size (conf.filenames[i]); + } + + return (intmax_t) size; +} + +/* Get the log sources used. + * + * On success, a newly malloc'd string containing the log source either + * from filename(s) and/or STDIN is returned. */ +char * +get_log_source_str (int max_len) +{ + char *str = xstrdup (""); + int i, len = 0; + + for (i = 0; i < conf.filenames_idx; ++i) { + if (conf.filenames[i][0] == '-' && conf.filenames[i][1] == '\0') + append_str (&str, "STDIN"); + else + append_str (&str, conf.filenames[i]); + if (i != conf.filenames_idx - 1) + append_str (&str, "; "); + } + + len = strlen (str); + if (max_len > 0 && len > 0 && len > max_len) { + str[max_len - 3] = 0; + append_str (&str, "..."); + } + + return str; +} diff --git a/goaccess++/src/commons.h b/goaccess++/src/commons.h new file mode 100644 index 0000000..9b01dc3 --- /dev/null +++ b/goaccess++/src/commons.h @@ -0,0 +1,272 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef COMMONS_H_INCLUDED +#define COMMONS_H_INCLUDED + +#include <time.h> +#include <stdint.h> + +/* Remove the __attribute__ stuff when the compiler is not GCC. */ +#if !__GNUC__ +#define __attribute__(x) /**/ +#endif +#define GO_UNUSED __attribute__((unused)) +#define GO_VERSION "1.3" +#define GO_WEBSITE "http://goaccess.io/" +struct tm *now_tm; + +/* common char array buffer size */ +#define INIT_BUF_SIZE 1024 + +/* total number of modules */ +#ifdef HAVE_GEOLOCATION +#define TOTAL_MODULES 15 +#else +#define TOTAL_MODULES 14 +#endif + +/* maximum number of items within a panel */ +#define MAX_CHOICES 366 +/* real-time */ +#define MAX_CHOICES_RT 50 + +/* date and time length - e.g., 2016/12/12 12:12:12 -0600 */ +#define DATE_TIME 25 + 1 +/* date length - e.g., 2016/12/12 */ +#define DATE_LEN 10 + 1 +/* date length - e.g., 12:12:12 */ +#define TIME_LEN 8 + 1 +/* hour + ':' + min length - e.g., 12:12 */ +#define HRMI_LEN 4 + 1 + 1 + +#define YR_FMT "%Y" +#define MO_FMT "%M" +#define DT_FMT "%d" + +/* maximum protocol string length */ +#define REQ_PROTO_LEN 9 + +#define IGNORE_LEVEL_PANEL 1 +#define IGNORE_LEVEL_REQ 2 + +/* Type of IP */ +typedef enum +{ + TYPE_IPINV, + TYPE_IPV4, + TYPE_IPV6 +} GTypeIP; + +/* Type of Modules */ +typedef enum MODULES +{ + VISITORS, + REQUESTS, + REQUESTS_STATIC, + NOT_FOUND, + HOSTS, + OS, + BROWSERS, + VISIT_TIMES, + VIRTUAL_HOSTS, + REFERRERS, + REFERRING_SITES, + KEYPHRASES, + STATUS_CODES, + REMOTE_USER, +#ifdef HAVE_GEOLOCATION + GEO_LOCATION, +#endif +} GModule; + +/* Metric totals. These are metrics that have a percent value and are + * calculated values. */ +typedef struct GPercTotals_ +{ + int hits; /* total valid hits */ + int visitors; /* total visitors */ + uint64_t bw; /* total bandwidth */ +} GPercTotals; + +/* Metrics within GHolder or GDashData */ +typedef struct GMetrics +{ + /* metric id can be used to identify + * a specific data field */ + uint8_t id; + char *data; + char *method; + char *protocol; + + float hits_perc; + float visitors_perc; + float bw_perc; + + int hits; + int visitors; + + /* holder has a numeric value, while + * dashboard has a displayable string value */ + union + { + char *sbw; + uint64_t nbw; + } bw; + + /* holder has a numeric value, while + * dashboard has a displayable string value */ + union + { + char *sts; + uint64_t nts; + } avgts; + + /* holder has a numeric value, while + * dashboard has a displayable string value */ + union + { + char *sts; + uint64_t nts; + } cumts; + + /* holder has a numeric value, while + * dashboard has a displayable string value */ + union + { + char *sts; + uint64_t nts; + } maxts; +} GMetrics; + +/* Holder sub item */ +typedef struct GSubItem_ +{ + GModule module; + GMetrics *metrics; + struct GSubItem_ *prev; + struct GSubItem_ *next; +} GSubItem; + +/* Double linked-list of sub items */ +typedef struct GSubList_ +{ + int size; + struct GSubItem_ *head; + struct GSubItem_ *tail; +} GSubList; + +/* Holder item */ +typedef struct GHolderItem_ +{ + GSubList *sub_list; + GMetrics *metrics; +} GHolderItem; + +/* Holder of GRawData */ +typedef struct GHolder_ +{ + GHolderItem *items; /* holder items */ + GModule module; /* current module */ + int idx; /* holder index */ + int holder_size; /* number of allocated items */ + int ht_size; /* size of the hash table/store */ + int sub_items_size; /* number of sub items */ +} GHolder; + +/* Enum-to-string */ +typedef struct GEnum_ +{ + const char *str; + int idx; +} GEnum; + +/* A metric can contain a root/data/uniq node id */ +typedef struct GDataMap_ +{ + int data; + int root; +} GDataMap; + +typedef struct GAgentItem_ +{ + char *agent; +} GAgentItem; + +typedef struct GAgents_ +{ + int size; + struct GAgentItem_ *items; +} GAgents; + +#define FOREACH_MODULE(item, array) \ + for (; (item < ARRAY_SIZE(array)) && array[item] != -1; ++item) + +/* Processing time */ +extern time_t end_proc; +extern time_t timestamp; +extern time_t start_proc; + +/* list of available modules/panels */ +extern int module_list[TOTAL_MODULES]; + +/* *INDENT-OFF* */ +GAgentItem *new_gagent_item (uint32_t size); +GAgents *new_gagents (void); +void free_agents_array (GAgents *agents); + +float get_percentage (unsigned long long total, unsigned long long hit); +int get_max_choices (void); +int get_module_enum (const char *str); +int has_timestamp (const char *fmt); +int str2enum (const GEnum map[], int len, const char *str); + +int enable_panel (GModule mod); +int get_module_index (int module); +int get_next_module (GModule module); +int get_prev_module (GModule module); +int ignore_panel (GModule mod); +int init_modules (void); +int remove_module(GModule module); +uint32_t get_num_modules (void); +void verify_panels (void); + +char *get_log_source_str (int max_len); +intmax_t get_log_sizes (void); + +void display_default_config_file (void); +void display_storage (void); +void display_version (void); +/* *INDENT-ON* */ + +#endif diff --git a/goaccess++/src/commons.o b/goaccess++/src/commons.o new file mode 100644 index 0000000..f0716b9 Binary files /dev/null and b/goaccess++/src/commons.o differ diff --git a/goaccess++/src/config.h b/goaccess++/src/config.h new file mode 100644 index 0000000..ae8e1c5 --- /dev/null +++ b/goaccess++/src/config.h @@ -0,0 +1,325 @@ +/* src/config.h. Generated from config.h.in by configure. */ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#define ENABLE_NLS 1 + +/* Define to 1 if you have the `alarm' function. */ +#define HAVE_ALARM 1 + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +#define HAVE_ARPA_INET_H 1 + +/* "Build using BZ2" */ +/* #undef HAVE_BZ2 */ + +/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the + CoreFoundation framework. */ +/* #undef HAVE_CFLOCALECOPYCURRENT */ + +/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in + the CoreFoundation framework. */ +/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ + +/* Define to 1 if you have the <curses.h> header file. */ +/* #undef HAVE_CURSES_H */ + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +#define HAVE_DCGETTEXT 1 + +/* Define to 1 if you have the <fcntl.h> header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `floor' function. */ +/* #undef HAVE_FLOOR */ + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#define HAVE_FSEEKO 1 + +/* Build using GeoIP. */ +#define HAVE_GEOLOCATION 1 + +/* Define to 1 if you have the `gethostbyaddr' function. */ +#define HAVE_GETHOSTBYADDR 1 + +/* Define to 1 if you have the `gethostbyname' function. */ +#define HAVE_GETHOSTBYNAME 1 + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#define HAVE_GETTEXT 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define if you have the iconv() function and it works. */ +/* #undef HAVE_ICONV */ + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +/* #undef HAVE_LIBCRYPTO */ + +/* Define to 1 if you have the `GeoIP' library (-lGeoIP). */ +#define HAVE_LIBGEOIP 1 + +/* Define to 1 if you have the `intl' library (-lintl). */ +/* #undef HAVE_LIBINTL */ + +/* Define to 1 if you have the `maxminddb' library (-lmaxminddb). */ +/* #undef HAVE_LIBMAXMINDDB */ + +/* Define to 1 if you have the `ncurses' library (-lncurses). */ +/* #undef HAVE_LIBNCURSES */ + +/* "ncursesw is present." */ +#define HAVE_LIBNCURSESW 1 + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#define HAVE_LIBNSL 1 + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the `ssl' library (-lssl). */ +/* #undef HAVE_LIBSSL */ + +/* Define to 1 if you have the `tokyocabinet' library (-ltokyocabinet). */ +/* #undef HAVE_LIBTOKYOCABINET */ + +/* Define to 1 if you have the <limits.h> header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the <locale.h> header file. */ +#define HAVE_LOCALE_H 1 + +/* Define to 1 if you have the `malloc' function. */ +#define HAVE_MALLOC 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the `mkfifo' function. */ +#define HAVE_MKFIFO 1 + +/* Define to 1 if you have the <ncursesw/ncurses.h> header file. */ +#define HAVE_NCURSESW_NCURSES_H 1 + +/* Define to 1 if you have the <ncurses.h> header file. */ +#define HAVE_NCURSES_H 1 + +/* Define to 1 if you have the <ncurses/ncurses.h> header file. */ +/* #undef HAVE_NCURSES_NCURSES_H */ + +/* Define to 1 if you have the <netdb.h> header file. */ +#define HAVE_NETDB_H 1 + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#define HAVE_PTRDIFF_T 1 + +/* Define to 1 if you have the `realloc' function. */ +#define HAVE_REALLOC 1 + +/* Define to 1 if you have the `realpath' function. */ +#define HAVE_REALPATH 1 + +/* Define to 1 if you have the `regcomp' function. */ +#define HAVE_REGCOMP 1 + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +/* #undef HAVE_STAT_EMPTY_STRING_BUG */ + +/* Define to 1 if you have the <stddef.h> header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strcspn' function. */ +#define HAVE_STRCSPN 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the `strftime' function. */ +#define HAVE_STRFTIME 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strncasecmp' function. */ +#define HAVE_STRNCASECMP 1 + +/* Define to 1 if you have the `strpbrk' function. */ +#define HAVE_STRPBRK 1 + +/* Define to 1 if you have the `strrchr' function. */ +#define HAVE_STRRCHR 1 + +/* Define to 1 if you have the `strspn' function. */ +#define HAVE_STRSPN 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Define to 1 if you have the `strtoull' function. */ +#define HAVE_STRTOULL 1 + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/time.h> header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* "Build using ZLIB" */ +/* #undef HAVE_ZLIB */ + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "goaccess" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "goaccess@prosoftcorp.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "goaccess" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "goaccess 1.3" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "goaccess" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "http://goaccess.io" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "1.3" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* "Build using on-disk B+ Tree database" */ +/* #undef TCB_BTREE */ + +/* "Build using on-memory hash database" */ +/* #undef TCB_MEMHASH */ + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#define TIME_WITH_SYS_TIME 1 + +/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Version number of package */ +#define VERSION "1.3" + +/* Build using GNU getline. */ +/* #undef WITH_GETLINE */ + +/* Debug option */ +/* #undef _DEBUG */ + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +/* #undef _LARGEFILE_SOURCE */ + +/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT32_T */ + +/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT64_T */ + +/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT8_T */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +/* #undef int64_t */ + +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ +/* #undef int8_t */ + +/* Define to `long int' if <sys/types.h> does not define. */ +/* #undef off_t */ + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +/* #undef size_t */ + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint32_t */ + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint64_t */ + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint8_t */ diff --git a/goaccess++/src/config.h.in b/goaccess++/src/config.h.in new file mode 100644 index 0000000..5d81edc --- /dev/null +++ b/goaccess++/src/config.h.in @@ -0,0 +1,324 @@ +/* src/config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define to 1 if you have the `alarm' function. */ +#undef HAVE_ALARM + +/* Define to 1 if you have the <arpa/inet.h> header file. */ +#undef HAVE_ARPA_INET_H + +/* "Build using BZ2" */ +#undef HAVE_BZ2 + +/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the + CoreFoundation framework. */ +#undef HAVE_CFLOCALECOPYCURRENT + +/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in + the CoreFoundation framework. */ +#undef HAVE_CFPREFERENCESCOPYAPPVALUE + +/* Define to 1 if you have the <curses.h> header file. */ +#undef HAVE_CURSES_H + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the <fcntl.h> header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `floor' function. */ +#undef HAVE_FLOOR + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#undef HAVE_FSEEKO + +/* Build using GeoIP. */ +#undef HAVE_GEOLOCATION + +/* Define to 1 if you have the `gethostbyaddr' function. */ +#undef HAVE_GETHOSTBYADDR + +/* Define to 1 if you have the `gethostbyname' function. */ +#undef HAVE_GETHOSTBYNAME + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + +/* Define if you have the iconv() function and it works. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#undef HAVE_LIBCRYPTO + +/* Define to 1 if you have the `GeoIP' library (-lGeoIP). */ +#undef HAVE_LIBGEOIP + +/* Define to 1 if you have the `intl' library (-lintl). */ +#undef HAVE_LIBINTL + +/* Define to 1 if you have the `maxminddb' library (-lmaxminddb). */ +#undef HAVE_LIBMAXMINDDB + +/* Define to 1 if you have the `ncurses' library (-lncurses). */ +#undef HAVE_LIBNCURSES + +/* "ncursesw is present." */ +#undef HAVE_LIBNCURSESW + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#undef HAVE_LIBPTHREAD + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#undef HAVE_LIBSSL + +/* Define to 1 if you have the `tokyocabinet' library (-ltokyocabinet). */ +#undef HAVE_LIBTOKYOCABINET + +/* Define to 1 if you have the <limits.h> header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the <locale.h> header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if you have the `malloc' function. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `memset' function. */ +#undef HAVE_MEMSET + +/* Define to 1 if you have the `mkfifo' function. */ +#undef HAVE_MKFIFO + +/* Define to 1 if you have the <ncursesw/ncurses.h> header file. */ +#undef HAVE_NCURSESW_NCURSES_H + +/* Define to 1 if you have the <ncurses.h> header file. */ +#undef HAVE_NCURSES_H + +/* Define to 1 if you have the <ncurses/ncurses.h> header file. */ +#undef HAVE_NCURSES_NCURSES_H + +/* Define to 1 if you have the <netdb.h> header file. */ +#undef HAVE_NETDB_H + +/* Define to 1 if you have the <netinet/in.h> header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#undef HAVE_PTRDIFF_T + +/* Define to 1 if you have the `realloc' function. */ +#undef HAVE_REALLOC + +/* Define to 1 if you have the `realpath' function. */ +#undef HAVE_REALPATH + +/* Define to 1 if you have the `regcomp' function. */ +#undef HAVE_REGCOMP + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +#undef HAVE_STAT_EMPTY_STRING_BUG + +/* Define to 1 if you have the <stddef.h> header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strcspn' function. */ +#undef HAVE_STRCSPN + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the `strftime' function. */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strncasecmp' function. */ +#undef HAVE_STRNCASECMP + +/* Define to 1 if you have the `strpbrk' function. */ +#undef HAVE_STRPBRK + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strspn' function. */ +#undef HAVE_STRSPN + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the `strtol' function. */ +#undef HAVE_STRTOL + +/* Define to 1 if you have the `strtoull' function. */ +#undef HAVE_STRTOULL + +/* Define to 1 if you have the <sys/socket.h> header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/time.h> header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* "Build using ZLIB" */ +#undef HAVE_ZLIB + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#undef LSTAT_FOLLOWS_SLASHED_SYMLINK + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#undef NO_MINUS_C_MINUS_O + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* "Build using on-disk B+ Tree database" */ +#undef TCB_BTREE + +/* "Build using on-memory hash database" */ +#undef TCB_MEMHASH + +/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */ +#undef TIME_WITH_SYS_TIME + +/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +#undef TM_IN_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Build using GNU getline. */ +#undef WITH_GETLINE + +/* Debug option */ +#undef _DEBUG + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +#undef _LARGEFILE_SOURCE + +/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT32_T + +/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT64_T + +/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>, + <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +#undef _UINT8_T + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to the type of a signed integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef int64_t + +/* Define to the type of a signed integer type of width exactly 8 bits if such + a type exists and the standard includes do not define it. */ +#undef int8_t + +/* Define to `long int' if <sys/types.h> does not define. */ +#undef off_t + +/* Define to `unsigned int' if <sys/types.h> does not define. */ +#undef size_t + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +#undef uint32_t + +/* Define to the type of an unsigned integer type of width exactly 64 bits if + such a type exists and the standard includes do not define it. */ +#undef uint64_t + +/* Define to the type of an unsigned integer type of width exactly 8 bits if + such a type exists and the standard includes do not define it. */ +#undef uint8_t diff --git a/goaccess++/src/csv.c b/goaccess++/src/csv.c new file mode 100644 index 0000000..5ccce0b --- /dev/null +++ b/goaccess++/src/csv.c @@ -0,0 +1,327 @@ +/** + * output.c -- output csv to the standard output stream + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#include <ctype.h> + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> +#include <inttypes.h> + +#include "csv.h" + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#include "error.h" +#include "ui.h" +#include "util.h" + +/* Panel output */ +typedef struct GPanel_ +{ + GModule module; + void (*render) (FILE * fp, GHolder * h, GPercTotals totals); +} GPanel; + +static void print_csv_data (FILE * fp, GHolder * h, GPercTotals totals); + +/* *INDENT-OFF* */ +/* A function pointer for each panel */ +static GPanel paneling[] = { + {VISITORS , print_csv_data} , + {REQUESTS , print_csv_data} , + {REQUESTS_STATIC , print_csv_data} , + {NOT_FOUND , print_csv_data} , + {HOSTS , print_csv_data} , + {OS , print_csv_data} , + {BROWSERS , print_csv_data} , + {VISIT_TIMES , print_csv_data} , + {VIRTUAL_HOSTS , print_csv_data} , + {REFERRERS , print_csv_data} , + {REFERRING_SITES , print_csv_data} , + {KEYPHRASES , print_csv_data} , + {STATUS_CODES , print_csv_data} , + {REMOTE_USER , print_csv_data} , +#ifdef HAVE_GEOLOCATION + {GEO_LOCATION , print_csv_data} , +#endif +}; +/* *INDENT-ON* */ + +/* Get a panel from the GPanel structure given a module. + * + * On error, or if not found, NULL is returned. + * On success, the panel value is returned. */ +static GPanel * +panel_lookup (GModule module) +{ + int i, num_panels = ARRAY_SIZE (paneling); + + for (i = 0; i < num_panels; i++) { + if (paneling[i].module == module) + return &paneling[i]; + } + return NULL; +} + +/* Iterate over the string and escape CSV output. */ +static void +escape_cvs_output (FILE * fp, char *s) +{ + while (*s) { + switch (*s) { + case '"': + fprintf (fp, "\"\""); + break; + default: + fputc (*s, fp); + break; + } + s++; + } +} + +/* Output metrics. + * + * On success, outputs item value. */ +static void +print_csv_metric_block (FILE * fp, GMetrics * nmetrics) +{ + /* basic metrics */ + fprintf (fp, "\"%d\",", nmetrics->hits); + fprintf (fp, "\"%4.2f%%\",", nmetrics->hits_perc); + fprintf (fp, "\"%d\",", nmetrics->visitors); + fprintf (fp, "\"%4.2f%%\",", nmetrics->visitors_perc); + + /* bandwidth */ + if (conf.bandwidth) { + fprintf (fp, "\"%lld\",", (long long) nmetrics->bw.nbw); + fprintf (fp, "\"%4.2f%%\",", nmetrics->bw_perc); + } + + /* time served metrics */ + if (conf.serve_usecs) { + fprintf (fp, "\"%lld\",", (long long) nmetrics->avgts.nts); + fprintf (fp, "\"%lld\",", (long long) nmetrics->cumts.nts); + fprintf (fp, "\"%lld\",", (long long) nmetrics->maxts.nts); + } + + /* request method */ + if (conf.append_method && nmetrics->method) + fprintf (fp, "\"%s\"", nmetrics->method); + fprintf (fp, ","); + + /* request protocol */ + if (conf.append_protocol && nmetrics->protocol) + fprintf (fp, "\"%s\"", nmetrics->protocol); + fprintf (fp, ","); + + /* data field */ + fprintf (fp, "\""); + escape_cvs_output (fp, nmetrics->data); + fprintf (fp, "\"\r\n"); +} + +/* Output a sublist (double linked-list) items for a particular parent node. + * + * On error, it exits early. + * On success, outputs item value. */ +static void +print_csv_sub_items (FILE * fp, GHolder * h, int idx, GPercTotals totals) +{ + GMetrics *nmetrics; + GSubList *sub_list = h->items[idx].sub_list; + GSubItem *iter; + + int i = 0; + + if (sub_list == NULL) + return; + + for (iter = sub_list->head; iter; iter = iter->next, i++) { + set_data_metrics (iter->metrics, &nmetrics, totals); + + fprintf (fp, "\"%d\",", i); /* idx */ + fprintf (fp, "\"%d\",", idx); /* parent idx */ + fprintf (fp, "\"%s\",", module_to_id (h->module)); + + /* output metrics */ + print_csv_metric_block (fp, nmetrics); + free (nmetrics); + } +} + +/* Output first-level items. + * + * On success, outputs item value. */ +static void +print_csv_data (FILE * fp, GHolder * h, GPercTotals totals) +{ + GMetrics *nmetrics; + int i; + + for (i = 0; i < h->idx; i++) { + set_data_metrics (h->items[i].metrics, &nmetrics, totals); + + fprintf (fp, "\"%d\",", i); /* idx */ + fprintf (fp, ","); /* no parent */ + fprintf (fp, "\"%s\",", module_to_id (h->module)); + + /* output metrics */ + print_csv_metric_block (fp, nmetrics); + + if (h->sub_items_size) + print_csv_sub_items (fp, h, i, totals); + + free (nmetrics); + } +} + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +/* Output general statistics information. */ +static void +print_csv_summary (FILE * fp, GLog * glog) +{ + char now[DATE_TIME]; + char *source = NULL; + const char *fmt; + int i = 0, total = 0; + long long t = 0LL; + + generate_time (); + strftime (now, DATE_TIME, "%Y-%m-%d %H:%M:%S %z", now_tm); + + /* generated date time */ + fmt = "\"%d\",,\"%s\",,,,,,,,\"%s\",\"%s\"\r\n"; + fprintf (fp, fmt, i++, GENER_ID, now, OVERALL_DATETIME); + + /* total requests */ + fmt = "\"%d\",,\"%s\",,,,,,,,\"%d\",\"%s\"\r\n"; + total = glog->processed; + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_REQ); + + /* valid requests */ + fmt = "\"%d\",,\"%s\",,,,,,,,\"%d\",\"%s\"\r\n"; + total = glog->valid; + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_VALID); + + /* invalid requests */ + total = glog->invalid; + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_FAILED); + + /* generated time */ + fmt = "\"%d\",,\"%s\",,,,,,,,\"%lld\",\"%s\"\r\n"; + t = (long long) end_proc - start_proc; + fprintf (fp, fmt, i++, GENER_ID, t, OVERALL_GENTIME); + + /* visitors */ + fmt = "\"%d\",,\"%s\",,,,,,,,\"%d\",\"%s\"\r\n"; + total = ht_get_size_uniqmap (VISITORS); + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_VISITORS); + + /* files */ + total = ht_get_size_datamap (REQUESTS); + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_FILES); + + /* excluded hits */ + total = glog->excluded_ip; + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_EXCL_HITS); + + /* referrers */ + total = ht_get_size_datamap (REFERRERS); + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_REF); + + /* not found */ + total = ht_get_size_datamap (NOT_FOUND); + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_NOTFOUND); + + /* static files */ + total = ht_get_size_datamap (REQUESTS_STATIC); + fprintf (fp, fmt, i++, GENER_ID, total, OVERALL_STATIC); + + /* log size */ + fmt = "\"%d\",,\"%s\",,,,,,,,\"%jd\",\"%s\"\r\n"; + fprintf (fp, fmt, i++, GENER_ID, (intmax_t) get_log_sizes (), + OVERALL_LOGSIZE); + + /* bandwidth */ + fmt = "\"%d\",,\"%s\",,,,,,,,\"%llu\",\"%s\"\r\n"; + fprintf (fp, fmt, i++, GENER_ID, glog->resp_size, OVERALL_BANDWIDTH); + + /* log path */ + source = get_log_source_str (0); + fmt = "\"%d\",,\"%s\",,,,,,,,\"%s\",\"%s\"\r\n"; + fprintf (fp, fmt, i++, GENER_ID, source, OVERALL_LOG); + free (source); +} + +#pragma GCC diagnostic warning "-Wformat-nonliteral" + +/* Entry point to generate a a csv report writing it to the fp */ +void +output_csv (GLog * glog, GHolder * holder, const char *filename) +{ + GModule module; + GPercTotals totals; + const GPanel *panel = NULL; + size_t idx = 0; + FILE *fp; + + fp = (filename != NULL) ? fopen (filename, "w") : stdout; + if (!fp) + FATAL ("Unable to open CSV file: %s.", strerror (errno)); + + if (!conf.no_csv_summary) + print_csv_summary (fp, glog); + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + if (!(panel = panel_lookup (module))) + continue; + + set_module_totals (module, &totals); + panel->render (fp, holder + module, totals); + } + + fclose (fp); +} diff --git a/goaccess++/src/csv.h b/goaccess++/src/csv.h new file mode 100644 index 0000000..bde8143 --- /dev/null +++ b/goaccess++/src/csv.h @@ -0,0 +1,43 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef CSV_H_INCLUDED +#define CSV_H_INCLUDED + +#include <stdio.h> +#include "parser.h" +#include "settings.h" + +void output_csv (GLog * glog, GHolder * holder, const char *filename); + +#endif diff --git a/goaccess++/src/csv.o b/goaccess++/src/csv.o new file mode 100644 index 0000000..83d7a53 Binary files /dev/null and b/goaccess++/src/csv.o differ diff --git a/goaccess++/src/d3js.h b/goaccess++/src/d3js.h new file mode 100644 index 0000000..cc55532 --- /dev/null +++ b/goaccess++/src/d3js.h @@ -0,0 +1,13744 @@ +const char d3_js[151140] = { + 0x21, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x26, 0x26, 0x28, 0x6e, 0x2e, 0x6f, 0x77, 0x6e, 0x65, 0x72, + 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x7c, 0x7c, 0x6e, + 0x2e, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x7c, 0x7c, + 0x6e, 0x29, 0x2e, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x26, 0x26, 0x28, + 0x6e, 0x2e, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x44, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x6e, 0x2e, 0x6f, 0x77, 0x6e, + 0x65, 0x72, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x69, 0x65, 0x77, + 0x7c, 0x7c, 0x6e, 0x2e, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x26, 0x26, 0x6e, 0x7c, 0x7c, 0x6e, 0x2e, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x56, 0x69, 0x65, 0x77, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x3e, 0x6e, 0x3f, 0x2d, 0x31, 0x3a, 0x6e, 0x3e, 0x74, 0x3f, + 0x31, 0x3a, 0x6e, 0x3e, 0x3d, 0x74, 0x3f, 0x30, 0x3a, 0x30, 0x2f, + 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x3d, 0x6e, 0x3f, 0x30, + 0x2f, 0x30, 0x3a, 0x2b, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x21, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, + 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x7b, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, + 0x75, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x33, 0x26, 0x26, 0x28, 0x72, 0x3d, 0x30, 0x29, 0x2c, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x34, 0x26, 0x26, 0x28, 0x75, + 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, + 0x75, 0x3e, 0x72, 0x3b, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, + 0x3d, 0x72, 0x2b, 0x75, 0x3e, 0x3e, 0x3e, 0x31, 0x3b, 0x6e, 0x28, + 0x74, 0x5b, 0x69, 0x5d, 0x2c, 0x65, 0x29, 0x3c, 0x30, 0x3f, 0x72, + 0x3d, 0x69, 0x2b, 0x31, 0x3a, 0x75, 0x3d, 0x69, 0x7d, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x2c, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x33, 0x26, + 0x26, 0x28, 0x72, 0x3d, 0x30, 0x29, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x34, 0x26, 0x26, 0x28, 0x75, 0x3d, 0x74, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, 0x75, 0x3e, 0x72, 0x3b, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x72, 0x2b, 0x75, + 0x3e, 0x3e, 0x3e, 0x31, 0x3b, 0x6e, 0x28, 0x74, 0x5b, 0x69, 0x5d, + 0x2c, 0x65, 0x29, 0x3e, 0x30, 0x3f, 0x75, 0x3d, 0x69, 0x3a, 0x72, + 0x3d, 0x69, 0x2b, 0x31, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x72, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x31, 0x3b, 0x6e, 0x2a, 0x74, 0x25, 0x31, + 0x3b, 0x29, 0x74, 0x2a, 0x3d, 0x31, 0x30, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x29, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x79, 0x28, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x74, 0x79, 0x70, 0x65, 0x2c, 0x65, 0x2c, 0x7b, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x74, 0x5b, 0x65, 0x5d, 0x2c, 0x65, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x21, 0x31, 0x7d, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6c, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x3d, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x6e, 0x2b, 0x3d, + 0x22, 0x22, 0x29, 0x3d, 0x3d, 0x3d, 0x70, 0x61, 0x7c, 0x7c, 0x6e, + 0x5b, 0x30, 0x5d, 0x3d, 0x3d, 0x3d, 0x76, 0x61, 0x3f, 0x76, 0x61, + 0x2b, 0x6e, 0x3a, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x66, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x28, 0x6e, 0x2b, 0x3d, 0x22, 0x22, 0x29, 0x5b, + 0x30, 0x5d, 0x3d, 0x3d, 0x3d, 0x76, 0x61, 0x3f, 0x6e, 0x2e, 0x73, + 0x6c, 0x69, 0x63, 0x65, 0x28, 0x31, 0x29, 0x3a, 0x6e, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x28, + 0x6e, 0x29, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, + 0x6e, 0x3d, 0x73, 0x28, 0x6e, 0x29, 0x29, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x26, 0x26, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x5b, 0x6e, + 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x70, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x5b, + 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x29, + 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x66, 0x28, 0x74, 0x29, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x28, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x30, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x20, 0x69, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x29, 0x2b, 0x2b, 0x6e, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x28, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x20, + 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x29, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x31, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x21, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x5f, 0x3d, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x28, 0x6e, 0x75, 0x6c, 0x6c, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x79, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x4d, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x3d, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x2c, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3d, 0x3d, 0x3d, + 0x74, 0x3f, 0x6e, 0x3a, 0x72, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x78, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x3b, 0x74, 0x3d, + 0x74, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x30, 0x29, + 0x2e, 0x74, 0x6f, 0x55, 0x70, 0x70, 0x65, 0x72, 0x43, 0x61, 0x73, + 0x65, 0x28, 0x29, 0x2b, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, + 0x28, 0x31, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x64, 0x61, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x72, 0x3e, 0x65, 0x3b, 0x2b, + 0x2b, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x64, + 0x61, 0x5b, 0x65, 0x5d, 0x2b, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x75, + 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x75, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x62, 0x28, 0x29, 0x7b, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x28, 0x29, 0x7b, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x28, + 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x28, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x2c, 0x72, 0x3d, 0x65, 0x2c, 0x75, 0x3d, 0x2d, + 0x31, 0x2c, 0x69, 0x3d, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, 0x28, 0x74, + 0x3d, 0x72, 0x5b, 0x75, 0x5d, 0x2e, 0x6f, 0x6e, 0x29, 0x26, 0x26, + 0x74, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x5b, 0x5d, 0x2c, 0x72, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x6c, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x2e, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x75, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x69, 0x2c, 0x6f, 0x3d, 0x72, 0x2e, 0x67, 0x65, + 0x74, 0x28, 0x74, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x3f, 0x6f, 0x26, + 0x26, 0x6f, 0x2e, 0x6f, 0x6e, 0x3a, 0x28, 0x6f, 0x26, 0x26, 0x28, + 0x6f, 0x2e, 0x6f, 0x6e, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x65, + 0x3d, 0x65, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, + 0x69, 0x3d, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, + 0x28, 0x6f, 0x29, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x28, 0x65, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x69, 0x2b, + 0x31, 0x29, 0x29, 0x2c, 0x72, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x28, 0x74, 0x29, 0x29, 0x2c, 0x75, 0x26, 0x26, 0x65, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x2e, 0x73, 0x65, 0x74, 0x28, + 0x74, 0x2c, 0x7b, 0x6f, 0x6e, 0x3a, 0x75, 0x7d, 0x29, 0x29, 0x2c, + 0x6e, 0x29, 0x7d, 0x2c, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x28, 0x29, 0x7b, 0x74, 0x61, 0x2e, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x28, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6b, + 0x28, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x2c, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x3b, 0x6e, 0x3d, 0x74, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3b, 0x29, 0x74, 0x3d, 0x6e, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x28, 0x6e, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x5f, 0x2c, 0x65, 0x3d, 0x30, 0x2c, + 0x72, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x65, + 0x3c, 0x72, 0x3b, 0x29, 0x74, 0x5b, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x5b, 0x65, 0x5d, 0x5d, 0x3d, 0x77, 0x28, + 0x74, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x2e, 0x6f, 0x66, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x75, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x3d, 0x75, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x3b, 0x75, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x3d, 0x6e, 0x2c, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x3d, 0x75, 0x2c, 0x74, 0x5b, 0x75, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x5d, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x65, 0x2c, + 0x72, 0x29, 0x7d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x7b, + 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x69, 0x7d, + 0x7d, 0x7d, 0x2c, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x41, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x79, 0x61, 0x28, 0x6e, 0x2c, 0x5f, 0x61, + 0x29, 0x2c, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x4e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, + 0x3f, 0x6e, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, + 0x61, 0x28, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x29, 0x7d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, + 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x3f, 0x6e, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x78, 0x61, 0x28, 0x6e, 0x2c, + 0x74, 0x68, 0x69, 0x73, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, + 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x53, 0x28, 0x6e, 0x2e, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x2c, 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x75, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, + 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x4e, 0x53, 0x28, 0x6e, 0x2e, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x2c, 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, + 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x74, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x65, 0x3f, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x29, + 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x6e, 0x2c, 0x65, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, + 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, + 0x3b, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x65, 0x3f, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x53, 0x28, 0x6e, + 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x6e, 0x2e, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x29, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, + 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x4e, 0x53, 0x28, 0x6e, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, + 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2c, 0x65, 0x29, 0x7d, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x74, 0x61, + 0x2e, 0x6e, 0x73, 0x2e, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x79, + 0x28, 0x6e, 0x29, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, + 0x3f, 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x3f, 0x72, 0x3a, + 0x65, 0x3a, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, + 0x3f, 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x3f, 0x61, 0x3a, + 0x6f, 0x3a, 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x3f, 0x69, + 0x3a, 0x75, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x71, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x2e, + 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x5c, 0x73, + 0x2b, 0x2f, 0x67, 0x2c, 0x22, 0x20, 0x22, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4c, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, + 0x20, 0x52, 0x65, 0x67, 0x45, 0x78, 0x70, 0x28, 0x22, 0x28, 0x3f, + 0x3a, 0x5e, 0x7c, 0x5c, 0x5c, 0x73, 0x2b, 0x29, 0x22, 0x2b, 0x74, + 0x61, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x28, 0x6e, + 0x29, 0x2b, 0x22, 0x28, 0x3f, 0x3a, 0x5c, 0x5c, 0x73, 0x2b, 0x7c, + 0x24, 0x29, 0x22, 0x2c, 0x22, 0x67, 0x22, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x6e, 0x2b, 0x22, + 0x22, 0x29, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x2e, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x28, 0x2f, 0x5e, 0x7c, 0x5c, 0x73, 0x2b, + 0x2f, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x52, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x2d, 0x31, + 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x75, 0x3b, 0x29, 0x6e, 0x5b, 0x65, + 0x5d, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x74, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x2d, 0x31, 0x2c, 0x72, 0x3d, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x2b, 0x2b, 0x65, 0x3c, + 0x75, 0x3b, 0x29, 0x6e, 0x5b, 0x65, 0x5d, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x72, 0x29, 0x7d, 0x6e, 0x3d, 0x54, 0x28, 0x6e, 0x29, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x44, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x75, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3f, 0x72, 0x3a, 0x65, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x4c, 0x28, 0x6e, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x75, 0x3d, 0x65, 0x2e, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x75, 0x2e, 0x61, 0x64, 0x64, 0x28, + 0x6e, 0x29, 0x3a, 0x75, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x28, 0x6e, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x65, + 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x28, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x29, + 0x7c, 0x7c, 0x22, 0x22, 0x3b, 0x72, 0x3f, 0x28, 0x74, 0x2e, 0x6c, + 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x2c, + 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x75, 0x29, 0x7c, 0x7c, + 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x28, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, + 0x2c, 0x71, 0x28, 0x75, 0x2b, 0x22, 0x20, 0x22, 0x2b, 0x6e, 0x29, + 0x29, 0x29, 0x3a, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x22, 0x2c, 0x71, 0x28, 0x75, 0x2e, 0x72, 0x65, 0x70, + 0x6c, 0x61, 0x63, 0x65, 0x28, 0x74, 0x2c, 0x22, 0x20, 0x22, 0x29, + 0x29, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x50, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, + 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x29, 0x7b, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, + 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, + 0x3d, 0x3d, 0x72, 0x3f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6e, 0x29, 0x3a, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, + 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x65, 0x29, 0x7d, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, + 0x3f, 0x72, 0x3a, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x74, 0x3f, 0x69, 0x3a, 0x75, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, + 0x29, 0x7b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x6e, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x5b, 0x6e, 0x5d, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, + 0x3d, 0x65, 0x3f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x5b, 0x6e, 0x5d, 0x3a, 0x74, 0x68, 0x69, 0x73, + 0x5b, 0x6e, 0x5d, 0x3d, 0x65, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, 0x3f, 0x65, + 0x3a, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3f, + 0x75, 0x3a, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6a, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2c, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x55, 0x52, 0x49, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3f, 0x74, 0x2e, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x4e, 0x53, 0x28, 0x65, 0x2c, 0x6e, 0x29, 0x3a, 0x74, 0x2e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x77, + 0x6e, 0x65, 0x72, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x4e, 0x53, 0x28, 0x6e, 0x2e, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x2c, 0x6e, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, + 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x3f, 0x6e, 0x3a, 0x28, 0x6e, 0x3d, + 0x74, 0x61, 0x2e, 0x6e, 0x73, 0x2e, 0x71, 0x75, 0x61, 0x6c, 0x69, + 0x66, 0x79, 0x28, 0x6e, 0x29, 0x29, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x3f, 0x65, 0x3a, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6e, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x6e, 0x26, 0x26, + 0x6e, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, + 0x6c, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x48, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x5f, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x3a, 0x6e, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x62, 0x61, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x6e, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x49, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7c, 0x7c, + 0x28, 0x6e, 0x3d, 0x65, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x26, 0x26, 0x65, 0x3f, 0x6e, + 0x28, 0x74, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, + 0x2c, 0x65, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, + 0x29, 0x3a, 0x21, 0x74, 0x2d, 0x21, 0x65, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x59, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x72, 0x3e, 0x65, 0x3b, 0x65, 0x2b, 0x2b, + 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, + 0x69, 0x3d, 0x6e, 0x5b, 0x65, 0x5d, 0x2c, 0x6f, 0x3d, 0x30, 0x2c, + 0x61, 0x3d, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x61, 0x3e, 0x6f, 0x3b, 0x6f, 0x2b, 0x2b, 0x29, 0x28, 0x75, 0x3d, + 0x69, 0x5b, 0x6f, 0x5d, 0x29, 0x26, 0x26, 0x74, 0x28, 0x75, 0x2c, + 0x6f, 0x2c, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x5a, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x79, 0x61, 0x28, 0x6e, 0x2c, 0x53, 0x61, 0x29, 0x2c, + 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x56, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, + 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, 0x2c, 0x75, 0x2c, + 0x69, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x2c, 0x61, 0x3d, + 0x6e, 0x5b, 0x69, 0x5d, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x2c, 0x63, 0x3d, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x21, 0x3d, 0x65, 0x26, 0x26, + 0x28, 0x65, 0x3d, 0x69, 0x2c, 0x74, 0x3d, 0x30, 0x29, 0x2c, 0x75, + 0x3e, 0x3d, 0x74, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x75, 0x2b, 0x31, + 0x29, 0x3b, 0x21, 0x28, 0x6f, 0x3d, 0x61, 0x5b, 0x74, 0x5d, 0x29, + 0x26, 0x26, 0x2b, 0x2b, 0x74, 0x3c, 0x63, 0x3b, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x58, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6f, 0x5d, 0x3b, 0x74, + 0x26, 0x26, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x74, + 0x2e, 0x24, 0x29, 0x2c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6f, 0x5d, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x63, 0x28, 0x74, 0x2c, 0x72, + 0x61, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x29, 0x3b, 0x72, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, + 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x5b, 0x6f, 0x5d, 0x3d, 0x75, 0x2c, 0x75, 0x2e, 0x24, 0x3d, 0x65, + 0x29, 0x2c, 0x75, 0x2e, 0x5f, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, + 0x52, 0x65, 0x67, 0x45, 0x78, 0x70, 0x28, 0x22, 0x5e, 0x5f, 0x5f, + 0x6f, 0x6e, 0x28, 0x5b, 0x5e, 0x2e, 0x5d, 0x2b, 0x29, 0x22, 0x2b, + 0x74, 0x61, 0x2e, 0x72, 0x65, 0x71, 0x75, 0x6f, 0x74, 0x65, 0x28, + 0x6e, 0x29, 0x2b, 0x22, 0x24, 0x22, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x72, 0x2e, + 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x29, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x75, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x72, + 0x5d, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, + 0x65, 0x6e, 0x65, 0x72, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x75, + 0x2c, 0x75, 0x2e, 0x24, 0x29, 0x2c, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x72, 0x5d, 0x7d, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x22, 0x5f, 0x5f, 0x6f, 0x6e, + 0x22, 0x2b, 0x6e, 0x2c, 0x61, 0x3d, 0x6e, 0x2e, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x2e, 0x22, 0x29, 0x2c, 0x63, + 0x3d, 0x24, 0x3b, 0x61, 0x3e, 0x30, 0x26, 0x26, 0x28, 0x6e, 0x3d, + 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x61, + 0x29, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x6b, 0x61, + 0x2e, 0x67, 0x65, 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x26, 0x26, 0x28, 0x6e, 0x3d, 0x6c, + 0x2c, 0x63, 0x3d, 0x42, 0x29, 0x2c, 0x61, 0x3f, 0x74, 0x3f, 0x75, + 0x3a, 0x72, 0x3a, 0x74, 0x3f, 0x62, 0x3a, 0x69, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x24, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x3b, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x3d, 0x65, 0x2c, 0x74, 0x5b, 0x30, 0x5d, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, + 0x3b, 0x74, 0x72, 0x79, 0x7b, 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x74, 0x29, 0x7d, 0x66, + 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x7b, 0x74, 0x61, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x72, 0x7d, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x24, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, 0x72, 0x65, 0x6c, 0x61, 0x74, + 0x65, 0x64, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3b, 0x72, 0x26, + 0x26, 0x28, 0x72, 0x3d, 0x3d, 0x3d, 0x74, 0x7c, 0x7c, 0x38, 0x26, + 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, 0x44, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x29, 0x7c, 0x7c, 0x65, 0x2e, + 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x57, 0x28, + 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x22, 0x2e, + 0x64, 0x72, 0x61, 0x67, 0x73, 0x75, 0x70, 0x70, 0x72, 0x65, 0x73, + 0x73, 0x2d, 0x22, 0x2b, 0x20, 0x2b, 0x2b, 0x41, 0x61, 0x2c, 0x75, + 0x3d, 0x22, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x22, 0x2b, 0x72, 0x2c, + 0x69, 0x3d, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x28, 0x74, 0x28, 0x65, 0x29, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, + 0x74, 0x6f, 0x75, 0x63, 0x68, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x2b, + 0x72, 0x2c, 0x53, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x64, 0x72, + 0x61, 0x67, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x2b, 0x72, 0x2c, + 0x53, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x2b, 0x72, 0x2c, + 0x53, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, + 0x3d, 0x45, 0x61, 0x26, 0x26, 0x28, 0x45, 0x61, 0x3d, 0x22, 0x6f, + 0x6e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x22, 0x69, 0x6e, 0x20, 0x65, 0x3f, 0x21, 0x31, 0x3a, 0x78, + 0x28, 0x65, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2c, 0x22, 0x75, + 0x73, 0x65, 0x72, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x22, 0x29, + 0x29, 0x2c, 0x45, 0x61, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, + 0x3d, 0x6e, 0x28, 0x65, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x2c, 0x61, 0x3d, 0x6f, 0x5b, 0x45, 0x61, 0x5d, 0x3b, 0x6f, 0x5b, + 0x45, 0x61, 0x5d, 0x3d, 0x22, 0x6e, 0x6f, 0x6e, 0x65, 0x22, 0x7d, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, + 0x69, 0x2e, 0x6f, 0x6e, 0x28, 0x72, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, + 0x29, 0x2c, 0x45, 0x61, 0x26, 0x26, 0x28, 0x6f, 0x5b, 0x45, 0x61, + 0x5d, 0x3d, 0x61, 0x29, 0x2c, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x69, 0x2e, 0x6f, 0x6e, 0x28, 0x75, 0x2c, 0x6e, + 0x75, 0x6c, 0x6c, 0x29, 0x7d, 0x3b, 0x69, 0x2e, 0x6f, 0x6e, 0x28, + 0x75, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x53, 0x28, 0x29, 0x2c, 0x74, 0x28, 0x29, 0x7d, 0x2c, + 0x21, 0x30, 0x29, 0x2c, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x28, 0x74, 0x2c, 0x30, 0x29, 0x7d, 0x7d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a, 0x28, + 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x26, + 0x26, 0x28, 0x65, 0x3d, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, + 0x65, 0x64, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x5b, 0x30, + 0x5d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x2e, + 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x53, 0x56, 0x47, 0x45, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x7c, 0x7c, 0x6e, 0x3b, 0x69, 0x66, 0x28, + 0x72, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x56, 0x47, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x75, 0x3d, 0x72, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, + 0x56, 0x47, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x29, 0x3b, 0x69, + 0x66, 0x28, 0x30, 0x3e, 0x4e, 0x61, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x3d, 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x69, 0x66, 0x28, + 0x69, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x58, 0x7c, 0x7c, + 0x69, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x59, 0x29, 0x7b, + 0x72, 0x3d, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x28, 0x22, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x29, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x22, 0x73, 0x76, 0x67, 0x22, 0x29, + 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x7b, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x22, 0x61, 0x62, 0x73, 0x6f, + 0x6c, 0x75, 0x74, 0x65, 0x22, 0x2c, 0x74, 0x6f, 0x70, 0x3a, 0x30, + 0x2c, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x30, 0x2c, 0x6d, 0x61, 0x72, + 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x2c, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x3a, 0x30, 0x2c, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x3a, 0x22, 0x6e, 0x6f, 0x6e, 0x65, 0x22, 0x7d, 0x2c, 0x22, 0x69, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x22, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x72, 0x5b, 0x30, 0x5d, 0x5b, + 0x30, 0x5d, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, + 0x6e, 0x43, 0x54, 0x4d, 0x28, 0x29, 0x3b, 0x4e, 0x61, 0x3d, 0x21, + 0x28, 0x6f, 0x2e, 0x66, 0x7c, 0x7c, 0x6f, 0x2e, 0x65, 0x29, 0x2c, + 0x72, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x7d, + 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4e, 0x61, 0x3f, + 0x28, 0x75, 0x2e, 0x78, 0x3d, 0x65, 0x2e, 0x70, 0x61, 0x67, 0x65, + 0x58, 0x2c, 0x75, 0x2e, 0x79, 0x3d, 0x65, 0x2e, 0x70, 0x61, 0x67, + 0x65, 0x59, 0x29, 0x3a, 0x28, 0x75, 0x2e, 0x78, 0x3d, 0x65, 0x2e, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x58, 0x2c, 0x75, 0x2e, 0x79, + 0x3d, 0x65, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x59, 0x29, + 0x2c, 0x75, 0x3d, 0x75, 0x2e, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x43, + 0x54, 0x4d, 0x28, 0x29, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x28, 0x29, 0x29, 0x2c, 0x5b, 0x75, 0x2e, 0x78, 0x2c, 0x75, + 0x2e, 0x79, 0x5d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x69, 0x6e, + 0x67, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x63, 0x74, + 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x65, + 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x58, 0x2d, 0x61, 0x2e, + 0x6c, 0x65, 0x66, 0x74, 0x2d, 0x6e, 0x2e, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x4c, 0x65, 0x66, 0x74, 0x2c, 0x65, 0x2e, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x59, 0x2d, 0x61, 0x2e, 0x74, 0x6f, 0x70, + 0x2d, 0x6e, 0x2e, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x54, 0x6f, + 0x70, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x47, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x63, + 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x54, 0x6f, 0x75, 0x63, 0x68, + 0x65, 0x73, 0x5b, 0x30, 0x5d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x4b, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3e, 0x30, 0x3f, 0x31, 0x3a, + 0x30, 0x3e, 0x6e, 0x3f, 0x2d, 0x31, 0x3a, 0x30, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x51, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x2d, 0x6e, 0x5b, 0x30, 0x5d, 0x29, + 0x2a, 0x28, 0x65, 0x5b, 0x31, 0x5d, 0x2d, 0x6e, 0x5b, 0x31, 0x5d, + 0x29, 0x2d, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2d, 0x6e, 0x5b, 0x31, + 0x5d, 0x29, 0x2a, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x2d, 0x6e, 0x5b, + 0x30, 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6e, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3e, 0x31, 0x3f, 0x30, 0x3a, 0x2d, + 0x31, 0x3e, 0x6e, 0x3f, 0x71, 0x61, 0x3a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x74, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3e, + 0x31, 0x3f, 0x52, 0x61, 0x3a, 0x2d, 0x31, 0x3e, 0x6e, 0x3f, 0x2d, + 0x52, 0x61, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x73, 0x69, + 0x6e, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x65, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x28, 0x28, 0x6e, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x65, 0x78, 0x70, 0x28, 0x6e, 0x29, 0x29, 0x2d, 0x31, + 0x2f, 0x6e, 0x29, 0x2f, 0x32, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x28, 0x6e, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x65, 0x78, 0x70, 0x28, 0x6e, 0x29, 0x29, 0x2b, + 0x31, 0x2f, 0x6e, 0x29, 0x2f, 0x32, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x74, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x28, 0x6e, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x65, 0x78, 0x70, 0x28, 0x32, 0x2a, 0x6e, + 0x29, 0x29, 0x2d, 0x31, 0x29, 0x2f, 0x28, 0x6e, 0x2b, 0x31, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x28, 0x6e, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, + 0x28, 0x6e, 0x2f, 0x32, 0x29, 0x29, 0x2a, 0x6e, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x74, 0x28, 0x29, + 0x7b, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, + 0x61, 0x74, 0x3f, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x68, 0x3d, + 0x2b, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x3d, 0x2b, + 0x74, 0x2c, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x6c, 0x3d, 0x2b, 0x65, 0x29, 0x29, 0x3a, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3c, 0x32, 0x3f, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x3f, 0x6e, + 0x65, 0x77, 0x20, 0x61, 0x74, 0x28, 0x6e, 0x2e, 0x68, 0x2c, 0x6e, + 0x2e, 0x73, 0x2c, 0x6e, 0x2e, 0x6c, 0x29, 0x3a, 0x62, 0x74, 0x28, + 0x22, 0x22, 0x2b, 0x6e, 0x2c, 0x5f, 0x74, 0x2c, 0x61, 0x74, 0x29, + 0x3a, 0x6e, 0x65, 0x77, 0x20, 0x61, 0x74, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x63, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x3e, 0x33, 0x36, 0x30, 0x3f, 0x6e, 0x2d, 0x3d, 0x33, 0x36, + 0x30, 0x3a, 0x30, 0x3e, 0x6e, 0x26, 0x26, 0x28, 0x6e, 0x2b, 0x3d, + 0x33, 0x36, 0x30, 0x29, 0x2c, 0x36, 0x30, 0x3e, 0x6e, 0x3f, 0x69, + 0x2b, 0x28, 0x6f, 0x2d, 0x69, 0x29, 0x2a, 0x6e, 0x2f, 0x36, 0x30, + 0x3a, 0x31, 0x38, 0x30, 0x3e, 0x6e, 0x3f, 0x6f, 0x3a, 0x32, 0x34, + 0x30, 0x3e, 0x6e, 0x3f, 0x69, 0x2b, 0x28, 0x6f, 0x2d, 0x69, 0x29, + 0x2a, 0x28, 0x32, 0x34, 0x30, 0x2d, 0x6e, 0x29, 0x2f, 0x36, 0x30, + 0x3a, 0x69, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x28, 0x32, 0x35, 0x35, 0x2a, 0x72, 0x28, 0x6e, 0x29, 0x29, + 0x7d, 0x76, 0x61, 0x72, 0x20, 0x69, 0x2c, 0x6f, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x69, 0x73, 0x4e, 0x61, + 0x4e, 0x28, 0x6e, 0x29, 0x3f, 0x30, 0x3a, 0x28, 0x6e, 0x25, 0x3d, + 0x33, 0x36, 0x30, 0x29, 0x3c, 0x30, 0x3f, 0x6e, 0x2b, 0x33, 0x36, + 0x30, 0x3a, 0x6e, 0x2c, 0x74, 0x3d, 0x69, 0x73, 0x4e, 0x61, 0x4e, + 0x28, 0x74, 0x29, 0x3f, 0x30, 0x3a, 0x30, 0x3e, 0x74, 0x3f, 0x30, + 0x3a, 0x74, 0x3e, 0x31, 0x3f, 0x31, 0x3a, 0x74, 0x2c, 0x65, 0x3d, + 0x30, 0x3e, 0x65, 0x3f, 0x30, 0x3a, 0x65, 0x3e, 0x31, 0x3f, 0x31, + 0x3a, 0x65, 0x2c, 0x6f, 0x3d, 0x2e, 0x35, 0x3e, 0x3d, 0x65, 0x3f, + 0x65, 0x2a, 0x28, 0x31, 0x2b, 0x74, 0x29, 0x3a, 0x65, 0x2b, 0x74, + 0x2d, 0x65, 0x2a, 0x74, 0x2c, 0x69, 0x3d, 0x32, 0x2a, 0x65, 0x2d, + 0x6f, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x6d, 0x74, 0x28, 0x75, 0x28, + 0x6e, 0x2b, 0x31, 0x32, 0x30, 0x29, 0x2c, 0x75, 0x28, 0x6e, 0x29, + 0x2c, 0x75, 0x28, 0x6e, 0x2d, 0x31, 0x32, 0x30, 0x29, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x74, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x6c, 0x74, + 0x3f, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x68, 0x3d, 0x2b, 0x6e, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x3d, 0x2b, 0x74, 0x2c, + 0x76, 0x6f, 0x69, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, + 0x3d, 0x2b, 0x65, 0x29, 0x29, 0x3a, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3c, 0x32, 0x3f, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x6f, 0x66, 0x20, 0x6c, 0x74, 0x3f, 0x6e, 0x65, 0x77, + 0x20, 0x6c, 0x74, 0x28, 0x6e, 0x2e, 0x68, 0x2c, 0x6e, 0x2e, 0x63, + 0x2c, 0x6e, 0x2e, 0x6c, 0x29, 0x3a, 0x6e, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x66, 0x74, 0x3f, + 0x67, 0x74, 0x28, 0x6e, 0x2e, 0x6c, 0x2c, 0x6e, 0x2e, 0x61, 0x2c, + 0x6e, 0x2e, 0x62, 0x29, 0x3a, 0x67, 0x74, 0x28, 0x28, 0x6e, 0x3d, + 0x77, 0x74, 0x28, 0x28, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x72, 0x67, + 0x62, 0x28, 0x6e, 0x29, 0x29, 0x2e, 0x72, 0x2c, 0x6e, 0x2e, 0x67, + 0x2c, 0x6e, 0x2e, 0x62, 0x29, 0x29, 0x2e, 0x6c, 0x2c, 0x6e, 0x2e, + 0x61, 0x2c, 0x6e, 0x2e, 0x62, 0x29, 0x3a, 0x6e, 0x65, 0x77, 0x20, + 0x6c, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x6e, 0x29, + 0x26, 0x26, 0x28, 0x6e, 0x3d, 0x30, 0x29, 0x2c, 0x69, 0x73, 0x4e, + 0x61, 0x4e, 0x28, 0x74, 0x29, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x30, + 0x29, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x66, 0x74, 0x28, 0x65, 0x2c, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x2a, + 0x3d, 0x44, 0x61, 0x29, 0x2a, 0x74, 0x2c, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x29, 0x2a, 0x74, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x74, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x66, 0x74, + 0x3f, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x3d, 0x2b, 0x6e, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x3d, 0x2b, 0x74, 0x2c, + 0x76, 0x6f, 0x69, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x62, + 0x3d, 0x2b, 0x65, 0x29, 0x29, 0x3a, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3c, 0x32, 0x3f, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, + 0x63, 0x65, 0x6f, 0x66, 0x20, 0x66, 0x74, 0x3f, 0x6e, 0x65, 0x77, + 0x20, 0x66, 0x74, 0x28, 0x6e, 0x2e, 0x6c, 0x2c, 0x6e, 0x2e, 0x61, + 0x2c, 0x6e, 0x2e, 0x62, 0x29, 0x3a, 0x6e, 0x20, 0x69, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66, 0x20, 0x6c, 0x74, 0x3f, + 0x73, 0x74, 0x28, 0x6e, 0x2e, 0x68, 0x2c, 0x6e, 0x2e, 0x63, 0x2c, + 0x6e, 0x2e, 0x6c, 0x29, 0x3a, 0x77, 0x74, 0x28, 0x28, 0x6e, 0x3d, + 0x6d, 0x74, 0x28, 0x6e, 0x29, 0x29, 0x2e, 0x72, 0x2c, 0x6e, 0x2e, + 0x67, 0x2c, 0x6e, 0x2e, 0x62, 0x29, 0x3a, 0x6e, 0x65, 0x77, 0x20, + 0x66, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x74, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x28, 0x6e, 0x2b, 0x31, 0x36, 0x29, 0x2f, 0x31, 0x31, + 0x36, 0x2c, 0x75, 0x3d, 0x72, 0x2b, 0x74, 0x2f, 0x35, 0x30, 0x30, + 0x2c, 0x69, 0x3d, 0x72, 0x2d, 0x65, 0x2f, 0x32, 0x30, 0x30, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x3d, 0x70, 0x74, + 0x28, 0x75, 0x29, 0x2a, 0x58, 0x61, 0x2c, 0x72, 0x3d, 0x70, 0x74, + 0x28, 0x72, 0x29, 0x2a, 0x24, 0x61, 0x2c, 0x69, 0x3d, 0x70, 0x74, + 0x28, 0x69, 0x29, 0x2a, 0x42, 0x61, 0x2c, 0x6e, 0x65, 0x77, 0x20, + 0x6d, 0x74, 0x28, 0x64, 0x74, 0x28, 0x33, 0x2e, 0x32, 0x34, 0x30, + 0x34, 0x35, 0x34, 0x32, 0x2a, 0x75, 0x2d, 0x31, 0x2e, 0x35, 0x33, + 0x37, 0x31, 0x33, 0x38, 0x35, 0x2a, 0x72, 0x2d, 0x2e, 0x34, 0x39, + 0x38, 0x35, 0x33, 0x31, 0x34, 0x2a, 0x69, 0x29, 0x2c, 0x64, 0x74, + 0x28, 0x2d, 0x2e, 0x39, 0x36, 0x39, 0x32, 0x36, 0x36, 0x2a, 0x75, + 0x2b, 0x31, 0x2e, 0x38, 0x37, 0x36, 0x30, 0x31, 0x30, 0x38, 0x2a, + 0x72, 0x2b, 0x2e, 0x30, 0x34, 0x31, 0x35, 0x35, 0x36, 0x2a, 0x69, + 0x29, 0x2c, 0x64, 0x74, 0x28, 0x2e, 0x30, 0x35, 0x35, 0x36, 0x34, + 0x33, 0x34, 0x2a, 0x75, 0x2d, 0x2e, 0x32, 0x30, 0x34, 0x30, 0x32, + 0x35, 0x39, 0x2a, 0x72, 0x2b, 0x31, 0x2e, 0x30, 0x35, 0x37, 0x32, + 0x32, 0x35, 0x32, 0x2a, 0x69, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x74, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x3e, 0x30, 0x3f, 0x6e, 0x65, 0x77, 0x20, 0x6c, 0x74, + 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, + 0x28, 0x65, 0x2c, 0x74, 0x29, 0x2a, 0x50, 0x61, 0x2c, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x74, 0x2a, 0x74, + 0x2b, 0x65, 0x2a, 0x65, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x6e, 0x65, + 0x77, 0x20, 0x6c, 0x74, 0x28, 0x30, 0x2f, 0x30, 0x2c, 0x30, 0x2f, + 0x30, 0x2c, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3e, 0x2e, 0x32, 0x30, 0x36, + 0x38, 0x39, 0x33, 0x30, 0x33, 0x34, 0x3f, 0x6e, 0x2a, 0x6e, 0x2a, + 0x6e, 0x3a, 0x28, 0x6e, 0x2d, 0x34, 0x2f, 0x32, 0x39, 0x29, 0x2f, + 0x37, 0x2e, 0x37, 0x38, 0x37, 0x30, 0x33, 0x37, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x74, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3e, + 0x2e, 0x30, 0x30, 0x38, 0x38, 0x35, 0x36, 0x3f, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x6e, 0x2c, 0x31, 0x2f, 0x33, + 0x29, 0x3a, 0x37, 0x2e, 0x37, 0x38, 0x37, 0x30, 0x33, 0x37, 0x2a, + 0x6e, 0x2b, 0x34, 0x2f, 0x32, 0x39, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x74, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x32, 0x35, 0x35, 0x2a, + 0x28, 0x2e, 0x30, 0x30, 0x33, 0x30, 0x34, 0x3e, 0x3d, 0x6e, 0x3f, + 0x31, 0x32, 0x2e, 0x39, 0x32, 0x2a, 0x6e, 0x3a, 0x31, 0x2e, 0x30, + 0x35, 0x35, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, + 0x28, 0x6e, 0x2c, 0x31, 0x2f, 0x32, 0x2e, 0x34, 0x29, 0x2d, 0x2e, + 0x30, 0x35, 0x35, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x6f, 0x66, 0x20, 0x6d, 0x74, 0x3f, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x72, 0x3d, 0x7e, 0x7e, 0x6e, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x67, 0x3d, 0x7e, 0x7e, 0x74, 0x2c, 0x76, 0x6f, 0x69, + 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x62, 0x3d, 0x7e, 0x7e, + 0x65, 0x29, 0x29, 0x3a, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, + 0x3f, 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, + 0x6f, 0x66, 0x20, 0x6d, 0x74, 0x3f, 0x6e, 0x65, 0x77, 0x20, 0x6d, + 0x74, 0x28, 0x6e, 0x2e, 0x72, 0x2c, 0x6e, 0x2e, 0x67, 0x2c, 0x6e, + 0x2e, 0x62, 0x29, 0x3a, 0x62, 0x74, 0x28, 0x22, 0x22, 0x2b, 0x6e, + 0x2c, 0x6d, 0x74, 0x2c, 0x63, 0x74, 0x29, 0x3a, 0x6e, 0x65, 0x77, + 0x20, 0x6d, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x74, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x65, 0x77, 0x20, 0x6d, 0x74, 0x28, 0x6e, 0x3e, 0x3e, 0x31, + 0x36, 0x2c, 0x6e, 0x3e, 0x3e, 0x38, 0x26, 0x32, 0x35, 0x35, 0x2c, + 0x32, 0x35, 0x35, 0x26, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x74, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, 0x74, 0x28, 0x6e, + 0x29, 0x2b, 0x22, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x78, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x36, 0x3e, 0x6e, 0x3f, 0x22, + 0x30, 0x22, 0x2b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, + 0x28, 0x30, 0x2c, 0x6e, 0x29, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x28, 0x31, 0x36, 0x29, 0x3a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x6e, + 0x29, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, + 0x31, 0x36, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x62, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, + 0x6f, 0x3d, 0x30, 0x2c, 0x61, 0x3d, 0x30, 0x2c, 0x63, 0x3d, 0x30, + 0x3b, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x2f, 0x28, 0x5b, 0x61, 0x2d, + 0x7a, 0x5d, 0x2b, 0x29, 0x5c, 0x28, 0x28, 0x2e, 0x2a, 0x29, 0x5c, + 0x29, 0x2f, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x6e, 0x3d, 0x6e, + 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, + 0x65, 0x28, 0x29, 0x29, 0x29, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, + 0x28, 0x75, 0x3d, 0x72, 0x5b, 0x32, 0x5d, 0x2e, 0x73, 0x70, 0x6c, + 0x69, 0x74, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x2c, 0x72, 0x5b, 0x31, + 0x5d, 0x29, 0x7b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x68, 0x73, 0x6c, + 0x22, 0x3a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x28, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, + 0x75, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x75, 0x5b, 0x31, 0x5d, 0x29, + 0x2f, 0x31, 0x30, 0x30, 0x2c, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, + 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x75, 0x5b, 0x32, 0x5d, 0x29, 0x2f, + 0x31, 0x30, 0x30, 0x29, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x72, + 0x67, 0x62, 0x22, 0x3a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x28, 0x6b, 0x74, 0x28, 0x75, 0x5b, 0x30, 0x5d, 0x29, 0x2c, + 0x6b, 0x74, 0x28, 0x75, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x6b, 0x74, + 0x28, 0x75, 0x5b, 0x32, 0x5d, 0x29, 0x29, 0x7d, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x28, 0x69, 0x3d, 0x47, 0x61, 0x2e, 0x67, 0x65, + 0x74, 0x28, 0x6e, 0x29, 0x29, 0x3f, 0x74, 0x28, 0x69, 0x2e, 0x72, + 0x2c, 0x69, 0x2e, 0x67, 0x2c, 0x69, 0x2e, 0x62, 0x29, 0x3a, 0x28, + 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x7c, 0x7c, 0x22, 0x23, + 0x22, 0x21, 0x3d, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, + 0x74, 0x28, 0x30, 0x29, 0x7c, 0x7c, 0x69, 0x73, 0x4e, 0x61, 0x4e, + 0x28, 0x69, 0x3d, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6e, 0x74, + 0x28, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x31, 0x29, + 0x2c, 0x31, 0x36, 0x29, 0x29, 0x7c, 0x7c, 0x28, 0x34, 0x3d, 0x3d, + 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x6f, 0x3d, 0x28, 0x33, 0x38, 0x34, 0x30, 0x26, 0x69, 0x29, 0x3e, + 0x3e, 0x34, 0x2c, 0x6f, 0x3d, 0x6f, 0x3e, 0x3e, 0x34, 0x7c, 0x6f, + 0x2c, 0x61, 0x3d, 0x32, 0x34, 0x30, 0x26, 0x69, 0x2c, 0x61, 0x3d, + 0x61, 0x3e, 0x3e, 0x34, 0x7c, 0x61, 0x2c, 0x63, 0x3d, 0x31, 0x35, + 0x26, 0x69, 0x2c, 0x63, 0x3d, 0x63, 0x3c, 0x3c, 0x34, 0x7c, 0x63, + 0x29, 0x3a, 0x37, 0x3d, 0x3d, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x26, 0x26, 0x28, 0x6f, 0x3d, 0x28, 0x31, 0x36, + 0x37, 0x31, 0x31, 0x36, 0x38, 0x30, 0x26, 0x69, 0x29, 0x3e, 0x3e, + 0x31, 0x36, 0x2c, 0x61, 0x3d, 0x28, 0x36, 0x35, 0x32, 0x38, 0x30, + 0x26, 0x69, 0x29, 0x3e, 0x3e, 0x38, 0x2c, 0x63, 0x3d, 0x32, 0x35, + 0x35, 0x26, 0x69, 0x29, 0x29, 0x2c, 0x74, 0x28, 0x6f, 0x2c, 0x61, + 0x2c, 0x63, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x5f, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x2c, 0x69, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6e, + 0x2f, 0x3d, 0x32, 0x35, 0x35, 0x2c, 0x74, 0x2f, 0x3d, 0x32, 0x35, + 0x35, 0x2c, 0x65, 0x2f, 0x3d, 0x32, 0x35, 0x35, 0x29, 0x2c, 0x6f, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x2c, 0x61, 0x3d, 0x6f, 0x2d, 0x69, + 0x2c, 0x63, 0x3d, 0x28, 0x6f, 0x2b, 0x69, 0x29, 0x2f, 0x32, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x3f, 0x28, 0x75, + 0x3d, 0x2e, 0x35, 0x3e, 0x63, 0x3f, 0x61, 0x2f, 0x28, 0x6f, 0x2b, + 0x69, 0x29, 0x3a, 0x61, 0x2f, 0x28, 0x32, 0x2d, 0x6f, 0x2d, 0x69, + 0x29, 0x2c, 0x72, 0x3d, 0x6e, 0x3d, 0x3d, 0x6f, 0x3f, 0x28, 0x74, + 0x2d, 0x65, 0x29, 0x2f, 0x61, 0x2b, 0x28, 0x65, 0x3e, 0x74, 0x3f, + 0x36, 0x3a, 0x30, 0x29, 0x3a, 0x74, 0x3d, 0x3d, 0x6f, 0x3f, 0x28, + 0x65, 0x2d, 0x6e, 0x29, 0x2f, 0x61, 0x2b, 0x32, 0x3a, 0x28, 0x6e, + 0x2d, 0x74, 0x29, 0x2f, 0x61, 0x2b, 0x34, 0x2c, 0x72, 0x2a, 0x3d, + 0x36, 0x30, 0x29, 0x3a, 0x28, 0x72, 0x3d, 0x30, 0x2f, 0x30, 0x2c, + 0x75, 0x3d, 0x63, 0x3e, 0x30, 0x26, 0x26, 0x31, 0x3e, 0x63, 0x3f, + 0x30, 0x3a, 0x72, 0x29, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x61, 0x74, + 0x28, 0x72, 0x2c, 0x75, 0x2c, 0x63, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x74, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x6e, 0x3d, 0x53, 0x74, 0x28, 0x6e, + 0x29, 0x2c, 0x74, 0x3d, 0x53, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x65, + 0x3d, 0x53, 0x74, 0x28, 0x65, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x76, 0x74, 0x28, 0x28, 0x2e, 0x34, 0x31, 0x32, 0x34, + 0x35, 0x36, 0x34, 0x2a, 0x6e, 0x2b, 0x2e, 0x33, 0x35, 0x37, 0x35, + 0x37, 0x36, 0x31, 0x2a, 0x74, 0x2b, 0x2e, 0x31, 0x38, 0x30, 0x34, + 0x33, 0x37, 0x35, 0x2a, 0x65, 0x29, 0x2f, 0x58, 0x61, 0x29, 0x2c, + 0x75, 0x3d, 0x76, 0x74, 0x28, 0x28, 0x2e, 0x32, 0x31, 0x32, 0x36, + 0x37, 0x32, 0x39, 0x2a, 0x6e, 0x2b, 0x2e, 0x37, 0x31, 0x35, 0x31, + 0x35, 0x32, 0x32, 0x2a, 0x74, 0x2b, 0x2e, 0x30, 0x37, 0x32, 0x31, + 0x37, 0x35, 0x2a, 0x65, 0x29, 0x2f, 0x24, 0x61, 0x29, 0x2c, 0x69, + 0x3d, 0x76, 0x74, 0x28, 0x28, 0x2e, 0x30, 0x31, 0x39, 0x33, 0x33, + 0x33, 0x39, 0x2a, 0x6e, 0x2b, 0x2e, 0x31, 0x31, 0x39, 0x31, 0x39, + 0x32, 0x2a, 0x74, 0x2b, 0x2e, 0x39, 0x35, 0x30, 0x33, 0x30, 0x34, + 0x31, 0x2a, 0x65, 0x29, 0x2f, 0x42, 0x61, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x74, 0x28, 0x31, 0x31, 0x36, + 0x2a, 0x75, 0x2d, 0x31, 0x36, 0x2c, 0x35, 0x30, 0x30, 0x2a, 0x28, + 0x72, 0x2d, 0x75, 0x29, 0x2c, 0x32, 0x30, 0x30, 0x2a, 0x28, 0x75, + 0x2d, 0x69, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x53, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x28, 0x6e, 0x2f, 0x3d, 0x32, 0x35, 0x35, + 0x29, 0x3c, 0x3d, 0x2e, 0x30, 0x34, 0x30, 0x34, 0x35, 0x3f, 0x6e, + 0x2f, 0x31, 0x32, 0x2e, 0x39, 0x32, 0x3a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x28, 0x6e, 0x2b, 0x2e, 0x30, 0x35, + 0x35, 0x29, 0x2f, 0x31, 0x2e, 0x30, 0x35, 0x35, 0x2c, 0x32, 0x2e, + 0x34, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6b, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, + 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x22, 0x25, 0x22, 0x3d, 0x3d, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x41, 0x74, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2d, 0x31, 0x29, 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x32, 0x2e, 0x35, 0x35, 0x2a, 0x74, + 0x29, 0x3a, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x45, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x6e, 0x3f, 0x6e, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x41, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x32, 0x3d, 0x3d, 0x3d, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x26, 0x26, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, + 0x20, 0x65, 0x26, 0x26, 0x28, 0x72, 0x3d, 0x65, 0x2c, 0x65, 0x3d, + 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x4e, 0x74, 0x28, 0x74, 0x2c, + 0x65, 0x2c, 0x6e, 0x2c, 0x72, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x74, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6e, 0x2c, 0x74, 0x3d, 0x63, 0x2e, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x74, 0x26, 0x26, + 0x7a, 0x74, 0x28, 0x63, 0x29, 0x7c, 0x7c, 0x74, 0x3e, 0x3d, 0x32, + 0x30, 0x30, 0x26, 0x26, 0x33, 0x30, 0x30, 0x3e, 0x74, 0x7c, 0x7c, + 0x33, 0x30, 0x34, 0x3d, 0x3d, 0x3d, 0x74, 0x29, 0x7b, 0x74, 0x72, + 0x79, 0x7b, 0x6e, 0x3d, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x69, 0x2c, 0x63, 0x29, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, + 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, + 0x6f, 0x69, 0x64, 0x20, 0x6f, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x69, 0x2c, 0x72, 0x29, 0x7d, + 0x6f, 0x2e, 0x6c, 0x6f, 0x61, 0x64, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x69, 0x2c, 0x6e, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x6f, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x69, 0x2c, 0x63, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x69, 0x3d, 0x7b, 0x7d, 0x2c, 0x6f, 0x3d, 0x74, 0x61, 0x2e, 0x64, + 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x22, 0x2c, 0x22, + 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x22, 0x2c, 0x22, + 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x2c, 0x22, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x22, 0x29, 0x2c, 0x61, 0x3d, 0x7b, 0x7d, 0x2c, 0x63, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x58, 0x4d, 0x4c, 0x48, 0x74, 0x74, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2c, 0x6c, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x58, 0x44, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x7c, 0x7c, 0x22, + 0x77, 0x69, 0x74, 0x68, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x22, 0x69, 0x6e, 0x20, 0x63, 0x7c, 0x7c, + 0x21, 0x2f, 0x5e, 0x28, 0x68, 0x74, 0x74, 0x70, 0x28, 0x73, 0x29, + 0x3f, 0x3a, 0x29, 0x3f, 0x5c, 0x2f, 0x5c, 0x2f, 0x2f, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x28, 0x6e, 0x29, 0x7c, 0x7c, 0x28, 0x63, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x58, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x29, 0x2c, 0x22, 0x6f, + 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x69, 0x6e, 0x20, 0x63, 0x3f, + 0x63, 0x2e, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x3d, 0x63, 0x2e, + 0x6f, 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3d, 0x75, 0x3a, 0x63, + 0x2e, 0x6f, 0x6e, 0x72, 0x65, 0x61, 0x64, 0x79, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x63, 0x2e, + 0x72, 0x65, 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3e, + 0x33, 0x26, 0x26, 0x75, 0x28, 0x29, 0x7d, 0x2c, 0x63, 0x2e, 0x6f, + 0x6e, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x3b, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x3d, 0x6e, 0x3b, 0x74, 0x72, 0x79, 0x7b, 0x6f, 0x2e, 0x70, + 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x69, 0x2c, 0x63, 0x29, 0x7d, 0x66, 0x69, 0x6e, 0x61, + 0x6c, 0x6c, 0x79, 0x7b, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x3d, 0x74, 0x7d, 0x7d, 0x2c, 0x69, 0x2e, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x28, 0x6e, 0x2b, 0x22, 0x22, 0x29, + 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, + 0x65, 0x28, 0x29, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, + 0x3f, 0x61, 0x5b, 0x6e, 0x5d, 0x3a, 0x28, 0x6e, 0x75, 0x6c, 0x6c, + 0x3d, 0x3d, 0x74, 0x3f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, + 0x61, 0x5b, 0x6e, 0x5d, 0x3a, 0x61, 0x5b, 0x6e, 0x5d, 0x3d, 0x74, + 0x2b, 0x22, 0x22, 0x2c, 0x69, 0x29, 0x7d, 0x2c, 0x69, 0x2e, 0x6d, + 0x69, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x74, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x3f, + 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x6e, 0x2b, 0x22, 0x22, 0x2c, 0x69, + 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x6c, 0x3d, 0x6e, 0x2c, 0x69, 0x29, 0x3a, 0x6c, 0x7d, + 0x2c, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3d, + 0x6e, 0x2c, 0x69, 0x7d, 0x2c, 0x5b, 0x22, 0x67, 0x65, 0x74, 0x22, + 0x2c, 0x22, 0x70, 0x6f, 0x73, 0x74, 0x22, 0x5d, 0x2e, 0x66, 0x6f, + 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x69, 0x5b, 0x6e, 0x5d, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x2e, 0x73, + 0x65, 0x6e, 0x64, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x69, + 0x2c, 0x5b, 0x6e, 0x5d, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, + 0x28, 0x72, 0x61, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x29, 0x29, 0x29, 0x7d, 0x7d, 0x29, 0x2c, 0x69, 0x2e, + 0x73, 0x65, 0x6e, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x29, 0x7b, 0x69, + 0x66, 0x28, 0x32, 0x3d, 0x3d, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x26, 0x26, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x72, + 0x26, 0x26, 0x28, 0x75, 0x3d, 0x72, 0x2c, 0x72, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x29, 0x2c, 0x63, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x28, + 0x65, 0x2c, 0x6e, 0x2c, 0x21, 0x30, 0x29, 0x2c, 0x6e, 0x75, 0x6c, + 0x6c, 0x3d, 0x3d, 0x74, 0x7c, 0x7c, 0x22, 0x61, 0x63, 0x63, 0x65, + 0x70, 0x74, 0x22, 0x69, 0x6e, 0x20, 0x61, 0x7c, 0x7c, 0x28, 0x61, + 0x2e, 0x61, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3d, 0x74, 0x2b, 0x22, + 0x2c, 0x2a, 0x2f, 0x2a, 0x22, 0x29, 0x2c, 0x63, 0x2e, 0x73, 0x65, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x29, 0x63, 0x2e, 0x73, + 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x28, 0x73, 0x2c, 0x61, 0x5b, 0x73, 0x5d, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, + 0x6c, 0x6c, 0x21, 0x3d, 0x74, 0x26, 0x26, 0x63, 0x2e, 0x6f, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x4d, 0x69, 0x6d, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x26, 0x26, 0x63, 0x2e, 0x6f, 0x76, 0x65, 0x72, + 0x72, 0x69, 0x64, 0x65, 0x4d, 0x69, 0x6d, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, + 0x6c, 0x26, 0x26, 0x28, 0x63, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3d, 0x6c, 0x29, 0x2c, + 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x75, 0x26, 0x26, 0x69, 0x2e, + 0x6f, 0x6e, 0x28, 0x22, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x2c, + 0x75, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x6c, 0x6f, 0x61, 0x64, + 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x75, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6e, + 0x29, 0x7d, 0x29, 0x2c, 0x6f, 0x2e, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x73, 0x65, 0x6e, 0x64, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x69, 0x2c, 0x63, 0x29, 0x2c, 0x63, 0x2e, 0x73, 0x65, 0x6e, 0x64, + 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x72, 0x3f, 0x6e, 0x75, + 0x6c, 0x6c, 0x3a, 0x72, 0x29, 0x2c, 0x69, 0x7d, 0x2c, 0x69, 0x2e, + 0x61, 0x62, 0x6f, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x63, 0x2e, 0x61, 0x62, 0x6f, 0x72, 0x74, 0x28, 0x29, + 0x2c, 0x69, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x62, 0x69, + 0x6e, 0x64, 0x28, 0x69, 0x2c, 0x6f, 0x2c, 0x22, 0x6f, 0x6e, 0x22, + 0x29, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x72, 0x3f, 0x69, + 0x3a, 0x69, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x43, 0x74, 0x28, 0x72, + 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x43, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x31, 0x3d, 0x3d, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x6e, 0x28, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, 0x3f, 0x65, 0x3a, 0x6e, 0x75, + 0x6c, 0x6c, 0x29, 0x7d, 0x3a, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x74, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x26, 0x26, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x22, 0x21, 0x3d, 0x3d, 0x74, 0x3f, 0x6e, 0x2e, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x3a, 0x6e, 0x2e, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x65, 0x78, + 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x71, 0x74, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, + 0x4c, 0x74, 0x28, 0x29, 0x2c, 0x74, 0x3d, 0x54, 0x74, 0x28, 0x29, + 0x2d, 0x6e, 0x3b, 0x74, 0x3e, 0x32, 0x34, 0x3f, 0x28, 0x69, 0x73, + 0x46, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x28, 0x74, 0x29, 0x26, 0x26, + 0x28, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x28, 0x74, 0x63, 0x29, 0x2c, 0x74, 0x63, 0x3d, 0x73, + 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x71, + 0x74, 0x2c, 0x74, 0x29, 0x29, 0x2c, 0x6e, 0x63, 0x3d, 0x30, 0x29, + 0x3a, 0x28, 0x6e, 0x63, 0x3d, 0x31, 0x2c, 0x72, 0x63, 0x28, 0x71, + 0x74, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x4c, 0x74, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x3d, 0x44, 0x61, 0x74, 0x65, 0x2e, 0x6e, 0x6f, 0x77, 0x28, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x63, 0x3d, 0x4b, 0x61, + 0x3b, 0x65, 0x63, 0x3b, 0x29, 0x6e, 0x3e, 0x3d, 0x65, 0x63, 0x2e, + 0x74, 0x26, 0x26, 0x28, 0x65, 0x63, 0x2e, 0x66, 0x3d, 0x65, 0x63, + 0x2e, 0x63, 0x28, 0x6e, 0x2d, 0x65, 0x63, 0x2e, 0x74, 0x29, 0x29, + 0x2c, 0x65, 0x63, 0x3d, 0x65, 0x63, 0x2e, 0x6e, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x74, 0x28, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x2c, 0x74, 0x3d, + 0x4b, 0x61, 0x2c, 0x65, 0x3d, 0x31, 0x2f, 0x30, 0x3b, 0x74, 0x3b, + 0x29, 0x74, 0x2e, 0x66, 0x3f, 0x74, 0x3d, 0x6e, 0x3f, 0x6e, 0x2e, + 0x6e, 0x3d, 0x74, 0x2e, 0x6e, 0x3a, 0x4b, 0x61, 0x3d, 0x74, 0x2e, + 0x6e, 0x3a, 0x28, 0x74, 0x2e, 0x74, 0x3c, 0x65, 0x26, 0x26, 0x28, + 0x65, 0x3d, 0x74, 0x2e, 0x74, 0x29, 0x2c, 0x74, 0x3d, 0x28, 0x6e, + 0x3d, 0x74, 0x29, 0x2e, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x51, 0x61, 0x3d, 0x6e, 0x2c, 0x65, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x74, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x2d, 0x28, 0x6e, 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x63, 0x65, 0x69, 0x6c, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, + 0x6f, 0x67, 0x28, 0x6e, 0x29, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x4c, 0x4e, 0x31, 0x30, 0x29, 0x3a, 0x31, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x74, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x31, 0x30, 0x2c, + 0x33, 0x2a, 0x67, 0x61, 0x28, 0x38, 0x2d, 0x74, 0x29, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x3a, 0x74, 0x3e, 0x38, 0x3f, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x2f, 0x65, 0x7d, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2a, 0x65, 0x7d, 0x2c, 0x73, + 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x3a, 0x6e, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x74, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x64, + 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, + 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, 0x2c, 0x72, + 0x3d, 0x6e, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x69, 0x6e, 0x67, + 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x79, 0x2c, 0x69, 0x3d, 0x72, 0x26, 0x26, 0x65, 0x3f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x75, + 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x69, + 0x3d, 0x5b, 0x5d, 0x2c, 0x6f, 0x3d, 0x30, 0x2c, 0x61, 0x3d, 0x72, + 0x5b, 0x30, 0x5d, 0x2c, 0x63, 0x3d, 0x30, 0x3b, 0x75, 0x3e, 0x30, + 0x26, 0x26, 0x61, 0x3e, 0x30, 0x26, 0x26, 0x28, 0x63, 0x2b, 0x61, + 0x2b, 0x31, 0x3e, 0x74, 0x26, 0x26, 0x28, 0x61, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x31, 0x2c, 0x74, 0x2d, + 0x63, 0x29, 0x29, 0x2c, 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x28, 0x75, 0x2d, 0x3d, 0x61, 0x2c, 0x75, 0x2b, 0x61, 0x29, 0x29, + 0x2c, 0x21, 0x28, 0x28, 0x63, 0x2b, 0x3d, 0x61, 0x2b, 0x31, 0x29, + 0x3e, 0x74, 0x29, 0x29, 0x3b, 0x29, 0x61, 0x3d, 0x72, 0x5b, 0x6f, + 0x3d, 0x28, 0x6f, 0x2b, 0x31, 0x29, 0x25, 0x72, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x28, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x65, 0x29, 0x7d, + 0x3a, 0x79, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x69, 0x63, 0x2e, 0x65, 0x78, + 0x65, 0x63, 0x28, 0x6e, 0x29, 0x2c, 0x72, 0x3d, 0x65, 0x5b, 0x31, + 0x5d, 0x7c, 0x7c, 0x22, 0x20, 0x22, 0x2c, 0x6f, 0x3d, 0x65, 0x5b, + 0x32, 0x5d, 0x7c, 0x7c, 0x22, 0x3e, 0x22, 0x2c, 0x61, 0x3d, 0x65, + 0x5b, 0x33, 0x5d, 0x7c, 0x7c, 0x22, 0x2d, 0x22, 0x2c, 0x63, 0x3d, + 0x65, 0x5b, 0x34, 0x5d, 0x7c, 0x7c, 0x22, 0x22, 0x2c, 0x6c, 0x3d, + 0x65, 0x5b, 0x35, 0x5d, 0x2c, 0x73, 0x3d, 0x2b, 0x65, 0x5b, 0x36, + 0x5d, 0x2c, 0x66, 0x3d, 0x65, 0x5b, 0x37, 0x5d, 0x2c, 0x68, 0x3d, + 0x65, 0x5b, 0x38, 0x5d, 0x2c, 0x67, 0x3d, 0x65, 0x5b, 0x39, 0x5d, + 0x2c, 0x70, 0x3d, 0x31, 0x2c, 0x76, 0x3d, 0x22, 0x22, 0x2c, 0x64, + 0x3d, 0x22, 0x22, 0x2c, 0x6d, 0x3d, 0x21, 0x31, 0x2c, 0x79, 0x3d, + 0x21, 0x30, 0x3b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x28, 0x68, + 0x26, 0x26, 0x28, 0x68, 0x3d, 0x2b, 0x68, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x29, 0x29, 0x2c, + 0x28, 0x6c, 0x7c, 0x7c, 0x22, 0x30, 0x22, 0x3d, 0x3d, 0x3d, 0x72, + 0x26, 0x26, 0x22, 0x3d, 0x22, 0x3d, 0x3d, 0x3d, 0x6f, 0x29, 0x26, + 0x26, 0x28, 0x6c, 0x3d, 0x72, 0x3d, 0x22, 0x30, 0x22, 0x2c, 0x6f, + 0x3d, 0x22, 0x3d, 0x22, 0x29, 0x2c, 0x67, 0x29, 0x7b, 0x63, 0x61, + 0x73, 0x65, 0x22, 0x6e, 0x22, 0x3a, 0x66, 0x3d, 0x21, 0x30, 0x2c, + 0x67, 0x3d, 0x22, 0x67, 0x22, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x3b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x25, 0x22, 0x3a, 0x70, 0x3d, + 0x31, 0x30, 0x30, 0x2c, 0x64, 0x3d, 0x22, 0x25, 0x22, 0x2c, 0x67, + 0x3d, 0x22, 0x66, 0x22, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, + 0x63, 0x61, 0x73, 0x65, 0x22, 0x70, 0x22, 0x3a, 0x70, 0x3d, 0x31, + 0x30, 0x30, 0x2c, 0x64, 0x3d, 0x22, 0x25, 0x22, 0x2c, 0x67, 0x3d, + 0x22, 0x72, 0x22, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, + 0x61, 0x73, 0x65, 0x22, 0x62, 0x22, 0x3a, 0x63, 0x61, 0x73, 0x65, + 0x22, 0x6f, 0x22, 0x3a, 0x63, 0x61, 0x73, 0x65, 0x22, 0x78, 0x22, + 0x3a, 0x63, 0x61, 0x73, 0x65, 0x22, 0x58, 0x22, 0x3a, 0x22, 0x23, + 0x22, 0x3d, 0x3d, 0x3d, 0x63, 0x26, 0x26, 0x28, 0x76, 0x3d, 0x22, + 0x30, 0x22, 0x2b, 0x67, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, + 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, 0x29, 0x3b, 0x63, 0x61, + 0x73, 0x65, 0x22, 0x63, 0x22, 0x3a, 0x79, 0x3d, 0x21, 0x31, 0x3b, + 0x63, 0x61, 0x73, 0x65, 0x22, 0x64, 0x22, 0x3a, 0x6d, 0x3d, 0x21, + 0x30, 0x2c, 0x68, 0x3d, 0x30, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, + 0x3b, 0x63, 0x61, 0x73, 0x65, 0x22, 0x73, 0x22, 0x3a, 0x70, 0x3d, + 0x2d, 0x31, 0x2c, 0x67, 0x3d, 0x22, 0x72, 0x22, 0x7d, 0x22, 0x24, + 0x22, 0x3d, 0x3d, 0x3d, 0x63, 0x26, 0x26, 0x28, 0x76, 0x3d, 0x75, + 0x5b, 0x30, 0x5d, 0x2c, 0x64, 0x3d, 0x75, 0x5b, 0x31, 0x5d, 0x29, + 0x2c, 0x22, 0x72, 0x22, 0x21, 0x3d, 0x67, 0x7c, 0x7c, 0x68, 0x7c, + 0x7c, 0x28, 0x67, 0x3d, 0x22, 0x67, 0x22, 0x29, 0x2c, 0x6e, 0x75, + 0x6c, 0x6c, 0x21, 0x3d, 0x68, 0x26, 0x26, 0x28, 0x22, 0x67, 0x22, + 0x3d, 0x3d, 0x67, 0x3f, 0x68, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x6d, 0x61, 0x78, 0x28, 0x31, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x6d, 0x69, 0x6e, 0x28, 0x32, 0x31, 0x2c, 0x68, 0x29, 0x29, 0x3a, + 0x28, 0x22, 0x65, 0x22, 0x3d, 0x3d, 0x67, 0x7c, 0x7c, 0x22, 0x66, + 0x22, 0x3d, 0x3d, 0x67, 0x29, 0x26, 0x26, 0x28, 0x68, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x30, 0x2c, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x32, 0x30, 0x2c, + 0x68, 0x29, 0x29, 0x29, 0x29, 0x2c, 0x67, 0x3d, 0x6f, 0x63, 0x2e, + 0x67, 0x65, 0x74, 0x28, 0x67, 0x29, 0x7c, 0x7c, 0x55, 0x74, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x4d, 0x3d, 0x6c, 0x26, 0x26, 0x66, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x3d, 0x64, 0x3b, 0x69, 0x66, 0x28, 0x6d, 0x26, 0x26, + 0x6e, 0x25, 0x31, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, + 0x22, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x30, 0x3e, 0x6e, + 0x7c, 0x7c, 0x30, 0x3d, 0x3d, 0x3d, 0x6e, 0x26, 0x26, 0x30, 0x3e, + 0x31, 0x2f, 0x6e, 0x3f, 0x28, 0x6e, 0x3d, 0x2d, 0x6e, 0x2c, 0x22, + 0x2d, 0x22, 0x29, 0x3a, 0x22, 0x2d, 0x22, 0x3d, 0x3d, 0x3d, 0x61, + 0x3f, 0x22, 0x22, 0x3a, 0x61, 0x3b, 0x69, 0x66, 0x28, 0x30, 0x3e, + 0x70, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, 0x74, 0x61, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x50, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x28, 0x6e, 0x2c, 0x68, 0x29, 0x3b, 0x6e, 0x3d, 0x63, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x6e, 0x29, 0x2c, 0x65, + 0x3d, 0x63, 0x2e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x2b, 0x64, + 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x2a, 0x3d, 0x70, 0x3b, + 0x6e, 0x3d, 0x67, 0x28, 0x6e, 0x2c, 0x68, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x78, 0x2c, 0x62, 0x2c, 0x5f, 0x3d, 0x6e, 0x2e, 0x6c, + 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, + 0x22, 0x2e, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x30, 0x3e, 0x5f, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x77, 0x3d, 0x79, 0x3f, 0x6e, + 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4f, + 0x66, 0x28, 0x22, 0x65, 0x22, 0x29, 0x3a, 0x2d, 0x31, 0x3b, 0x30, + 0x3e, 0x77, 0x3f, 0x28, 0x78, 0x3d, 0x6e, 0x2c, 0x62, 0x3d, 0x22, + 0x22, 0x29, 0x3a, 0x28, 0x78, 0x3d, 0x6e, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x2c, 0x77, 0x29, + 0x2c, 0x62, 0x3d, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x28, 0x77, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x78, 0x3d, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x2c, 0x5f, 0x29, 0x2c, 0x62, + 0x3d, 0x74, 0x2b, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x28, 0x5f, 0x2b, 0x31, 0x29, 0x3b, 0x21, 0x6c, + 0x26, 0x26, 0x66, 0x26, 0x26, 0x28, 0x78, 0x3d, 0x69, 0x28, 0x78, + 0x2c, 0x31, 0x2f, 0x30, 0x29, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x53, 0x3d, 0x76, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b, + 0x78, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b, 0x62, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b, 0x28, 0x4d, 0x3f, 0x30, + 0x3a, 0x75, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x2c, + 0x6b, 0x3d, 0x73, 0x3e, 0x53, 0x3f, 0x6e, 0x65, 0x77, 0x20, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x28, 0x53, 0x3d, 0x73, 0x2d, 0x53, 0x2b, + 0x31, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x72, 0x29, 0x3a, + 0x22, 0x22, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, + 0x26, 0x26, 0x28, 0x78, 0x3d, 0x69, 0x28, 0x6b, 0x2b, 0x78, 0x2c, + 0x6b, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x73, 0x2d, + 0x62, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x31, 0x2f, + 0x30, 0x29, 0x29, 0x2c, 0x75, 0x2b, 0x3d, 0x76, 0x2c, 0x6e, 0x3d, + 0x78, 0x2b, 0x62, 0x2c, 0x28, 0x22, 0x3c, 0x22, 0x3d, 0x3d, 0x3d, + 0x6f, 0x3f, 0x75, 0x2b, 0x6e, 0x2b, 0x6b, 0x3a, 0x22, 0x3e, 0x22, + 0x3d, 0x3d, 0x3d, 0x6f, 0x3f, 0x6b, 0x2b, 0x75, 0x2b, 0x6e, 0x3a, + 0x22, 0x5e, 0x22, 0x3d, 0x3d, 0x3d, 0x6f, 0x3f, 0x6b, 0x2e, 0x73, + 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x2c, + 0x53, 0x3e, 0x3e, 0x3d, 0x31, 0x29, 0x2b, 0x75, 0x2b, 0x6e, 0x2b, + 0x6b, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x28, 0x53, 0x29, 0x3a, 0x75, 0x2b, 0x28, 0x4d, 0x3f, 0x6e, 0x3a, + 0x6b, 0x2b, 0x6e, 0x29, 0x29, 0x2b, 0x65, 0x7d, 0x7d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x74, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2b, 0x22, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6a, 0x74, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x5f, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, + 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x31, 0x3f, 0x44, 0x61, + 0x74, 0x65, 0x2e, 0x55, 0x54, 0x43, 0x2e, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3a, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x74, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x74, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x28, 0x74, 0x29, 0x2c, 0x72, + 0x3d, 0x69, 0x28, 0x65, 0x2c, 0x31, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2d, 0x74, 0x3e, 0x74, 0x2d, 0x65, + 0x3f, 0x65, 0x3a, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x28, 0x65, 0x3d, 0x6e, 0x28, 0x6e, + 0x65, 0x77, 0x20, 0x63, 0x63, 0x28, 0x65, 0x2d, 0x31, 0x29, 0x29, + 0x2c, 0x31, 0x29, 0x2c, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x63, 0x63, 0x28, 0x2b, 0x6e, 0x29, 0x2c, + 0x65, 0x29, 0x2c, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x6e, 0x2c, 0x72, 0x2c, 0x69, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x75, 0x28, 0x6e, 0x29, + 0x2c, 0x61, 0x3d, 0x5b, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x3e, + 0x31, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x72, 0x3e, 0x6f, 0x3b, + 0x29, 0x65, 0x28, 0x6f, 0x29, 0x25, 0x69, 0x7c, 0x7c, 0x61, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, + 0x74, 0x65, 0x28, 0x2b, 0x6f, 0x29, 0x29, 0x2c, 0x74, 0x28, 0x6f, + 0x2c, 0x31, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x28, 0x3b, 0x72, 0x3e, 0x6f, 0x3b, 0x29, 0x61, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, + 0x65, 0x28, 0x2b, 0x6f, 0x29, 0x29, 0x2c, 0x74, 0x28, 0x6f, 0x2c, + 0x31, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x74, 0x72, 0x79, + 0x7b, 0x63, 0x63, 0x3d, 0x6a, 0x74, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x6a, 0x74, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2e, 0x5f, 0x3d, 0x6e, 0x2c, + 0x6f, 0x28, 0x72, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x7b, 0x63, 0x63, 0x3d, 0x44, 0x61, + 0x74, 0x65, 0x7d, 0x7d, 0x6e, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, + 0x3d, 0x6e, 0x2c, 0x6e, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3d, + 0x72, 0x2c, 0x6e, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x3d, 0x75, 0x2c, + 0x6e, 0x2e, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3d, 0x69, 0x2c, + 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x6f, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x63, 0x3d, 0x6e, 0x2e, 0x75, 0x74, 0x63, 0x3d, + 0x48, 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x63, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x3d, 0x63, + 0x2c, 0x63, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3d, 0x48, 0x74, + 0x28, 0x72, 0x29, 0x2c, 0x63, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x3d, + 0x48, 0x74, 0x28, 0x75, 0x29, 0x2c, 0x63, 0x2e, 0x6f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x3d, 0x48, 0x74, 0x28, 0x69, 0x29, 0x2c, 0x63, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x61, 0x2c, 0x6e, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x48, 0x74, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, + 0x65, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x63, 0x63, 0x3d, 0x6a, + 0x74, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x65, 0x77, + 0x20, 0x6a, 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x72, 0x2e, 0x5f, 0x3d, 0x74, 0x2c, 0x6e, 0x28, 0x72, 0x2c, 0x65, + 0x29, 0x2e, 0x5f, 0x7d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, + 0x7b, 0x63, 0x63, 0x3d, 0x44, 0x61, 0x74, 0x65, 0x7d, 0x7d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x74, + 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x74, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x75, 0x2c, + 0x69, 0x2c, 0x6f, 0x3d, 0x5b, 0x5d, 0x2c, 0x61, 0x3d, 0x2d, 0x31, + 0x2c, 0x63, 0x3d, 0x30, 0x3b, 0x2b, 0x2b, 0x61, 0x3c, 0x72, 0x3b, + 0x29, 0x33, 0x37, 0x3d, 0x3d, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28, 0x61, 0x29, 0x26, + 0x26, 0x28, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x63, 0x2c, 0x61, 0x29, 0x29, + 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x75, 0x3d, 0x73, + 0x63, 0x5b, 0x65, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, + 0x74, 0x28, 0x2b, 0x2b, 0x61, 0x29, 0x5d, 0x29, 0x26, 0x26, 0x28, + 0x65, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, + 0x2b, 0x2b, 0x61, 0x29, 0x29, 0x2c, 0x28, 0x69, 0x3d, 0x4e, 0x5b, + 0x65, 0x5d, 0x29, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x69, 0x28, 0x74, + 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x75, 0x3f, 0x22, 0x65, + 0x22, 0x3d, 0x3d, 0x3d, 0x65, 0x3f, 0x22, 0x20, 0x22, 0x3a, 0x22, + 0x30, 0x22, 0x3a, 0x75, 0x29, 0x29, 0x2c, 0x6f, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x65, 0x29, 0x2c, 0x63, 0x3d, 0x61, 0x2b, 0x31, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x28, 0x63, 0x2c, 0x61, 0x29, 0x29, 0x2c, 0x6f, 0x2e, 0x6a, + 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x72, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x70, + 0x61, 0x72, 0x73, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x3d, 0x7b, 0x79, 0x3a, 0x31, 0x39, 0x30, 0x30, 0x2c, 0x6d, 0x3a, + 0x30, 0x2c, 0x64, 0x3a, 0x31, 0x2c, 0x48, 0x3a, 0x30, 0x2c, 0x4d, + 0x3a, 0x30, 0x2c, 0x53, 0x3a, 0x30, 0x2c, 0x4c, 0x3a, 0x30, 0x2c, + 0x5a, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x75, 0x3d, 0x65, + 0x28, 0x72, 0x2c, 0x6e, 0x2c, 0x74, 0x2c, 0x30, 0x29, 0x3b, 0x69, + 0x66, 0x28, 0x75, 0x21, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x3b, 0x22, 0x70, 0x22, 0x69, 0x6e, 0x20, 0x72, + 0x26, 0x26, 0x28, 0x72, 0x2e, 0x48, 0x3d, 0x72, 0x2e, 0x48, 0x25, + 0x31, 0x32, 0x2b, 0x31, 0x32, 0x2a, 0x72, 0x2e, 0x70, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x21, + 0x3d, 0x72, 0x2e, 0x5a, 0x26, 0x26, 0x63, 0x63, 0x21, 0x3d, 0x3d, + 0x6a, 0x74, 0x2c, 0x6f, 0x3d, 0x6e, 0x65, 0x77, 0x28, 0x69, 0x3f, + 0x6a, 0x74, 0x3a, 0x63, 0x63, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x6a, 0x22, 0x69, 0x6e, 0x20, 0x72, 0x3f, 0x6f, + 0x2e, 0x73, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, 0x65, 0x61, + 0x72, 0x28, 0x72, 0x2e, 0x79, 0x2c, 0x30, 0x2c, 0x72, 0x2e, 0x6a, + 0x29, 0x3a, 0x22, 0x77, 0x22, 0x69, 0x6e, 0x20, 0x72, 0x26, 0x26, + 0x28, 0x22, 0x57, 0x22, 0x69, 0x6e, 0x20, 0x72, 0x7c, 0x7c, 0x22, + 0x55, 0x22, 0x69, 0x6e, 0x20, 0x72, 0x29, 0x3f, 0x28, 0x6f, 0x2e, + 0x73, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, 0x65, 0x61, 0x72, + 0x28, 0x72, 0x2e, 0x79, 0x2c, 0x30, 0x2c, 0x31, 0x29, 0x2c, 0x6f, + 0x2e, 0x73, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, 0x65, 0x61, + 0x72, 0x28, 0x72, 0x2e, 0x79, 0x2c, 0x30, 0x2c, 0x22, 0x57, 0x22, + 0x69, 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x72, 0x2e, 0x77, 0x2b, 0x36, + 0x29, 0x25, 0x37, 0x2b, 0x37, 0x2a, 0x72, 0x2e, 0x57, 0x2d, 0x28, + 0x6f, 0x2e, 0x67, 0x65, 0x74, 0x44, 0x61, 0x79, 0x28, 0x29, 0x2b, + 0x35, 0x29, 0x25, 0x37, 0x3a, 0x72, 0x2e, 0x77, 0x2b, 0x37, 0x2a, + 0x72, 0x2e, 0x55, 0x2d, 0x28, 0x6f, 0x2e, 0x67, 0x65, 0x74, 0x44, + 0x61, 0x79, 0x28, 0x29, 0x2b, 0x36, 0x29, 0x25, 0x37, 0x29, 0x29, + 0x3a, 0x6f, 0x2e, 0x73, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, + 0x65, 0x61, 0x72, 0x28, 0x72, 0x2e, 0x79, 0x2c, 0x72, 0x2e, 0x6d, + 0x2c, 0x72, 0x2e, 0x64, 0x29, 0x2c, 0x6f, 0x2e, 0x73, 0x65, 0x74, + 0x48, 0x6f, 0x75, 0x72, 0x73, 0x28, 0x72, 0x2e, 0x48, 0x2b, 0x28, + 0x72, 0x2e, 0x5a, 0x2f, 0x31, 0x30, 0x30, 0x7c, 0x30, 0x29, 0x2c, + 0x72, 0x2e, 0x4d, 0x2b, 0x72, 0x2e, 0x5a, 0x25, 0x31, 0x30, 0x30, + 0x2c, 0x72, 0x2e, 0x53, 0x2c, 0x72, 0x2e, 0x4c, 0x29, 0x2c, 0x69, + 0x3f, 0x6f, 0x2e, 0x5f, 0x3a, 0x6f, 0x7d, 0x2c, 0x74, 0x2e, 0x74, + 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x2c, 0x74, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, + 0x3d, 0x30, 0x2c, 0x63, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2c, 0x6c, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x63, 0x3e, 0x61, 0x3b, 0x29, 0x7b, 0x69, 0x66, + 0x28, 0x72, 0x3e, 0x3d, 0x6c, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x2d, 0x31, 0x3b, 0x69, 0x66, 0x28, 0x75, 0x3d, 0x74, 0x2e, + 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28, + 0x61, 0x2b, 0x2b, 0x29, 0x2c, 0x33, 0x37, 0x3d, 0x3d, 0x3d, 0x75, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6f, 0x3d, 0x74, 0x2e, 0x63, 0x68, + 0x61, 0x72, 0x41, 0x74, 0x28, 0x61, 0x2b, 0x2b, 0x29, 0x2c, 0x69, + 0x3d, 0x43, 0x5b, 0x6f, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x63, 0x3f, + 0x74, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x61, 0x2b, + 0x2b, 0x29, 0x3a, 0x6f, 0x5d, 0x2c, 0x21, 0x69, 0x7c, 0x7c, 0x28, + 0x72, 0x3d, 0x69, 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x29, + 0x3c, 0x30, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x31, + 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x75, 0x21, + 0x3d, 0x65, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, 0x65, + 0x41, 0x74, 0x28, 0x72, 0x2b, 0x2b, 0x29, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x2d, 0x31, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, + 0x5f, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x3d, 0x30, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x5f, 0x2e, + 0x65, 0x78, 0x65, 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x28, 0x65, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x77, 0x3d, 0x77, 0x2e, + 0x67, 0x65, 0x74, 0x28, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x74, 0x6f, + 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, + 0x29, 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x78, 0x2e, 0x6c, 0x61, 0x73, 0x74, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x72, 0x3d, 0x78, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x74, + 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x29, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, + 0x2e, 0x77, 0x3d, 0x62, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x72, 0x5b, + 0x30, 0x5d, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, + 0x61, 0x73, 0x65, 0x28, 0x29, 0x29, 0x2c, 0x65, 0x2b, 0x72, 0x5b, + 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, + 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x45, + 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, + 0x30, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x45, 0x2e, 0x65, + 0x78, 0x65, 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, + 0x28, 0x65, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x6d, 0x3d, 0x41, 0x2e, 0x67, + 0x65, 0x74, 0x28, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x74, 0x6f, 0x4c, + 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, 0x29, + 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x53, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x53, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x74, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x29, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, + 0x6d, 0x3d, 0x6b, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x72, 0x5b, 0x30, + 0x5d, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, + 0x73, 0x65, 0x28, 0x29, 0x29, 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, + 0x5d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, + 0x31, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x72, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x4e, 0x2e, + 0x63, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, + 0x29, 0x2c, 0x74, 0x2c, 0x72, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, + 0x28, 0x6e, 0x2c, 0x4e, 0x2e, 0x78, 0x2e, 0x74, 0x6f, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x2c, 0x74, 0x2c, 0x72, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x4e, 0x2e, 0x58, + 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, + 0x2c, 0x74, 0x2c, 0x72, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x4d, 0x2e, 0x67, + 0x65, 0x74, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, + 0x65, 0x2c, 0x65, 0x2b, 0x3d, 0x32, 0x29, 0x2e, 0x74, 0x6f, 0x4c, + 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, + 0x6c, 0x3d, 0x3d, 0x72, 0x3f, 0x2d, 0x31, 0x3a, 0x28, 0x6e, 0x2e, + 0x70, 0x3d, 0x72, 0x2c, 0x65, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x66, 0x3d, 0x6e, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, + 0x65, 0x2c, 0x68, 0x3d, 0x6e, 0x2e, 0x64, 0x61, 0x74, 0x65, 0x2c, + 0x67, 0x3d, 0x6e, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x2c, 0x70, 0x3d, + 0x6e, 0x2e, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x73, 0x2c, 0x76, + 0x3d, 0x6e, 0x2e, 0x64, 0x61, 0x79, 0x73, 0x2c, 0x64, 0x3d, 0x6e, + 0x2e, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x79, 0x73, 0x2c, + 0x6d, 0x3d, 0x6e, 0x2e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x2c, + 0x79, 0x3d, 0x6e, 0x2e, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x4d, 0x6f, + 0x6e, 0x74, 0x68, 0x73, 0x3b, 0x74, 0x2e, 0x75, 0x74, 0x63, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, + 0x28, 0x6e, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x63, 0x63, 0x3d, + 0x6a, 0x74, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x65, + 0x77, 0x20, 0x63, 0x63, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x2e, 0x5f, 0x3d, 0x6e, 0x2c, 0x72, 0x28, 0x74, 0x29, + 0x7d, 0x66, 0x69, 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x7b, 0x63, 0x63, + 0x3d, 0x44, 0x61, 0x74, 0x65, 0x7d, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x63, 0x63, 0x3d, 0x6a, 0x74, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x72, 0x2e, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x26, 0x26, 0x74, 0x2e, 0x5f, 0x7d, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x7b, 0x63, 0x63, 0x3d, 0x44, 0x61, + 0x74, 0x65, 0x7d, 0x7d, 0x2c, 0x65, 0x2e, 0x74, 0x6f, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x72, 0x2e, 0x74, 0x6f, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x65, 0x7d, 0x2c, 0x74, 0x2e, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x3d, 0x74, 0x2e, 0x75, 0x74, 0x63, 0x2e, + 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x3d, 0x61, 0x65, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x4d, 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, + 0x29, 0x2c, 0x78, 0x3d, 0x59, 0x74, 0x28, 0x76, 0x29, 0x2c, 0x62, + 0x3d, 0x5a, 0x74, 0x28, 0x76, 0x29, 0x2c, 0x5f, 0x3d, 0x59, 0x74, + 0x28, 0x64, 0x29, 0x2c, 0x77, 0x3d, 0x5a, 0x74, 0x28, 0x64, 0x29, + 0x2c, 0x53, 0x3d, 0x59, 0x74, 0x28, 0x6d, 0x29, 0x2c, 0x6b, 0x3d, + 0x5a, 0x74, 0x28, 0x6d, 0x29, 0x2c, 0x45, 0x3d, 0x59, 0x74, 0x28, + 0x79, 0x29, 0x2c, 0x41, 0x3d, 0x5a, 0x74, 0x28, 0x79, 0x29, 0x3b, + 0x70, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x4d, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x6e, 0x2e, 0x74, + 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, + 0x29, 0x2c, 0x74, 0x29, 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x4e, 0x3d, 0x7b, 0x61, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x64, 0x5b, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x44, 0x61, + 0x79, 0x28, 0x29, 0x5d, 0x7d, 0x2c, 0x41, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x5b, 0x6e, 0x2e, 0x67, 0x65, + 0x74, 0x44, 0x61, 0x79, 0x28, 0x29, 0x5d, 0x7d, 0x2c, 0x62, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, 0x5b, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x28, 0x29, + 0x5d, 0x7d, 0x2c, 0x42, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6d, 0x5b, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x6f, + 0x6e, 0x74, 0x68, 0x28, 0x29, 0x5d, 0x7d, 0x2c, 0x63, 0x3a, 0x74, + 0x28, 0x66, 0x29, 0x2c, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x6e, 0x2e, 0x67, + 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x2c, 0x74, 0x2c, + 0x32, 0x29, 0x7d, 0x2c, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x6e, 0x2e, 0x67, + 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x2c, 0x74, 0x2c, + 0x32, 0x29, 0x7d, 0x2c, 0x48, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x6e, 0x2e, 0x67, + 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x28, 0x29, 0x2c, 0x74, + 0x2c, 0x32, 0x29, 0x7d, 0x2c, 0x49, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x6e, 0x2e, + 0x67, 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x28, 0x29, 0x25, + 0x31, 0x32, 0x7c, 0x7c, 0x31, 0x32, 0x2c, 0x74, 0x2c, 0x32, 0x29, + 0x7d, 0x2c, 0x6a, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x31, 0x2b, 0x61, 0x63, 0x2e, + 0x64, 0x61, 0x79, 0x4f, 0x66, 0x59, 0x65, 0x61, 0x72, 0x28, 0x6e, + 0x29, 0x2c, 0x74, 0x2c, 0x33, 0x29, 0x7d, 0x2c, 0x4c, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, + 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x28, 0x29, 0x2c, 0x74, + 0x2c, 0x33, 0x29, 0x7d, 0x2c, 0x6d, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x6e, 0x2e, + 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x28, 0x29, 0x2b, + 0x31, 0x2c, 0x74, 0x2c, 0x32, 0x29, 0x7d, 0x2c, 0x4d, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, + 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x75, 0x74, + 0x65, 0x73, 0x28, 0x29, 0x2c, 0x74, 0x2c, 0x32, 0x29, 0x7d, 0x2c, + 0x70, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, + 0x5b, 0x2b, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x48, 0x6f, 0x75, + 0x72, 0x73, 0x28, 0x29, 0x3e, 0x3d, 0x31, 0x32, 0x29, 0x5d, 0x7d, + 0x2c, 0x53, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x49, 0x74, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x53, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x28, 0x29, 0x2c, 0x74, 0x2c, + 0x32, 0x29, 0x7d, 0x2c, 0x55, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x61, 0x63, 0x2e, + 0x73, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x4f, 0x66, 0x59, 0x65, 0x61, + 0x72, 0x28, 0x6e, 0x29, 0x2c, 0x74, 0x2c, 0x32, 0x29, 0x7d, 0x2c, + 0x77, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x44, 0x61, 0x79, 0x28, 0x29, 0x7d, 0x2c, + 0x57, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x49, 0x74, 0x28, 0x61, 0x63, 0x2e, 0x6d, 0x6f, 0x6e, 0x64, + 0x61, 0x79, 0x4f, 0x66, 0x59, 0x65, 0x61, 0x72, 0x28, 0x6e, 0x29, + 0x2c, 0x74, 0x2c, 0x32, 0x29, 0x7d, 0x2c, 0x78, 0x3a, 0x74, 0x28, + 0x68, 0x29, 0x2c, 0x58, 0x3a, 0x74, 0x28, 0x67, 0x29, 0x2c, 0x79, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x49, 0x74, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x46, 0x75, 0x6c, + 0x6c, 0x59, 0x65, 0x61, 0x72, 0x28, 0x29, 0x25, 0x31, 0x30, 0x30, + 0x2c, 0x74, 0x2c, 0x32, 0x29, 0x7d, 0x2c, 0x59, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x49, 0x74, 0x28, + 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, 0x65, + 0x61, 0x72, 0x28, 0x29, 0x25, 0x31, 0x65, 0x34, 0x2c, 0x74, 0x2c, + 0x34, 0x29, 0x7d, 0x2c, 0x5a, 0x3a, 0x69, 0x65, 0x2c, 0x22, 0x25, + 0x22, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x25, 0x22, + 0x7d, 0x7d, 0x2c, 0x43, 0x3d, 0x7b, 0x61, 0x3a, 0x72, 0x2c, 0x41, + 0x3a, 0x75, 0x2c, 0x62, 0x3a, 0x69, 0x2c, 0x42, 0x3a, 0x6f, 0x2c, + 0x63, 0x3a, 0x61, 0x2c, 0x64, 0x3a, 0x51, 0x74, 0x2c, 0x65, 0x3a, + 0x51, 0x74, 0x2c, 0x48, 0x3a, 0x74, 0x65, 0x2c, 0x49, 0x3a, 0x74, + 0x65, 0x2c, 0x6a, 0x3a, 0x6e, 0x65, 0x2c, 0x4c, 0x3a, 0x75, 0x65, + 0x2c, 0x6d, 0x3a, 0x4b, 0x74, 0x2c, 0x4d, 0x3a, 0x65, 0x65, 0x2c, + 0x70, 0x3a, 0x73, 0x2c, 0x53, 0x3a, 0x72, 0x65, 0x2c, 0x55, 0x3a, + 0x58, 0x74, 0x2c, 0x77, 0x3a, 0x56, 0x74, 0x2c, 0x57, 0x3a, 0x24, + 0x74, 0x2c, 0x78, 0x3a, 0x63, 0x2c, 0x58, 0x3a, 0x6c, 0x2c, 0x79, + 0x3a, 0x57, 0x74, 0x2c, 0x59, 0x3a, 0x42, 0x74, 0x2c, 0x5a, 0x3a, + 0x4a, 0x74, 0x2c, 0x22, 0x25, 0x22, 0x3a, 0x6f, 0x65, 0x7d, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x74, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x3d, 0x30, 0x3e, 0x6e, 0x3f, 0x22, 0x2d, 0x22, 0x3a, 0x22, 0x22, + 0x2c, 0x75, 0x3d, 0x28, 0x72, 0x3f, 0x2d, 0x6e, 0x3a, 0x6e, 0x29, + 0x2b, 0x22, 0x22, 0x2c, 0x69, 0x3d, 0x75, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x72, 0x2b, 0x28, 0x65, 0x3e, 0x69, 0x3f, 0x6e, 0x65, 0x77, 0x20, + 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x65, 0x2d, 0x69, 0x2b, 0x31, + 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x2b, 0x75, + 0x3a, 0x75, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x59, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x52, 0x65, 0x67, + 0x45, 0x78, 0x70, 0x28, 0x22, 0x5e, 0x28, 0x3f, 0x3a, 0x22, 0x2b, + 0x6e, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x74, 0x61, 0x2e, 0x72, 0x65, + 0x71, 0x75, 0x6f, 0x74, 0x65, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, + 0x28, 0x22, 0x7c, 0x22, 0x29, 0x2b, 0x22, 0x29, 0x22, 0x2c, 0x22, + 0x69, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x5a, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x65, 0x77, 0x20, + 0x6c, 0x2c, 0x65, 0x3d, 0x2d, 0x31, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x65, 0x3c, + 0x72, 0x3b, 0x29, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x6e, 0x5b, + 0x65, 0x5d, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, 0x77, 0x65, 0x72, 0x43, + 0x61, 0x73, 0x65, 0x28, 0x29, 0x2c, 0x65, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, 0x74, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, 0x6c, 0x61, 0x73, 0x74, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, + 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, 0x65, + 0x2b, 0x31, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x77, 0x3d, 0x2b, 0x72, 0x5b, + 0x30, 0x5d, 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x58, 0x74, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, 0x6c, + 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, 0x78, + 0x65, 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, + 0x65, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x55, 0x3d, 0x2b, 0x72, 0x5b, 0x30, + 0x5d, 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x24, 0x74, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, 0x6c, 0x61, + 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, 0x78, 0x65, + 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, + 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, + 0x3f, 0x28, 0x6e, 0x2e, 0x57, 0x3d, 0x2b, 0x72, 0x5b, 0x30, 0x5d, + 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x74, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, 0x6c, 0x61, 0x73, + 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, + 0x65, 0x2b, 0x34, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x79, 0x3d, 0x2b, 0x72, + 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x57, 0x74, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, + 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, + 0x78, 0x65, 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, + 0x28, 0x65, 0x2c, 0x65, 0x2b, 0x32, 0x29, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x79, + 0x3d, 0x47, 0x74, 0x28, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x29, 0x2c, + 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a, 0x74, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2f, + 0x5e, 0x5b, 0x2b, 0x2d, 0x5d, 0x5c, 0x64, 0x7b, 0x34, 0x7d, 0x24, + 0x2f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x74, 0x3d, 0x74, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, 0x65, 0x2b, 0x35, + 0x29, 0x29, 0x3f, 0x28, 0x6e, 0x2e, 0x5a, 0x3d, 0x2d, 0x74, 0x2c, + 0x65, 0x2b, 0x35, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x47, 0x74, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2b, 0x28, + 0x6e, 0x3e, 0x36, 0x38, 0x3f, 0x31, 0x39, 0x30, 0x30, 0x3a, 0x32, + 0x65, 0x33, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x4b, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, + 0x7b, 0x66, 0x63, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, + 0x66, 0x63, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x74, 0x2e, 0x73, + 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, 0x65, 0x2b, 0x32, 0x29, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, + 0x28, 0x6e, 0x2e, 0x6d, 0x3d, 0x72, 0x5b, 0x30, 0x5d, 0x2d, 0x31, + 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x51, 0x74, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, 0x6c, 0x61, 0x73, + 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, + 0x65, 0x2b, 0x32, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x64, 0x3d, 0x2b, 0x72, + 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x65, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, + 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, + 0x78, 0x65, 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, + 0x28, 0x65, 0x2c, 0x65, 0x2b, 0x33, 0x29, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x6a, + 0x3d, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x2b, 0x72, 0x5b, + 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, + 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, + 0x66, 0x63, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x66, + 0x63, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, + 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, 0x65, 0x2b, 0x32, 0x29, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x28, + 0x6e, 0x2e, 0x48, 0x3d, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x65, + 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x74, + 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, 0x65, 0x2b, + 0x32, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x4d, 0x3d, 0x2b, 0x72, 0x5b, 0x30, + 0x5d, 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, 0x2e, 0x6c, 0x61, + 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, 0x65, 0x78, 0x65, + 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, + 0x2c, 0x65, 0x2b, 0x32, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x53, 0x3d, 0x2b, + 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3a, 0x2d, 0x31, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, + 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x63, + 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, + 0x30, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x66, 0x63, 0x2e, + 0x65, 0x78, 0x65, 0x63, 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x28, 0x65, 0x2c, 0x65, 0x2b, 0x33, 0x29, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x28, 0x6e, 0x2e, + 0x4c, 0x3d, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x2b, 0x72, + 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, + 0x3a, 0x2d, 0x31, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x69, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x28, 0x29, 0x2c, 0x65, 0x3d, 0x74, 0x3e, 0x30, 0x3f, 0x22, 0x2d, + 0x22, 0x3a, 0x22, 0x2b, 0x22, 0x2c, 0x72, 0x3d, 0x67, 0x61, 0x28, + 0x74, 0x29, 0x2f, 0x36, 0x30, 0x7c, 0x30, 0x2c, 0x75, 0x3d, 0x67, + 0x61, 0x28, 0x74, 0x29, 0x25, 0x36, 0x30, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2b, 0x49, 0x74, 0x28, 0x72, 0x2c, + 0x22, 0x30, 0x22, 0x2c, 0x32, 0x29, 0x2b, 0x49, 0x74, 0x28, 0x75, + 0x2c, 0x22, 0x30, 0x22, 0x2c, 0x32, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x65, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x68, 0x63, 0x2e, 0x6c, 0x61, 0x73, + 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x72, 0x3d, 0x68, 0x63, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x28, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x65, 0x2c, + 0x65, 0x2b, 0x31, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x72, 0x3f, 0x65, 0x2b, 0x72, 0x5b, 0x30, 0x5d, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x2d, 0x31, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x65, 0x28, + 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, + 0x65, 0x3d, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x74, 0x3b, + 0x29, 0x6e, 0x5b, 0x65, 0x5d, 0x5b, 0x30, 0x5d, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x28, 0x6e, 0x5b, 0x65, 0x5d, 0x5b, 0x30, 0x5d, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x30, 0x2c, 0x72, + 0x3d, 0x6e, 0x5b, 0x65, 0x5d, 0x3b, 0x21, 0x72, 0x5b, 0x31, 0x5d, + 0x28, 0x74, 0x29, 0x3b, 0x29, 0x72, 0x3d, 0x6e, 0x5b, 0x2b, 0x2b, + 0x65, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, + 0x5b, 0x30, 0x5d, 0x28, 0x74, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x65, 0x28, 0x29, 0x7b, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, + 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x72, 0x3d, 0x65, 0x2e, 0x73, 0x3d, 0x6e, 0x2b, 0x74, + 0x2c, 0x75, 0x3d, 0x72, 0x2d, 0x6e, 0x2c, 0x69, 0x3d, 0x72, 0x2d, + 0x75, 0x3b, 0x65, 0x2e, 0x74, 0x3d, 0x6e, 0x2d, 0x69, 0x2b, 0x28, + 0x74, 0x2d, 0x75, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x73, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x6e, 0x26, 0x26, 0x64, 0x63, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, + 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6e, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x26, 0x26, 0x64, 0x63, 0x5b, + 0x6e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x66, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x3d, 0x2d, 0x31, 0x2c, 0x69, + 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x65, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x3b, 0x2b, 0x2b, 0x75, + 0x3c, 0x69, 0x3b, 0x29, 0x72, 0x3d, 0x6e, 0x5b, 0x75, 0x5d, 0x2c, + 0x74, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x72, 0x5b, 0x30, + 0x5d, 0x2c, 0x72, 0x5b, 0x31, 0x5d, 0x2c, 0x72, 0x5b, 0x32, 0x5d, + 0x29, 0x3b, 0x74, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x68, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x2d, 0x31, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x28, 0x29, 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x72, + 0x3b, 0x29, 0x66, 0x65, 0x28, 0x6e, 0x5b, 0x65, 0x5d, 0x2c, 0x74, + 0x2c, 0x31, 0x29, 0x3b, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x65, 0x28, 0x29, 0x7b, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x2a, 0x3d, 0x44, 0x61, 0x2c, + 0x74, 0x3d, 0x74, 0x2a, 0x44, 0x61, 0x2f, 0x32, 0x2b, 0x71, 0x61, + 0x2f, 0x34, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2d, + 0x72, 0x2c, 0x6f, 0x3d, 0x65, 0x3e, 0x3d, 0x30, 0x3f, 0x31, 0x3a, + 0x2d, 0x31, 0x2c, 0x61, 0x3d, 0x6f, 0x2a, 0x65, 0x2c, 0x63, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x29, + 0x2c, 0x6c, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, + 0x28, 0x74, 0x29, 0x2c, 0x73, 0x3d, 0x69, 0x2a, 0x6c, 0x2c, 0x66, + 0x3d, 0x75, 0x2a, 0x63, 0x2b, 0x73, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x61, 0x29, 0x2c, 0x68, 0x3d, 0x73, + 0x2a, 0x6f, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, + 0x28, 0x61, 0x29, 0x3b, 0x79, 0x63, 0x2e, 0x61, 0x64, 0x64, 0x28, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, + 0x68, 0x2c, 0x66, 0x29, 0x29, 0x2c, 0x72, 0x3d, 0x6e, 0x2c, 0x75, + 0x3d, 0x63, 0x2c, 0x69, 0x3d, 0x6c, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x3b, 0x4d, + 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x2c, 0x61, 0x29, 0x7b, + 0x4d, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, 0x2c, + 0x72, 0x3d, 0x28, 0x74, 0x3d, 0x6f, 0x29, 0x2a, 0x44, 0x61, 0x2c, + 0x75, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, + 0x61, 0x3d, 0x28, 0x65, 0x3d, 0x61, 0x29, 0x2a, 0x44, 0x61, 0x2f, + 0x32, 0x2b, 0x71, 0x61, 0x2f, 0x34, 0x29, 0x2c, 0x69, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x61, 0x29, 0x7d, + 0x2c, 0x4d, 0x63, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x65, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x5b, 0x30, + 0x5d, 0x2c, 0x65, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x72, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x65, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x72, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x29, 0x2c, + 0x72, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x74, 0x29, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, + 0x28, 0x65, 0x29, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x76, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x5b, 0x30, 0x5d, + 0x2a, 0x74, 0x5b, 0x30, 0x5d, 0x2b, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, + 0x74, 0x5b, 0x31, 0x5d, 0x2b, 0x6e, 0x5b, 0x32, 0x5d, 0x2a, 0x74, + 0x5b, 0x32, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x64, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, + 0x74, 0x5b, 0x32, 0x5d, 0x2d, 0x6e, 0x5b, 0x32, 0x5d, 0x2a, 0x74, + 0x5b, 0x31, 0x5d, 0x2c, 0x6e, 0x5b, 0x32, 0x5d, 0x2a, 0x74, 0x5b, + 0x30, 0x5d, 0x2d, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x74, 0x5b, 0x32, + 0x5d, 0x2c, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x74, 0x5b, 0x31, 0x5d, + 0x2d, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x74, 0x5b, 0x30, 0x5d, 0x5d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, + 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x5b, 0x30, 0x5d, + 0x2b, 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, + 0x2b, 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, 0x5b, 0x32, 0x5d, + 0x2b, 0x3d, 0x74, 0x5b, 0x32, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x65, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x5b, + 0x30, 0x5d, 0x2a, 0x74, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x74, + 0x2c, 0x6e, 0x5b, 0x32, 0x5d, 0x2a, 0x74, 0x5d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x65, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x6e, 0x5b, 0x30, 0x5d, + 0x2a, 0x6e, 0x5b, 0x30, 0x5d, 0x2b, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, + 0x6e, 0x5b, 0x31, 0x5d, 0x2b, 0x6e, 0x5b, 0x32, 0x5d, 0x2a, 0x6e, + 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x6e, 0x5b, 0x30, 0x5d, 0x2f, 0x3d, + 0x74, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2f, 0x3d, 0x74, 0x2c, 0x6e, + 0x5b, 0x32, 0x5d, 0x2f, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x78, 0x65, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x6e, 0x5b, 0x31, 0x5d, + 0x2c, 0x6e, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x74, 0x74, 0x28, 0x6e, + 0x5b, 0x32, 0x5d, 0x29, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x61, 0x28, + 0x6e, 0x5b, 0x30, 0x5d, 0x2d, 0x74, 0x5b, 0x30, 0x5d, 0x29, 0x3c, + 0x43, 0x61, 0x26, 0x26, 0x67, 0x61, 0x28, 0x6e, 0x5b, 0x31, 0x5d, + 0x2d, 0x74, 0x5b, 0x31, 0x5d, 0x29, 0x3c, 0x43, 0x61, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x65, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x2a, 0x3d, 0x44, 0x61, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x63, 0x6f, 0x73, 0x28, 0x74, 0x2a, 0x3d, 0x44, 0x61, 0x29, 0x3b, + 0x77, 0x65, 0x28, 0x65, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, + 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x2c, 0x65, 0x2a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x29, 0x2c, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x65, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x2b, 0x2b, 0x78, + 0x63, 0x2c, 0x5f, 0x63, 0x2b, 0x3d, 0x28, 0x6e, 0x2d, 0x5f, 0x63, + 0x29, 0x2f, 0x78, 0x63, 0x2c, 0x77, 0x63, 0x2b, 0x3d, 0x28, 0x74, + 0x2d, 0x77, 0x63, 0x29, 0x2f, 0x78, 0x63, 0x2c, 0x53, 0x63, 0x2b, + 0x3d, 0x28, 0x65, 0x2d, 0x53, 0x63, 0x29, 0x2f, 0x78, 0x63, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x65, + 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6e, 0x28, 0x6e, 0x2c, 0x75, 0x29, 0x7b, 0x6e, 0x2a, 0x3d, + 0x44, 0x61, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x75, 0x2a, 0x3d, 0x44, + 0x61, 0x29, 0x2c, 0x6f, 0x3d, 0x69, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x2c, 0x61, 0x3d, 0x69, + 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, + 0x29, 0x2c, 0x63, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, + 0x6e, 0x28, 0x75, 0x29, 0x2c, 0x6c, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x28, 0x6c, 0x3d, 0x65, 0x2a, + 0x63, 0x2d, 0x72, 0x2a, 0x61, 0x29, 0x2a, 0x6c, 0x2b, 0x28, 0x6c, + 0x3d, 0x72, 0x2a, 0x6f, 0x2d, 0x74, 0x2a, 0x63, 0x29, 0x2a, 0x6c, + 0x2b, 0x28, 0x6c, 0x3d, 0x74, 0x2a, 0x61, 0x2d, 0x65, 0x2a, 0x6f, + 0x29, 0x2a, 0x6c, 0x29, 0x2c, 0x74, 0x2a, 0x6f, 0x2b, 0x65, 0x2a, + 0x61, 0x2b, 0x72, 0x2a, 0x63, 0x29, 0x3b, 0x62, 0x63, 0x2b, 0x3d, + 0x6c, 0x2c, 0x6b, 0x63, 0x2b, 0x3d, 0x6c, 0x2a, 0x28, 0x74, 0x2b, + 0x28, 0x74, 0x3d, 0x6f, 0x29, 0x29, 0x2c, 0x45, 0x63, 0x2b, 0x3d, + 0x6c, 0x2a, 0x28, 0x65, 0x2b, 0x28, 0x65, 0x3d, 0x61, 0x29, 0x29, + 0x2c, 0x41, 0x63, 0x2b, 0x3d, 0x6c, 0x2a, 0x28, 0x72, 0x2b, 0x28, + 0x72, 0x3d, 0x63, 0x29, 0x29, 0x2c, 0x77, 0x65, 0x28, 0x74, 0x2c, + 0x65, 0x2c, 0x72, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, + 0x65, 0x2c, 0x72, 0x3b, 0x71, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x75, 0x2c, 0x69, 0x29, 0x7b, 0x75, 0x2a, 0x3d, 0x44, 0x61, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x63, 0x6f, 0x73, 0x28, 0x69, 0x2a, 0x3d, 0x44, 0x61, 0x29, 0x3b, + 0x74, 0x3d, 0x6f, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, + 0x73, 0x28, 0x75, 0x29, 0x2c, 0x65, 0x3d, 0x6f, 0x2a, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x75, 0x29, 0x2c, 0x72, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x69, + 0x29, 0x2c, 0x71, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, + 0x6e, 0x2c, 0x77, 0x65, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, + 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6b, 0x65, 0x28, 0x29, 0x7b, 0x71, 0x63, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3d, 0x5f, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x65, 0x28, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x6e, 0x2a, 0x3d, 0x44, 0x61, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, + 0x73, 0x28, 0x74, 0x2a, 0x3d, 0x44, 0x61, 0x29, 0x2c, 0x6f, 0x3d, + 0x65, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, + 0x6e, 0x29, 0x2c, 0x61, 0x3d, 0x65, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x29, 0x2c, 0x63, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x2c, + 0x6c, 0x3d, 0x75, 0x2a, 0x63, 0x2d, 0x69, 0x2a, 0x61, 0x2c, 0x73, + 0x3d, 0x69, 0x2a, 0x6f, 0x2d, 0x72, 0x2a, 0x63, 0x2c, 0x66, 0x3d, + 0x72, 0x2a, 0x61, 0x2d, 0x75, 0x2a, 0x6f, 0x2c, 0x68, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x6c, 0x2a, + 0x6c, 0x2b, 0x73, 0x2a, 0x73, 0x2b, 0x66, 0x2a, 0x66, 0x29, 0x2c, + 0x67, 0x3d, 0x72, 0x2a, 0x6f, 0x2b, 0x75, 0x2a, 0x61, 0x2b, 0x69, + 0x2a, 0x63, 0x2c, 0x70, 0x3d, 0x68, 0x26, 0x26, 0x2d, 0x6e, 0x74, + 0x28, 0x67, 0x29, 0x2f, 0x68, 0x2c, 0x76, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x68, 0x2c, 0x67, + 0x29, 0x3b, 0x4e, 0x63, 0x2b, 0x3d, 0x70, 0x2a, 0x6c, 0x2c, 0x43, + 0x63, 0x2b, 0x3d, 0x70, 0x2a, 0x73, 0x2c, 0x7a, 0x63, 0x2b, 0x3d, + 0x70, 0x2a, 0x66, 0x2c, 0x62, 0x63, 0x2b, 0x3d, 0x76, 0x2c, 0x6b, + 0x63, 0x2b, 0x3d, 0x76, 0x2a, 0x28, 0x72, 0x2b, 0x28, 0x72, 0x3d, + 0x6f, 0x29, 0x29, 0x2c, 0x45, 0x63, 0x2b, 0x3d, 0x76, 0x2a, 0x28, + 0x75, 0x2b, 0x28, 0x75, 0x3d, 0x61, 0x29, 0x29, 0x2c, 0x41, 0x63, + 0x2b, 0x3d, 0x76, 0x2a, 0x28, 0x69, 0x2b, 0x28, 0x69, 0x3d, 0x63, + 0x29, 0x29, 0x2c, 0x77, 0x65, 0x28, 0x72, 0x2c, 0x75, 0x2c, 0x69, + 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, + 0x2c, 0x75, 0x2c, 0x69, 0x3b, 0x71, 0x63, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6f, 0x2c, 0x61, 0x29, 0x7b, 0x74, 0x3d, 0x6f, 0x2c, 0x65, + 0x3d, 0x61, 0x2c, 0x71, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x3d, 0x6e, 0x2c, 0x6f, 0x2a, 0x3d, 0x44, 0x61, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x63, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, + 0x73, 0x28, 0x61, 0x2a, 0x3d, 0x44, 0x61, 0x29, 0x3b, 0x72, 0x3d, + 0x63, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, + 0x6f, 0x29, 0x2c, 0x75, 0x3d, 0x63, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6f, 0x29, 0x2c, 0x69, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x61, 0x29, 0x2c, + 0x77, 0x65, 0x28, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x29, 0x7d, 0x2c, + 0x71, 0x63, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x2c, 0x71, 0x63, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x6b, 0x65, 0x2c, 0x71, + 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x5f, 0x65, 0x7d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, + 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x65, 0x2c, 0x72, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3d, 0x6e, + 0x28, 0x65, 0x2c, 0x72, 0x29, 0x2c, 0x74, 0x28, 0x65, 0x5b, 0x30, + 0x5d, 0x2c, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x7d, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, + 0x74, 0x26, 0x26, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x26, 0x26, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, + 0x2c, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x3d, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, + 0x65, 0x2c, 0x72, 0x29, 0x2c, 0x65, 0x26, 0x26, 0x6e, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x2c, + 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x7d, 0x29, 0x2c, 0x65, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x65, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x30, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x65, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x5b, 0x5d, 0x2c, 0x6f, + 0x3d, 0x5b, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x66, 0x6f, + 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, + 0x28, 0x28, 0x74, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2d, 0x31, 0x29, 0x3c, 0x3d, 0x30, 0x29, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, + 0x2c, 0x72, 0x3d, 0x6e, 0x5b, 0x74, 0x5d, 0x3b, 0x69, 0x66, 0x28, + 0x62, 0x65, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x29, 0x7b, 0x75, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, + 0x30, 0x3b, 0x74, 0x3e, 0x61, 0x3b, 0x2b, 0x2b, 0x61, 0x29, 0x75, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x28, 0x65, 0x3d, 0x6e, + 0x5b, 0x61, 0x5d, 0x29, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x5b, 0x31, + 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, + 0x6f, 0x69, 0x64, 0x20, 0x75, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, + 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x71, 0x65, 0x28, 0x65, 0x2c, 0x6e, 0x2c, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x21, 0x30, 0x29, 0x2c, 0x6c, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x71, 0x65, 0x28, 0x65, 0x2c, 0x6e, 0x75, + 0x6c, 0x6c, 0x2c, 0x63, 0x2c, 0x21, 0x31, 0x29, 0x3b, 0x63, 0x2e, + 0x6f, 0x3d, 0x6c, 0x2c, 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x63, 0x29, 0x2c, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6c, + 0x29, 0x2c, 0x63, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x71, 0x65, 0x28, + 0x72, 0x2c, 0x6e, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x21, 0x31, + 0x29, 0x2c, 0x6c, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x71, 0x65, 0x28, + 0x72, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x63, 0x2c, 0x21, 0x30, + 0x29, 0x2c, 0x63, 0x2e, 0x6f, 0x3d, 0x6c, 0x2c, 0x69, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x63, 0x29, 0x2c, 0x6f, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x6c, 0x29, 0x7d, 0x7d, 0x29, 0x2c, 0x6f, 0x2e, + 0x73, 0x6f, 0x72, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x7a, 0x65, 0x28, + 0x69, 0x29, 0x2c, 0x7a, 0x65, 0x28, 0x6f, 0x29, 0x2c, 0x69, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x30, 0x2c, 0x63, 0x3d, + 0x65, 0x2c, 0x6c, 0x3d, 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x6c, 0x3e, 0x61, 0x3b, 0x2b, 0x2b, 0x61, 0x29, 0x6f, + 0x5b, 0x61, 0x5d, 0x2e, 0x65, 0x3d, 0x63, 0x3d, 0x21, 0x63, 0x3b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x73, 0x2c, 0x66, + 0x2c, 0x68, 0x3d, 0x69, 0x5b, 0x30, 0x5d, 0x3b, 0x3b, 0x29, 0x7b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x67, 0x3d, 0x68, + 0x2c, 0x70, 0x3d, 0x21, 0x30, 0x3b, 0x67, 0x2e, 0x76, 0x3b, 0x29, + 0x69, 0x66, 0x28, 0x28, 0x67, 0x3d, 0x67, 0x2e, 0x6e, 0x29, 0x3d, + 0x3d, 0x3d, 0x68, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, + 0x73, 0x3d, 0x67, 0x2e, 0x7a, 0x2c, 0x75, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x3b, 0x64, 0x6f, + 0x7b, 0x69, 0x66, 0x28, 0x67, 0x2e, 0x76, 0x3d, 0x67, 0x2e, 0x6f, + 0x2e, 0x76, 0x3d, 0x21, 0x30, 0x2c, 0x67, 0x2e, 0x65, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x70, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x61, 0x3d, 0x30, 0x2c, 0x6c, 0x3d, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x6c, 0x3e, 0x61, 0x3b, 0x2b, + 0x2b, 0x61, 0x29, 0x75, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, + 0x28, 0x66, 0x3d, 0x73, 0x5b, 0x61, 0x5d, 0x29, 0x5b, 0x30, 0x5d, + 0x2c, 0x66, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x72, 0x28, 0x67, 0x2e, 0x78, 0x2c, 0x67, 0x2e, 0x6e, 0x2e, + 0x78, 0x2c, 0x31, 0x2c, 0x75, 0x29, 0x3b, 0x67, 0x3d, 0x67, 0x2e, + 0x6e, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x70, + 0x29, 0x7b, 0x73, 0x3d, 0x67, 0x2e, 0x70, 0x2e, 0x7a, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x3b, 0x61, 0x3e, + 0x3d, 0x30, 0x3b, 0x2d, 0x2d, 0x61, 0x29, 0x75, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x28, 0x28, 0x66, 0x3d, 0x73, 0x5b, 0x61, 0x5d, + 0x29, 0x5b, 0x30, 0x5d, 0x2c, 0x66, 0x5b, 0x31, 0x5d, 0x29, 0x7d, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x72, 0x28, 0x67, 0x2e, 0x78, 0x2c, + 0x67, 0x2e, 0x70, 0x2e, 0x78, 0x2c, 0x2d, 0x31, 0x2c, 0x75, 0x29, + 0x3b, 0x67, 0x3d, 0x67, 0x2e, 0x70, 0x7d, 0x67, 0x3d, 0x67, 0x2e, + 0x6f, 0x2c, 0x73, 0x3d, 0x67, 0x2e, 0x7a, 0x2c, 0x70, 0x3d, 0x21, + 0x70, 0x7d, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x21, 0x67, 0x2e, + 0x76, 0x29, 0x3b, 0x75, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, + 0x64, 0x28, 0x29, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x69, + 0x66, 0x28, 0x74, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x6e, + 0x5b, 0x30, 0x5d, 0x3b, 0x2b, 0x2b, 0x72, 0x3c, 0x74, 0x3b, 0x29, + 0x75, 0x2e, 0x6e, 0x3d, 0x65, 0x3d, 0x6e, 0x5b, 0x72, 0x5d, 0x2c, + 0x65, 0x2e, 0x70, 0x3d, 0x75, 0x2c, 0x75, 0x3d, 0x65, 0x3b, 0x75, + 0x2e, 0x6e, 0x3d, 0x65, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x65, + 0x2e, 0x70, 0x3d, 0x75, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x71, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x78, + 0x3d, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x7a, 0x3d, 0x74, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x3d, 0x65, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x65, 0x3d, 0x72, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x76, 0x3d, 0x21, 0x31, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x6e, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x4c, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x2c, 0x69, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x75, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x3b, 0x6e, 0x28, + 0x74, 0x3d, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x3d, 0x72, 0x5b, + 0x31, 0x5d, 0x29, 0x26, 0x26, 0x69, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x75, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x3b, 0x64, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, + 0x65, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, + 0x29, 0x7b, 0x79, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x61, + 0x2c, 0x64, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6c, 0x28, 0x29, 0x7b, 0x79, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3d, 0x6f, 0x2c, 0x64, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x45, 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x76, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x5b, 0x6e, 0x2c, 0x74, + 0x5d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x75, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x3b, 0x78, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x5b, 0x31, 0x5d, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x66, 0x28, 0x29, 0x7b, 0x78, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x76, 0x3d, 0x5b, 0x5d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, + 0x28, 0x29, 0x7b, 0x73, 0x28, 0x76, 0x5b, 0x30, 0x5d, 0x5b, 0x30, + 0x5d, 0x2c, 0x76, 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x2c, + 0x78, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x2c, 0x74, 0x3d, 0x78, 0x2e, + 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x28, 0x29, 0x2c, 0x65, 0x3d, 0x4d, + 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x29, 0x2c, 0x72, + 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69, + 0x66, 0x28, 0x76, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2c, 0x70, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x76, 0x29, 0x2c, 0x76, 0x3d, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x72, 0x29, 0x69, 0x66, 0x28, 0x31, + 0x26, 0x74, 0x29, 0x7b, 0x6e, 0x3d, 0x65, 0x5b, 0x30, 0x5d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x2c, 0x6f, 0x3d, 0x2d, + 0x31, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x3e, 0x30, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x62, 0x7c, 0x7c, 0x28, 0x69, 0x2e, 0x70, 0x6f, + 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, + 0x29, 0x2c, 0x62, 0x3d, 0x21, 0x30, 0x29, 0x2c, 0x69, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x3b, + 0x2b, 0x2b, 0x6f, 0x3c, 0x72, 0x3b, 0x29, 0x69, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x28, 0x28, 0x75, 0x3d, 0x6e, 0x5b, 0x6f, 0x5d, + 0x29, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x5b, 0x31, 0x5d, 0x29, 0x3b, + 0x69, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, + 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x72, 0x3e, 0x31, 0x26, + 0x26, 0x32, 0x26, 0x74, 0x26, 0x26, 0x65, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x65, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2e, 0x63, + 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x65, 0x2e, 0x73, 0x68, 0x69, + 0x66, 0x74, 0x28, 0x29, 0x29, 0x29, 0x2c, 0x67, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x65, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x28, 0x54, 0x65, 0x29, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x67, + 0x2c, 0x70, 0x2c, 0x76, 0x2c, 0x64, 0x3d, 0x74, 0x28, 0x69, 0x29, + 0x2c, 0x6d, 0x3d, 0x75, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x28, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x72, 0x5b, 0x31, 0x5d, 0x29, + 0x2c, 0x79, 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x6f, + 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, + 0x63, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x6c, + 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x79, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, + 0x73, 0x2c, 0x79, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x3d, 0x66, 0x2c, 0x79, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x45, 0x6e, 0x64, 0x3d, 0x68, 0x2c, 0x67, 0x3d, 0x5b, 0x5d, 0x2c, + 0x70, 0x3d, 0x5b, 0x5d, 0x7d, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x79, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3d, 0x6f, 0x2c, 0x79, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x63, 0x2c, 0x79, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x6c, 0x2c, 0x67, 0x3d, + 0x74, 0x61, 0x2e, 0x6d, 0x65, 0x72, 0x67, 0x65, 0x28, 0x67, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x46, 0x65, 0x28, 0x6d, + 0x2c, 0x70, 0x29, 0x3b, 0x67, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x62, 0x7c, 0x7c, 0x28, 0x69, 0x2e, 0x70, 0x6f, + 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, + 0x29, 0x2c, 0x62, 0x3d, 0x21, 0x30, 0x29, 0x2c, 0x43, 0x65, 0x28, + 0x67, 0x2c, 0x44, 0x65, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x69, 0x29, + 0x29, 0x3a, 0x6e, 0x26, 0x26, 0x28, 0x62, 0x7c, 0x7c, 0x28, 0x69, + 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x28, 0x29, 0x2c, 0x62, 0x3d, 0x21, 0x30, 0x29, 0x2c, + 0x69, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x28, 0x29, 0x2c, 0x65, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x31, 0x2c, 0x69, 0x29, 0x2c, 0x69, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x29, 0x2c, + 0x62, 0x26, 0x26, 0x28, 0x69, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x62, 0x3d, 0x21, + 0x31, 0x29, 0x2c, 0x67, 0x3d, 0x70, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x7d, 0x2c, 0x73, 0x70, 0x68, 0x65, 0x72, 0x65, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x2e, + 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x28, 0x29, 0x2c, 0x69, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x65, 0x28, 0x6e, 0x75, + 0x6c, 0x6c, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x31, 0x2c, 0x69, + 0x29, 0x2c, 0x69, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x28, 0x29, 0x2c, 0x69, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, + 0x6e, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x7d, 0x2c, 0x4d, 0x3d, + 0x52, 0x65, 0x28, 0x29, 0x2c, 0x78, 0x3d, 0x74, 0x28, 0x4d, 0x29, + 0x2c, 0x62, 0x3d, 0x21, 0x31, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x79, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x54, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3e, 0x31, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x52, 0x65, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6e, 0x2c, 0x74, 0x3d, 0x5b, 0x5d, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, + 0x3d, 0x5b, 0x5d, 0x29, 0x7d, 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x5b, 0x74, 0x2c, 0x65, 0x5d, 0x29, 0x7d, 0x2c, 0x6c, 0x69, 0x6e, + 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x62, 0x2c, 0x62, 0x75, 0x66, 0x66, + 0x65, 0x72, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x3d, 0x5b, 0x5d, + 0x2c, 0x6e, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x65, 0x7d, 0x2c, + 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x31, 0x26, 0x26, 0x74, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x74, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, + 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x2e, 0x73, + 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x29, 0x29, 0x7d, 0x7d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x65, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x28, 0x28, 0x6e, 0x3d, 0x6e, 0x2e, 0x78, 0x29, 0x5b, 0x30, + 0x5d, 0x3c, 0x30, 0x3f, 0x6e, 0x5b, 0x31, 0x5d, 0x2d, 0x52, 0x61, + 0x2d, 0x43, 0x61, 0x3a, 0x52, 0x61, 0x2d, 0x6e, 0x5b, 0x31, 0x5d, + 0x29, 0x2d, 0x28, 0x28, 0x74, 0x3d, 0x74, 0x2e, 0x78, 0x29, 0x5b, + 0x30, 0x5d, 0x3c, 0x30, 0x3f, 0x74, 0x5b, 0x31, 0x5d, 0x2d, 0x52, + 0x61, 0x2d, 0x43, 0x61, 0x3a, 0x52, 0x61, 0x2d, 0x74, 0x5b, 0x31, + 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x50, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x2c, 0x65, 0x3d, 0x30, 0x2f, 0x30, 0x2c, 0x72, 0x3d, 0x30, + 0x2f, 0x30, 0x2c, 0x75, 0x3d, 0x30, 0x2f, 0x30, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x74, 0x3d, 0x31, 0x7d, + 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x69, 0x2c, 0x6f, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x61, 0x3d, 0x69, 0x3e, 0x30, 0x3f, 0x71, 0x61, + 0x3a, 0x2d, 0x71, 0x61, 0x2c, 0x63, 0x3d, 0x67, 0x61, 0x28, 0x69, + 0x2d, 0x65, 0x29, 0x3b, 0x67, 0x61, 0x28, 0x63, 0x2d, 0x71, 0x61, + 0x29, 0x3c, 0x43, 0x61, 0x3f, 0x28, 0x6e, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x28, 0x65, 0x2c, 0x72, 0x3d, 0x28, 0x72, 0x2b, 0x6f, + 0x29, 0x2f, 0x32, 0x3e, 0x30, 0x3f, 0x52, 0x61, 0x3a, 0x2d, 0x52, + 0x61, 0x29, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, + 0x75, 0x2c, 0x72, 0x29, 0x2c, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x45, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x6e, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x61, 0x2c, 0x72, 0x29, 0x2c, + 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x2c, 0x72, + 0x29, 0x2c, 0x74, 0x3d, 0x30, 0x29, 0x3a, 0x75, 0x21, 0x3d, 0x3d, + 0x61, 0x26, 0x26, 0x63, 0x3e, 0x3d, 0x71, 0x61, 0x26, 0x26, 0x28, + 0x67, 0x61, 0x28, 0x65, 0x2d, 0x75, 0x29, 0x3c, 0x43, 0x61, 0x26, + 0x26, 0x28, 0x65, 0x2d, 0x3d, 0x75, 0x2a, 0x43, 0x61, 0x29, 0x2c, + 0x67, 0x61, 0x28, 0x69, 0x2d, 0x61, 0x29, 0x3c, 0x43, 0x61, 0x26, + 0x26, 0x28, 0x69, 0x2d, 0x3d, 0x61, 0x2a, 0x43, 0x61, 0x29, 0x2c, + 0x72, 0x3d, 0x55, 0x65, 0x28, 0x65, 0x2c, 0x72, 0x2c, 0x69, 0x2c, + 0x6f, 0x29, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, + 0x75, 0x2c, 0x72, 0x29, 0x2c, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x45, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x6e, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x61, 0x2c, 0x72, 0x29, 0x2c, + 0x74, 0x3d, 0x30, 0x29, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x28, 0x65, 0x3d, 0x69, 0x2c, 0x72, 0x3d, 0x6f, 0x29, 0x2c, + 0x75, 0x3d, 0x61, 0x7d, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, + 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x28, 0x29, 0x2c, 0x65, 0x3d, 0x72, 0x3d, 0x30, 0x2f, 0x30, 0x7d, + 0x2c, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x32, 0x2d, 0x74, 0x7d, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x65, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x2d, 0x65, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x61, 0x28, 0x6f, 0x29, + 0x3e, 0x43, 0x61, 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, + 0x61, 0x6e, 0x28, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, + 0x6e, 0x28, 0x74, 0x29, 0x2a, 0x28, 0x69, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x72, 0x29, 0x29, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x65, 0x29, 0x2d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x72, 0x29, + 0x2a, 0x28, 0x75, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, + 0x73, 0x28, 0x74, 0x29, 0x29, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x29, 0x29, 0x2f, 0x28, 0x75, 0x2a, + 0x69, 0x2a, 0x6f, 0x29, 0x29, 0x3a, 0x28, 0x74, 0x2b, 0x72, 0x29, + 0x2f, 0x32, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6a, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3b, 0x69, 0x66, 0x28, + 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x29, 0x75, 0x3d, 0x65, + 0x2a, 0x52, 0x61, 0x2c, 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x28, 0x2d, 0x71, 0x61, 0x2c, 0x75, 0x29, 0x2c, 0x72, 0x2e, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x30, 0x2c, 0x75, 0x29, 0x2c, 0x72, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x71, 0x61, 0x2c, 0x75, + 0x29, 0x2c, 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x71, + 0x61, 0x2c, 0x30, 0x29, 0x2c, 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x28, 0x71, 0x61, 0x2c, 0x2d, 0x75, 0x29, 0x2c, 0x72, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x30, 0x2c, 0x2d, 0x75, 0x29, + 0x2c, 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x2d, 0x71, + 0x61, 0x2c, 0x2d, 0x75, 0x29, 0x2c, 0x72, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x28, 0x2d, 0x71, 0x61, 0x2c, 0x30, 0x29, 0x2c, 0x72, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x2d, 0x71, 0x61, 0x2c, + 0x75, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, + 0x67, 0x61, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2d, 0x74, 0x5b, 0x30, + 0x5d, 0x29, 0x3e, 0x43, 0x61, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x69, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x3c, 0x74, 0x5b, 0x30, 0x5d, + 0x3f, 0x71, 0x61, 0x3a, 0x2d, 0x71, 0x61, 0x3b, 0x75, 0x3d, 0x65, + 0x2a, 0x69, 0x2f, 0x32, 0x2c, 0x72, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x28, 0x2d, 0x69, 0x2c, 0x75, 0x29, 0x2c, 0x72, 0x2e, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x30, 0x2c, 0x75, 0x29, 0x2c, 0x72, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x69, 0x2c, 0x75, 0x29, + 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x72, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x74, 0x5b, 0x31, + 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x46, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x72, 0x3d, + 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x75, 0x3d, 0x5b, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x65, 0x29, 0x2c, 0x2d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x65, 0x29, 0x2c, + 0x30, 0x5d, 0x2c, 0x69, 0x3d, 0x30, 0x2c, 0x6f, 0x3d, 0x30, 0x3b, + 0x79, 0x63, 0x2e, 0x72, 0x65, 0x73, 0x65, 0x74, 0x28, 0x29, 0x3b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x30, + 0x2c, 0x63, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x63, 0x3e, 0x61, 0x3b, 0x2b, 0x2b, 0x61, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x74, 0x5b, 0x61, 0x5d, 0x2c, 0x73, + 0x3d, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69, + 0x66, 0x28, 0x73, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x66, 0x3d, 0x6c, 0x5b, 0x30, 0x5d, 0x2c, 0x68, 0x3d, 0x66, + 0x5b, 0x30, 0x5d, 0x2c, 0x67, 0x3d, 0x66, 0x5b, 0x31, 0x5d, 0x2f, + 0x32, 0x2b, 0x71, 0x61, 0x2f, 0x34, 0x2c, 0x70, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x67, 0x29, 0x2c, 0x76, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x67, + 0x29, 0x2c, 0x64, 0x3d, 0x31, 0x3b, 0x3b, 0x29, 0x7b, 0x64, 0x3d, + 0x3d, 0x3d, 0x73, 0x26, 0x26, 0x28, 0x64, 0x3d, 0x30, 0x29, 0x2c, + 0x6e, 0x3d, 0x6c, 0x5b, 0x64, 0x5d, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x6d, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x79, 0x3d, 0x6e, 0x5b, + 0x31, 0x5d, 0x2f, 0x32, 0x2b, 0x71, 0x61, 0x2f, 0x34, 0x2c, 0x4d, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x79, + 0x29, 0x2c, 0x78, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, + 0x73, 0x28, 0x79, 0x29, 0x2c, 0x62, 0x3d, 0x6d, 0x2d, 0x68, 0x2c, + 0x5f, 0x3d, 0x62, 0x3e, 0x3d, 0x30, 0x3f, 0x31, 0x3a, 0x2d, 0x31, + 0x2c, 0x77, 0x3d, 0x5f, 0x2a, 0x62, 0x2c, 0x53, 0x3d, 0x77, 0x3e, + 0x71, 0x61, 0x2c, 0x6b, 0x3d, 0x70, 0x2a, 0x4d, 0x3b, 0x69, 0x66, + 0x28, 0x79, 0x63, 0x2e, 0x61, 0x64, 0x64, 0x28, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x6b, 0x2a, 0x5f, + 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x77, + 0x29, 0x2c, 0x76, 0x2a, 0x78, 0x2b, 0x6b, 0x2a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x77, 0x29, 0x29, 0x29, 0x2c, + 0x69, 0x2b, 0x3d, 0x53, 0x3f, 0x62, 0x2b, 0x5f, 0x2a, 0x4c, 0x61, + 0x3a, 0x62, 0x2c, 0x53, 0x5e, 0x68, 0x3e, 0x3d, 0x65, 0x5e, 0x6d, + 0x3e, 0x3d, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x45, 0x3d, + 0x64, 0x65, 0x28, 0x70, 0x65, 0x28, 0x66, 0x29, 0x2c, 0x70, 0x65, + 0x28, 0x6e, 0x29, 0x29, 0x3b, 0x4d, 0x65, 0x28, 0x45, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x41, 0x3d, 0x64, 0x65, 0x28, 0x75, 0x2c, + 0x45, 0x29, 0x3b, 0x4d, 0x65, 0x28, 0x41, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x4e, 0x3d, 0x28, 0x53, 0x5e, 0x62, 0x3e, 0x3d, 0x30, + 0x3f, 0x2d, 0x31, 0x3a, 0x31, 0x29, 0x2a, 0x74, 0x74, 0x28, 0x41, + 0x5b, 0x32, 0x5d, 0x29, 0x3b, 0x28, 0x72, 0x3e, 0x4e, 0x7c, 0x7c, + 0x72, 0x3d, 0x3d, 0x3d, 0x4e, 0x26, 0x26, 0x28, 0x45, 0x5b, 0x30, + 0x5d, 0x7c, 0x7c, 0x45, 0x5b, 0x31, 0x5d, 0x29, 0x29, 0x26, 0x26, + 0x28, 0x6f, 0x2b, 0x3d, 0x53, 0x5e, 0x62, 0x3e, 0x3d, 0x30, 0x3f, + 0x31, 0x3a, 0x2d, 0x31, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x21, 0x64, + 0x2b, 0x2b, 0x29, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x68, 0x3d, + 0x6d, 0x2c, 0x70, 0x3d, 0x4d, 0x2c, 0x76, 0x3d, 0x78, 0x2c, 0x66, + 0x3d, 0x6e, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, + 0x2d, 0x43, 0x61, 0x3e, 0x69, 0x7c, 0x7c, 0x43, 0x61, 0x3e, 0x69, + 0x26, 0x26, 0x30, 0x3e, 0x79, 0x63, 0x29, 0x5e, 0x31, 0x26, 0x6f, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x48, + 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x29, 0x3e, 0x69, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x69, 0x2c, 0x63, + 0x2c, 0x6c, 0x2c, 0x73, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x7b, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x6c, 0x3d, 0x63, 0x3d, 0x21, 0x31, 0x2c, 0x73, 0x3d, 0x31, 0x7d, + 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x66, 0x2c, 0x68, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x67, 0x2c, 0x70, 0x3d, 0x5b, 0x66, 0x2c, 0x68, + 0x5d, 0x2c, 0x76, 0x3d, 0x74, 0x28, 0x66, 0x2c, 0x68, 0x29, 0x2c, + 0x64, 0x3d, 0x6f, 0x3f, 0x76, 0x3f, 0x30, 0x3a, 0x75, 0x28, 0x66, + 0x2c, 0x68, 0x29, 0x3a, 0x76, 0x3f, 0x75, 0x28, 0x66, 0x2b, 0x28, + 0x30, 0x3e, 0x66, 0x3f, 0x71, 0x61, 0x3a, 0x2d, 0x71, 0x61, 0x29, + 0x2c, 0x68, 0x29, 0x3a, 0x30, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x65, + 0x26, 0x26, 0x28, 0x6c, 0x3d, 0x63, 0x3d, 0x76, 0x29, 0x26, 0x26, + 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x28, 0x29, 0x2c, 0x76, 0x21, 0x3d, 0x3d, 0x63, 0x26, 0x26, 0x28, + 0x67, 0x3d, 0x72, 0x28, 0x65, 0x2c, 0x70, 0x29, 0x2c, 0x28, 0x62, + 0x65, 0x28, 0x65, 0x2c, 0x67, 0x29, 0x7c, 0x7c, 0x62, 0x65, 0x28, + 0x70, 0x2c, 0x67, 0x29, 0x29, 0x26, 0x26, 0x28, 0x70, 0x5b, 0x30, + 0x5d, 0x2b, 0x3d, 0x43, 0x61, 0x2c, 0x70, 0x5b, 0x31, 0x5d, 0x2b, + 0x3d, 0x43, 0x61, 0x2c, 0x76, 0x3d, 0x74, 0x28, 0x70, 0x5b, 0x30, + 0x5d, 0x2c, 0x70, 0x5b, 0x31, 0x5d, 0x29, 0x29, 0x29, 0x2c, 0x76, + 0x21, 0x3d, 0x3d, 0x63, 0x29, 0x73, 0x3d, 0x30, 0x2c, 0x76, 0x3f, + 0x28, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x28, 0x29, 0x2c, 0x67, 0x3d, 0x72, 0x28, 0x70, 0x2c, 0x65, + 0x29, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x67, + 0x5b, 0x30, 0x5d, 0x2c, 0x67, 0x5b, 0x31, 0x5d, 0x29, 0x29, 0x3a, + 0x28, 0x67, 0x3d, 0x72, 0x28, 0x65, 0x2c, 0x70, 0x29, 0x2c, 0x6e, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x67, 0x5b, 0x30, 0x5d, + 0x2c, 0x67, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x6e, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x29, 0x2c, 0x65, 0x3d, + 0x67, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x61, + 0x26, 0x26, 0x65, 0x26, 0x26, 0x6f, 0x5e, 0x76, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6d, 0x3b, 0x64, 0x26, 0x69, 0x7c, 0x7c, 0x21, + 0x28, 0x6d, 0x3d, 0x72, 0x28, 0x70, 0x2c, 0x65, 0x2c, 0x21, 0x30, + 0x29, 0x29, 0x7c, 0x7c, 0x28, 0x73, 0x3d, 0x30, 0x2c, 0x6f, 0x3f, + 0x28, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x28, 0x29, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x28, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x6d, 0x5b, + 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, + 0x2c, 0x6d, 0x5b, 0x31, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x6e, + 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x29, + 0x3a, 0x28, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x6d, + 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x6d, 0x5b, 0x31, 0x5d, + 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x45, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x6e, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, + 0x30, 0x5d, 0x2c, 0x6d, 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x29, + 0x29, 0x29, 0x7d, 0x21, 0x76, 0x7c, 0x7c, 0x65, 0x26, 0x26, 0x62, + 0x65, 0x28, 0x65, 0x2c, 0x70, 0x29, 0x7c, 0x7c, 0x6e, 0x2e, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x70, 0x5b, 0x30, 0x5d, 0x2c, 0x70, + 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x65, 0x3d, 0x70, 0x2c, 0x63, 0x3d, + 0x76, 0x2c, 0x69, 0x3d, 0x64, 0x7d, 0x2c, 0x6c, 0x69, 0x6e, 0x65, + 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x63, 0x26, 0x26, 0x6e, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x65, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x63, 0x6c, 0x65, 0x61, 0x6e, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x7c, 0x28, 0x6c, + 0x26, 0x26, 0x63, 0x29, 0x3c, 0x3c, 0x31, 0x7d, 0x7d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x3d, 0x70, 0x65, 0x28, 0x6e, 0x29, 0x2c, 0x75, 0x3d, 0x70, 0x65, + 0x28, 0x74, 0x29, 0x2c, 0x6f, 0x3d, 0x5b, 0x31, 0x2c, 0x30, 0x2c, + 0x30, 0x5d, 0x2c, 0x61, 0x3d, 0x64, 0x65, 0x28, 0x72, 0x2c, 0x75, + 0x29, 0x2c, 0x63, 0x3d, 0x76, 0x65, 0x28, 0x61, 0x2c, 0x61, 0x29, + 0x2c, 0x6c, 0x3d, 0x61, 0x5b, 0x30, 0x5d, 0x2c, 0x73, 0x3d, 0x63, + 0x2d, 0x6c, 0x2a, 0x6c, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x73, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x65, 0x26, 0x26, 0x6e, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x66, 0x3d, 0x69, 0x2a, 0x63, 0x2f, + 0x73, 0x2c, 0x68, 0x3d, 0x2d, 0x69, 0x2a, 0x6c, 0x2f, 0x73, 0x2c, + 0x67, 0x3d, 0x64, 0x65, 0x28, 0x6f, 0x2c, 0x61, 0x29, 0x2c, 0x70, + 0x3d, 0x79, 0x65, 0x28, 0x6f, 0x2c, 0x66, 0x29, 0x2c, 0x76, 0x3d, + 0x79, 0x65, 0x28, 0x61, 0x2c, 0x68, 0x29, 0x3b, 0x6d, 0x65, 0x28, + 0x70, 0x2c, 0x76, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x3d, + 0x67, 0x2c, 0x6d, 0x3d, 0x76, 0x65, 0x28, 0x70, 0x2c, 0x64, 0x29, + 0x2c, 0x79, 0x3d, 0x76, 0x65, 0x28, 0x64, 0x2c, 0x64, 0x29, 0x2c, + 0x4d, 0x3d, 0x6d, 0x2a, 0x6d, 0x2d, 0x79, 0x2a, 0x28, 0x76, 0x65, + 0x28, 0x70, 0x2c, 0x70, 0x29, 0x2d, 0x31, 0x29, 0x3b, 0x69, 0x66, + 0x28, 0x21, 0x28, 0x30, 0x3e, 0x4d, 0x29, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x78, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x4d, 0x29, 0x2c, 0x62, 0x3d, 0x79, 0x65, 0x28, + 0x64, 0x2c, 0x28, 0x2d, 0x6d, 0x2d, 0x78, 0x29, 0x2f, 0x79, 0x29, + 0x3b, 0x69, 0x66, 0x28, 0x6d, 0x65, 0x28, 0x62, 0x2c, 0x70, 0x29, + 0x2c, 0x62, 0x3d, 0x78, 0x65, 0x28, 0x62, 0x29, 0x2c, 0x21, 0x65, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x62, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x5f, 0x2c, 0x77, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, + 0x2c, 0x53, 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x6b, 0x3d, 0x6e, + 0x5b, 0x31, 0x5d, 0x2c, 0x45, 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x3b, + 0x77, 0x3e, 0x53, 0x26, 0x26, 0x28, 0x5f, 0x3d, 0x77, 0x2c, 0x77, + 0x3d, 0x53, 0x2c, 0x53, 0x3d, 0x5f, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x41, 0x3d, 0x53, 0x2d, 0x77, 0x2c, 0x4e, 0x3d, 0x67, 0x61, + 0x28, 0x41, 0x2d, 0x71, 0x61, 0x29, 0x3c, 0x43, 0x61, 0x2c, 0x43, + 0x3d, 0x4e, 0x7c, 0x7c, 0x43, 0x61, 0x3e, 0x41, 0x3b, 0x69, 0x66, + 0x28, 0x21, 0x4e, 0x26, 0x26, 0x6b, 0x3e, 0x45, 0x26, 0x26, 0x28, + 0x5f, 0x3d, 0x6b, 0x2c, 0x6b, 0x3d, 0x45, 0x2c, 0x45, 0x3d, 0x5f, + 0x29, 0x2c, 0x43, 0x3f, 0x4e, 0x3f, 0x6b, 0x2b, 0x45, 0x3e, 0x30, + 0x5e, 0x62, 0x5b, 0x31, 0x5d, 0x3c, 0x28, 0x67, 0x61, 0x28, 0x62, + 0x5b, 0x30, 0x5d, 0x2d, 0x77, 0x29, 0x3c, 0x43, 0x61, 0x3f, 0x6b, + 0x3a, 0x45, 0x29, 0x3a, 0x6b, 0x3c, 0x3d, 0x62, 0x5b, 0x31, 0x5d, + 0x26, 0x26, 0x62, 0x5b, 0x31, 0x5d, 0x3c, 0x3d, 0x45, 0x3a, 0x41, + 0x3e, 0x71, 0x61, 0x5e, 0x28, 0x77, 0x3c, 0x3d, 0x62, 0x5b, 0x30, + 0x5d, 0x26, 0x26, 0x62, 0x5b, 0x30, 0x5d, 0x3c, 0x3d, 0x53, 0x29, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x7a, 0x3d, 0x79, 0x65, 0x28, + 0x64, 0x2c, 0x28, 0x2d, 0x6d, 0x2b, 0x78, 0x29, 0x2f, 0x79, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x65, 0x28, + 0x7a, 0x2c, 0x70, 0x29, 0x2c, 0x5b, 0x62, 0x2c, 0x78, 0x65, 0x28, + 0x7a, 0x29, 0x5d, 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6f, 0x3f, 0x6e, 0x3a, 0x71, + 0x61, 0x2d, 0x6e, 0x2c, 0x75, 0x3d, 0x30, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x2d, 0x72, 0x3e, 0x74, 0x3f, 0x75, 0x7c, 0x3d, + 0x31, 0x3a, 0x74, 0x3e, 0x72, 0x26, 0x26, 0x28, 0x75, 0x7c, 0x3d, + 0x32, 0x29, 0x2c, 0x2d, 0x72, 0x3e, 0x65, 0x3f, 0x75, 0x7c, 0x3d, + 0x34, 0x3a, 0x65, 0x3e, 0x72, 0x26, 0x26, 0x28, 0x75, 0x7c, 0x3d, + 0x38, 0x29, 0x2c, 0x75, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, + 0x2c, 0x6f, 0x3d, 0x69, 0x3e, 0x30, 0x2c, 0x61, 0x3d, 0x67, 0x61, + 0x28, 0x69, 0x29, 0x3e, 0x43, 0x61, 0x2c, 0x63, 0x3d, 0x67, 0x72, + 0x28, 0x6e, 0x2c, 0x36, 0x2a, 0x44, 0x61, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4c, 0x65, 0x28, 0x74, 0x2c, 0x65, + 0x2c, 0x63, 0x2c, 0x6f, 0x3f, 0x5b, 0x30, 0x2c, 0x2d, 0x6e, 0x5d, + 0x3a, 0x5b, 0x2d, 0x71, 0x61, 0x2c, 0x6e, 0x2d, 0x71, 0x61, 0x5d, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x4f, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x69, 0x2c, 0x6f, 0x3d, 0x75, 0x2e, 0x61, 0x2c, 0x61, + 0x3d, 0x75, 0x2e, 0x62, 0x2c, 0x63, 0x3d, 0x6f, 0x2e, 0x78, 0x2c, + 0x6c, 0x3d, 0x6f, 0x2e, 0x79, 0x2c, 0x73, 0x3d, 0x61, 0x2e, 0x78, + 0x2c, 0x66, 0x3d, 0x61, 0x2e, 0x79, 0x2c, 0x68, 0x3d, 0x30, 0x2c, + 0x67, 0x3d, 0x31, 0x2c, 0x70, 0x3d, 0x73, 0x2d, 0x63, 0x2c, 0x76, + 0x3d, 0x66, 0x2d, 0x6c, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x3d, 0x6e, + 0x2d, 0x63, 0x2c, 0x70, 0x7c, 0x7c, 0x21, 0x28, 0x69, 0x3e, 0x30, + 0x29, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x2f, 0x3d, 0x70, 0x2c, + 0x30, 0x3e, 0x70, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x68, 0x3e, 0x69, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x67, 0x3e, 0x69, + 0x26, 0x26, 0x28, 0x67, 0x3d, 0x69, 0x29, 0x7d, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x69, 0x66, 0x28, 0x70, 0x3e, 0x30, 0x29, 0x7b, 0x69, + 0x66, 0x28, 0x69, 0x3e, 0x67, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x3b, 0x69, 0x3e, 0x68, 0x26, 0x26, 0x28, 0x68, 0x3d, 0x69, + 0x29, 0x7d, 0x69, 0x66, 0x28, 0x69, 0x3d, 0x65, 0x2d, 0x63, 0x2c, + 0x70, 0x7c, 0x7c, 0x21, 0x28, 0x30, 0x3e, 0x69, 0x29, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x69, 0x2f, 0x3d, 0x70, 0x2c, 0x30, 0x3e, 0x70, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x3e, 0x67, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x69, 0x3e, 0x68, 0x26, 0x26, 0x28, + 0x68, 0x3d, 0x69, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, + 0x66, 0x28, 0x70, 0x3e, 0x30, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x68, + 0x3e, 0x69, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x67, + 0x3e, 0x69, 0x26, 0x26, 0x28, 0x67, 0x3d, 0x69, 0x29, 0x7d, 0x69, + 0x66, 0x28, 0x69, 0x3d, 0x74, 0x2d, 0x6c, 0x2c, 0x76, 0x7c, 0x7c, + 0x21, 0x28, 0x69, 0x3e, 0x30, 0x29, 0x29, 0x7b, 0x69, 0x66, 0x28, + 0x69, 0x2f, 0x3d, 0x76, 0x2c, 0x30, 0x3e, 0x76, 0x29, 0x7b, 0x69, + 0x66, 0x28, 0x68, 0x3e, 0x69, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x3b, 0x67, 0x3e, 0x69, 0x26, 0x26, 0x28, 0x67, 0x3d, 0x69, + 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x76, + 0x3e, 0x30, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x3e, 0x67, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x69, 0x3e, 0x68, 0x26, + 0x26, 0x28, 0x68, 0x3d, 0x69, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x69, + 0x3d, 0x72, 0x2d, 0x6c, 0x2c, 0x76, 0x7c, 0x7c, 0x21, 0x28, 0x30, + 0x3e, 0x69, 0x29, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x2f, 0x3d, + 0x76, 0x2c, 0x30, 0x3e, 0x76, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, + 0x3e, 0x67, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x69, + 0x3e, 0x68, 0x26, 0x26, 0x28, 0x68, 0x3d, 0x69, 0x29, 0x7d, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x76, 0x3e, 0x30, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x68, 0x3e, 0x69, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x3b, 0x67, 0x3e, 0x69, 0x26, 0x26, 0x28, 0x67, + 0x3d, 0x69, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x68, 0x3e, 0x30, 0x26, 0x26, 0x28, 0x75, 0x2e, 0x61, 0x3d, 0x7b, + 0x78, 0x3a, 0x63, 0x2b, 0x68, 0x2a, 0x70, 0x2c, 0x79, 0x3a, 0x6c, + 0x2b, 0x68, 0x2a, 0x76, 0x7d, 0x29, 0x2c, 0x31, 0x3e, 0x67, 0x26, + 0x26, 0x28, 0x75, 0x2e, 0x62, 0x3d, 0x7b, 0x78, 0x3a, 0x63, 0x2b, + 0x67, 0x2a, 0x70, 0x2c, 0x79, 0x3a, 0x6c, 0x2b, 0x67, 0x2a, 0x76, + 0x7d, 0x29, 0x2c, 0x75, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x65, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x72, 0x2c, + 0x75, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, + 0x61, 0x28, 0x72, 0x5b, 0x30, 0x5d, 0x2d, 0x6e, 0x29, 0x3c, 0x43, + 0x61, 0x3f, 0x75, 0x3e, 0x30, 0x3f, 0x30, 0x3a, 0x33, 0x3a, 0x67, + 0x61, 0x28, 0x72, 0x5b, 0x30, 0x5d, 0x2d, 0x65, 0x29, 0x3c, 0x43, + 0x61, 0x3f, 0x75, 0x3e, 0x30, 0x3f, 0x32, 0x3a, 0x31, 0x3a, 0x67, + 0x61, 0x28, 0x72, 0x5b, 0x31, 0x5d, 0x2d, 0x74, 0x29, 0x3c, 0x43, + 0x61, 0x3f, 0x75, 0x3e, 0x30, 0x3f, 0x31, 0x3a, 0x30, 0x3a, 0x75, + 0x3e, 0x30, 0x3f, 0x33, 0x3a, 0x32, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x28, 0x6e, + 0x2e, 0x78, 0x2c, 0x74, 0x2e, 0x78, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x75, 0x28, 0x6e, + 0x2c, 0x31, 0x29, 0x2c, 0x72, 0x3d, 0x75, 0x28, 0x74, 0x2c, 0x31, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x21, + 0x3d, 0x3d, 0x72, 0x3f, 0x65, 0x2d, 0x72, 0x3a, 0x30, 0x3d, 0x3d, + 0x3d, 0x65, 0x3f, 0x74, 0x5b, 0x31, 0x5d, 0x2d, 0x6e, 0x5b, 0x31, + 0x5d, 0x3a, 0x31, 0x3d, 0x3d, 0x3d, 0x65, 0x3f, 0x6e, 0x5b, 0x30, + 0x5d, 0x2d, 0x74, 0x5b, 0x30, 0x5d, 0x3a, 0x32, 0x3d, 0x3d, 0x3d, + 0x65, 0x3f, 0x6e, 0x5b, 0x31, 0x5d, 0x2d, 0x74, 0x5b, 0x31, 0x5d, + 0x3a, 0x74, 0x5b, 0x30, 0x5d, 0x2d, 0x6e, 0x5b, 0x30, 0x5d, 0x7d, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x61, 0x29, 0x7b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x6e, 0x29, 0x7b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x30, + 0x2c, 0x65, 0x3d, 0x64, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2c, 0x72, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x75, 0x3d, 0x30, + 0x3b, 0x65, 0x3e, 0x75, 0x3b, 0x2b, 0x2b, 0x75, 0x29, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x2c, 0x6f, 0x3d, 0x31, + 0x2c, 0x61, 0x3d, 0x64, 0x5b, 0x75, 0x5d, 0x2c, 0x63, 0x3d, 0x61, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x6c, 0x3d, 0x61, + 0x5b, 0x30, 0x5d, 0x3b, 0x63, 0x3e, 0x6f, 0x3b, 0x2b, 0x2b, 0x6f, + 0x29, 0x69, 0x3d, 0x61, 0x5b, 0x6f, 0x5d, 0x2c, 0x6c, 0x5b, 0x31, + 0x5d, 0x3c, 0x3d, 0x72, 0x3f, 0x69, 0x5b, 0x31, 0x5d, 0x3e, 0x72, + 0x26, 0x26, 0x51, 0x28, 0x6c, 0x2c, 0x69, 0x2c, 0x6e, 0x29, 0x3e, + 0x30, 0x26, 0x26, 0x2b, 0x2b, 0x74, 0x3a, 0x69, 0x5b, 0x31, 0x5d, + 0x3c, 0x3d, 0x72, 0x26, 0x26, 0x51, 0x28, 0x6c, 0x2c, 0x69, 0x2c, + 0x6e, 0x29, 0x3c, 0x30, 0x26, 0x26, 0x2d, 0x2d, 0x74, 0x2c, 0x6c, + 0x3d, 0x69, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, + 0x21, 0x3d, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6c, 0x28, 0x69, 0x2c, 0x61, 0x2c, 0x63, 0x2c, + 0x6c, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x30, 0x2c, + 0x66, 0x3d, 0x30, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, + 0x3d, 0x3d, 0x69, 0x7c, 0x7c, 0x28, 0x73, 0x3d, 0x75, 0x28, 0x69, + 0x2c, 0x63, 0x29, 0x29, 0x21, 0x3d, 0x3d, 0x28, 0x66, 0x3d, 0x75, + 0x28, 0x61, 0x2c, 0x63, 0x29, 0x29, 0x7c, 0x7c, 0x6f, 0x28, 0x69, + 0x2c, 0x61, 0x29, 0x3c, 0x30, 0x5e, 0x63, 0x3e, 0x30, 0x29, 0x7b, + 0x64, 0x6f, 0x20, 0x6c, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, + 0x30, 0x3d, 0x3d, 0x3d, 0x73, 0x7c, 0x7c, 0x33, 0x3d, 0x3d, 0x3d, + 0x73, 0x3f, 0x6e, 0x3a, 0x65, 0x2c, 0x73, 0x3e, 0x31, 0x3f, 0x72, + 0x3a, 0x74, 0x29, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x28, + 0x73, 0x3d, 0x28, 0x73, 0x2b, 0x63, 0x2b, 0x34, 0x29, 0x25, 0x34, + 0x29, 0x21, 0x3d, 0x3d, 0x66, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x6c, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x61, 0x5b, + 0x30, 0x5d, 0x2c, 0x61, 0x5b, 0x31, 0x5d, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x28, 0x75, 0x2c, + 0x69, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, + 0x3e, 0x3d, 0x6e, 0x26, 0x26, 0x65, 0x3e, 0x3d, 0x75, 0x26, 0x26, + 0x69, 0x3e, 0x3d, 0x74, 0x26, 0x26, 0x72, 0x3e, 0x3d, 0x69, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x73, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x26, 0x26, 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x68, 0x28, 0x29, 0x7b, 0x43, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3d, 0x70, 0x2c, 0x64, 0x26, 0x26, 0x64, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x6d, 0x3d, 0x5b, 0x5d, 0x29, 0x2c, 0x53, + 0x3d, 0x21, 0x30, 0x2c, 0x77, 0x3d, 0x21, 0x31, 0x2c, 0x62, 0x3d, + 0x5f, 0x3d, 0x30, 0x2f, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x28, 0x29, 0x7b, 0x76, 0x26, 0x26, + 0x28, 0x70, 0x28, 0x79, 0x2c, 0x4d, 0x29, 0x2c, 0x78, 0x26, 0x26, + 0x77, 0x26, 0x26, 0x41, 0x2e, 0x72, 0x65, 0x6a, 0x6f, 0x69, 0x6e, + 0x28, 0x29, 0x2c, 0x76, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x41, + 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x29, 0x29, 0x29, + 0x2c, 0x43, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x66, 0x2c, + 0x77, 0x26, 0x26, 0x61, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, + 0x64, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x70, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x2d, 0x54, + 0x63, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, + 0x54, 0x63, 0x2c, 0x6e, 0x29, 0x29, 0x2c, 0x74, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x2d, 0x54, 0x63, 0x2c, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x54, 0x63, + 0x2c, 0x74, 0x29, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x73, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x64, + 0x26, 0x26, 0x6d, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x5b, 0x6e, + 0x2c, 0x74, 0x5d, 0x29, 0x2c, 0x53, 0x29, 0x79, 0x3d, 0x6e, 0x2c, + 0x4d, 0x3d, 0x74, 0x2c, 0x78, 0x3d, 0x65, 0x2c, 0x53, 0x3d, 0x21, + 0x31, 0x2c, 0x65, 0x26, 0x26, 0x28, 0x61, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x61, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x29, + 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x65, 0x26, + 0x26, 0x77, 0x29, 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x7b, 0x61, 0x3a, 0x7b, 0x78, 0x3a, + 0x62, 0x2c, 0x79, 0x3a, 0x5f, 0x7d, 0x2c, 0x62, 0x3a, 0x7b, 0x78, + 0x3a, 0x6e, 0x2c, 0x79, 0x3a, 0x74, 0x7d, 0x7d, 0x3b, 0x4e, 0x28, + 0x72, 0x29, 0x3f, 0x28, 0x77, 0x7c, 0x7c, 0x28, 0x61, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, + 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x72, 0x2e, 0x61, + 0x2e, 0x78, 0x2c, 0x72, 0x2e, 0x61, 0x2e, 0x79, 0x29, 0x29, 0x2c, + 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x72, 0x2e, 0x62, + 0x2e, 0x78, 0x2c, 0x72, 0x2e, 0x62, 0x2e, 0x79, 0x29, 0x2c, 0x65, + 0x7c, 0x7c, 0x61, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x28, 0x29, 0x2c, 0x6b, 0x3d, 0x21, 0x31, 0x29, 0x3a, 0x65, 0x26, + 0x26, 0x28, 0x61, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x28, 0x29, 0x2c, 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x2c, 0x6b, 0x3d, 0x21, 0x31, + 0x29, 0x7d, 0x62, 0x3d, 0x6e, 0x2c, 0x5f, 0x3d, 0x74, 0x2c, 0x77, + 0x3d, 0x65, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x76, 0x2c, 0x64, 0x2c, + 0x6d, 0x2c, 0x79, 0x2c, 0x4d, 0x2c, 0x78, 0x2c, 0x62, 0x2c, 0x5f, + 0x2c, 0x77, 0x2c, 0x53, 0x2c, 0x6b, 0x2c, 0x45, 0x3d, 0x61, 0x2c, + 0x41, 0x3d, 0x52, 0x65, 0x28, 0x29, 0x2c, 0x4e, 0x3d, 0x4f, 0x65, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x2c, 0x43, + 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x66, 0x2c, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x68, 0x2c, + 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x67, 0x2c, 0x70, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x61, 0x3d, 0x41, 0x2c, 0x76, 0x3d, 0x5b, 0x5d, 0x2c, 0x64, + 0x3d, 0x5b, 0x5d, 0x2c, 0x6b, 0x3d, 0x21, 0x30, 0x7d, 0x2c, 0x70, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x61, + 0x3d, 0x45, 0x2c, 0x76, 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x65, 0x72, + 0x67, 0x65, 0x28, 0x76, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x3d, 0x63, 0x28, 0x5b, 0x6e, 0x2c, 0x72, 0x5d, 0x29, 0x2c, 0x65, + 0x3d, 0x6b, 0x26, 0x26, 0x74, 0x2c, 0x75, 0x3d, 0x76, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x28, 0x65, 0x7c, 0x7c, 0x75, + 0x29, 0x26, 0x26, 0x28, 0x61, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x65, + 0x26, 0x26, 0x28, 0x61, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x6c, 0x28, 0x6e, 0x75, 0x6c, + 0x6c, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x31, 0x2c, 0x61, 0x29, + 0x2c, 0x61, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, + 0x29, 0x29, 0x2c, 0x75, 0x26, 0x26, 0x43, 0x65, 0x28, 0x76, 0x2c, + 0x69, 0x2c, 0x74, 0x2c, 0x6c, 0x2c, 0x61, 0x29, 0x2c, 0x61, 0x2e, + 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, + 0x29, 0x29, 0x2c, 0x76, 0x3d, 0x64, 0x3d, 0x6d, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x7d, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x43, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x59, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x3d, 0x30, 0x2c, 0x65, 0x3d, 0x71, 0x61, 0x2f, 0x33, + 0x2c, 0x72, 0x3d, 0x69, 0x72, 0x28, 0x6e, 0x29, 0x2c, 0x75, 0x3d, + 0x72, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x75, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, + 0x65, 0x6c, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x72, 0x28, 0x74, 0x3d, + 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x71, 0x61, 0x2f, 0x31, 0x38, 0x30, + 0x2c, 0x65, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x71, 0x61, 0x2f, + 0x31, 0x38, 0x30, 0x29, 0x3a, 0x5b, 0x74, 0x2f, 0x71, 0x61, 0x2a, + 0x31, 0x38, 0x30, 0x2c, 0x65, 0x2f, 0x71, 0x61, 0x2a, 0x31, 0x38, + 0x30, 0x5d, 0x7d, 0x2c, 0x75, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x5a, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, + 0x69, 0x2d, 0x32, 0x2a, 0x75, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x73, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x29, 0x2f, 0x75, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x65, 0x2a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x2a, 0x3d, 0x75, 0x29, + 0x2c, 0x6f, 0x2d, 0x65, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, + 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x5d, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x6e, 0x29, 0x2c, 0x75, 0x3d, 0x28, 0x72, 0x2b, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x29, 0x2f, 0x32, + 0x2c, 0x69, 0x3d, 0x31, 0x2b, 0x72, 0x2a, 0x28, 0x32, 0x2a, 0x75, + 0x2d, 0x72, 0x29, 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x73, 0x71, 0x72, 0x74, 0x28, 0x69, 0x29, 0x2f, 0x75, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x69, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x6f, 0x2d, 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x5b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, + 0x32, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x2f, 0x75, 0x2c, 0x74, 0x74, + 0x28, 0x28, 0x69, 0x2d, 0x28, 0x6e, 0x2a, 0x6e, 0x2b, 0x65, 0x2a, + 0x65, 0x29, 0x2a, 0x75, 0x2a, 0x75, 0x29, 0x2f, 0x28, 0x32, 0x2a, + 0x75, 0x29, 0x29, 0x5d, 0x7d, 0x2c, 0x65, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, 0x65, 0x28, 0x29, 0x7b, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x44, 0x63, 0x2b, 0x3d, 0x75, 0x2a, + 0x6e, 0x2d, 0x72, 0x2a, 0x74, 0x2c, 0x72, 0x3d, 0x6e, 0x2c, 0x75, + 0x3d, 0x74, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x2c, 0x75, 0x3b, 0x48, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x69, 0x2c, 0x6f, 0x29, 0x7b, 0x48, 0x63, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3d, 0x6e, 0x2c, 0x74, 0x3d, 0x72, 0x3d, 0x69, 0x2c, + 0x65, 0x3d, 0x75, 0x3d, 0x6f, 0x7d, 0x2c, 0x48, 0x63, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6e, 0x28, 0x74, 0x2c, + 0x65, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x58, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x50, + 0x63, 0x3e, 0x6e, 0x26, 0x26, 0x28, 0x50, 0x63, 0x3d, 0x6e, 0x29, + 0x2c, 0x6e, 0x3e, 0x6a, 0x63, 0x26, 0x26, 0x28, 0x6a, 0x63, 0x3d, + 0x6e, 0x29, 0x2c, 0x55, 0x63, 0x3e, 0x74, 0x26, 0x26, 0x28, 0x55, + 0x63, 0x3d, 0x74, 0x29, 0x2c, 0x74, 0x3e, 0x46, 0x63, 0x26, 0x26, + 0x28, 0x46, 0x63, 0x3d, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x24, 0x65, 0x28, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x22, 0x4d, 0x22, 0x2c, 0x6e, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x74, + 0x2c, 0x69, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6f, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x4d, 0x22, 0x2c, 0x6e, 0x2c, + 0x22, 0x2c, 0x22, 0x2c, 0x74, 0x29, 0x2c, 0x61, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x3d, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x4c, 0x22, 0x2c, + 0x6e, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x74, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, 0x7b, + 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x29, + 0x7b, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x5a, 0x22, + 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x42, 0x65, 0x28, + 0x34, 0x2e, 0x35, 0x29, 0x2c, 0x6f, 0x3d, 0x5b, 0x5d, 0x2c, 0x61, + 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x6e, 0x2c, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x61, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x74, 0x7d, 0x2c, 0x6c, 0x69, + 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x72, 0x2c, 0x70, 0x6f, 0x6c, + 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x61, + 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x75, 0x7d, + 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x61, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, + 0x72, 0x2c, 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, + 0x7d, 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x69, 0x3d, 0x42, 0x65, 0x28, 0x6e, 0x29, 0x2c, 0x61, 0x7d, 0x2c, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6f, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6e, 0x3d, 0x6f, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, + 0x22, 0x22, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6f, 0x3d, 0x5b, 0x5d, 0x2c, 0x6e, 0x7d, 0x7d, 0x7d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x65, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x6d, 0x30, 0x2c, + 0x22, 0x2b, 0x6e, 0x2b, 0x22, 0x61, 0x22, 0x2b, 0x6e, 0x2b, 0x22, + 0x2c, 0x22, 0x2b, 0x6e, 0x2b, 0x22, 0x20, 0x30, 0x20, 0x31, 0x2c, + 0x31, 0x20, 0x30, 0x2c, 0x22, 0x2b, 0x2d, 0x32, 0x2a, 0x6e, 0x2b, + 0x22, 0x61, 0x22, 0x2b, 0x6e, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x6e, + 0x2b, 0x22, 0x20, 0x30, 0x20, 0x31, 0x2c, 0x31, 0x20, 0x30, 0x2c, + 0x22, 0x2b, 0x32, 0x2a, 0x6e, 0x2b, 0x22, 0x7a, 0x22, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x57, 0x65, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x5f, 0x63, 0x2b, 0x3d, 0x6e, 0x2c, + 0x77, 0x63, 0x2b, 0x3d, 0x74, 0x2c, 0x2b, 0x2b, 0x53, 0x63, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a, 0x65, + 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6e, 0x28, 0x6e, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x75, 0x3d, 0x6e, 0x2d, 0x74, 0x2c, 0x69, 0x3d, 0x72, 0x2d, + 0x65, 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x75, 0x2a, 0x75, 0x2b, 0x69, 0x2a, 0x69, 0x29, + 0x3b, 0x6b, 0x63, 0x2b, 0x3d, 0x6f, 0x2a, 0x28, 0x74, 0x2b, 0x6e, + 0x29, 0x2f, 0x32, 0x2c, 0x45, 0x63, 0x2b, 0x3d, 0x6f, 0x2a, 0x28, + 0x65, 0x2b, 0x72, 0x29, 0x2f, 0x32, 0x2c, 0x41, 0x63, 0x2b, 0x3d, + 0x6f, 0x2c, 0x57, 0x65, 0x28, 0x74, 0x3d, 0x6e, 0x2c, 0x65, 0x3d, + 0x72, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3b, + 0x49, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, 0x2c, 0x75, 0x29, + 0x7b, 0x49, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, + 0x2c, 0x57, 0x65, 0x28, 0x74, 0x3d, 0x72, 0x2c, 0x65, 0x3d, 0x75, + 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x47, 0x65, 0x28, 0x29, 0x7b, 0x49, 0x63, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x3d, 0x57, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4b, 0x65, 0x28, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, + 0x2d, 0x72, 0x2c, 0x69, 0x3d, 0x74, 0x2d, 0x75, 0x2c, 0x6f, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x65, + 0x2a, 0x65, 0x2b, 0x69, 0x2a, 0x69, 0x29, 0x3b, 0x6b, 0x63, 0x2b, + 0x3d, 0x6f, 0x2a, 0x28, 0x72, 0x2b, 0x6e, 0x29, 0x2f, 0x32, 0x2c, + 0x45, 0x63, 0x2b, 0x3d, 0x6f, 0x2a, 0x28, 0x75, 0x2b, 0x74, 0x29, + 0x2f, 0x32, 0x2c, 0x41, 0x63, 0x2b, 0x3d, 0x6f, 0x2c, 0x6f, 0x3d, + 0x75, 0x2a, 0x6e, 0x2d, 0x72, 0x2a, 0x74, 0x2c, 0x4e, 0x63, 0x2b, + 0x3d, 0x6f, 0x2a, 0x28, 0x72, 0x2b, 0x6e, 0x29, 0x2c, 0x43, 0x63, + 0x2b, 0x3d, 0x6f, 0x2a, 0x28, 0x75, 0x2b, 0x74, 0x29, 0x2c, 0x7a, + 0x63, 0x2b, 0x3d, 0x33, 0x2a, 0x6f, 0x2c, 0x57, 0x65, 0x28, 0x72, + 0x3d, 0x6e, 0x2c, 0x75, 0x3d, 0x74, 0x29, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3b, 0x49, 0x63, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x69, 0x2c, 0x6f, 0x29, 0x7b, 0x49, + 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, 0x2c, 0x57, + 0x65, 0x28, 0x74, 0x3d, 0x72, 0x3d, 0x69, 0x2c, 0x65, 0x3d, 0x75, + 0x3d, 0x6f, 0x29, 0x7d, 0x2c, 0x49, 0x63, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, + 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x51, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, + 0x6e, 0x2e, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x6f, 0x28, 0x74, 0x2b, + 0x6f, 0x2c, 0x65, 0x29, 0x2c, 0x6e, 0x2e, 0x61, 0x72, 0x63, 0x28, + 0x74, 0x2c, 0x65, 0x2c, 0x6f, 0x2c, 0x30, 0x2c, 0x4c, 0x61, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, + 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x6e, 0x2e, 0x6d, 0x6f, 0x76, + 0x65, 0x54, 0x6f, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x2c, 0x61, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x72, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x74, 0x2c, 0x65, + 0x29, 0x7b, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x54, 0x6f, 0x28, + 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x29, 0x7b, 0x61, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x29, 0x7b, 0x6e, 0x2e, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x28, 0x29, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x34, 0x2e, 0x35, 0x2c, 0x61, + 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x74, 0x2c, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x61, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x65, 0x7d, 0x2c, 0x6c, 0x69, + 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x75, 0x2c, 0x70, 0x6f, 0x6c, + 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x61, + 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x69, 0x7d, + 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x61, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, + 0x75, 0x2c, 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x74, + 0x7d, 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6f, 0x3d, 0x6e, 0x2c, 0x61, 0x7d, 0x2c, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x3a, 0x62, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6e, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x61, 0x3f, 0x72, 0x3a, + 0x65, 0x29, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x72, 0x28, 0x74, 0x2c, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x72, + 0x29, 0x7b, 0x65, 0x3d, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x2c, + 0x74, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x65, 0x5b, 0x30, + 0x5d, 0x2c, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x7d, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x74, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x65, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x65, 0x3d, 0x6e, 0x28, + 0x65, 0x2c, 0x72, 0x29, 0x2c, 0x74, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x5b, 0x31, 0x5d, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x72, 0x28, 0x29, 0x7b, 0x4d, 0x3d, 0x30, 0x2f, 0x30, 0x2c, 0x53, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x69, 0x2c, 0x74, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, + 0x3d, 0x70, 0x65, 0x28, 0x5b, 0x65, 0x2c, 0x72, 0x5d, 0x29, 0x2c, + 0x6f, 0x3d, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x3b, 0x75, 0x28, + 0x4d, 0x2c, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x2c, 0x5f, 0x2c, 0x77, + 0x2c, 0x4d, 0x3d, 0x6f, 0x5b, 0x30, 0x5d, 0x2c, 0x78, 0x3d, 0x6f, + 0x5b, 0x31, 0x5d, 0x2c, 0x79, 0x3d, 0x65, 0x2c, 0x62, 0x3d, 0x69, + 0x5b, 0x30, 0x5d, 0x2c, 0x5f, 0x3d, 0x69, 0x5b, 0x31, 0x5d, 0x2c, + 0x77, 0x3d, 0x69, 0x5b, 0x32, 0x5d, 0x2c, 0x61, 0x2c, 0x74, 0x29, + 0x2c, 0x74, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x4d, 0x2c, + 0x78, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x28, 0x29, 0x7b, 0x53, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x3d, 0x65, 0x2c, 0x74, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, + 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x29, 0x7b, 0x72, 0x28, 0x29, 0x2c, + 0x53, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6c, 0x2c, 0x53, + 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x73, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x28, 0x66, 0x3d, 0x6e, 0x2c, + 0x68, 0x3d, 0x74, 0x29, 0x2c, 0x67, 0x3d, 0x4d, 0x2c, 0x70, 0x3d, + 0x78, 0x2c, 0x76, 0x3d, 0x62, 0x2c, 0x64, 0x3d, 0x5f, 0x2c, 0x6d, + 0x3d, 0x77, 0x2c, 0x53, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, + 0x69, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x73, 0x28, 0x29, 0x7b, 0x75, 0x28, 0x4d, 0x2c, 0x78, 0x2c, 0x79, + 0x2c, 0x62, 0x2c, 0x5f, 0x2c, 0x77, 0x2c, 0x67, 0x2c, 0x70, 0x2c, + 0x66, 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x61, 0x2c, 0x74, + 0x29, 0x2c, 0x53, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x3d, 0x6f, 0x2c, 0x6f, 0x28, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x66, 0x2c, 0x68, 0x2c, 0x67, 0x2c, 0x70, 0x2c, 0x76, 0x2c, 0x64, + 0x2c, 0x6d, 0x2c, 0x79, 0x2c, 0x4d, 0x2c, 0x78, 0x2c, 0x62, 0x2c, + 0x5f, 0x2c, 0x77, 0x2c, 0x53, 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x3a, 0x65, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x3a, 0x72, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, + 0x64, 0x3a, 0x6f, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x6f, 0x6c, + 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, + 0x2c, 0x53, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x3d, 0x63, 0x7d, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, + 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x79, + 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x53, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x72, + 0x7d, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x53, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, + 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x61, 0x2c, 0x63, 0x2c, + 0x6c, 0x2c, 0x73, 0x2c, 0x66, 0x2c, 0x68, 0x2c, 0x67, 0x2c, 0x70, + 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x79, 0x3d, 0x73, 0x2d, 0x74, 0x2c, 0x4d, 0x3d, 0x66, 0x2d, + 0x65, 0x2c, 0x78, 0x3d, 0x79, 0x2a, 0x79, 0x2b, 0x4d, 0x2a, 0x4d, + 0x3b, 0x69, 0x66, 0x28, 0x78, 0x3e, 0x34, 0x2a, 0x69, 0x26, 0x26, + 0x64, 0x2d, 0x2d, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x62, 0x3d, + 0x61, 0x2b, 0x67, 0x2c, 0x5f, 0x3d, 0x63, 0x2b, 0x70, 0x2c, 0x77, + 0x3d, 0x6c, 0x2b, 0x76, 0x2c, 0x53, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x62, 0x2a, 0x62, 0x2b, 0x5f, + 0x2a, 0x5f, 0x2b, 0x77, 0x2a, 0x77, 0x29, 0x2c, 0x6b, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x61, 0x73, 0x69, 0x6e, 0x28, 0x77, 0x2f, + 0x3d, 0x53, 0x29, 0x2c, 0x45, 0x3d, 0x67, 0x61, 0x28, 0x67, 0x61, + 0x28, 0x77, 0x29, 0x2d, 0x31, 0x29, 0x3c, 0x43, 0x61, 0x7c, 0x7c, + 0x67, 0x61, 0x28, 0x72, 0x2d, 0x68, 0x29, 0x3c, 0x43, 0x61, 0x3f, + 0x28, 0x72, 0x2b, 0x68, 0x29, 0x2f, 0x32, 0x3a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x5f, 0x2c, 0x62, + 0x29, 0x2c, 0x41, 0x3d, 0x6e, 0x28, 0x45, 0x2c, 0x6b, 0x29, 0x2c, + 0x4e, 0x3d, 0x41, 0x5b, 0x30, 0x5d, 0x2c, 0x43, 0x3d, 0x41, 0x5b, + 0x31, 0x5d, 0x2c, 0x7a, 0x3d, 0x4e, 0x2d, 0x74, 0x2c, 0x71, 0x3d, + 0x43, 0x2d, 0x65, 0x2c, 0x4c, 0x3d, 0x4d, 0x2a, 0x7a, 0x2d, 0x79, + 0x2a, 0x71, 0x3b, 0x28, 0x4c, 0x2a, 0x4c, 0x2f, 0x78, 0x3e, 0x69, + 0x7c, 0x7c, 0x67, 0x61, 0x28, 0x28, 0x79, 0x2a, 0x7a, 0x2b, 0x4d, + 0x2a, 0x71, 0x29, 0x2f, 0x78, 0x2d, 0x2e, 0x35, 0x29, 0x3e, 0x2e, + 0x33, 0x7c, 0x7c, 0x6f, 0x3e, 0x61, 0x2a, 0x67, 0x2b, 0x63, 0x2a, + 0x70, 0x2b, 0x6c, 0x2a, 0x76, 0x29, 0x26, 0x26, 0x28, 0x75, 0x28, + 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x61, 0x2c, 0x63, 0x2c, 0x6c, + 0x2c, 0x4e, 0x2c, 0x43, 0x2c, 0x45, 0x2c, 0x62, 0x2f, 0x3d, 0x53, + 0x2c, 0x5f, 0x2f, 0x3d, 0x53, 0x2c, 0x77, 0x2c, 0x64, 0x2c, 0x6d, + 0x29, 0x2c, 0x6d, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x4e, + 0x2c, 0x43, 0x29, 0x2c, 0x75, 0x28, 0x4e, 0x2c, 0x43, 0x2c, 0x45, + 0x2c, 0x62, 0x2c, 0x5f, 0x2c, 0x77, 0x2c, 0x73, 0x2c, 0x66, 0x2c, + 0x68, 0x2c, 0x67, 0x2c, 0x70, 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, + 0x29, 0x29, 0x7d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x2e, + 0x35, 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, + 0x73, 0x28, 0x33, 0x30, 0x2a, 0x44, 0x61, 0x29, 0x2c, 0x61, 0x3d, + 0x31, 0x36, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x2e, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x61, 0x3d, 0x28, 0x69, 0x3d, 0x6e, 0x2a, + 0x6e, 0x29, 0x3e, 0x30, 0x26, 0x26, 0x31, 0x36, 0x2c, 0x74, 0x29, + 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, + 0x69, 0x29, 0x7d, 0x2c, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x72, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x28, 0x5b, 0x74, + 0x2a, 0x50, 0x61, 0x2c, 0x65, 0x2a, 0x50, 0x61, 0x5d, 0x29, 0x7d, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x72, 0x28, 0x74, 0x28, + 0x6e, 0x29, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x65, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x3d, 0x6e, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, + 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x74, 0x2c, + 0x73, 0x70, 0x68, 0x65, 0x72, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6e, 0x2e, 0x73, 0x70, + 0x68, 0x65, 0x72, 0x65, 0x28, 0x29, 0x7d, 0x2c, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6e, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x7d, 0x2c, + 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6e, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x2c, 0x70, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x6e, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x7d, 0x2c, 0x70, 0x6f, 0x6c, + 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6e, 0x2e, 0x70, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, 0x29, + 0x7d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x75, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x72, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x7d, 0x29, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x72, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x3d, 0x61, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x44, 0x61, + 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x44, 0x61, 0x29, 0x2c, 0x5b, + 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x68, 0x2b, 0x63, 0x2c, 0x6c, 0x2d, + 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x68, 0x5d, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x61, 0x2e, + 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x28, 0x6e, 0x5b, 0x30, + 0x5d, 0x2d, 0x63, 0x29, 0x2f, 0x68, 0x2c, 0x28, 0x6c, 0x2d, 0x6e, + 0x5b, 0x31, 0x5d, 0x29, 0x2f, 0x68, 0x29, 0x2c, 0x6e, 0x26, 0x26, + 0x5b, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x50, 0x61, 0x2c, 0x6e, 0x5b, + 0x31, 0x5d, 0x2a, 0x50, 0x61, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, 0x7b, 0x61, 0x3d, + 0x41, 0x65, 0x28, 0x6f, 0x3d, 0x6c, 0x72, 0x28, 0x6d, 0x2c, 0x4d, + 0x2c, 0x78, 0x29, 0x2c, 0x69, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x3d, 0x69, 0x28, 0x76, 0x2c, 0x64, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x3d, 0x67, 0x2d, 0x6e, 0x5b, + 0x30, 0x5d, 0x2a, 0x68, 0x2c, 0x6c, 0x3d, 0x70, 0x2b, 0x6e, 0x5b, + 0x31, 0x5d, 0x2a, 0x68, 0x2c, 0x75, 0x28, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x26, 0x26, 0x28, + 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x3d, 0x21, 0x31, 0x2c, + 0x73, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x74, 0x7d, 0x76, + 0x61, 0x72, 0x20, 0x69, 0x2c, 0x6f, 0x2c, 0x61, 0x2c, 0x63, 0x2c, + 0x6c, 0x2c, 0x73, 0x2c, 0x66, 0x3d, 0x6e, 0x72, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x69, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x2c, 0x5b, 0x6e, 0x5b, 0x30, 0x5d, + 0x2a, 0x68, 0x2b, 0x63, 0x2c, 0x6c, 0x2d, 0x6e, 0x5b, 0x31, 0x5d, + 0x2a, 0x68, 0x5d, 0x7d, 0x29, 0x2c, 0x68, 0x3d, 0x31, 0x35, 0x30, + 0x2c, 0x67, 0x3d, 0x34, 0x38, 0x30, 0x2c, 0x70, 0x3d, 0x32, 0x35, + 0x30, 0x2c, 0x76, 0x3d, 0x30, 0x2c, 0x64, 0x3d, 0x30, 0x2c, 0x6d, + 0x3d, 0x30, 0x2c, 0x4d, 0x3d, 0x30, 0x2c, 0x78, 0x3d, 0x30, 0x2c, + 0x62, 0x3d, 0x4c, 0x63, 0x2c, 0x5f, 0x3d, 0x79, 0x2c, 0x77, 0x3d, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x53, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x73, 0x26, 0x26, 0x28, 0x73, 0x2e, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x3d, 0x21, 0x31, 0x29, 0x2c, 0x73, 0x3d, 0x6f, + 0x72, 0x28, 0x62, 0x28, 0x6f, 0x2c, 0x66, 0x28, 0x5f, 0x28, 0x6e, + 0x29, 0x29, 0x29, 0x29, 0x2c, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x3d, 0x21, 0x30, 0x2c, 0x73, 0x7d, 0x2c, 0x74, 0x2e, 0x63, + 0x6c, 0x69, 0x70, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x62, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, + 0x3f, 0x28, 0x77, 0x3d, 0x6e, 0x2c, 0x4c, 0x63, 0x29, 0x3a, 0x48, + 0x65, 0x28, 0x28, 0x77, 0x3d, 0x2b, 0x6e, 0x29, 0x2a, 0x44, 0x61, + 0x29, 0x2c, 0x75, 0x28, 0x29, 0x29, 0x3a, 0x77, 0x7d, 0x2c, 0x74, + 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x53, 0x3d, 0x6e, 0x2c, 0x5f, 0x3d, + 0x6e, 0x3f, 0x49, 0x65, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x5b, 0x30, + 0x5d, 0x2c, 0x6e, 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, + 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, + 0x5b, 0x31, 0x5d, 0x29, 0x3a, 0x79, 0x2c, 0x75, 0x28, 0x29, 0x29, + 0x3a, 0x53, 0x7d, 0x2c, 0x74, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x68, 0x3d, 0x2b, 0x6e, 0x2c, 0x72, + 0x28, 0x29, 0x29, 0x3a, 0x68, 0x7d, 0x2c, 0x74, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x67, 0x3d, 0x2b, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x70, 0x3d, + 0x2b, 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x72, 0x28, 0x29, 0x29, 0x3a, + 0x5b, 0x67, 0x2c, 0x70, 0x5d, 0x7d, 0x2c, 0x74, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x76, 0x3d, + 0x6e, 0x5b, 0x30, 0x5d, 0x25, 0x33, 0x36, 0x30, 0x2a, 0x44, 0x61, + 0x2c, 0x64, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x25, 0x33, 0x36, 0x30, + 0x2a, 0x44, 0x61, 0x2c, 0x72, 0x28, 0x29, 0x29, 0x3a, 0x5b, 0x76, + 0x2a, 0x50, 0x61, 0x2c, 0x64, 0x2a, 0x50, 0x61, 0x5d, 0x7d, 0x2c, + 0x74, 0x2e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x6d, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x25, 0x33, 0x36, + 0x30, 0x2a, 0x44, 0x61, 0x2c, 0x4d, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, + 0x25, 0x33, 0x36, 0x30, 0x2a, 0x44, 0x61, 0x2c, 0x78, 0x3d, 0x6e, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x32, 0x3f, 0x6e, + 0x5b, 0x32, 0x5d, 0x25, 0x33, 0x36, 0x30, 0x2a, 0x44, 0x61, 0x3a, + 0x30, 0x2c, 0x72, 0x28, 0x29, 0x29, 0x3a, 0x5b, 0x6d, 0x2a, 0x50, + 0x61, 0x2c, 0x4d, 0x2a, 0x50, 0x61, 0x2c, 0x78, 0x2a, 0x50, 0x61, + 0x5d, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x62, 0x69, 0x6e, + 0x64, 0x28, 0x74, 0x2c, 0x66, 0x2c, 0x22, 0x70, 0x72, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x69, 0x3d, 0x6e, 0x2e, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x2c, 0x74, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, 0x69, 0x2e, 0x69, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x26, 0x26, 0x65, 0x2c, 0x72, 0x28, 0x29, 0x7d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x72, 0x72, 0x28, 0x6e, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x6e, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x74, 0x2a, 0x44, 0x61, 0x2c, + 0x65, 0x2a, 0x44, 0x61, 0x29, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x72, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, + 0x2c, 0x74, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x63, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x3e, 0x71, 0x61, 0x3f, + 0x6e, 0x2d, 0x4c, 0x61, 0x3a, 0x2d, 0x71, 0x61, 0x3e, 0x6e, 0x3f, + 0x6e, 0x2b, 0x4c, 0x61, 0x3a, 0x6e, 0x2c, 0x74, 0x5d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x72, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x3f, 0x74, 0x7c, 0x7c, 0x65, 0x3f, 0x41, + 0x65, 0x28, 0x66, 0x72, 0x28, 0x6e, 0x29, 0x2c, 0x68, 0x72, 0x28, + 0x74, 0x2c, 0x65, 0x29, 0x29, 0x3a, 0x66, 0x72, 0x28, 0x6e, 0x29, + 0x3a, 0x74, 0x7c, 0x7c, 0x65, 0x3f, 0x68, 0x72, 0x28, 0x74, 0x2c, + 0x65, 0x29, 0x3a, 0x63, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2b, 0x3d, 0x6e, 0x2c, 0x5b, + 0x74, 0x3e, 0x71, 0x61, 0x3f, 0x74, 0x2d, 0x4c, 0x61, 0x3a, 0x2d, + 0x71, 0x61, 0x3e, 0x74, 0x3f, 0x74, 0x2b, 0x4c, 0x61, 0x3a, 0x74, + 0x2c, 0x65, 0x5d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x66, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x73, 0x72, 0x28, 0x6e, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x69, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x3d, 0x73, 0x72, 0x28, 0x2d, 0x6e, 0x29, 0x2c, + 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x68, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x29, 0x2c, 0x61, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, + 0x2a, 0x65, 0x2c, 0x63, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x69, 0x6e, 0x28, 0x6e, 0x29, 0x2a, 0x65, 0x2c, 0x6c, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x2c, + 0x73, 0x3d, 0x6c, 0x2a, 0x72, 0x2b, 0x61, 0x2a, 0x75, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x63, 0x2a, 0x69, 0x2d, 0x73, + 0x2a, 0x6f, 0x2c, 0x61, 0x2a, 0x72, 0x2d, 0x6c, 0x2a, 0x75, 0x29, + 0x2c, 0x74, 0x74, 0x28, 0x73, 0x2a, 0x69, 0x2b, 0x63, 0x2a, 0x6f, + 0x29, 0x5d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x2c, 0x75, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, + 0x29, 0x2c, 0x69, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, + 0x73, 0x28, 0x74, 0x29, 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, + 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x29, + 0x2c, 0x61, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, + 0x28, 0x6e, 0x29, 0x2a, 0x65, 0x2c, 0x63, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x29, 0x2a, 0x65, 0x2c, + 0x6c, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x74, 0x29, 0x2c, 0x73, 0x3d, 0x6c, 0x2a, 0x69, 0x2d, 0x63, 0x2a, + 0x6f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x63, 0x2a, + 0x69, 0x2b, 0x6c, 0x2a, 0x6f, 0x2c, 0x61, 0x2a, 0x72, 0x2b, 0x73, + 0x2a, 0x75, 0x29, 0x2c, 0x74, 0x74, 0x28, 0x73, 0x2a, 0x72, 0x2d, + 0x61, 0x2a, 0x75, 0x29, 0x5d, 0x7d, 0x2c, 0x65, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x72, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x2c, + 0x72, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x2c, 0x69, + 0x2c, 0x6f, 0x2c, 0x61, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x63, + 0x3d, 0x6f, 0x2a, 0x74, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, + 0x75, 0x3f, 0x28, 0x75, 0x3d, 0x70, 0x72, 0x28, 0x65, 0x2c, 0x75, + 0x29, 0x2c, 0x69, 0x3d, 0x70, 0x72, 0x28, 0x65, 0x2c, 0x69, 0x29, + 0x2c, 0x28, 0x6f, 0x3e, 0x30, 0x3f, 0x69, 0x3e, 0x75, 0x3a, 0x75, + 0x3e, 0x69, 0x29, 0x26, 0x26, 0x28, 0x75, 0x2b, 0x3d, 0x6f, 0x2a, + 0x4c, 0x61, 0x29, 0x29, 0x3a, 0x28, 0x75, 0x3d, 0x6e, 0x2b, 0x6f, + 0x2a, 0x4c, 0x61, 0x2c, 0x69, 0x3d, 0x6e, 0x2d, 0x2e, 0x35, 0x2a, + 0x63, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x6c, 0x2c, 0x73, 0x3d, 0x75, 0x3b, 0x6f, 0x3e, 0x30, 0x3f, 0x73, + 0x3e, 0x69, 0x3a, 0x69, 0x3e, 0x73, 0x3b, 0x73, 0x2d, 0x3d, 0x63, + 0x29, 0x61, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x28, 0x6c, + 0x3d, 0x78, 0x65, 0x28, 0x5b, 0x65, 0x2c, 0x2d, 0x72, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x73, 0x29, 0x2c, + 0x2d, 0x72, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, + 0x28, 0x73, 0x29, 0x5d, 0x29, 0x29, 0x5b, 0x30, 0x5d, 0x2c, 0x6c, + 0x5b, 0x31, 0x5d, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x70, 0x65, 0x28, 0x74, + 0x29, 0x3b, 0x65, 0x5b, 0x30, 0x5d, 0x2d, 0x3d, 0x6e, 0x2c, 0x4d, + 0x65, 0x28, 0x65, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, + 0x6e, 0x74, 0x28, 0x2d, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x28, 0x2d, 0x65, 0x5b, 0x32, + 0x5d, 0x3c, 0x30, 0x3f, 0x2d, 0x72, 0x3a, 0x72, 0x29, 0x2b, 0x32, + 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x50, 0x49, 0x2d, 0x43, 0x61, + 0x29, 0x25, 0x28, 0x32, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x50, + 0x49, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x76, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x61, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2d, 0x43, 0x61, 0x2c, + 0x65, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x2c, + 0x74, 0x5d, 0x7d, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x61, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2d, + 0x43, 0x61, 0x2c, 0x65, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, + 0x74, 0x28, 0x74, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x5b, 0x74, 0x2c, 0x6e, 0x5d, 0x7d, 0x29, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x72, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x72, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x4d, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x29, 0x2c, + 0x69, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x74, 0x29, 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, + 0x6f, 0x73, 0x28, 0x72, 0x29, 0x2c, 0x61, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x72, 0x29, 0x2c, 0x63, 0x3d, + 0x75, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, + 0x6e, 0x29, 0x2c, 0x6c, 0x3d, 0x75, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x29, 0x2c, 0x73, 0x3d, 0x6f, + 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x65, + 0x29, 0x2c, 0x66, 0x3d, 0x6f, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x73, 0x69, 0x6e, 0x28, 0x65, 0x29, 0x2c, 0x68, 0x3d, 0x32, 0x2a, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x73, 0x69, 0x6e, 0x28, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x69, 0x74, + 0x28, 0x72, 0x2d, 0x74, 0x29, 0x2b, 0x75, 0x2a, 0x6f, 0x2a, 0x69, + 0x74, 0x28, 0x65, 0x2d, 0x6e, 0x29, 0x29, 0x29, 0x2c, 0x67, 0x3d, + 0x31, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x68, 0x29, 0x2c, 0x70, 0x3d, 0x68, 0x3f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, + 0x28, 0x6e, 0x2a, 0x3d, 0x68, 0x29, 0x2a, 0x67, 0x2c, 0x65, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x68, 0x2d, + 0x6e, 0x29, 0x2a, 0x67, 0x2c, 0x72, 0x3d, 0x65, 0x2a, 0x63, 0x2b, + 0x74, 0x2a, 0x73, 0x2c, 0x75, 0x3d, 0x65, 0x2a, 0x6c, 0x2b, 0x74, + 0x2a, 0x66, 0x2c, 0x6f, 0x3d, 0x65, 0x2a, 0x69, 0x2b, 0x74, 0x2a, + 0x61, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x75, 0x2c, + 0x72, 0x29, 0x2a, 0x50, 0x61, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x6f, 0x2c, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x72, 0x2a, 0x72, 0x2b, + 0x75, 0x2a, 0x75, 0x29, 0x29, 0x2a, 0x50, 0x61, 0x5d, 0x7d, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x2a, 0x50, 0x61, + 0x2c, 0x74, 0x2a, 0x50, 0x61, 0x5d, 0x7d, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x70, 0x2e, 0x64, 0x69, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x3d, 0x68, 0x2c, 0x70, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x78, 0x72, 0x28, 0x29, 0x7b, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, + 0x6e, 0x2c, 0x75, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x75, 0x2a, + 0x3d, 0x44, 0x61, 0x29, 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x75, 0x29, 0x2c, 0x61, 0x3d, 0x67, + 0x61, 0x28, 0x28, 0x6e, 0x2a, 0x3d, 0x44, 0x61, 0x29, 0x2d, 0x74, + 0x29, 0x2c, 0x63, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, + 0x73, 0x28, 0x61, 0x29, 0x3b, 0x59, 0x63, 0x2b, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x28, 0x61, 0x3d, + 0x6f, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x61, 0x29, 0x29, 0x2a, 0x61, 0x2b, 0x28, 0x61, 0x3d, 0x72, 0x2a, + 0x69, 0x2d, 0x65, 0x2a, 0x6f, 0x2a, 0x63, 0x29, 0x2a, 0x61, 0x29, + 0x2c, 0x65, 0x2a, 0x69, 0x2b, 0x72, 0x2a, 0x6f, 0x2a, 0x63, 0x29, + 0x2c, 0x74, 0x3d, 0x6e, 0x2c, 0x65, 0x3d, 0x69, 0x2c, 0x72, 0x3d, + 0x6f, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, + 0x3b, 0x5a, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x2c, 0x69, + 0x29, 0x7b, 0x74, 0x3d, 0x75, 0x2a, 0x44, 0x61, 0x2c, 0x65, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x69, 0x2a, + 0x3d, 0x44, 0x61, 0x29, 0x2c, 0x72, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x69, 0x29, 0x2c, 0x5a, 0x63, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, 0x7d, 0x2c, 0x5a, 0x63, + 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x5a, 0x63, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x5a, 0x63, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x62, 0x7d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, + 0x6f, 0x73, 0x28, 0x74, 0x29, 0x2c, 0x75, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x65, 0x29, 0x2c, 0x69, 0x3d, + 0x6e, 0x28, 0x72, 0x2a, 0x75, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x5b, 0x69, 0x2a, 0x75, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x74, 0x29, 0x2c, 0x69, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x65, 0x29, 0x5d, + 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x72, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x6e, 0x2a, 0x6e, 0x2b, 0x65, 0x2a, 0x65, 0x29, + 0x2c, 0x75, 0x3d, 0x74, 0x28, 0x72, 0x29, 0x2c, 0x69, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x75, 0x29, 0x2c, + 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, + 0x75, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x6e, + 0x2a, 0x69, 0x2c, 0x72, 0x2a, 0x6f, 0x29, 0x2c, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x61, 0x73, 0x69, 0x6e, 0x28, 0x72, 0x26, 0x26, 0x65, + 0x2a, 0x69, 0x2f, 0x72, 0x29, 0x5d, 0x7d, 0x2c, 0x65, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x72, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6f, + 0x3e, 0x30, 0x3f, 0x2d, 0x52, 0x61, 0x2b, 0x43, 0x61, 0x3e, 0x74, + 0x26, 0x26, 0x28, 0x74, 0x3d, 0x2d, 0x52, 0x61, 0x2b, 0x43, 0x61, + 0x29, 0x3a, 0x74, 0x3e, 0x52, 0x61, 0x2d, 0x43, 0x61, 0x26, 0x26, + 0x28, 0x74, 0x3d, 0x52, 0x61, 0x2d, 0x43, 0x61, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6f, 0x2f, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x75, 0x28, 0x74, 0x29, 0x2c, 0x69, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x65, 0x2a, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x69, 0x2a, + 0x6e, 0x29, 0x2c, 0x6f, 0x2d, 0x65, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x69, 0x2a, 0x6e, 0x29, 0x5d, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x2c, 0x75, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x74, 0x61, 0x6e, 0x28, 0x71, 0x61, 0x2f, 0x34, 0x2b, 0x6e, 0x2f, + 0x32, 0x29, 0x7d, 0x2c, 0x69, 0x3d, 0x6e, 0x3d, 0x3d, 0x3d, 0x74, + 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, + 0x29, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, + 0x72, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, + 0x74, 0x29, 0x29, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, + 0x67, 0x28, 0x75, 0x28, 0x74, 0x29, 0x2f, 0x75, 0x28, 0x6e, 0x29, + 0x29, 0x2c, 0x6f, 0x3d, 0x72, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x70, 0x6f, 0x77, 0x28, 0x75, 0x28, 0x6e, 0x29, 0x2c, 0x69, 0x29, + 0x2f, 0x69, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, + 0x3f, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6f, 0x2d, + 0x74, 0x2c, 0x72, 0x3d, 0x4b, 0x28, 0x69, 0x29, 0x2a, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x6e, 0x2a, 0x6e, + 0x2b, 0x65, 0x2a, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x5b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, + 0x32, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x2f, 0x69, 0x2c, 0x32, 0x2a, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x28, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x6f, 0x2f, 0x72, + 0x2c, 0x31, 0x2f, 0x69, 0x29, 0x29, 0x2d, 0x52, 0x61, 0x5d, 0x7d, + 0x2c, 0x65, 0x29, 0x3a, 0x53, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x72, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x69, 0x2d, 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x5b, 0x65, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, + 0x6e, 0x28, 0x75, 0x2a, 0x6e, 0x29, 0x2c, 0x69, 0x2d, 0x65, 0x2a, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x75, 0x2a, + 0x6e, 0x29, 0x5d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, 0x2c, + 0x75, 0x3d, 0x6e, 0x3d, 0x3d, 0x3d, 0x74, 0x3f, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6e, 0x29, 0x3a, 0x28, 0x72, + 0x2d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x74, + 0x29, 0x29, 0x2f, 0x28, 0x74, 0x2d, 0x6e, 0x29, 0x2c, 0x69, 0x3d, + 0x72, 0x2f, 0x75, 0x2b, 0x6e, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x67, 0x61, 0x28, 0x75, 0x29, 0x3c, 0x43, 0x61, 0x3f, + 0x61, 0x72, 0x3a, 0x28, 0x65, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, + 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x69, 0x2d, 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, + 0x6e, 0x2c, 0x65, 0x29, 0x2f, 0x75, 0x2c, 0x69, 0x2d, 0x4b, 0x28, + 0x75, 0x29, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, + 0x74, 0x28, 0x6e, 0x2a, 0x6e, 0x2b, 0x65, 0x2a, 0x65, 0x29, 0x5d, + 0x7d, 0x2c, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x53, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x2c, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x74, 0x61, 0x6e, 0x28, 0x71, 0x61, 0x2f, 0x34, 0x2b, 0x74, + 0x2f, 0x32, 0x29, 0x29, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6b, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x75, 0x72, 0x28, 0x6e, + 0x29, 0x2c, 0x72, 0x3d, 0x65, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2c, 0x75, 0x3d, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, + 0x61, 0x74, 0x65, 0x2c, 0x69, 0x3d, 0x65, 0x2e, 0x63, 0x6c, 0x69, + 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x72, 0x2e, 0x61, 0x70, + 0x70, 0x6c, 0x79, 0x28, 0x65, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x3d, 0x3d, 0x3d, 0x65, 0x3f, 0x74, 0x3f, 0x65, + 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, + 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3a, 0x65, 0x3a, 0x6e, 0x7d, + 0x2c, 0x65, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x75, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x65, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x3d, 0x3d, 0x65, 0x3f, 0x74, 0x3f, + 0x65, 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3a, 0x65, 0x3a, 0x6e, + 0x7d, 0x2c, 0x65, 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, + 0x69, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x65, 0x2c, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x69, + 0x66, 0x28, 0x6f, 0x3d, 0x3d, 0x3d, 0x65, 0x29, 0x7b, 0x69, 0x66, + 0x28, 0x74, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x71, 0x61, 0x2a, 0x72, + 0x28, 0x29, 0x2c, 0x63, 0x3d, 0x75, 0x28, 0x29, 0x3b, 0x69, 0x28, + 0x5b, 0x5b, 0x63, 0x5b, 0x30, 0x5d, 0x2d, 0x61, 0x2c, 0x63, 0x5b, + 0x31, 0x5d, 0x2d, 0x61, 0x5d, 0x2c, 0x5b, 0x63, 0x5b, 0x30, 0x5d, + 0x2b, 0x61, 0x2c, 0x63, 0x5b, 0x31, 0x5d, 0x2b, 0x61, 0x5d, 0x5d, + 0x29, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x74, 0x26, 0x26, + 0x28, 0x6f, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x2c, 0x65, 0x2e, 0x63, + 0x6c, 0x69, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x28, 0x6e, + 0x75, 0x6c, 0x6c, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x45, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x74, + 0x61, 0x6e, 0x28, 0x71, 0x61, 0x2f, 0x34, 0x2b, 0x74, 0x2f, 0x32, + 0x29, 0x29, 0x2c, 0x2d, 0x6e, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x72, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x5b, 0x30, 0x5d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, + 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x5b, 0x31, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x65, 0x3d, 0x5b, 0x30, + 0x2c, 0x31, 0x5d, 0x2c, 0x72, 0x3d, 0x32, 0x2c, 0x75, 0x3d, 0x32, + 0x3b, 0x74, 0x3e, 0x75, 0x3b, 0x75, 0x2b, 0x2b, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x3b, 0x72, 0x3e, 0x31, 0x26, 0x26, 0x51, 0x28, + 0x6e, 0x5b, 0x65, 0x5b, 0x72, 0x2d, 0x32, 0x5d, 0x5d, 0x2c, 0x6e, + 0x5b, 0x65, 0x5b, 0x72, 0x2d, 0x31, 0x5d, 0x5d, 0x2c, 0x6e, 0x5b, + 0x75, 0x5d, 0x29, 0x3c, 0x3d, 0x30, 0x3b, 0x29, 0x2d, 0x2d, 0x72, + 0x3b, 0x65, 0x5b, 0x72, 0x2b, 0x2b, 0x5d, 0x3d, 0x75, 0x7d, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x73, 0x6c, 0x69, + 0x63, 0x65, 0x28, 0x30, 0x2c, 0x72, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x72, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x5b, 0x30, 0x5d, 0x2d, 0x74, 0x5b, 0x30, 0x5d, 0x7c, 0x7c, 0x6e, + 0x5b, 0x31, 0x5d, 0x2d, 0x74, 0x5b, 0x31, 0x5d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x71, 0x72, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x2d, 0x74, 0x5b, 0x30, 0x5d, + 0x29, 0x2a, 0x28, 0x6e, 0x5b, 0x31, 0x5d, 0x2d, 0x74, 0x5b, 0x31, + 0x5d, 0x29, 0x3c, 0x28, 0x65, 0x5b, 0x31, 0x5d, 0x2d, 0x74, 0x5b, + 0x31, 0x5d, 0x29, 0x2a, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2d, 0x74, + 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x4c, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x6e, + 0x5b, 0x30, 0x5d, 0x2c, 0x69, 0x3d, 0x65, 0x5b, 0x30, 0x5d, 0x2c, + 0x6f, 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x2d, 0x75, 0x2c, 0x61, 0x3d, + 0x72, 0x5b, 0x30, 0x5d, 0x2d, 0x69, 0x2c, 0x63, 0x3d, 0x6e, 0x5b, + 0x31, 0x5d, 0x2c, 0x6c, 0x3d, 0x65, 0x5b, 0x31, 0x5d, 0x2c, 0x73, + 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2d, 0x63, 0x2c, 0x66, 0x3d, 0x72, + 0x5b, 0x31, 0x5d, 0x2d, 0x6c, 0x2c, 0x68, 0x3d, 0x28, 0x61, 0x2a, + 0x28, 0x63, 0x2d, 0x6c, 0x29, 0x2d, 0x66, 0x2a, 0x28, 0x75, 0x2d, + 0x69, 0x29, 0x29, 0x2f, 0x28, 0x66, 0x2a, 0x6f, 0x2d, 0x61, 0x2a, + 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x75, + 0x2b, 0x68, 0x2a, 0x6f, 0x2c, 0x63, 0x2b, 0x68, 0x2a, 0x73, 0x5d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, + 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x3d, 0x6e, 0x5b, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x28, 0x74, 0x5b, 0x30, 0x5d, + 0x2d, 0x65, 0x5b, 0x30, 0x5d, 0x7c, 0x7c, 0x74, 0x5b, 0x31, 0x5d, + 0x2d, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x72, 0x28, 0x29, 0x7b, 0x74, + 0x75, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x69, 0x74, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x44, + 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x65, 0x6c, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x7c, 0x7c, 0x6e, + 0x65, 0x77, 0x20, 0x52, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x3d, 0x6e, 0x2c, + 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x50, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x58, 0x72, 0x28, 0x6e, 0x29, + 0x2c, 0x51, 0x63, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, + 0x6e, 0x29, 0x2c, 0x65, 0x6c, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x6e, 0x29, 0x2c, 0x74, 0x75, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x72, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x63, + 0x69, 0x72, 0x63, 0x6c, 0x65, 0x2c, 0x65, 0x3d, 0x74, 0x2e, 0x78, + 0x2c, 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x79, 0x2c, 0x75, 0x3d, 0x7b, + 0x78, 0x3a, 0x65, 0x2c, 0x79, 0x3a, 0x72, 0x7d, 0x2c, 0x69, 0x3d, + 0x6e, 0x2e, 0x50, 0x2c, 0x6f, 0x3d, 0x6e, 0x2e, 0x4e, 0x2c, 0x61, + 0x3d, 0x5b, 0x6e, 0x5d, 0x3b, 0x50, 0x72, 0x28, 0x6e, 0x29, 0x3b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, 0x69, + 0x3b, 0x63, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x26, 0x26, + 0x67, 0x61, 0x28, 0x65, 0x2d, 0x63, 0x2e, 0x63, 0x69, 0x72, 0x63, + 0x6c, 0x65, 0x2e, 0x78, 0x29, 0x3c, 0x43, 0x61, 0x26, 0x26, 0x67, + 0x61, 0x28, 0x72, 0x2d, 0x63, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x6c, + 0x65, 0x2e, 0x63, 0x79, 0x29, 0x3c, 0x43, 0x61, 0x3b, 0x29, 0x69, + 0x3d, 0x63, 0x2e, 0x50, 0x2c, 0x61, 0x2e, 0x75, 0x6e, 0x73, 0x68, + 0x69, 0x66, 0x74, 0x28, 0x63, 0x29, 0x2c, 0x50, 0x72, 0x28, 0x63, + 0x29, 0x2c, 0x63, 0x3d, 0x69, 0x3b, 0x61, 0x2e, 0x75, 0x6e, 0x73, + 0x68, 0x69, 0x66, 0x74, 0x28, 0x63, 0x29, 0x2c, 0x58, 0x72, 0x28, + 0x63, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x6c, 0x3d, 0x6f, 0x3b, 0x6c, 0x2e, 0x63, 0x69, 0x72, 0x63, 0x6c, + 0x65, 0x26, 0x26, 0x67, 0x61, 0x28, 0x65, 0x2d, 0x6c, 0x2e, 0x63, + 0x69, 0x72, 0x63, 0x6c, 0x65, 0x2e, 0x78, 0x29, 0x3c, 0x43, 0x61, + 0x26, 0x26, 0x67, 0x61, 0x28, 0x72, 0x2d, 0x6c, 0x2e, 0x63, 0x69, + 0x72, 0x63, 0x6c, 0x65, 0x2e, 0x63, 0x79, 0x29, 0x3c, 0x43, 0x61, + 0x3b, 0x29, 0x6f, 0x3d, 0x6c, 0x2e, 0x4e, 0x2c, 0x61, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x6c, 0x29, 0x2c, 0x50, 0x72, 0x28, 0x6c, + 0x29, 0x2c, 0x6c, 0x3d, 0x6f, 0x3b, 0x61, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x6c, 0x29, 0x2c, 0x58, 0x72, 0x28, 0x6c, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x73, 0x2c, 0x66, 0x3d, 0x61, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x73, + 0x3d, 0x31, 0x3b, 0x66, 0x3e, 0x73, 0x3b, 0x2b, 0x2b, 0x73, 0x29, + 0x6c, 0x3d, 0x61, 0x5b, 0x73, 0x5d, 0x2c, 0x63, 0x3d, 0x61, 0x5b, + 0x73, 0x2d, 0x31, 0x5d, 0x2c, 0x4b, 0x72, 0x28, 0x6c, 0x2e, 0x65, + 0x64, 0x67, 0x65, 0x2c, 0x63, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, + 0x6c, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, 0x75, 0x29, 0x3b, 0x63, + 0x3d, 0x61, 0x5b, 0x30, 0x5d, 0x2c, 0x6c, 0x3d, 0x61, 0x5b, 0x66, + 0x2d, 0x31, 0x5d, 0x2c, 0x6c, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x3d, + 0x4a, 0x72, 0x28, 0x63, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, 0x6c, + 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, + 0x75, 0x29, 0x2c, 0x56, 0x72, 0x28, 0x63, 0x29, 0x2c, 0x56, 0x72, + 0x28, 0x6c, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6a, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, + 0x75, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x78, 0x2c, 0x6f, 0x3d, 0x6e, + 0x2e, 0x79, 0x2c, 0x61, 0x3d, 0x51, 0x63, 0x2e, 0x5f, 0x3b, 0x61, + 0x3b, 0x29, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x46, 0x72, 0x28, 0x61, + 0x2c, 0x6f, 0x29, 0x2d, 0x69, 0x2c, 0x72, 0x3e, 0x43, 0x61, 0x29, + 0x61, 0x3d, 0x61, 0x2e, 0x4c, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x7b, + 0x69, 0x66, 0x28, 0x75, 0x3d, 0x69, 0x2d, 0x48, 0x72, 0x28, 0x61, + 0x2c, 0x6f, 0x29, 0x2c, 0x21, 0x28, 0x75, 0x3e, 0x43, 0x61, 0x29, + 0x29, 0x7b, 0x72, 0x3e, 0x2d, 0x43, 0x61, 0x3f, 0x28, 0x74, 0x3d, + 0x61, 0x2e, 0x50, 0x2c, 0x65, 0x3d, 0x61, 0x29, 0x3a, 0x75, 0x3e, + 0x2d, 0x43, 0x61, 0x3f, 0x28, 0x74, 0x3d, 0x61, 0x2c, 0x65, 0x3d, + 0x61, 0x2e, 0x4e, 0x29, 0x3a, 0x74, 0x3d, 0x65, 0x3d, 0x61, 0x3b, + 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x69, 0x66, 0x28, 0x21, 0x61, + 0x2e, 0x52, 0x29, 0x7b, 0x74, 0x3d, 0x61, 0x3b, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x7d, 0x61, 0x3d, 0x61, 0x2e, 0x52, 0x7d, 0x76, 0x61, + 0x72, 0x20, 0x63, 0x3d, 0x44, 0x72, 0x28, 0x6e, 0x29, 0x3b, 0x69, + 0x66, 0x28, 0x51, 0x63, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, + 0x28, 0x74, 0x2c, 0x63, 0x29, 0x2c, 0x74, 0x7c, 0x7c, 0x65, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x3d, 0x3d, 0x65, 0x29, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x58, 0x72, 0x28, 0x74, 0x29, + 0x2c, 0x65, 0x3d, 0x44, 0x72, 0x28, 0x74, 0x2e, 0x73, 0x69, 0x74, + 0x65, 0x29, 0x2c, 0x51, 0x63, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, + 0x74, 0x28, 0x63, 0x2c, 0x65, 0x29, 0x2c, 0x63, 0x2e, 0x65, 0x64, + 0x67, 0x65, 0x3d, 0x65, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x3d, 0x4a, + 0x72, 0x28, 0x74, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, 0x63, 0x2e, + 0x73, 0x69, 0x74, 0x65, 0x29, 0x2c, 0x56, 0x72, 0x28, 0x74, 0x29, + 0x2c, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x56, 0x72, 0x28, 0x65, 0x29, + 0x3b, 0x69, 0x66, 0x28, 0x21, 0x65, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x63, 0x2e, 0x65, + 0x64, 0x67, 0x65, 0x3d, 0x4a, 0x72, 0x28, 0x74, 0x2e, 0x73, 0x69, + 0x74, 0x65, 0x2c, 0x63, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x29, 0x29, + 0x3b, 0x58, 0x72, 0x28, 0x74, 0x29, 0x2c, 0x58, 0x72, 0x28, 0x65, + 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x74, 0x2e, 0x73, + 0x69, 0x74, 0x65, 0x2c, 0x73, 0x3d, 0x6c, 0x2e, 0x78, 0x2c, 0x66, + 0x3d, 0x6c, 0x2e, 0x79, 0x2c, 0x68, 0x3d, 0x6e, 0x2e, 0x78, 0x2d, + 0x73, 0x2c, 0x67, 0x3d, 0x6e, 0x2e, 0x79, 0x2d, 0x66, 0x2c, 0x70, + 0x3d, 0x65, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, 0x76, 0x3d, 0x70, + 0x2e, 0x78, 0x2d, 0x73, 0x2c, 0x64, 0x3d, 0x70, 0x2e, 0x79, 0x2d, + 0x66, 0x2c, 0x6d, 0x3d, 0x32, 0x2a, 0x28, 0x68, 0x2a, 0x64, 0x2d, + 0x67, 0x2a, 0x76, 0x29, 0x2c, 0x79, 0x3d, 0x68, 0x2a, 0x68, 0x2b, + 0x67, 0x2a, 0x67, 0x2c, 0x4d, 0x3d, 0x76, 0x2a, 0x76, 0x2b, 0x64, + 0x2a, 0x64, 0x2c, 0x78, 0x3d, 0x7b, 0x78, 0x3a, 0x28, 0x64, 0x2a, + 0x79, 0x2d, 0x67, 0x2a, 0x4d, 0x29, 0x2f, 0x6d, 0x2b, 0x73, 0x2c, + 0x79, 0x3a, 0x28, 0x68, 0x2a, 0x4d, 0x2d, 0x76, 0x2a, 0x79, 0x29, + 0x2f, 0x6d, 0x2b, 0x66, 0x7d, 0x3b, 0x4b, 0x72, 0x28, 0x65, 0x2e, + 0x65, 0x64, 0x67, 0x65, 0x2c, 0x6c, 0x2c, 0x70, 0x2c, 0x78, 0x29, + 0x2c, 0x63, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x3d, 0x4a, 0x72, 0x28, + 0x6c, 0x2c, 0x6e, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x78, 0x29, + 0x2c, 0x65, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x3d, 0x4a, 0x72, 0x28, + 0x6e, 0x2c, 0x70, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x78, 0x29, + 0x2c, 0x56, 0x72, 0x28, 0x74, 0x29, 0x2c, 0x56, 0x72, 0x28, 0x65, + 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x46, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, + 0x72, 0x3d, 0x65, 0x2e, 0x78, 0x2c, 0x75, 0x3d, 0x65, 0x2e, 0x79, + 0x2c, 0x69, 0x3d, 0x75, 0x2d, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x21, + 0x69, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x6e, 0x2e, 0x50, 0x3b, 0x69, + 0x66, 0x28, 0x21, 0x6f, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x2d, 0x31, 0x2f, 0x30, 0x3b, 0x65, 0x3d, 0x6f, 0x2e, 0x73, 0x69, + 0x74, 0x65, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x65, 0x2e, + 0x78, 0x2c, 0x63, 0x3d, 0x65, 0x2e, 0x79, 0x2c, 0x6c, 0x3d, 0x63, + 0x2d, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x6c, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x3d, 0x61, 0x2d, 0x72, 0x2c, 0x66, 0x3d, 0x31, 0x2f, 0x69, + 0x2d, 0x31, 0x2f, 0x6c, 0x2c, 0x68, 0x3d, 0x73, 0x2f, 0x6c, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x3f, 0x28, 0x2d, + 0x68, 0x2b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, + 0x28, 0x68, 0x2a, 0x68, 0x2d, 0x32, 0x2a, 0x66, 0x2a, 0x28, 0x73, + 0x2a, 0x73, 0x2f, 0x28, 0x2d, 0x32, 0x2a, 0x6c, 0x29, 0x2d, 0x63, + 0x2b, 0x6c, 0x2f, 0x32, 0x2b, 0x75, 0x2d, 0x69, 0x2f, 0x32, 0x29, + 0x29, 0x29, 0x2f, 0x66, 0x2b, 0x72, 0x3a, 0x28, 0x72, 0x2b, 0x61, + 0x29, 0x2f, 0x32, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x48, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x4e, 0x3b, 0x69, 0x66, + 0x28, 0x65, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x46, + 0x72, 0x28, 0x65, 0x2c, 0x74, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x6e, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2e, 0x79, 0x3d, 0x3d, 0x3d, + 0x74, 0x3f, 0x72, 0x2e, 0x78, 0x3a, 0x31, 0x2f, 0x30, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x72, 0x28, + 0x6e, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x69, 0x74, + 0x65, 0x3d, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x64, + 0x67, 0x65, 0x73, 0x3d, 0x5b, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x72, 0x28, 0x6e, 0x29, 0x7b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, + 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, 0x2c, + 0x63, 0x2c, 0x6c, 0x2c, 0x73, 0x2c, 0x66, 0x3d, 0x6e, 0x5b, 0x30, + 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x68, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, + 0x5b, 0x30, 0x5d, 0x2c, 0x67, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x5b, + 0x31, 0x5d, 0x2c, 0x70, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x5b, 0x31, + 0x5d, 0x2c, 0x76, 0x3d, 0x4b, 0x63, 0x2c, 0x64, 0x3d, 0x76, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x64, 0x2d, 0x2d, 0x3b, + 0x29, 0x69, 0x66, 0x28, 0x69, 0x3d, 0x76, 0x5b, 0x64, 0x5d, 0x2c, + 0x69, 0x26, 0x26, 0x69, 0x2e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x28, 0x29, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x61, 0x3d, 0x69, + 0x2e, 0x65, 0x64, 0x67, 0x65, 0x73, 0x2c, 0x63, 0x3d, 0x61, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x6f, 0x3d, 0x30, 0x3b, + 0x63, 0x3e, 0x6f, 0x3b, 0x29, 0x73, 0x3d, 0x61, 0x5b, 0x6f, 0x5d, + 0x2e, 0x65, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x72, 0x3d, 0x73, 0x2e, + 0x78, 0x2c, 0x75, 0x3d, 0x73, 0x2e, 0x79, 0x2c, 0x6c, 0x3d, 0x61, + 0x5b, 0x2b, 0x2b, 0x6f, 0x25, 0x63, 0x5d, 0x2e, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x28, 0x29, 0x2c, 0x74, 0x3d, 0x6c, 0x2e, 0x78, 0x2c, + 0x65, 0x3d, 0x6c, 0x2e, 0x79, 0x2c, 0x28, 0x67, 0x61, 0x28, 0x72, + 0x2d, 0x74, 0x29, 0x3e, 0x43, 0x61, 0x7c, 0x7c, 0x67, 0x61, 0x28, + 0x75, 0x2d, 0x65, 0x29, 0x3e, 0x43, 0x61, 0x29, 0x26, 0x26, 0x28, + 0x61, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x6f, 0x2c, + 0x30, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x51, 0x72, 0x28, 0x47, 0x72, + 0x28, 0x69, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, 0x73, 0x2c, 0x67, + 0x61, 0x28, 0x72, 0x2d, 0x66, 0x29, 0x3c, 0x43, 0x61, 0x26, 0x26, + 0x70, 0x2d, 0x75, 0x3e, 0x43, 0x61, 0x3f, 0x7b, 0x78, 0x3a, 0x66, + 0x2c, 0x79, 0x3a, 0x67, 0x61, 0x28, 0x74, 0x2d, 0x66, 0x29, 0x3c, + 0x43, 0x61, 0x3f, 0x65, 0x3a, 0x70, 0x7d, 0x3a, 0x67, 0x61, 0x28, + 0x75, 0x2d, 0x70, 0x29, 0x3c, 0x43, 0x61, 0x26, 0x26, 0x68, 0x2d, + 0x72, 0x3e, 0x43, 0x61, 0x3f, 0x7b, 0x78, 0x3a, 0x67, 0x61, 0x28, + 0x65, 0x2d, 0x70, 0x29, 0x3c, 0x43, 0x61, 0x3f, 0x74, 0x3a, 0x68, + 0x2c, 0x79, 0x3a, 0x70, 0x7d, 0x3a, 0x67, 0x61, 0x28, 0x72, 0x2d, + 0x68, 0x29, 0x3c, 0x43, 0x61, 0x26, 0x26, 0x75, 0x2d, 0x67, 0x3e, + 0x43, 0x61, 0x3f, 0x7b, 0x78, 0x3a, 0x68, 0x2c, 0x79, 0x3a, 0x67, + 0x61, 0x28, 0x74, 0x2d, 0x68, 0x29, 0x3c, 0x43, 0x61, 0x3f, 0x65, + 0x3a, 0x67, 0x7d, 0x3a, 0x67, 0x61, 0x28, 0x75, 0x2d, 0x67, 0x29, + 0x3c, 0x43, 0x61, 0x26, 0x26, 0x72, 0x2d, 0x66, 0x3e, 0x43, 0x61, + 0x3f, 0x7b, 0x78, 0x3a, 0x67, 0x61, 0x28, 0x65, 0x2d, 0x67, 0x29, + 0x3c, 0x43, 0x61, 0x3f, 0x74, 0x3a, 0x66, 0x2c, 0x79, 0x3a, 0x67, + 0x7d, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x69, 0x2e, 0x73, + 0x69, 0x74, 0x65, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x29, 0x2c, + 0x2b, 0x2b, 0x63, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x59, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x61, 0x6e, + 0x67, 0x6c, 0x65, 0x2d, 0x6e, 0x2e, 0x61, 0x6e, 0x67, 0x6c, 0x65, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5a, + 0x72, 0x28, 0x29, 0x7b, 0x74, 0x75, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x78, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x79, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, + 0x72, 0x63, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x69, 0x74, + 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x79, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x56, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x50, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, + 0x4e, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x26, 0x26, 0x65, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x73, 0x69, 0x74, + 0x65, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, + 0x69, 0x3d, 0x65, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x3b, 0x69, 0x66, + 0x28, 0x72, 0x21, 0x3d, 0x3d, 0x69, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6f, 0x3d, 0x75, 0x2e, 0x78, 0x2c, 0x61, 0x3d, 0x75, 0x2e, + 0x79, 0x2c, 0x63, 0x3d, 0x72, 0x2e, 0x78, 0x2d, 0x6f, 0x2c, 0x6c, + 0x3d, 0x72, 0x2e, 0x79, 0x2d, 0x61, 0x2c, 0x73, 0x3d, 0x69, 0x2e, + 0x78, 0x2d, 0x6f, 0x2c, 0x66, 0x3d, 0x69, 0x2e, 0x79, 0x2d, 0x61, + 0x2c, 0x68, 0x3d, 0x32, 0x2a, 0x28, 0x63, 0x2a, 0x66, 0x2d, 0x6c, + 0x2a, 0x73, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x28, 0x68, 0x3e, + 0x3d, 0x2d, 0x7a, 0x61, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x67, 0x3d, 0x63, 0x2a, 0x63, 0x2b, 0x6c, 0x2a, 0x6c, 0x2c, 0x70, + 0x3d, 0x73, 0x2a, 0x73, 0x2b, 0x66, 0x2a, 0x66, 0x2c, 0x76, 0x3d, + 0x28, 0x66, 0x2a, 0x67, 0x2d, 0x6c, 0x2a, 0x70, 0x29, 0x2f, 0x68, + 0x2c, 0x64, 0x3d, 0x28, 0x63, 0x2a, 0x70, 0x2d, 0x73, 0x2a, 0x67, + 0x29, 0x2f, 0x68, 0x2c, 0x66, 0x3d, 0x64, 0x2b, 0x61, 0x2c, 0x6d, + 0x3d, 0x72, 0x6c, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x7c, 0x7c, + 0x6e, 0x65, 0x77, 0x20, 0x5a, 0x72, 0x3b, 0x6d, 0x2e, 0x61, 0x72, + 0x63, 0x3d, 0x6e, 0x2c, 0x6d, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x3d, + 0x75, 0x2c, 0x6d, 0x2e, 0x78, 0x3d, 0x76, 0x2b, 0x6f, 0x2c, 0x6d, + 0x2e, 0x79, 0x3d, 0x66, 0x2b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x71, 0x72, 0x74, 0x28, 0x76, 0x2a, 0x76, 0x2b, 0x64, 0x2a, 0x64, + 0x29, 0x2c, 0x6d, 0x2e, 0x63, 0x79, 0x3d, 0x66, 0x2c, 0x6e, 0x2e, + 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x3d, 0x6d, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x79, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x2c, 0x4d, 0x3d, 0x74, 0x6c, 0x2e, 0x5f, 0x3b, 0x4d, 0x3b, + 0x29, 0x69, 0x66, 0x28, 0x6d, 0x2e, 0x79, 0x3c, 0x4d, 0x2e, 0x79, + 0x7c, 0x7c, 0x6d, 0x2e, 0x79, 0x3d, 0x3d, 0x3d, 0x4d, 0x2e, 0x79, + 0x26, 0x26, 0x6d, 0x2e, 0x78, 0x3c, 0x3d, 0x4d, 0x2e, 0x78, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x21, 0x4d, 0x2e, 0x4c, 0x29, 0x7b, 0x79, + 0x3d, 0x4d, 0x2e, 0x50, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, + 0x4d, 0x3d, 0x4d, 0x2e, 0x4c, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, + 0x69, 0x66, 0x28, 0x21, 0x4d, 0x2e, 0x52, 0x29, 0x7b, 0x79, 0x3d, + 0x4d, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x4d, 0x3d, 0x4d, + 0x2e, 0x52, 0x7d, 0x74, 0x6c, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, + 0x74, 0x28, 0x79, 0x2c, 0x6d, 0x29, 0x2c, 0x79, 0x7c, 0x7c, 0x28, + 0x6e, 0x6c, 0x3d, 0x6d, 0x29, 0x7d, 0x7d, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x58, 0x72, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x63, + 0x69, 0x72, 0x63, 0x6c, 0x65, 0x3b, 0x74, 0x26, 0x26, 0x28, 0x74, + 0x2e, 0x50, 0x7c, 0x7c, 0x28, 0x6e, 0x6c, 0x3d, 0x74, 0x2e, 0x4e, + 0x29, 0x2c, 0x74, 0x6c, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x28, 0x74, 0x29, 0x2c, 0x72, 0x6c, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x74, 0x29, 0x2c, 0x74, 0x75, 0x28, 0x74, 0x29, 0x2c, 0x6e, + 0x2e, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x24, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x47, 0x63, 0x2c, + 0x72, 0x3d, 0x4f, 0x65, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x5b, 0x30, + 0x5d, 0x2c, 0x6e, 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, + 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, + 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x75, 0x3d, 0x65, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x75, 0x2d, 0x2d, 0x3b, 0x29, 0x74, + 0x3d, 0x65, 0x5b, 0x75, 0x5d, 0x2c, 0x28, 0x21, 0x42, 0x72, 0x28, + 0x74, 0x2c, 0x6e, 0x29, 0x7c, 0x7c, 0x21, 0x72, 0x28, 0x74, 0x29, + 0x7c, 0x7c, 0x67, 0x61, 0x28, 0x74, 0x2e, 0x61, 0x2e, 0x78, 0x2d, + 0x74, 0x2e, 0x62, 0x2e, 0x78, 0x29, 0x3c, 0x43, 0x61, 0x26, 0x26, + 0x67, 0x61, 0x28, 0x74, 0x2e, 0x61, 0x2e, 0x79, 0x2d, 0x74, 0x2e, + 0x62, 0x2e, 0x79, 0x29, 0x3c, 0x43, 0x61, 0x29, 0x26, 0x26, 0x28, + 0x74, 0x2e, 0x61, 0x3d, 0x74, 0x2e, 0x62, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x2c, 0x65, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x63, 0x65, 0x28, + 0x75, 0x2c, 0x31, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x62, 0x3b, + 0x69, 0x66, 0x28, 0x65, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x21, 0x30, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x2c, + 0x69, 0x3d, 0x6e, 0x2e, 0x61, 0x2c, 0x6f, 0x3d, 0x74, 0x5b, 0x30, + 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x61, 0x3d, 0x74, 0x5b, 0x31, 0x5d, + 0x5b, 0x30, 0x5d, 0x2c, 0x63, 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x5b, + 0x31, 0x5d, 0x2c, 0x6c, 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x5b, 0x31, + 0x5d, 0x2c, 0x73, 0x3d, 0x6e, 0x2e, 0x6c, 0x2c, 0x66, 0x3d, 0x6e, + 0x2e, 0x72, 0x2c, 0x68, 0x3d, 0x73, 0x2e, 0x78, 0x2c, 0x67, 0x3d, + 0x73, 0x2e, 0x79, 0x2c, 0x70, 0x3d, 0x66, 0x2e, 0x78, 0x2c, 0x76, + 0x3d, 0x66, 0x2e, 0x79, 0x2c, 0x64, 0x3d, 0x28, 0x68, 0x2b, 0x70, + 0x29, 0x2f, 0x32, 0x2c, 0x6d, 0x3d, 0x28, 0x67, 0x2b, 0x76, 0x29, + 0x2f, 0x32, 0x3b, 0x69, 0x66, 0x28, 0x76, 0x3d, 0x3d, 0x3d, 0x67, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6f, 0x3e, 0x64, 0x7c, 0x7c, 0x64, + 0x3e, 0x3d, 0x61, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, + 0x69, 0x66, 0x28, 0x68, 0x3e, 0x70, 0x29, 0x7b, 0x69, 0x66, 0x28, + 0x69, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x2e, 0x79, 0x3e, 0x3d, + 0x6c, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x69, 0x3d, 0x7b, 0x78, 0x3a, 0x64, 0x2c, 0x79, + 0x3a, 0x63, 0x7d, 0x3b, 0x65, 0x3d, 0x7b, 0x78, 0x3a, 0x64, 0x2c, + 0x79, 0x3a, 0x6c, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x69, + 0x66, 0x28, 0x69, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x2e, 0x79, + 0x3c, 0x63, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x69, 0x3d, 0x7b, 0x78, 0x3a, 0x64, 0x2c, + 0x79, 0x3a, 0x6c, 0x7d, 0x3b, 0x65, 0x3d, 0x7b, 0x78, 0x3a, 0x64, + 0x2c, 0x79, 0x3a, 0x63, 0x7d, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x69, 0x66, 0x28, 0x72, 0x3d, 0x28, 0x68, 0x2d, 0x70, 0x29, + 0x2f, 0x28, 0x76, 0x2d, 0x67, 0x29, 0x2c, 0x75, 0x3d, 0x6d, 0x2d, + 0x72, 0x2a, 0x64, 0x2c, 0x2d, 0x31, 0x3e, 0x72, 0x7c, 0x7c, 0x72, + 0x3e, 0x31, 0x29, 0x69, 0x66, 0x28, 0x68, 0x3e, 0x70, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x69, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x2e, + 0x79, 0x3e, 0x3d, 0x6c, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x3d, 0x7b, 0x78, 0x3a, + 0x28, 0x63, 0x2d, 0x75, 0x29, 0x2f, 0x72, 0x2c, 0x79, 0x3a, 0x63, + 0x7d, 0x3b, 0x65, 0x3d, 0x7b, 0x78, 0x3a, 0x28, 0x6c, 0x2d, 0x75, + 0x29, 0x2f, 0x72, 0x2c, 0x79, 0x3a, 0x6c, 0x7d, 0x7d, 0x65, 0x6c, + 0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x29, 0x7b, 0x69, 0x66, + 0x28, 0x69, 0x2e, 0x79, 0x3c, 0x63, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x3d, 0x7b, + 0x78, 0x3a, 0x28, 0x6c, 0x2d, 0x75, 0x29, 0x2f, 0x72, 0x2c, 0x79, + 0x3a, 0x6c, 0x7d, 0x3b, 0x65, 0x3d, 0x7b, 0x78, 0x3a, 0x28, 0x63, + 0x2d, 0x75, 0x29, 0x2f, 0x72, 0x2c, 0x79, 0x3a, 0x63, 0x7d, 0x7d, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x76, 0x3e, 0x67, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x29, 0x7b, 0x69, 0x66, 0x28, + 0x69, 0x2e, 0x78, 0x3e, 0x3d, 0x61, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x3d, 0x7b, + 0x78, 0x3a, 0x6f, 0x2c, 0x79, 0x3a, 0x72, 0x2a, 0x6f, 0x2b, 0x75, + 0x7d, 0x3b, 0x65, 0x3d, 0x7b, 0x78, 0x3a, 0x61, 0x2c, 0x79, 0x3a, + 0x72, 0x2a, 0x61, 0x2b, 0x75, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, + 0x7b, 0x69, 0x66, 0x28, 0x69, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, + 0x2e, 0x78, 0x3c, 0x6f, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x3d, 0x7b, 0x78, 0x3a, + 0x61, 0x2c, 0x79, 0x3a, 0x72, 0x2a, 0x61, 0x2b, 0x75, 0x7d, 0x3b, + 0x65, 0x3d, 0x7b, 0x78, 0x3a, 0x6f, 0x2c, 0x79, 0x3a, 0x72, 0x2a, + 0x6f, 0x2b, 0x75, 0x7d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x2e, 0x61, 0x3d, 0x69, 0x2c, 0x6e, 0x2e, 0x62, 0x3d, + 0x65, 0x2c, 0x21, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x57, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x3d, 0x6e, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x72, 0x3d, 0x74, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x62, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x4a, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x6e, 0x65, + 0x77, 0x20, 0x57, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x63, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x75, 0x29, 0x2c, 0x65, 0x26, 0x26, 0x4b, 0x72, + 0x28, 0x75, 0x2c, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x2c, 0x72, + 0x26, 0x26, 0x4b, 0x72, 0x28, 0x75, 0x2c, 0x74, 0x2c, 0x6e, 0x2c, + 0x72, 0x29, 0x2c, 0x4b, 0x63, 0x5b, 0x6e, 0x2e, 0x69, 0x5d, 0x2e, + 0x65, 0x64, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x6e, 0x65, 0x77, 0x20, 0x51, 0x72, 0x28, 0x75, 0x2c, 0x6e, 0x2c, + 0x74, 0x29, 0x29, 0x2c, 0x4b, 0x63, 0x5b, 0x74, 0x2e, 0x69, 0x5d, + 0x2e, 0x65, 0x64, 0x67, 0x65, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x6e, 0x65, 0x77, 0x20, 0x51, 0x72, 0x28, 0x75, 0x2c, 0x74, + 0x2c, 0x6e, 0x29, 0x29, 0x2c, 0x75, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x47, 0x72, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, + 0x65, 0x77, 0x20, 0x57, 0x72, 0x28, 0x6e, 0x2c, 0x6e, 0x75, 0x6c, + 0x6c, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, + 0x2e, 0x61, 0x3d, 0x74, 0x2c, 0x72, 0x2e, 0x62, 0x3d, 0x65, 0x2c, + 0x47, 0x63, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x29, 0x2c, + 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x4b, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, + 0x7b, 0x6e, 0x2e, 0x61, 0x7c, 0x7c, 0x6e, 0x2e, 0x62, 0x3f, 0x6e, + 0x2e, 0x6c, 0x3d, 0x3d, 0x3d, 0x65, 0x3f, 0x6e, 0x2e, 0x62, 0x3d, + 0x72, 0x3a, 0x6e, 0x2e, 0x61, 0x3d, 0x72, 0x3a, 0x28, 0x6e, 0x2e, + 0x61, 0x3d, 0x72, 0x2c, 0x6e, 0x2e, 0x6c, 0x3d, 0x74, 0x2c, 0x6e, + 0x2e, 0x72, 0x3d, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x51, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x2e, + 0x61, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x62, 0x3b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x3d, 0x6e, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x3d, 0x74, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x65, + 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, + 0x28, 0x65, 0x2e, 0x79, 0x2d, 0x74, 0x2e, 0x79, 0x2c, 0x65, 0x2e, + 0x78, 0x2d, 0x74, 0x2e, 0x78, 0x29, 0x3a, 0x6e, 0x2e, 0x6c, 0x3d, + 0x3d, 0x3d, 0x74, 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, + 0x61, 0x6e, 0x32, 0x28, 0x75, 0x2e, 0x78, 0x2d, 0x72, 0x2e, 0x78, + 0x2c, 0x72, 0x2e, 0x79, 0x2d, 0x75, 0x2e, 0x79, 0x29, 0x3a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x72, + 0x2e, 0x78, 0x2d, 0x75, 0x2e, 0x78, 0x2c, 0x75, 0x2e, 0x79, 0x2d, + 0x72, 0x2e, 0x79, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6e, 0x75, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x5f, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x75, 0x28, 0x6e, + 0x29, 0x7b, 0x6e, 0x2e, 0x55, 0x3d, 0x6e, 0x2e, 0x43, 0x3d, 0x6e, + 0x2e, 0x4c, 0x3d, 0x6e, 0x2e, 0x52, 0x3d, 0x6e, 0x2e, 0x50, 0x3d, + 0x6e, 0x2e, 0x4e, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x75, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, + 0x2c, 0x72, 0x3d, 0x74, 0x2e, 0x52, 0x2c, 0x75, 0x3d, 0x65, 0x2e, + 0x55, 0x3b, 0x75, 0x3f, 0x75, 0x2e, 0x4c, 0x3d, 0x3d, 0x3d, 0x65, + 0x3f, 0x75, 0x2e, 0x4c, 0x3d, 0x72, 0x3a, 0x75, 0x2e, 0x52, 0x3d, + 0x72, 0x3a, 0x6e, 0x2e, 0x5f, 0x3d, 0x72, 0x2c, 0x72, 0x2e, 0x55, + 0x3d, 0x75, 0x2c, 0x65, 0x2e, 0x55, 0x3d, 0x72, 0x2c, 0x65, 0x2e, + 0x52, 0x3d, 0x72, 0x2e, 0x4c, 0x2c, 0x65, 0x2e, 0x52, 0x26, 0x26, + 0x28, 0x65, 0x2e, 0x52, 0x2e, 0x55, 0x3d, 0x65, 0x29, 0x2c, 0x72, + 0x2e, 0x4c, 0x3d, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x72, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, 0x2c, 0x72, 0x3d, 0x74, + 0x2e, 0x4c, 0x2c, 0x75, 0x3d, 0x65, 0x2e, 0x55, 0x3b, 0x75, 0x3f, + 0x75, 0x2e, 0x4c, 0x3d, 0x3d, 0x3d, 0x65, 0x3f, 0x75, 0x2e, 0x4c, + 0x3d, 0x72, 0x3a, 0x75, 0x2e, 0x52, 0x3d, 0x72, 0x3a, 0x6e, 0x2e, + 0x5f, 0x3d, 0x72, 0x2c, 0x72, 0x2e, 0x55, 0x3d, 0x75, 0x2c, 0x65, + 0x2e, 0x55, 0x3d, 0x72, 0x2c, 0x65, 0x2e, 0x4c, 0x3d, 0x72, 0x2e, + 0x52, 0x2c, 0x65, 0x2e, 0x4c, 0x26, 0x26, 0x28, 0x65, 0x2e, 0x4c, + 0x2e, 0x55, 0x3d, 0x65, 0x29, 0x2c, 0x72, 0x2e, 0x52, 0x3d, 0x65, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, + 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x6e, + 0x2e, 0x4c, 0x3b, 0x29, 0x6e, 0x3d, 0x6e, 0x2e, 0x4c, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x75, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x2c, + 0x75, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, + 0x6f, 0x75, 0x29, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x47, 0x63, 0x3d, 0x5b, 0x5d, 0x2c, 0x4b, 0x63, + 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, + 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x2c, 0x51, + 0x63, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x6e, 0x75, 0x2c, 0x74, 0x6c, + 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x6e, 0x75, 0x3b, 0x3b, 0x29, 0x69, + 0x66, 0x28, 0x75, 0x3d, 0x6e, 0x6c, 0x2c, 0x69, 0x26, 0x26, 0x28, + 0x21, 0x75, 0x7c, 0x7c, 0x69, 0x2e, 0x79, 0x3c, 0x75, 0x2e, 0x79, + 0x7c, 0x7c, 0x69, 0x2e, 0x79, 0x3d, 0x3d, 0x3d, 0x75, 0x2e, 0x79, + 0x26, 0x26, 0x69, 0x2e, 0x78, 0x3c, 0x75, 0x2e, 0x78, 0x29, 0x29, + 0x28, 0x69, 0x2e, 0x78, 0x21, 0x3d, 0x3d, 0x65, 0x7c, 0x7c, 0x69, + 0x2e, 0x79, 0x21, 0x3d, 0x3d, 0x72, 0x29, 0x26, 0x26, 0x28, 0x4b, + 0x63, 0x5b, 0x69, 0x2e, 0x69, 0x5d, 0x3d, 0x6e, 0x65, 0x77, 0x20, + 0x4f, 0x72, 0x28, 0x69, 0x29, 0x2c, 0x6a, 0x72, 0x28, 0x69, 0x29, + 0x2c, 0x65, 0x3d, 0x69, 0x2e, 0x78, 0x2c, 0x72, 0x3d, 0x69, 0x2e, + 0x79, 0x29, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x70, 0x6f, 0x70, 0x28, + 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x21, + 0x75, 0x29, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x55, 0x72, 0x28, + 0x75, 0x2e, 0x61, 0x72, 0x63, 0x29, 0x7d, 0x74, 0x26, 0x26, 0x28, + 0x24, 0x72, 0x28, 0x74, 0x29, 0x2c, 0x49, 0x72, 0x28, 0x74, 0x29, + 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x7b, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x3a, 0x4b, 0x63, 0x2c, 0x65, 0x64, 0x67, 0x65, + 0x73, 0x3a, 0x47, 0x63, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x51, 0x63, 0x3d, 0x74, 0x6c, 0x3d, 0x47, 0x63, 0x3d, + 0x4b, 0x63, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6f, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x75, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x2e, 0x79, 0x2d, 0x6e, 0x2e, 0x79, 0x7c, 0x7c, 0x74, + 0x2e, 0x78, 0x2d, 0x6e, 0x2e, 0x78, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x75, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, + 0x6e, 0x2e, 0x78, 0x2d, 0x65, 0x2e, 0x78, 0x29, 0x2a, 0x28, 0x74, + 0x2e, 0x79, 0x2d, 0x6e, 0x2e, 0x79, 0x29, 0x2d, 0x28, 0x6e, 0x2e, + 0x78, 0x2d, 0x74, 0x2e, 0x78, 0x29, 0x2a, 0x28, 0x65, 0x2e, 0x79, + 0x2d, 0x6e, 0x2e, 0x79, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x78, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x75, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x79, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x73, 0x75, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x7b, 0x6c, 0x65, 0x61, 0x66, 0x3a, 0x21, 0x30, 0x2c, 0x6e, + 0x6f, 0x64, 0x65, 0x73, 0x3a, 0x5b, 0x5d, 0x2c, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x78, 0x3a, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x79, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, + 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, + 0x2c, 0x69, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x6e, 0x28, 0x74, + 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x29, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x2e, 0x35, 0x2a, 0x28, 0x65, + 0x2b, 0x75, 0x29, 0x2c, 0x61, 0x3d, 0x2e, 0x35, 0x2a, 0x28, 0x72, + 0x2b, 0x69, 0x29, 0x2c, 0x63, 0x3d, 0x74, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x73, 0x3b, 0x63, 0x5b, 0x30, 0x5d, 0x26, 0x26, 0x66, 0x75, + 0x28, 0x6e, 0x2c, 0x63, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x2c, 0x72, + 0x2c, 0x6f, 0x2c, 0x61, 0x29, 0x2c, 0x63, 0x5b, 0x31, 0x5d, 0x26, + 0x26, 0x66, 0x75, 0x28, 0x6e, 0x2c, 0x63, 0x5b, 0x31, 0x5d, 0x2c, + 0x6f, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x61, 0x29, 0x2c, 0x63, 0x5b, + 0x32, 0x5d, 0x26, 0x26, 0x66, 0x75, 0x28, 0x6e, 0x2c, 0x63, 0x5b, + 0x32, 0x5d, 0x2c, 0x65, 0x2c, 0x61, 0x2c, 0x6f, 0x2c, 0x69, 0x29, + 0x2c, 0x63, 0x5b, 0x33, 0x5d, 0x26, 0x26, 0x66, 0x75, 0x28, 0x6e, + 0x2c, 0x63, 0x5b, 0x33, 0x5d, 0x2c, 0x6f, 0x2c, 0x61, 0x2c, 0x75, + 0x2c, 0x69, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x68, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x61, 0x2c, 0x63, 0x3d, 0x31, 0x2f, 0x30, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x28, 0x6e, 0x2c, 0x73, 0x2c, + 0x66, 0x2c, 0x68, 0x2c, 0x67, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, + 0x28, 0x73, 0x3e, 0x69, 0x7c, 0x7c, 0x66, 0x3e, 0x6f, 0x7c, 0x7c, + 0x72, 0x3e, 0x68, 0x7c, 0x7c, 0x75, 0x3e, 0x67, 0x29, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x70, 0x3d, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x70, 0x2c, 0x76, 0x3d, + 0x74, 0x2d, 0x6e, 0x2e, 0x78, 0x2c, 0x64, 0x3d, 0x65, 0x2d, 0x6e, + 0x2e, 0x79, 0x2c, 0x6d, 0x3d, 0x76, 0x2a, 0x76, 0x2b, 0x64, 0x2a, + 0x64, 0x3b, 0x69, 0x66, 0x28, 0x63, 0x3e, 0x6d, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x79, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x71, 0x72, 0x74, 0x28, 0x63, 0x3d, 0x6d, 0x29, 0x3b, 0x72, 0x3d, + 0x74, 0x2d, 0x79, 0x2c, 0x75, 0x3d, 0x65, 0x2d, 0x79, 0x2c, 0x69, + 0x3d, 0x74, 0x2b, 0x79, 0x2c, 0x6f, 0x3d, 0x65, 0x2b, 0x79, 0x2c, + 0x61, 0x3d, 0x70, 0x7d, 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x4d, 0x3d, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x73, + 0x2c, 0x78, 0x3d, 0x2e, 0x35, 0x2a, 0x28, 0x73, 0x2b, 0x68, 0x29, + 0x2c, 0x62, 0x3d, 0x2e, 0x35, 0x2a, 0x28, 0x66, 0x2b, 0x67, 0x29, + 0x2c, 0x5f, 0x3d, 0x74, 0x3e, 0x3d, 0x78, 0x2c, 0x77, 0x3d, 0x65, + 0x3e, 0x3d, 0x62, 0x2c, 0x53, 0x3d, 0x77, 0x3c, 0x3c, 0x31, 0x7c, + 0x5f, 0x2c, 0x6b, 0x3d, 0x53, 0x2b, 0x34, 0x3b, 0x6b, 0x3e, 0x53, + 0x3b, 0x2b, 0x2b, 0x53, 0x29, 0x69, 0x66, 0x28, 0x6e, 0x3d, 0x4d, + 0x5b, 0x33, 0x26, 0x53, 0x5d, 0x29, 0x73, 0x77, 0x69, 0x74, 0x63, + 0x68, 0x28, 0x33, 0x26, 0x53, 0x29, 0x7b, 0x63, 0x61, 0x73, 0x65, + 0x20, 0x30, 0x3a, 0x6c, 0x28, 0x6e, 0x2c, 0x73, 0x2c, 0x66, 0x2c, + 0x78, 0x2c, 0x62, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, + 0x63, 0x61, 0x73, 0x65, 0x20, 0x31, 0x3a, 0x6c, 0x28, 0x6e, 0x2c, + 0x78, 0x2c, 0x66, 0x2c, 0x68, 0x2c, 0x62, 0x29, 0x3b, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x32, 0x3a, + 0x6c, 0x28, 0x6e, 0x2c, 0x73, 0x2c, 0x62, 0x2c, 0x78, 0x2c, 0x67, + 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61, 0x73, + 0x65, 0x20, 0x33, 0x3a, 0x6c, 0x28, 0x6e, 0x2c, 0x78, 0x2c, 0x62, + 0x2c, 0x68, 0x2c, 0x67, 0x29, 0x7d, 0x7d, 0x7d, 0x28, 0x6e, 0x2c, + 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x29, 0x2c, 0x61, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x75, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x3d, 0x74, 0x61, 0x2e, + 0x72, 0x67, 0x62, 0x28, 0x6e, 0x29, 0x2c, 0x74, 0x3d, 0x74, 0x61, + 0x2e, 0x72, 0x67, 0x62, 0x28, 0x74, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x72, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, + 0x67, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x62, 0x2c, 0x69, 0x3d, 0x74, + 0x2e, 0x72, 0x2d, 0x65, 0x2c, 0x6f, 0x3d, 0x74, 0x2e, 0x67, 0x2d, + 0x72, 0x2c, 0x61, 0x3d, 0x74, 0x2e, 0x62, 0x2d, 0x75, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x23, 0x22, 0x2b, 0x78, 0x74, 0x28, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x65, 0x2b, + 0x69, 0x2a, 0x6e, 0x29, 0x29, 0x2b, 0x78, 0x74, 0x28, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x72, 0x2b, + 0x6f, 0x2a, 0x6e, 0x29, 0x29, 0x2b, 0x78, 0x74, 0x28, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x75, 0x2b, + 0x61, 0x2a, 0x6e, 0x29, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x75, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, 0x7b, + 0x7d, 0x2c, 0x75, 0x3d, 0x7b, 0x7d, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x65, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x65, 0x20, 0x69, 0x6e, + 0x20, 0x74, 0x3f, 0x72, 0x5b, 0x65, 0x5d, 0x3d, 0x6d, 0x75, 0x28, + 0x6e, 0x5b, 0x65, 0x5d, 0x2c, 0x74, 0x5b, 0x65, 0x5d, 0x29, 0x3a, + 0x75, 0x5b, 0x65, 0x5d, 0x3d, 0x6e, 0x5b, 0x65, 0x5d, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x29, 0x65, + 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x7c, 0x7c, 0x28, 0x75, 0x5b, 0x65, + 0x5d, 0x3d, 0x74, 0x5b, 0x65, 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x20, + 0x69, 0x6e, 0x20, 0x72, 0x29, 0x75, 0x5b, 0x65, 0x5d, 0x3d, 0x72, + 0x5b, 0x65, 0x5d, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x75, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x2b, + 0x6e, 0x2c, 0x74, 0x3d, 0x2b, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2a, 0x28, 0x31, 0x2d, 0x65, 0x29, + 0x2b, 0x74, 0x2a, 0x65, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, + 0x69, 0x3d, 0x69, 0x6c, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x3d, 0x6f, 0x6c, 0x2e, 0x6c, 0x61, 0x73, 0x74, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x30, 0x2c, 0x6f, 0x3d, 0x2d, + 0x31, 0x2c, 0x61, 0x3d, 0x5b, 0x5d, 0x2c, 0x63, 0x3d, 0x5b, 0x5d, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6e, 0x2b, 0x3d, 0x22, 0x22, 0x2c, + 0x74, 0x2b, 0x3d, 0x22, 0x22, 0x3b, 0x28, 0x65, 0x3d, 0x69, 0x6c, + 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, 0x6e, 0x29, 0x29, 0x26, 0x26, + 0x28, 0x72, 0x3d, 0x6f, 0x6c, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x28, + 0x74, 0x29, 0x29, 0x3b, 0x29, 0x28, 0x75, 0x3d, 0x72, 0x2e, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x29, 0x3e, 0x69, 0x26, 0x26, 0x28, 0x75, + 0x3d, 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x69, 0x2c, + 0x75, 0x29, 0x2c, 0x61, 0x5b, 0x6f, 0x5d, 0x3f, 0x61, 0x5b, 0x6f, + 0x5d, 0x2b, 0x3d, 0x75, 0x3a, 0x61, 0x5b, 0x2b, 0x2b, 0x6f, 0x5d, + 0x3d, 0x75, 0x29, 0x2c, 0x28, 0x65, 0x3d, 0x65, 0x5b, 0x30, 0x5d, + 0x29, 0x3d, 0x3d, 0x3d, 0x28, 0x72, 0x3d, 0x72, 0x5b, 0x30, 0x5d, + 0x29, 0x3f, 0x61, 0x5b, 0x6f, 0x5d, 0x3f, 0x61, 0x5b, 0x6f, 0x5d, + 0x2b, 0x3d, 0x72, 0x3a, 0x61, 0x5b, 0x2b, 0x2b, 0x6f, 0x5d, 0x3d, + 0x72, 0x3a, 0x28, 0x61, 0x5b, 0x2b, 0x2b, 0x6f, 0x5d, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x63, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x7b, 0x69, 0x3a, 0x6f, 0x2c, 0x78, 0x3a, 0x76, 0x75, 0x28, 0x65, + 0x2c, 0x72, 0x29, 0x7d, 0x29, 0x29, 0x2c, 0x69, 0x3d, 0x6f, 0x6c, + 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x3c, 0x74, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x26, 0x26, 0x28, 0x75, 0x3d, + 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x69, 0x29, 0x2c, + 0x61, 0x5b, 0x6f, 0x5d, 0x3f, 0x61, 0x5b, 0x6f, 0x5d, 0x2b, 0x3d, + 0x75, 0x3a, 0x61, 0x5b, 0x2b, 0x2b, 0x6f, 0x5d, 0x3d, 0x75, 0x29, + 0x2c, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, + 0x3f, 0x63, 0x5b, 0x30, 0x5d, 0x3f, 0x28, 0x74, 0x3d, 0x63, 0x5b, + 0x30, 0x5d, 0x2e, 0x78, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x29, 0x2b, 0x22, 0x22, 0x7d, 0x29, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x3a, + 0x28, 0x74, 0x3d, 0x63, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x2c, 0x72, 0x3d, 0x30, 0x3b, 0x74, 0x3e, 0x72, 0x3b, 0x2b, 0x2b, + 0x72, 0x29, 0x61, 0x5b, 0x28, 0x65, 0x3d, 0x63, 0x5b, 0x72, 0x5d, + 0x29, 0x2e, 0x69, 0x5d, 0x3d, 0x65, 0x2e, 0x78, 0x28, 0x6e, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x2e, 0x6a, + 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x75, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, 0x74, 0x61, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x6f, 0x72, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2d, 0x2d, 0x72, + 0x3e, 0x3d, 0x30, 0x26, 0x26, 0x21, 0x28, 0x65, 0x3d, 0x74, 0x61, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, + 0x6f, 0x72, 0x73, 0x5b, 0x72, 0x5d, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x29, 0x3b, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x79, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x2c, 0x72, 0x3d, 0x5b, 0x5d, 0x2c, 0x75, 0x3d, 0x5b, + 0x5d, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x6f, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x61, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, + 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x30, 0x3b, 0x61, 0x3e, 0x65, 0x3b, + 0x2b, 0x2b, 0x65, 0x29, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x6d, 0x75, 0x28, 0x6e, 0x5b, 0x65, 0x5d, 0x2c, 0x74, 0x5b, 0x65, + 0x5d, 0x29, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x69, 0x3e, + 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x75, 0x5b, 0x65, 0x5d, 0x3d, + 0x6e, 0x5b, 0x65, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x6f, + 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x75, 0x5b, 0x65, 0x5d, + 0x3d, 0x74, 0x5b, 0x65, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x30, 0x3b, + 0x61, 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x75, 0x5b, 0x65, + 0x5d, 0x3d, 0x72, 0x5b, 0x65, 0x5d, 0x28, 0x6e, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x75, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3e, 0x3d, 0x74, 0x3f, + 0x30, 0x3a, 0x74, 0x3e, 0x3d, 0x31, 0x3f, 0x31, 0x3a, 0x6e, 0x28, + 0x74, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x78, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x31, 0x2d, 0x6e, 0x28, 0x31, 0x2d, 0x74, 0x29, 0x7d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x75, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2e, 0x35, 0x2a, 0x28, + 0x2e, 0x35, 0x3e, 0x74, 0x3f, 0x6e, 0x28, 0x32, 0x2a, 0x74, 0x29, + 0x3a, 0x32, 0x2d, 0x6e, 0x28, 0x32, 0x2d, 0x32, 0x2a, 0x74, 0x29, + 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x5f, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x2a, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x75, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2a, 0x6e, 0x2a, + 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x53, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x30, 0x3e, + 0x3d, 0x6e, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, + 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x3e, 0x3d, 0x31, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x6e, 0x2a, 0x6e, 0x2c, 0x65, 0x3d, 0x74, 0x2a, 0x6e, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 0x2a, 0x28, + 0x2e, 0x35, 0x3e, 0x6e, 0x3f, 0x65, 0x3a, 0x33, 0x2a, 0x28, 0x6e, + 0x2d, 0x74, 0x29, 0x2b, 0x65, 0x2d, 0x2e, 0x37, 0x35, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6b, 0x75, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, + 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x31, 0x2d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, + 0x28, 0x6e, 0x2a, 0x52, 0x61, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x32, 0x2c, 0x31, 0x30, 0x2a, 0x28, + 0x6e, 0x2d, 0x31, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x2d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x31, 0x2d, 0x6e, 0x2a, + 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x43, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x26, 0x26, 0x28, 0x74, + 0x3d, 0x2e, 0x34, 0x35, 0x29, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x65, 0x3d, 0x74, 0x2f, 0x4c, 0x61, 0x2a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x61, 0x73, 0x69, 0x6e, 0x28, 0x31, 0x2f, 0x6e, 0x29, + 0x3a, 0x28, 0x6e, 0x3d, 0x31, 0x2c, 0x65, 0x3d, 0x74, 0x2f, 0x34, + 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, + 0x2b, 0x6e, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, + 0x28, 0x32, 0x2c, 0x2d, 0x31, 0x30, 0x2a, 0x72, 0x29, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x28, 0x72, 0x2d, + 0x65, 0x29, 0x2a, 0x4c, 0x61, 0x2f, 0x74, 0x29, 0x7d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x75, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x7c, 0x7c, 0x28, 0x6e, 0x3d, 0x31, 0x2e, 0x37, 0x30, 0x31, 0x35, + 0x38, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x2a, 0x74, 0x2a, 0x28, 0x28, 0x6e, 0x2b, 0x31, 0x29, 0x2a, + 0x74, 0x2d, 0x6e, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x71, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x2f, 0x32, 0x2e, 0x37, + 0x35, 0x3e, 0x6e, 0x3f, 0x37, 0x2e, 0x35, 0x36, 0x32, 0x35, 0x2a, + 0x6e, 0x2a, 0x6e, 0x3a, 0x32, 0x2f, 0x32, 0x2e, 0x37, 0x35, 0x3e, + 0x6e, 0x3f, 0x37, 0x2e, 0x35, 0x36, 0x32, 0x35, 0x2a, 0x28, 0x6e, + 0x2d, 0x3d, 0x31, 0x2e, 0x35, 0x2f, 0x32, 0x2e, 0x37, 0x35, 0x29, + 0x2a, 0x6e, 0x2b, 0x2e, 0x37, 0x35, 0x3a, 0x32, 0x2e, 0x35, 0x2f, + 0x32, 0x2e, 0x37, 0x35, 0x3e, 0x6e, 0x3f, 0x37, 0x2e, 0x35, 0x36, + 0x32, 0x35, 0x2a, 0x28, 0x6e, 0x2d, 0x3d, 0x32, 0x2e, 0x32, 0x35, + 0x2f, 0x32, 0x2e, 0x37, 0x35, 0x29, 0x2a, 0x6e, 0x2b, 0x2e, 0x39, + 0x33, 0x37, 0x35, 0x3a, 0x37, 0x2e, 0x35, 0x36, 0x32, 0x35, 0x2a, + 0x28, 0x6e, 0x2d, 0x3d, 0x32, 0x2e, 0x36, 0x32, 0x35, 0x2f, 0x32, + 0x2e, 0x37, 0x35, 0x29, 0x2a, 0x6e, 0x2b, 0x2e, 0x39, 0x38, 0x34, + 0x33, 0x37, 0x35, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x4c, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, + 0x3d, 0x74, 0x61, 0x2e, 0x68, 0x63, 0x6c, 0x28, 0x6e, 0x29, 0x2c, + 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x68, 0x63, 0x6c, 0x28, 0x74, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x68, 0x2c, + 0x72, 0x3d, 0x6e, 0x2e, 0x63, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x6c, + 0x2c, 0x69, 0x3d, 0x74, 0x2e, 0x68, 0x2d, 0x65, 0x2c, 0x6f, 0x3d, + 0x74, 0x2e, 0x63, 0x2d, 0x72, 0x2c, 0x61, 0x3d, 0x74, 0x2e, 0x6c, + 0x2d, 0x75, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, + 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x6f, 0x29, 0x26, 0x26, 0x28, 0x6f, + 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, + 0x72, 0x29, 0x3f, 0x74, 0x2e, 0x63, 0x3a, 0x72, 0x29, 0x2c, 0x69, + 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x69, 0x29, 0x3f, 0x28, 0x69, 0x3d, + 0x30, 0x2c, 0x65, 0x3d, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x65, + 0x29, 0x3f, 0x74, 0x2e, 0x68, 0x3a, 0x65, 0x29, 0x3a, 0x69, 0x3e, + 0x31, 0x38, 0x30, 0x3f, 0x69, 0x2d, 0x3d, 0x33, 0x36, 0x30, 0x3a, + 0x2d, 0x31, 0x38, 0x30, 0x3e, 0x69, 0x26, 0x26, 0x28, 0x69, 0x2b, + 0x3d, 0x33, 0x36, 0x30, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x73, 0x74, 0x28, 0x65, 0x2b, 0x69, 0x2a, 0x6e, + 0x2c, 0x72, 0x2b, 0x6f, 0x2a, 0x6e, 0x2c, 0x75, 0x2b, 0x61, 0x2a, + 0x6e, 0x29, 0x2b, 0x22, 0x22, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x54, 0x75, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x68, 0x73, 0x6c, 0x28, + 0x6e, 0x29, 0x2c, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x68, 0x73, 0x6c, + 0x28, 0x74, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, + 0x2e, 0x68, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, 0x73, 0x2c, 0x75, 0x3d, + 0x6e, 0x2e, 0x6c, 0x2c, 0x69, 0x3d, 0x74, 0x2e, 0x68, 0x2d, 0x65, + 0x2c, 0x6f, 0x3d, 0x74, 0x2e, 0x73, 0x2d, 0x72, 0x2c, 0x61, 0x3d, + 0x74, 0x2e, 0x6c, 0x2d, 0x75, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x6f, 0x29, 0x26, + 0x26, 0x28, 0x6f, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x69, 0x73, 0x4e, + 0x61, 0x4e, 0x28, 0x72, 0x29, 0x3f, 0x74, 0x2e, 0x73, 0x3a, 0x72, + 0x29, 0x2c, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x69, 0x29, 0x3f, + 0x28, 0x69, 0x3d, 0x30, 0x2c, 0x65, 0x3d, 0x69, 0x73, 0x4e, 0x61, + 0x4e, 0x28, 0x65, 0x29, 0x3f, 0x74, 0x2e, 0x68, 0x3a, 0x65, 0x29, + 0x3a, 0x69, 0x3e, 0x31, 0x38, 0x30, 0x3f, 0x69, 0x2d, 0x3d, 0x33, + 0x36, 0x30, 0x3a, 0x2d, 0x31, 0x38, 0x30, 0x3e, 0x69, 0x26, 0x26, + 0x28, 0x69, 0x2b, 0x3d, 0x33, 0x36, 0x30, 0x29, 0x2c, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x74, 0x28, 0x65, 0x2b, + 0x69, 0x2a, 0x6e, 0x2c, 0x72, 0x2b, 0x6f, 0x2a, 0x6e, 0x2c, 0x75, + 0x2b, 0x61, 0x2a, 0x6e, 0x29, 0x2b, 0x22, 0x22, 0x7d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x75, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x6c, + 0x61, 0x62, 0x28, 0x6e, 0x29, 0x2c, 0x74, 0x3d, 0x74, 0x61, 0x2e, + 0x6c, 0x61, 0x62, 0x28, 0x74, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x6e, 0x2e, 0x6c, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, 0x61, + 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x62, 0x2c, 0x69, 0x3d, 0x74, 0x2e, + 0x6c, 0x2d, 0x65, 0x2c, 0x6f, 0x3d, 0x74, 0x2e, 0x61, 0x2d, 0x72, + 0x2c, 0x61, 0x3d, 0x74, 0x2e, 0x62, 0x2d, 0x75, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x68, 0x74, 0x28, 0x65, 0x2b, 0x69, 0x2a, 0x6e, 0x2c, + 0x72, 0x2b, 0x6f, 0x2a, 0x6e, 0x2c, 0x75, 0x2b, 0x61, 0x2a, 0x6e, + 0x29, 0x2b, 0x22, 0x22, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x44, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2d, 0x3d, + 0x6e, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x6e, + 0x2b, 0x74, 0x2a, 0x65, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x75, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x5b, 0x6e, 0x2e, 0x61, 0x2c, + 0x6e, 0x2e, 0x62, 0x5d, 0x2c, 0x65, 0x3d, 0x5b, 0x6e, 0x2e, 0x63, + 0x2c, 0x6e, 0x2e, 0x64, 0x5d, 0x2c, 0x72, 0x3d, 0x6a, 0x75, 0x28, + 0x74, 0x29, 0x2c, 0x75, 0x3d, 0x55, 0x75, 0x28, 0x74, 0x2c, 0x65, + 0x29, 0x2c, 0x69, 0x3d, 0x6a, 0x75, 0x28, 0x46, 0x75, 0x28, 0x65, + 0x2c, 0x74, 0x2c, 0x2d, 0x75, 0x29, 0x29, 0x7c, 0x7c, 0x30, 0x3b, + 0x74, 0x5b, 0x30, 0x5d, 0x2a, 0x65, 0x5b, 0x31, 0x5d, 0x3c, 0x65, + 0x5b, 0x30, 0x5d, 0x2a, 0x74, 0x5b, 0x31, 0x5d, 0x26, 0x26, 0x28, + 0x74, 0x5b, 0x30, 0x5d, 0x2a, 0x3d, 0x2d, 0x31, 0x2c, 0x74, 0x5b, + 0x31, 0x5d, 0x2a, 0x3d, 0x2d, 0x31, 0x2c, 0x72, 0x2a, 0x3d, 0x2d, + 0x31, 0x2c, 0x75, 0x2a, 0x3d, 0x2d, 0x31, 0x29, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x3d, 0x28, + 0x72, 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, + 0x32, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x74, 0x5b, 0x30, 0x5d, + 0x29, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, + 0x32, 0x28, 0x2d, 0x65, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x5b, 0x31, + 0x5d, 0x29, 0x29, 0x2a, 0x50, 0x61, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x3d, + 0x5b, 0x6e, 0x2e, 0x65, 0x2c, 0x6e, 0x2e, 0x66, 0x5d, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x3d, 0x5b, + 0x72, 0x2c, 0x69, 0x5d, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, + 0x6b, 0x65, 0x77, 0x3d, 0x69, 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x75, 0x2c, 0x69, 0x29, 0x2a, + 0x50, 0x61, 0x3a, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x55, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x5b, 0x30, 0x5d, + 0x2a, 0x74, 0x5b, 0x30, 0x5d, 0x2b, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, + 0x74, 0x5b, 0x31, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6a, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x55, 0x75, 0x28, 0x6e, 0x2c, 0x6e, 0x29, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x26, 0x26, + 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2f, 0x3d, 0x74, 0x2c, 0x6e, 0x5b, + 0x31, 0x5d, 0x2f, 0x3d, 0x74, 0x29, 0x2c, 0x74, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, 0x75, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x5b, 0x30, 0x5d, 0x2b, 0x3d, 0x65, 0x2a, 0x74, + 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2b, 0x3d, 0x65, + 0x2a, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x48, 0x75, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, + 0x5b, 0x5d, 0x2c, 0x75, 0x3d, 0x5b, 0x5d, 0x2c, 0x69, 0x3d, 0x74, + 0x61, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x28, 0x6e, 0x29, 0x2c, 0x6f, 0x3d, 0x74, 0x61, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x74, 0x29, 0x2c, + 0x61, 0x3d, 0x69, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x65, 0x2c, 0x63, 0x3d, 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x6c, 0x61, 0x74, 0x65, 0x2c, 0x6c, 0x3d, 0x69, 0x2e, 0x72, + 0x6f, 0x74, 0x61, 0x74, 0x65, 0x2c, 0x73, 0x3d, 0x6f, 0x2e, 0x72, + 0x6f, 0x74, 0x61, 0x74, 0x65, 0x2c, 0x66, 0x3d, 0x69, 0x2e, 0x73, + 0x6b, 0x65, 0x77, 0x2c, 0x68, 0x3d, 0x6f, 0x2e, 0x73, 0x6b, 0x65, + 0x77, 0x2c, 0x67, 0x3d, 0x69, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2c, 0x70, 0x3d, 0x6f, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x5b, 0x30, 0x5d, + 0x21, 0x3d, 0x63, 0x5b, 0x30, 0x5d, 0x7c, 0x7c, 0x61, 0x5b, 0x31, + 0x5d, 0x21, 0x3d, 0x63, 0x5b, 0x31, 0x5d, 0x3f, 0x28, 0x72, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x6c, 0x61, 0x74, 0x65, 0x28, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, + 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x22, + 0x29, 0x22, 0x29, 0x2c, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x7b, 0x69, 0x3a, 0x31, 0x2c, 0x78, 0x3a, 0x76, 0x75, 0x28, 0x61, + 0x5b, 0x30, 0x5d, 0x2c, 0x63, 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x2c, + 0x7b, 0x69, 0x3a, 0x33, 0x2c, 0x78, 0x3a, 0x76, 0x75, 0x28, 0x61, + 0x5b, 0x31, 0x5d, 0x2c, 0x63, 0x5b, 0x31, 0x5d, 0x29, 0x7d, 0x29, + 0x29, 0x3a, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x63, 0x5b, + 0x30, 0x5d, 0x7c, 0x7c, 0x63, 0x5b, 0x31, 0x5d, 0x3f, 0x22, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x22, 0x2b, + 0x63, 0x2b, 0x22, 0x29, 0x22, 0x3a, 0x22, 0x22, 0x29, 0x2c, 0x6c, + 0x21, 0x3d, 0x73, 0x3f, 0x28, 0x6c, 0x2d, 0x73, 0x3e, 0x31, 0x38, + 0x30, 0x3f, 0x73, 0x2b, 0x3d, 0x33, 0x36, 0x30, 0x3a, 0x73, 0x2d, + 0x6c, 0x3e, 0x31, 0x38, 0x30, 0x26, 0x26, 0x28, 0x6c, 0x2b, 0x3d, + 0x33, 0x36, 0x30, 0x29, 0x2c, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x7b, 0x69, 0x3a, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x72, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2b, 0x22, 0x72, 0x6f, + 0x74, 0x61, 0x74, 0x65, 0x28, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, + 0x2c, 0x22, 0x29, 0x22, 0x29, 0x2d, 0x32, 0x2c, 0x78, 0x3a, 0x76, + 0x75, 0x28, 0x6c, 0x2c, 0x73, 0x29, 0x7d, 0x29, 0x29, 0x3a, 0x73, + 0x26, 0x26, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x2e, + 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2b, 0x22, 0x72, 0x6f, 0x74, 0x61, + 0x74, 0x65, 0x28, 0x22, 0x2b, 0x73, 0x2b, 0x22, 0x29, 0x22, 0x29, + 0x2c, 0x66, 0x21, 0x3d, 0x68, 0x3f, 0x75, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x7b, 0x69, 0x3a, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x72, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2b, 0x22, 0x73, + 0x6b, 0x65, 0x77, 0x58, 0x28, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, + 0x2c, 0x22, 0x29, 0x22, 0x29, 0x2d, 0x32, 0x2c, 0x78, 0x3a, 0x76, + 0x75, 0x28, 0x66, 0x2c, 0x68, 0x29, 0x7d, 0x29, 0x3a, 0x68, 0x26, + 0x26, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x2e, 0x70, + 0x6f, 0x70, 0x28, 0x29, 0x2b, 0x22, 0x73, 0x6b, 0x65, 0x77, 0x58, + 0x28, 0x22, 0x2b, 0x68, 0x2b, 0x22, 0x29, 0x22, 0x29, 0x2c, 0x67, + 0x5b, 0x30, 0x5d, 0x21, 0x3d, 0x70, 0x5b, 0x30, 0x5d, 0x7c, 0x7c, + 0x67, 0x5b, 0x31, 0x5d, 0x21, 0x3d, 0x70, 0x5b, 0x31, 0x5d, 0x3f, + 0x28, 0x65, 0x3d, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, + 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2b, 0x22, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x28, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x22, + 0x2c, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x22, 0x29, 0x22, + 0x29, 0x2c, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x69, + 0x3a, 0x65, 0x2d, 0x34, 0x2c, 0x78, 0x3a, 0x76, 0x75, 0x28, 0x67, + 0x5b, 0x30, 0x5d, 0x2c, 0x70, 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x2c, + 0x7b, 0x69, 0x3a, 0x65, 0x2d, 0x32, 0x2c, 0x78, 0x3a, 0x76, 0x75, + 0x28, 0x67, 0x5b, 0x31, 0x5d, 0x2c, 0x70, 0x5b, 0x31, 0x5d, 0x29, + 0x7d, 0x29, 0x29, 0x3a, 0x28, 0x31, 0x21, 0x3d, 0x70, 0x5b, 0x30, + 0x5d, 0x7c, 0x7c, 0x31, 0x21, 0x3d, 0x70, 0x5b, 0x31, 0x5d, 0x29, + 0x26, 0x26, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x2e, + 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2b, 0x22, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x28, 0x22, 0x2b, 0x70, 0x2b, 0x22, 0x29, 0x22, 0x29, 0x2c, + 0x65, 0x3d, 0x75, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, + 0x69, 0x3d, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, 0x65, 0x3b, + 0x29, 0x72, 0x5b, 0x28, 0x74, 0x3d, 0x75, 0x5b, 0x69, 0x5d, 0x29, + 0x2e, 0x69, 0x5d, 0x3d, 0x74, 0x2e, 0x78, 0x28, 0x6e, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2e, 0x6a, 0x6f, + 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x75, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x3d, 0x28, 0x74, 0x2d, 0x3d, 0x6e, 0x3d, 0x2b, 0x6e, 0x29, 0x7c, + 0x7c, 0x31, 0x2f, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x28, 0x65, 0x2d, 0x6e, 0x29, 0x2f, 0x74, 0x7d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x75, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x3d, 0x28, 0x74, 0x2d, 0x3d, 0x6e, 0x3d, 0x2b, 0x6e, + 0x29, 0x7c, 0x7c, 0x31, 0x2f, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, + 0x78, 0x28, 0x30, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x31, 0x2c, 0x28, 0x65, 0x2d, 0x6e, 0x29, 0x2f, 0x74, + 0x29, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x59, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x2c, 0x72, 0x3d, 0x56, 0x75, 0x28, 0x74, + 0x2c, 0x65, 0x29, 0x2c, 0x75, 0x3d, 0x5b, 0x74, 0x5d, 0x3b, 0x74, + 0x21, 0x3d, 0x3d, 0x72, 0x3b, 0x29, 0x74, 0x3d, 0x74, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x75, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x74, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x69, 0x3d, 0x75, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x65, 0x21, 0x3d, 0x3d, 0x72, 0x3b, 0x29, 0x75, 0x2e, + 0x73, 0x70, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x69, 0x2c, 0x30, 0x2c, + 0x65, 0x29, 0x2c, 0x65, 0x3d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5a, + 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x5b, 0x5d, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, + 0x21, 0x3d, 0x65, 0x3b, 0x29, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x6e, 0x29, 0x2c, 0x6e, 0x3d, 0x65, 0x2c, 0x65, 0x3d, 0x65, + 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x6e, 0x29, 0x2c, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x56, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x6e, 0x3d, 0x3d, 0x3d, 0x74, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x5a, 0x75, 0x28, 0x6e, 0x29, + 0x2c, 0x72, 0x3d, 0x5a, 0x75, 0x28, 0x74, 0x29, 0x2c, 0x75, 0x3d, + 0x65, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2c, 0x69, 0x3d, 0x72, + 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2c, 0x6f, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x3b, 0x75, 0x3d, 0x3d, 0x3d, 0x69, 0x3b, 0x29, 0x6f, + 0x3d, 0x75, 0x2c, 0x75, 0x3d, 0x65, 0x2e, 0x70, 0x6f, 0x70, 0x28, + 0x29, 0x2c, 0x69, 0x3d, 0x72, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x58, 0x75, 0x28, + 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x66, 0x69, 0x78, 0x65, 0x64, 0x7c, + 0x3d, 0x32, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x24, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x66, 0x69, + 0x78, 0x65, 0x64, 0x26, 0x3d, 0x2d, 0x37, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x75, 0x28, 0x6e, 0x29, + 0x7b, 0x6e, 0x2e, 0x66, 0x69, 0x78, 0x65, 0x64, 0x7c, 0x3d, 0x34, + 0x2c, 0x6e, 0x2e, 0x70, 0x78, 0x3d, 0x6e, 0x2e, 0x78, 0x2c, 0x6e, + 0x2e, 0x70, 0x79, 0x3d, 0x6e, 0x2e, 0x79, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x57, 0x75, 0x28, 0x6e, 0x29, + 0x7b, 0x6e, 0x2e, 0x66, 0x69, 0x78, 0x65, 0x64, 0x26, 0x3d, 0x2d, + 0x35, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x4a, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x30, 0x3b, + 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x3d, 0x30, 0x2c, 0x21, 0x6e, 0x2e, 0x6c, 0x65, 0x61, 0x66, 0x29, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x2c, 0x6f, + 0x3d, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x61, 0x3d, + 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x63, 0x3d, + 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x63, 0x3c, 0x61, 0x3b, 0x29, 0x69, + 0x3d, 0x6f, 0x5b, 0x63, 0x5d, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x21, + 0x3d, 0x69, 0x26, 0x26, 0x28, 0x4a, 0x75, 0x28, 0x69, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x2c, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x67, + 0x65, 0x2b, 0x3d, 0x69, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x2c, 0x72, 0x2b, 0x3d, 0x69, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x67, + 0x65, 0x2a, 0x69, 0x2e, 0x63, 0x78, 0x2c, 0x75, 0x2b, 0x3d, 0x69, + 0x2e, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x2a, 0x69, 0x2e, 0x63, + 0x79, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x29, 0x7b, 0x6e, 0x2e, 0x6c, 0x65, 0x61, 0x66, 0x7c, + 0x7c, 0x28, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x78, + 0x2b, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, 0x28, 0x29, 0x2d, 0x2e, 0x35, 0x2c, 0x6e, 0x2e, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x79, 0x2b, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x2d, + 0x2e, 0x35, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x74, + 0x2a, 0x65, 0x5b, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x6e, 0x2e, 0x63, 0x68, + 0x61, 0x72, 0x67, 0x65, 0x2b, 0x3d, 0x6e, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x3d, 0x6c, 0x2c, + 0x72, 0x2b, 0x3d, 0x6c, 0x2a, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x2e, 0x78, 0x2c, 0x75, 0x2b, 0x3d, 0x6c, 0x2a, 0x6e, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2e, 0x79, 0x7d, 0x6e, 0x2e, 0x63, + 0x78, 0x3d, 0x72, 0x2f, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x67, + 0x65, 0x2c, 0x6e, 0x2e, 0x63, 0x79, 0x3d, 0x75, 0x2f, 0x6e, 0x2e, + 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x47, 0x75, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, + 0x2e, 0x72, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x22, 0x73, 0x6f, 0x72, 0x74, 0x22, 0x2c, 0x22, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x22, 0x2c, 0x22, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x29, 0x2c, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x73, 0x3d, 0x6e, 0x2c, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, + 0x73, 0x3d, 0x72, 0x69, 0x2c, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4b, 0x75, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x3d, 0x5b, 0x6e, 0x5d, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, + 0x28, 0x6e, 0x3d, 0x65, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x29, + 0x3b, 0x29, 0x69, 0x66, 0x28, 0x74, 0x28, 0x6e, 0x29, 0x2c, 0x28, + 0x75, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, + 0x6e, 0x29, 0x26, 0x26, 0x28, 0x72, 0x3d, 0x75, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x29, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x3b, 0x2d, 0x2d, 0x72, 0x3e, + 0x3d, 0x30, 0x3b, 0x29, 0x65, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x75, 0x5b, 0x72, 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x51, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x5b, 0x6e, 0x5d, 0x2c, 0x72, 0x3d, 0x5b, 0x5d, 0x3b, 0x6e, 0x75, + 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x6e, 0x3d, 0x65, 0x2e, 0x70, 0x6f, + 0x70, 0x28, 0x29, 0x29, 0x3b, 0x29, 0x69, 0x66, 0x28, 0x72, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x29, 0x2c, 0x28, 0x69, 0x3d, + 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x29, + 0x26, 0x26, 0x28, 0x75, 0x3d, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x3d, 0x2d, 0x31, 0x3b, 0x2b, + 0x2b, 0x6f, 0x3c, 0x75, 0x3b, 0x29, 0x65, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x69, 0x5b, 0x6f, 0x5d, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x6e, 0x3d, + 0x72, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x29, 0x3b, 0x29, 0x74, + 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6e, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x74, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, + 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2d, + 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x69, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, + 0x6d, 0x65, 0x72, 0x67, 0x65, 0x28, 0x6e, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x6e, 0x2e, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x7c, 0x7c, 0x5b, + 0x5d, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, + 0x6e, 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x74, 0x7d, + 0x7d, 0x29, 0x7d, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x78, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x69, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x79, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, + 0x6e, 0x2e, 0x79, 0x30, 0x3d, 0x74, 0x2c, 0x6e, 0x2e, 0x79, 0x3d, + 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, + 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x69, 0x28, + 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x2d, 0x31, 0x2c, 0x65, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x72, 0x3d, 0x5b, + 0x5d, 0x3b, 0x2b, 0x2b, 0x74, 0x3c, 0x65, 0x3b, 0x29, 0x72, 0x5b, + 0x74, 0x5d, 0x3d, 0x30, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6c, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x31, 0x2c, 0x72, + 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x5b, 0x31, + 0x5d, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x69, 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x28, + 0x74, 0x3d, 0x6e, 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x3e, + 0x75, 0x26, 0x26, 0x28, 0x72, 0x3d, 0x65, 0x2c, 0x75, 0x3d, 0x74, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x69, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x2e, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x28, 0x66, 0x69, + 0x2c, 0x30, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x66, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2b, 0x74, 0x5b, 0x31, + 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x68, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x67, 0x69, 0x28, 0x6e, 0x2c, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x74, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x29, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x4c, + 0x4e, 0x32, 0x2b, 0x31, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x69, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x3d, 0x2d, 0x31, 0x2c, 0x72, 0x3d, 0x2b, 0x6e, 0x5b, 0x30, 0x5d, + 0x2c, 0x75, 0x3d, 0x28, 0x6e, 0x5b, 0x31, 0x5d, 0x2d, 0x72, 0x29, + 0x2f, 0x74, 0x2c, 0x69, 0x3d, 0x5b, 0x5d, 0x3b, 0x2b, 0x2b, 0x65, + 0x3c, 0x3d, 0x74, 0x3b, 0x29, 0x69, 0x5b, 0x65, 0x5d, 0x3d, 0x75, + 0x2a, 0x65, 0x2b, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x69, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x70, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x5b, 0x74, 0x61, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6e, + 0x29, 0x2c, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x6e, 0x29, + 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x76, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x2d, 0x74, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x69, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, + 0x2e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x65, 0x78, 0x74, + 0x3b, 0x6e, 0x2e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x65, + 0x78, 0x74, 0x3d, 0x74, 0x2c, 0x74, 0x2e, 0x5f, 0x70, 0x61, 0x63, + 0x6b, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x3d, 0x6e, 0x2c, 0x74, 0x2e, + 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x3d, + 0x65, 0x2c, 0x65, 0x2e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x70, + 0x72, 0x65, 0x76, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x6e, 0x2e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x65, + 0x78, 0x74, 0x3d, 0x74, 0x2c, 0x74, 0x2e, 0x5f, 0x70, 0x61, 0x63, + 0x6b, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x3d, 0x6e, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x69, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, + 0x2e, 0x78, 0x2d, 0x6e, 0x2e, 0x78, 0x2c, 0x72, 0x3d, 0x74, 0x2e, + 0x79, 0x2d, 0x6e, 0x2e, 0x79, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x72, + 0x2b, 0x74, 0x2e, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x2e, 0x39, 0x39, 0x39, 0x2a, 0x75, 0x2a, 0x75, 0x3e, 0x65, 0x2a, + 0x65, 0x2b, 0x72, 0x2a, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, + 0x29, 0x7b, 0x73, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x6e, 0x2e, 0x78, 0x2d, 0x6e, 0x2e, 0x72, 0x2c, 0x73, + 0x29, 0x2c, 0x66, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, + 0x78, 0x28, 0x6e, 0x2e, 0x78, 0x2b, 0x6e, 0x2e, 0x72, 0x2c, 0x66, + 0x29, 0x2c, 0x68, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x6e, 0x2e, 0x79, 0x2d, 0x6e, 0x2e, 0x72, 0x2c, 0x68, + 0x29, 0x2c, 0x67, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, + 0x78, 0x28, 0x6e, 0x2e, 0x79, 0x2b, 0x6e, 0x2e, 0x72, 0x2c, 0x67, + 0x29, 0x7d, 0x69, 0x66, 0x28, 0x28, 0x65, 0x3d, 0x6e, 0x2e, 0x63, + 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x29, 0x26, 0x26, 0x28, + 0x6c, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, + 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, 0x2c, 0x63, 0x2c, 0x6c, 0x2c, + 0x73, 0x3d, 0x31, 0x2f, 0x30, 0x2c, 0x66, 0x3d, 0x2d, 0x31, 0x2f, + 0x30, 0x2c, 0x68, 0x3d, 0x31, 0x2f, 0x30, 0x2c, 0x67, 0x3d, 0x2d, + 0x31, 0x2f, 0x30, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x66, 0x6f, + 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x78, 0x69, 0x29, 0x2c, 0x72, + 0x3d, 0x65, 0x5b, 0x30, 0x5d, 0x2c, 0x72, 0x2e, 0x78, 0x3d, 0x2d, + 0x72, 0x2e, 0x72, 0x2c, 0x72, 0x2e, 0x79, 0x3d, 0x30, 0x2c, 0x74, + 0x28, 0x72, 0x29, 0x2c, 0x6c, 0x3e, 0x31, 0x26, 0x26, 0x28, 0x75, + 0x3d, 0x65, 0x5b, 0x31, 0x5d, 0x2c, 0x75, 0x2e, 0x78, 0x3d, 0x75, + 0x2e, 0x72, 0x2c, 0x75, 0x2e, 0x79, 0x3d, 0x30, 0x2c, 0x74, 0x28, + 0x75, 0x29, 0x2c, 0x6c, 0x3e, 0x32, 0x29, 0x29, 0x66, 0x6f, 0x72, + 0x28, 0x69, 0x3d, 0x65, 0x5b, 0x32, 0x5d, 0x2c, 0x77, 0x69, 0x28, + 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x29, 0x2c, 0x74, 0x28, 0x69, 0x29, + 0x2c, 0x64, 0x69, 0x28, 0x72, 0x2c, 0x69, 0x29, 0x2c, 0x72, 0x2e, + 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x3d, + 0x69, 0x2c, 0x64, 0x69, 0x28, 0x69, 0x2c, 0x75, 0x29, 0x2c, 0x75, + 0x3d, 0x72, 0x2e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x65, + 0x78, 0x74, 0x2c, 0x6f, 0x3d, 0x33, 0x3b, 0x6c, 0x3e, 0x6f, 0x3b, + 0x6f, 0x2b, 0x2b, 0x29, 0x7b, 0x77, 0x69, 0x28, 0x72, 0x2c, 0x75, + 0x2c, 0x69, 0x3d, 0x65, 0x5b, 0x6f, 0x5d, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x70, 0x3d, 0x30, 0x2c, 0x76, 0x3d, 0x31, 0x2c, 0x64, + 0x3d, 0x31, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x61, 0x3d, 0x75, 0x2e, + 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x3b, + 0x61, 0x21, 0x3d, 0x3d, 0x75, 0x3b, 0x61, 0x3d, 0x61, 0x2e, 0x5f, + 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x2c, 0x76, + 0x2b, 0x2b, 0x29, 0x69, 0x66, 0x28, 0x79, 0x69, 0x28, 0x61, 0x2c, + 0x69, 0x29, 0x29, 0x7b, 0x70, 0x3d, 0x31, 0x3b, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x7d, 0x69, 0x66, 0x28, 0x31, 0x3d, 0x3d, 0x70, 0x29, + 0x66, 0x6f, 0x72, 0x28, 0x63, 0x3d, 0x72, 0x2e, 0x5f, 0x70, 0x61, + 0x63, 0x6b, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x3b, 0x63, 0x21, 0x3d, + 0x3d, 0x61, 0x2e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x72, + 0x65, 0x76, 0x26, 0x26, 0x21, 0x79, 0x69, 0x28, 0x63, 0x2c, 0x69, + 0x29, 0x3b, 0x63, 0x3d, 0x63, 0x2e, 0x5f, 0x70, 0x61, 0x63, 0x6b, + 0x5f, 0x70, 0x72, 0x65, 0x76, 0x2c, 0x64, 0x2b, 0x2b, 0x29, 0x3b, + 0x70, 0x3f, 0x28, 0x64, 0x3e, 0x76, 0x7c, 0x7c, 0x76, 0x3d, 0x3d, + 0x64, 0x26, 0x26, 0x75, 0x2e, 0x72, 0x3c, 0x72, 0x2e, 0x72, 0x3f, + 0x6d, 0x69, 0x28, 0x72, 0x2c, 0x75, 0x3d, 0x61, 0x29, 0x3a, 0x6d, + 0x69, 0x28, 0x72, 0x3d, 0x63, 0x2c, 0x75, 0x29, 0x2c, 0x6f, 0x2d, + 0x2d, 0x29, 0x3a, 0x28, 0x64, 0x69, 0x28, 0x72, 0x2c, 0x69, 0x29, + 0x2c, 0x75, 0x3d, 0x69, 0x2c, 0x74, 0x28, 0x69, 0x29, 0x29, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x6d, 0x3d, 0x28, 0x73, 0x2b, 0x66, 0x29, + 0x2f, 0x32, 0x2c, 0x79, 0x3d, 0x28, 0x68, 0x2b, 0x67, 0x29, 0x2f, + 0x32, 0x2c, 0x4d, 0x3d, 0x30, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6f, + 0x3d, 0x30, 0x3b, 0x6c, 0x3e, 0x6f, 0x3b, 0x6f, 0x2b, 0x2b, 0x29, + 0x69, 0x3d, 0x65, 0x5b, 0x6f, 0x5d, 0x2c, 0x69, 0x2e, 0x78, 0x2d, + 0x3d, 0x6d, 0x2c, 0x69, 0x2e, 0x79, 0x2d, 0x3d, 0x79, 0x2c, 0x4d, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x4d, + 0x2c, 0x69, 0x2e, 0x72, 0x2b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x71, 0x72, 0x74, 0x28, 0x69, 0x2e, 0x78, 0x2a, 0x69, 0x2e, 0x78, + 0x2b, 0x69, 0x2e, 0x79, 0x2a, 0x69, 0x2e, 0x79, 0x29, 0x29, 0x3b, + 0x6e, 0x2e, 0x72, 0x3d, 0x4d, 0x2c, 0x65, 0x2e, 0x66, 0x6f, 0x72, + 0x45, 0x61, 0x63, 0x68, 0x28, 0x62, 0x69, 0x29, 0x7d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x78, 0x69, 0x28, + 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, + 0x6e, 0x65, 0x78, 0x74, 0x3d, 0x6e, 0x2e, 0x5f, 0x70, 0x61, 0x63, + 0x6b, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x3d, 0x6e, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x69, 0x28, 0x6e, + 0x29, 0x7b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6e, 0x2e, + 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x5f, 0x6e, 0x65, 0x78, 0x74, 0x2c, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6e, 0x2e, 0x5f, 0x70, + 0x61, 0x63, 0x6b, 0x5f, 0x70, 0x72, 0x65, 0x76, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5f, 0x69, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x75, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, + 0x65, 0x6e, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x78, 0x3d, 0x74, + 0x2b, 0x3d, 0x72, 0x2a, 0x6e, 0x2e, 0x78, 0x2c, 0x6e, 0x2e, 0x79, + 0x3d, 0x65, 0x2b, 0x3d, 0x72, 0x2a, 0x6e, 0x2e, 0x79, 0x2c, 0x6e, + 0x2e, 0x72, 0x2a, 0x3d, 0x72, 0x2c, 0x75, 0x29, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x2d, 0x31, 0x2c, 0x6f, + 0x3d, 0x75, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, + 0x2b, 0x69, 0x3c, 0x6f, 0x3b, 0x29, 0x5f, 0x69, 0x28, 0x75, 0x5b, + 0x69, 0x5d, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x6e, 0x2e, 0x72, 0x2b, 0x65, 0x2e, 0x72, 0x2c, 0x75, + 0x3d, 0x74, 0x2e, 0x78, 0x2d, 0x6e, 0x2e, 0x78, 0x2c, 0x69, 0x3d, + 0x74, 0x2e, 0x79, 0x2d, 0x6e, 0x2e, 0x79, 0x3b, 0x69, 0x66, 0x28, + 0x72, 0x26, 0x26, 0x28, 0x75, 0x7c, 0x7c, 0x69, 0x29, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x74, 0x2e, 0x72, 0x2b, 0x65, + 0x2e, 0x72, 0x2c, 0x61, 0x3d, 0x75, 0x2a, 0x75, 0x2b, 0x69, 0x2a, + 0x69, 0x3b, 0x6f, 0x2a, 0x3d, 0x6f, 0x2c, 0x72, 0x2a, 0x3d, 0x72, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, 0x2e, 0x35, 0x2b, 0x28, + 0x72, 0x2d, 0x6f, 0x29, 0x2f, 0x28, 0x32, 0x2a, 0x61, 0x29, 0x2c, + 0x6c, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, + 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x30, + 0x2c, 0x32, 0x2a, 0x6f, 0x2a, 0x28, 0x72, 0x2b, 0x61, 0x29, 0x2d, + 0x28, 0x72, 0x2d, 0x3d, 0x61, 0x29, 0x2a, 0x72, 0x2d, 0x6f, 0x2a, + 0x6f, 0x29, 0x29, 0x2f, 0x28, 0x32, 0x2a, 0x61, 0x29, 0x3b, 0x65, + 0x2e, 0x78, 0x3d, 0x6e, 0x2e, 0x78, 0x2b, 0x63, 0x2a, 0x75, 0x2b, + 0x6c, 0x2a, 0x69, 0x2c, 0x65, 0x2e, 0x79, 0x3d, 0x6e, 0x2e, 0x79, + 0x2b, 0x63, 0x2a, 0x69, 0x2d, 0x6c, 0x2a, 0x75, 0x7d, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x65, 0x2e, 0x78, 0x3d, 0x6e, 0x2e, 0x78, 0x2b, + 0x72, 0x2c, 0x65, 0x2e, 0x79, 0x3d, 0x6e, 0x2e, 0x79, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x69, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3d, 0x3d, + 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3f, 0x31, 0x3a, + 0x32, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6b, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x74, 0x5b, 0x30, 0x5d, 0x3a, + 0x6e, 0x2e, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x45, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x28, 0x74, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x3f, 0x65, 0x5b, 0x74, 0x2d, 0x31, 0x5d, 0x3a, 0x6e, 0x2e, + 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x41, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x65, 0x2f, 0x28, 0x74, 0x2e, 0x69, + 0x2d, 0x6e, 0x2e, 0x69, 0x29, 0x3b, 0x74, 0x2e, 0x63, 0x2d, 0x3d, + 0x72, 0x2c, 0x74, 0x2e, 0x73, 0x2b, 0x3d, 0x65, 0x2c, 0x6e, 0x2e, + 0x63, 0x2b, 0x3d, 0x72, 0x2c, 0x74, 0x2e, 0x7a, 0x2b, 0x3d, 0x65, + 0x2c, 0x74, 0x2e, 0x6d, 0x2b, 0x3d, 0x65, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 0x69, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, + 0x65, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x6e, + 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x2c, 0x69, + 0x3d, 0x75, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2d, + 0x2d, 0x69, 0x3e, 0x3d, 0x30, 0x3b, 0x29, 0x74, 0x3d, 0x75, 0x5b, + 0x69, 0x5d, 0x2c, 0x74, 0x2e, 0x7a, 0x2b, 0x3d, 0x65, 0x2c, 0x74, + 0x2e, 0x6d, 0x2b, 0x3d, 0x65, 0x2c, 0x65, 0x2b, 0x3d, 0x74, 0x2e, + 0x73, 0x2b, 0x28, 0x72, 0x2b, 0x3d, 0x74, 0x2e, 0x63, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x69, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x61, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x3d, 0x3d, 0x3d, 0x74, 0x2e, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x3f, 0x6e, 0x2e, 0x61, 0x3a, 0x65, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7a, 0x69, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, + 0x2b, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x6e, 0x2c, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x79, 0x7d, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x71, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x72, 0x65, 0x64, 0x75, 0x63, 0x65, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2b, 0x74, 0x2e, 0x78, 0x7d, 0x2c, 0x30, 0x29, 0x2f, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4c, 0x69, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x26, 0x26, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x4c, 0x69, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x29, + 0x3a, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x54, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x29, 0x3f, 0x54, 0x69, 0x28, 0x65, 0x5b, 0x74, + 0x2d, 0x31, 0x5d, 0x29, 0x3a, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x52, 0x69, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x78, 0x3a, 0x6e, 0x2e, + 0x78, 0x2c, 0x79, 0x3a, 0x6e, 0x2e, 0x79, 0x2c, 0x64, 0x78, 0x3a, + 0x6e, 0x2e, 0x64, 0x78, 0x2c, 0x64, 0x79, 0x3a, 0x6e, 0x2e, 0x64, + 0x79, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x44, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x78, 0x2b, 0x74, 0x5b, 0x33, + 0x5d, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, 0x79, 0x2b, 0x74, 0x5b, 0x30, + 0x5d, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x64, 0x78, 0x2d, 0x74, 0x5b, + 0x31, 0x5d, 0x2d, 0x74, 0x5b, 0x33, 0x5d, 0x2c, 0x69, 0x3d, 0x6e, + 0x2e, 0x64, 0x79, 0x2d, 0x74, 0x5b, 0x30, 0x5d, 0x2d, 0x74, 0x5b, + 0x32, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, + 0x3e, 0x75, 0x26, 0x26, 0x28, 0x65, 0x2b, 0x3d, 0x75, 0x2f, 0x32, + 0x2c, 0x75, 0x3d, 0x30, 0x29, 0x2c, 0x30, 0x3e, 0x69, 0x26, 0x26, + 0x28, 0x72, 0x2b, 0x3d, 0x69, 0x2f, 0x32, 0x2c, 0x69, 0x3d, 0x30, + 0x29, 0x2c, 0x7b, 0x78, 0x3a, 0x65, 0x2c, 0x79, 0x3a, 0x72, 0x2c, + 0x64, 0x78, 0x3a, 0x75, 0x2c, 0x64, 0x79, 0x3a, 0x69, 0x7d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x50, 0x69, + 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, + 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x3d, 0x6e, 0x5b, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3e, 0x74, 0x3f, 0x5b, 0x74, + 0x2c, 0x65, 0x5d, 0x3a, 0x5b, 0x65, 0x2c, 0x74, 0x5d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x69, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x3f, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x3a, 0x50, 0x69, 0x28, 0x6e, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x29, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6a, 0x69, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x75, 0x3d, 0x65, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, + 0x6e, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x69, 0x3d, 0x72, 0x28, 0x74, + 0x5b, 0x30, 0x5d, 0x2c, 0x74, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x28, 0x75, 0x28, 0x6e, 0x29, 0x29, 0x7d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x46, + 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x2c, 0x72, 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x2c, 0x69, 0x3d, 0x6e, + 0x5b, 0x72, 0x5d, 0x2c, 0x6f, 0x3d, 0x6e, 0x5b, 0x75, 0x5d, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x3e, 0x6f, 0x26, + 0x26, 0x28, 0x65, 0x3d, 0x72, 0x2c, 0x72, 0x3d, 0x75, 0x2c, 0x75, + 0x3d, 0x65, 0x2c, 0x65, 0x3d, 0x69, 0x2c, 0x69, 0x3d, 0x6f, 0x2c, + 0x6f, 0x3d, 0x65, 0x29, 0x2c, 0x6e, 0x5b, 0x72, 0x5d, 0x3d, 0x74, + 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x69, 0x29, 0x2c, 0x6e, + 0x5b, 0x75, 0x5d, 0x3d, 0x74, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, + 0x6f, 0x29, 0x2c, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x48, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3f, 0x7b, 0x66, 0x6c, 0x6f, + 0x6f, 0x72, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, + 0x74, 0x2f, 0x6e, 0x29, 0x2a, 0x6e, 0x7d, 0x2c, 0x63, 0x65, 0x69, + 0x6c, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x74, 0x2f, + 0x6e, 0x29, 0x2a, 0x6e, 0x7d, 0x7d, 0x3a, 0x6d, 0x6c, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4f, 0x69, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x75, 0x3d, 0x5b, 0x5d, 0x2c, 0x69, 0x3d, 0x5b, 0x5d, + 0x2c, 0x6f, 0x3d, 0x30, 0x2c, 0x61, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2c, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x2d, 0x31, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6e, 0x5b, 0x61, + 0x5d, 0x3c, 0x6e, 0x5b, 0x30, 0x5d, 0x26, 0x26, 0x28, 0x6e, 0x3d, + 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x29, 0x2e, 0x72, + 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, 0x2c, 0x74, 0x3d, + 0x74, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x29, 0x2e, 0x72, + 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, 0x29, 0x3b, 0x2b, + 0x2b, 0x6f, 0x3c, 0x3d, 0x61, 0x3b, 0x29, 0x75, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x65, 0x28, 0x6e, 0x5b, 0x6f, 0x2d, 0x31, 0x5d, + 0x2c, 0x6e, 0x5b, 0x6f, 0x5d, 0x29, 0x29, 0x2c, 0x69, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x72, 0x28, 0x74, 0x5b, 0x6f, 0x2d, 0x31, + 0x5d, 0x2c, 0x74, 0x5b, 0x6f, 0x5d, 0x29, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x3d, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, 0x65, 0x63, 0x74, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x31, 0x2c, 0x61, 0x29, 0x2d, 0x31, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x5b, 0x65, 0x5d, + 0x28, 0x75, 0x5b, 0x65, 0x5d, 0x28, 0x74, 0x29, 0x29, 0x7d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, 0x69, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2c, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x3e, 0x32, 0x3f, 0x4f, 0x69, 0x3a, 0x6a, 0x69, 0x2c, 0x63, + 0x3d, 0x72, 0x3f, 0x49, 0x75, 0x3a, 0x4f, 0x75, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x3d, 0x75, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x63, 0x2c, 0x65, 0x29, 0x2c, 0x61, 0x3d, 0x75, 0x28, + 0x74, 0x2c, 0x6e, 0x2c, 0x63, 0x2c, 0x6d, 0x75, 0x29, 0x2c, 0x69, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6f, 0x28, 0x6e, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x2c, + 0x61, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x2e, + 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x28, 0x6e, 0x29, 0x7d, 0x2c, 0x69, + 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x6e, 0x3d, 0x74, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x29, 0x2c, 0x75, 0x28, 0x29, 0x29, 0x3a, + 0x6e, 0x7d, 0x2c, 0x69, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x6e, 0x2c, 0x75, 0x28, 0x29, + 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x69, 0x2e, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x69, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x28, 0x6e, 0x29, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, + 0x6c, 0x61, 0x74, 0x65, 0x28, 0x44, 0x75, 0x29, 0x7d, 0x2c, 0x69, + 0x2e, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x72, 0x3d, 0x6e, 0x2c, 0x75, 0x28, 0x29, 0x29, 0x3a, 0x72, 0x7d, + 0x2c, 0x69, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, + 0x61, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, 0x6e, + 0x2c, 0x75, 0x28, 0x29, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x69, 0x2e, + 0x74, 0x69, 0x63, 0x6b, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x58, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, + 0x2c, 0x69, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x24, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, + 0x7d, 0x2c, 0x69, 0x2e, 0x6e, 0x69, 0x63, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5a, 0x69, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x2c, 0x75, 0x28, 0x29, 0x7d, 0x2c, 0x69, 0x2e, 0x63, + 0x6f, 0x70, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x49, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, + 0x7d, 0x2c, 0x75, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x59, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, + 0x72, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x22, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x2c, 0x22, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x2c, 0x22, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, + 0x22, 0x2c, 0x22, 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x22, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5a, 0x69, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x46, 0x69, 0x28, 0x6e, 0x2c, 0x48, 0x69, 0x28, 0x56, + 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x5b, 0x32, 0x5d, 0x29, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, + 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x75, 0x6c, 0x6c, + 0x3d, 0x3d, 0x74, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x31, 0x30, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x50, 0x69, 0x28, 0x6e, + 0x29, 0x2c, 0x72, 0x3d, 0x65, 0x5b, 0x31, 0x5d, 0x2d, 0x65, 0x5b, + 0x30, 0x5d, 0x2c, 0x75, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, + 0x6f, 0x77, 0x28, 0x31, 0x30, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x6c, 0x6f, 0x67, 0x28, 0x72, 0x2f, 0x74, 0x29, 0x2f, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x4c, 0x4e, 0x31, 0x30, 0x29, 0x29, 0x2c, 0x69, + 0x3d, 0x74, 0x2f, 0x72, 0x2a, 0x75, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x2e, 0x31, 0x35, 0x3e, 0x3d, 0x69, 0x3f, 0x75, 0x2a, + 0x3d, 0x31, 0x30, 0x3a, 0x2e, 0x33, 0x35, 0x3e, 0x3d, 0x69, 0x3f, + 0x75, 0x2a, 0x3d, 0x35, 0x3a, 0x2e, 0x37, 0x35, 0x3e, 0x3d, 0x69, + 0x26, 0x26, 0x28, 0x75, 0x2a, 0x3d, 0x32, 0x29, 0x2c, 0x65, 0x5b, + 0x30, 0x5d, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, + 0x6c, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x2f, 0x75, 0x29, 0x2a, 0x75, + 0x2c, 0x65, 0x5b, 0x31, 0x5d, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x65, 0x5b, 0x31, 0x5d, 0x2f, + 0x75, 0x29, 0x2a, 0x75, 0x2b, 0x2e, 0x35, 0x2a, 0x75, 0x2c, 0x65, + 0x5b, 0x32, 0x5d, 0x3d, 0x75, 0x2c, 0x65, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x58, 0x69, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x61, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2e, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x28, 0x74, 0x61, 0x2c, 0x56, 0x69, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x24, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x56, 0x69, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x75, 0x3d, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x65, + 0x63, 0x28, 0x65, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x75, 0x2e, 0x73, + 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x2c, 0x22, 0x73, 0x22, 0x3d, + 0x3d, 0x3d, 0x75, 0x5b, 0x38, 0x5d, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x3d, 0x74, 0x61, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x28, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x67, 0x61, 0x28, 0x72, 0x5b, + 0x30, 0x5d, 0x29, 0x2c, 0x67, 0x61, 0x28, 0x72, 0x5b, 0x31, 0x5d, + 0x29, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x75, 0x5b, 0x37, 0x5d, 0x7c, 0x7c, 0x28, 0x75, 0x5b, 0x37, 0x5d, + 0x3d, 0x22, 0x2e, 0x22, 0x2b, 0x42, 0x69, 0x28, 0x69, 0x2e, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x28, 0x72, 0x5b, 0x32, 0x5d, 0x29, 0x29, + 0x29, 0x2c, 0x75, 0x5b, 0x38, 0x5d, 0x3d, 0x22, 0x66, 0x22, 0x2c, + 0x65, 0x3d, 0x74, 0x61, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x28, 0x75, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, + 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, + 0x28, 0x69, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x6e, 0x29, + 0x29, 0x2b, 0x69, 0x2e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x7d, + 0x7d, 0x75, 0x5b, 0x37, 0x5d, 0x7c, 0x7c, 0x28, 0x75, 0x5b, 0x37, + 0x5d, 0x3d, 0x22, 0x2e, 0x22, 0x2b, 0x57, 0x69, 0x28, 0x75, 0x5b, + 0x38, 0x5d, 0x2c, 0x72, 0x29, 0x29, 0x2c, 0x65, 0x3d, 0x75, 0x2e, + 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x65, 0x3d, 0x22, 0x2c, 0x2e, 0x22, 0x2b, 0x42, + 0x69, 0x28, 0x72, 0x5b, 0x32, 0x5d, 0x29, 0x2b, 0x22, 0x66, 0x22, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x65, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, 0x69, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x6e, 0x29, 0x2f, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x4e, 0x31, 0x30, 0x2b, 0x2e, + 0x30, 0x31, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x57, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x3d, 0x42, 0x69, 0x28, 0x74, 0x5b, 0x32, + 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x20, 0x69, 0x6e, 0x20, 0x79, 0x6c, 0x3f, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x61, 0x62, 0x73, 0x28, 0x65, 0x2d, 0x42, 0x69, 0x28, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x67, 0x61, 0x28, + 0x74, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x67, 0x61, 0x28, 0x74, 0x5b, + 0x31, 0x5d, 0x29, 0x29, 0x29, 0x29, 0x2b, 0x20, 0x2b, 0x28, 0x22, + 0x65, 0x22, 0x21, 0x3d, 0x3d, 0x6e, 0x29, 0x3a, 0x65, 0x2d, 0x32, + 0x2a, 0x28, 0x22, 0x25, 0x22, 0x3d, 0x3d, 0x3d, 0x6e, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a, 0x69, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x65, 0x3f, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x30, 0x3e, + 0x6e, 0x3f, 0x30, 0x3a, 0x6e, 0x29, 0x3a, 0x2d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x6e, 0x3e, 0x30, 0x3f, 0x30, + 0x3a, 0x2d, 0x6e, 0x29, 0x29, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x6c, 0x6f, 0x67, 0x28, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3f, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x3a, + 0x2d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x74, + 0x2c, 0x2d, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x28, 0x75, 0x28, 0x74, 0x29, 0x29, + 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x28, 0x6e, 0x2e, 0x69, 0x6e, 0x76, 0x65, + 0x72, 0x74, 0x28, 0x74, 0x29, 0x29, 0x7d, 0x2c, 0x6f, 0x2e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, + 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x3e, 0x3d, 0x30, 0x2c, 0x6e, 0x2e, + 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x28, 0x72, 0x3d, 0x74, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x29, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x75, 0x29, 0x29, 0x2c, + 0x6f, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x6f, 0x2e, 0x62, 0x61, 0x73, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x2b, 0x65, 0x2c, + 0x6e, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x72, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x75, 0x29, 0x29, 0x2c, 0x6f, 0x29, 0x3a, + 0x74, 0x7d, 0x2c, 0x6f, 0x2e, 0x6e, 0x69, 0x63, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x3d, 0x46, 0x69, 0x28, 0x72, 0x2e, 0x6d, + 0x61, 0x70, 0x28, 0x75, 0x29, 0x2c, 0x65, 0x3f, 0x4d, 0x61, 0x74, + 0x68, 0x3a, 0x78, 0x6c, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, + 0x74, 0x29, 0x2c, 0x72, 0x3d, 0x74, 0x2e, 0x6d, 0x61, 0x70, 0x28, + 0x69, 0x29, 0x2c, 0x6f, 0x7d, 0x2c, 0x6f, 0x2e, 0x74, 0x69, 0x63, + 0x6b, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x50, 0x69, + 0x28, 0x72, 0x29, 0x2c, 0x6f, 0x3d, 0x5b, 0x5d, 0x2c, 0x61, 0x3d, + 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x63, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, + 0x2c, 0x6c, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, + 0x6f, 0x72, 0x28, 0x75, 0x28, 0x61, 0x29, 0x29, 0x2c, 0x73, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x75, + 0x28, 0x63, 0x29, 0x29, 0x2c, 0x66, 0x3d, 0x74, 0x25, 0x31, 0x3f, + 0x32, 0x3a, 0x74, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x73, 0x46, 0x69, + 0x6e, 0x69, 0x74, 0x65, 0x28, 0x73, 0x2d, 0x6c, 0x29, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x65, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, + 0x73, 0x3e, 0x6c, 0x3b, 0x6c, 0x2b, 0x2b, 0x29, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x68, 0x3d, 0x31, 0x3b, 0x66, 0x3e, + 0x68, 0x3b, 0x68, 0x2b, 0x2b, 0x29, 0x6f, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x69, 0x28, 0x6c, 0x29, 0x2a, 0x68, 0x29, 0x3b, 0x6f, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x69, 0x28, 0x6c, 0x29, 0x29, + 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x6f, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x69, 0x28, 0x6c, 0x29, 0x29, + 0x3b, 0x6c, 0x2b, 0x2b, 0x3c, 0x73, 0x3b, 0x29, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x68, 0x3d, 0x66, 0x2d, 0x31, 0x3b, + 0x68, 0x3e, 0x30, 0x3b, 0x68, 0x2d, 0x2d, 0x29, 0x6f, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x69, 0x28, 0x6c, 0x29, 0x2a, 0x68, 0x29, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x3d, 0x30, 0x3b, 0x6f, 0x5b, + 0x6c, 0x5d, 0x3c, 0x61, 0x3b, 0x6c, 0x2b, 0x2b, 0x29, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x73, 0x3d, 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x6f, 0x5b, 0x73, 0x2d, 0x31, 0x5d, 0x3e, 0x63, + 0x3b, 0x73, 0x2d, 0x2d, 0x29, 0x3b, 0x6f, 0x3d, 0x6f, 0x2e, 0x73, + 0x6c, 0x69, 0x63, 0x65, 0x28, 0x6c, 0x2c, 0x73, 0x29, 0x7d, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x2c, 0x6f, 0x2e, + 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x6c, + 0x3b, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x3f, 0x74, 0x3d, + 0x4d, 0x6c, 0x3a, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x21, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x74, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x28, 0x74, 0x29, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x72, 0x2c, 0x61, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x6d, 0x61, 0x78, 0x28, 0x2e, 0x31, 0x2c, 0x6e, 0x2f, 0x6f, 0x2e, + 0x74, 0x69, 0x63, 0x6b, 0x73, 0x28, 0x29, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x29, 0x2c, 0x63, 0x3d, 0x65, 0x3f, 0x28, 0x72, + 0x3d, 0x31, 0x65, 0x2d, 0x31, 0x32, 0x2c, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x29, 0x3a, 0x28, 0x72, 0x3d, 0x2d, + 0x31, 0x65, 0x2d, 0x31, 0x32, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x2f, 0x69, 0x28, 0x63, 0x28, 0x75, 0x28, 0x6e, 0x29, 0x2b, + 0x72, 0x29, 0x29, 0x3c, 0x3d, 0x61, 0x3f, 0x74, 0x28, 0x6e, 0x29, + 0x3a, 0x22, 0x22, 0x7d, 0x7d, 0x2c, 0x6f, 0x2e, 0x63, 0x6f, 0x70, + 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4a, 0x69, + 0x28, 0x6e, 0x2e, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x29, 0x2c, 0x74, + 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7d, 0x2c, 0x59, 0x69, 0x28, 0x6f, + 0x2c, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x47, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x28, 0x75, 0x28, 0x74, 0x29, 0x29, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x75, 0x3d, 0x4b, 0x69, 0x28, 0x74, 0x29, 0x2c, 0x69, 0x3d, + 0x4b, 0x69, 0x28, 0x31, 0x2f, 0x74, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, + 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, + 0x28, 0x6e, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x74, + 0x29, 0x29, 0x7d, 0x2c, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6e, 0x2e, 0x64, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x28, 0x28, 0x65, 0x3d, 0x74, 0x2e, 0x6d, 0x61, + 0x70, 0x28, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x29, 0x29, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x75, 0x29, 0x29, 0x2c, 0x72, 0x29, 0x3a, + 0x65, 0x7d, 0x2c, 0x72, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x73, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x58, 0x69, 0x28, + 0x65, 0x2c, 0x6e, 0x29, 0x7d, 0x2c, 0x72, 0x2e, 0x74, 0x69, 0x63, + 0x6b, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x24, 0x69, 0x28, 0x65, + 0x2c, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x2c, 0x72, 0x2e, 0x6e, 0x69, + 0x63, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x5a, 0x69, + 0x28, 0x65, 0x2c, 0x6e, 0x29, 0x29, 0x7d, 0x2c, 0x72, 0x2e, 0x65, + 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x75, 0x3d, 0x4b, 0x69, 0x28, 0x74, 0x3d, 0x6f, 0x29, 0x2c, + 0x69, 0x3d, 0x4b, 0x69, 0x28, 0x31, 0x2f, 0x74, 0x29, 0x2c, 0x6e, + 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x65, 0x2e, 0x6d, + 0x61, 0x70, 0x28, 0x75, 0x29, 0x29, 0x2c, 0x72, 0x29, 0x3a, 0x74, + 0x7d, 0x2c, 0x72, 0x2e, 0x63, 0x6f, 0x70, 0x79, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x69, 0x28, 0x6e, 0x2e, 0x63, + 0x6f, 0x70, 0x79, 0x28, 0x29, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7d, + 0x2c, 0x59, 0x69, 0x28, 0x72, 0x2c, 0x6e, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4b, 0x69, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3e, 0x74, 0x3f, 0x2d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x2d, 0x74, + 0x2c, 0x6e, 0x29, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, + 0x77, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x51, 0x69, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x5b, 0x28, 0x28, 0x75, 0x2e, 0x67, 0x65, 0x74, + 0x28, 0x65, 0x29, 0x7c, 0x7c, 0x28, 0x22, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x22, 0x3d, 0x3d, 0x3d, 0x74, 0x2e, 0x74, 0x3f, 0x75, 0x2e, + 0x73, 0x65, 0x74, 0x28, 0x65, 0x2c, 0x6e, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x65, 0x29, 0x29, 0x3a, 0x30, 0x2f, 0x30, 0x29, 0x29, + 0x2d, 0x31, 0x29, 0x25, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x72, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x2b, 0x65, 0x2a, 0x6e, 0x7d, 0x29, 0x7d, 0x76, + 0x61, 0x72, 0x20, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x3b, 0x6e, 0x3d, 0x5b, 0x5d, 0x2c, 0x75, 0x3d, 0x6e, 0x65, 0x77, + 0x20, 0x6c, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x69, 0x2c, 0x6f, 0x3d, 0x2d, 0x31, 0x2c, 0x61, 0x3d, 0x72, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x6f, 0x3c, + 0x61, 0x3b, 0x29, 0x75, 0x2e, 0x68, 0x61, 0x73, 0x28, 0x69, 0x3d, + 0x72, 0x5b, 0x6f, 0x5d, 0x29, 0x7c, 0x7c, 0x75, 0x2e, 0x73, 0x65, + 0x74, 0x28, 0x69, 0x2c, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x69, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x5b, 0x74, 0x2e, 0x74, 0x5d, 0x2e, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x28, 0x65, 0x2c, 0x74, 0x2e, 0x61, 0x29, 0x7d, 0x2c, 0x65, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x69, 0x3d, 0x6e, 0x2c, 0x6f, 0x3d, 0x30, 0x2c, 0x74, 0x3d, 0x7b, + 0x74, 0x3a, 0x22, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x2c, 0x61, + 0x3a, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x7d, + 0x2c, 0x65, 0x29, 0x3a, 0x69, 0x7d, 0x2c, 0x65, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x2c, 0x61, + 0x29, 0x7b, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x26, 0x26, + 0x28, 0x61, 0x3d, 0x30, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, + 0x3d, 0x75, 0x5b, 0x30, 0x5d, 0x2c, 0x6c, 0x3d, 0x75, 0x5b, 0x31, + 0x5d, 0x2c, 0x73, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x32, 0x3f, 0x28, 0x63, 0x3d, 0x28, 0x63, 0x2b, 0x6c, + 0x29, 0x2f, 0x32, 0x2c, 0x30, 0x29, 0x3a, 0x28, 0x6c, 0x2d, 0x63, + 0x29, 0x2f, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2d, 0x31, 0x2b, 0x61, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x3d, 0x72, 0x28, 0x63, 0x2b, 0x73, 0x2a, 0x61, + 0x2f, 0x32, 0x2c, 0x73, 0x29, 0x2c, 0x6f, 0x3d, 0x30, 0x2c, 0x74, + 0x3d, 0x7b, 0x74, 0x3a, 0x22, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x2c, 0x61, 0x3a, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x7d, 0x2c, 0x65, 0x7d, + 0x2c, 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x6f, 0x75, + 0x6e, 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x2c, 0x61, 0x29, + 0x7b, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x26, 0x26, 0x28, + 0x61, 0x3d, 0x30, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, + 0x75, 0x5b, 0x30, 0x5d, 0x2c, 0x6c, 0x3d, 0x75, 0x5b, 0x31, 0x5d, + 0x2c, 0x73, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3c, 0x32, 0x3f, 0x28, 0x63, 0x3d, 0x6c, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x28, 0x63, 0x2b, + 0x6c, 0x29, 0x2f, 0x32, 0x29, 0x2c, 0x30, 0x29, 0x3a, 0x28, 0x6c, + 0x2d, 0x63, 0x29, 0x2f, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2d, 0x31, 0x2b, 0x61, 0x29, 0x7c, 0x30, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x3d, 0x72, 0x28, 0x63, + 0x2b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x28, 0x73, 0x2a, 0x61, 0x2f, 0x32, 0x2b, 0x28, 0x6c, 0x2d, 0x63, + 0x2d, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, + 0x31, 0x2b, 0x61, 0x29, 0x2a, 0x73, 0x29, 0x2f, 0x32, 0x29, 0x2c, + 0x73, 0x29, 0x2c, 0x6f, 0x3d, 0x30, 0x2c, 0x74, 0x3d, 0x7b, 0x74, + 0x3a, 0x22, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x6f, 0x75, 0x6e, + 0x64, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x2c, 0x61, 0x3a, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x7d, 0x2c, + 0x65, 0x7d, 0x2c, 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, + 0x61, 0x6e, 0x64, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x75, 0x2c, 0x61, 0x2c, 0x63, 0x29, 0x7b, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x26, 0x26, 0x28, 0x61, 0x3d, + 0x30, 0x29, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x33, 0x26, + 0x26, 0x28, 0x63, 0x3d, 0x61, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x6c, 0x3d, 0x75, 0x5b, 0x31, 0x5d, 0x3c, 0x75, 0x5b, 0x30, 0x5d, + 0x2c, 0x73, 0x3d, 0x75, 0x5b, 0x6c, 0x2d, 0x30, 0x5d, 0x2c, 0x66, + 0x3d, 0x75, 0x5b, 0x31, 0x2d, 0x6c, 0x5d, 0x2c, 0x68, 0x3d, 0x28, + 0x66, 0x2d, 0x73, 0x29, 0x2f, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2d, 0x61, 0x2b, 0x32, 0x2a, 0x63, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x3d, 0x72, 0x28, + 0x73, 0x2b, 0x68, 0x2a, 0x63, 0x2c, 0x68, 0x29, 0x2c, 0x6c, 0x26, + 0x26, 0x69, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, + 0x29, 0x2c, 0x6f, 0x3d, 0x68, 0x2a, 0x28, 0x31, 0x2d, 0x61, 0x29, + 0x2c, 0x74, 0x3d, 0x7b, 0x74, 0x3a, 0x22, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x2c, 0x61, 0x3a, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x7d, 0x2c, 0x65, + 0x7d, 0x2c, 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x6f, + 0x75, 0x6e, 0x64, 0x42, 0x61, 0x6e, 0x64, 0x73, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x2c, 0x61, 0x2c, + 0x63, 0x29, 0x7b, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x26, + 0x26, 0x28, 0x61, 0x3d, 0x30, 0x29, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x33, 0x26, 0x26, 0x28, 0x63, 0x3d, 0x61, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x75, 0x5b, 0x31, 0x5d, 0x3c, + 0x75, 0x5b, 0x30, 0x5d, 0x2c, 0x73, 0x3d, 0x75, 0x5b, 0x6c, 0x2d, + 0x30, 0x5d, 0x2c, 0x66, 0x3d, 0x75, 0x5b, 0x31, 0x2d, 0x6c, 0x5d, + 0x2c, 0x68, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, + 0x6f, 0x72, 0x28, 0x28, 0x66, 0x2d, 0x73, 0x29, 0x2f, 0x28, 0x6e, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x61, 0x2b, 0x32, + 0x2a, 0x63, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x69, 0x3d, 0x72, 0x28, 0x73, 0x2b, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x28, 0x66, 0x2d, 0x73, + 0x2d, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, + 0x61, 0x29, 0x2a, 0x68, 0x29, 0x2f, 0x32, 0x29, 0x2c, 0x68, 0x29, + 0x2c, 0x6c, 0x26, 0x26, 0x69, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x28, 0x29, 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x68, 0x2a, 0x28, 0x31, + 0x2d, 0x61, 0x29, 0x29, 0x2c, 0x74, 0x3d, 0x7b, 0x74, 0x3a, 0x22, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x42, + 0x61, 0x6e, 0x64, 0x73, 0x22, 0x2c, 0x61, 0x3a, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x7d, 0x2c, 0x65, 0x7d, 0x2c, + 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x7d, 0x2c, + 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x50, + 0x69, 0x28, 0x74, 0x2e, 0x61, 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x2c, + 0x65, 0x2e, 0x63, 0x6f, 0x70, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x51, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, + 0x2c, 0x65, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x6e, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6e, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x74, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x61, 0x3d, 0x5b, 0x5d, 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x72, 0x3b, + 0x29, 0x61, 0x5b, 0x65, 0x2d, 0x31, 0x5d, 0x3d, 0x74, 0x61, 0x2e, + 0x71, 0x75, 0x61, 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x28, 0x6e, 0x2c, + 0x65, 0x2f, 0x72, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6f, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x6e, 0x3d, 0x2b, + 0x6e, 0x29, 0x3f, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x30, 0x3a, 0x74, + 0x5b, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, 0x65, 0x63, 0x74, 0x28, + 0x61, 0x2c, 0x6e, 0x29, 0x5d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x61, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x2e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6e, + 0x3d, 0x74, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x72, 0x29, 0x2e, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x28, 0x75, 0x29, 0x2e, 0x73, 0x6f, + 0x72, 0x74, 0x28, 0x65, 0x29, 0x2c, 0x69, 0x28, 0x29, 0x29, 0x3a, + 0x6e, 0x7d, 0x2c, 0x6f, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x6e, 0x2c, 0x69, 0x28, 0x29, + 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6f, 0x2e, 0x71, 0x75, 0x61, 0x6e, + 0x74, 0x69, 0x6c, 0x65, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x7d, 0x2c, 0x6f, 0x2e, 0x69, 0x6e, 0x76, 0x65, + 0x72, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3d, 0x74, 0x2e, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x65, 0x29, 0x2c, 0x30, + 0x3e, 0x65, 0x3f, 0x5b, 0x30, 0x2f, 0x30, 0x2c, 0x30, 0x2f, 0x30, + 0x5d, 0x3a, 0x5b, 0x65, 0x3e, 0x30, 0x3f, 0x61, 0x5b, 0x65, 0x2d, + 0x31, 0x5d, 0x3a, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x3c, 0x61, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x61, 0x5b, 0x65, + 0x5d, 0x3a, 0x6e, 0x5b, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2d, 0x31, 0x5d, 0x5d, 0x7d, 0x2c, 0x6f, 0x2e, 0x63, 0x6f, + 0x70, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x2c, 0x69, 0x28, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, + 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x5b, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x30, 0x2c, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6f, 0x2c, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x69, + 0x2a, 0x28, 0x74, 0x2d, 0x6e, 0x29, 0x29, 0x29, 0x29, 0x5d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x3d, + 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2f, 0x28, 0x74, + 0x2d, 0x6e, 0x29, 0x2c, 0x6f, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2d, 0x31, 0x2c, 0x72, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x2c, 0x6f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x6e, 0x3d, 0x2b, 0x65, 0x5b, 0x30, 0x5d, 0x2c, + 0x74, 0x3d, 0x2b, 0x65, 0x5b, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x2c, 0x75, 0x28, 0x29, 0x29, 0x3a, + 0x5b, 0x6e, 0x2c, 0x74, 0x5d, 0x7d, 0x2c, 0x72, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, 0x6e, + 0x2c, 0x75, 0x28, 0x29, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x72, 0x2e, + 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x3d, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, + 0x74, 0x29, 0x2c, 0x74, 0x3d, 0x30, 0x3e, 0x74, 0x3f, 0x30, 0x2f, + 0x30, 0x3a, 0x74, 0x2f, 0x69, 0x2b, 0x6e, 0x2c, 0x5b, 0x74, 0x2c, + 0x74, 0x2b, 0x31, 0x2f, 0x69, 0x5d, 0x7d, 0x2c, 0x72, 0x2e, 0x63, + 0x6f, 0x70, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x2c, + 0x75, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x65, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x65, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3e, + 0x3d, 0x65, 0x3f, 0x74, 0x5b, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, + 0x65, 0x63, 0x74, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x5d, 0x3a, 0x76, + 0x6f, 0x69, 0x64, 0x20, 0x30, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x65, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x6e, 0x3d, 0x74, 0x2c, 0x65, 0x29, 0x3a, + 0x6e, 0x7d, 0x2c, 0x65, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x6e, 0x2c, 0x65, 0x29, 0x3a, + 0x74, 0x7d, 0x2c, 0x65, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3d, 0x74, 0x2e, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x4f, 0x66, 0x28, 0x65, 0x29, 0x2c, 0x5b, 0x6e, 0x5b, + 0x65, 0x2d, 0x31, 0x5d, 0x2c, 0x6e, 0x5b, 0x65, 0x5d, 0x5d, 0x7d, + 0x2c, 0x65, 0x2e, 0x63, 0x6f, 0x70, 0x79, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7d, 0x2c, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x72, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2b, 0x6e, 0x7d, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x69, 0x6e, 0x76, 0x65, + 0x72, 0x74, 0x3d, 0x74, 0x2c, 0x74, 0x2e, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x3d, 0x74, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x6e, 0x3d, 0x65, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x74, 0x29, 0x2c, 0x74, 0x29, 0x3a, 0x6e, 0x7d, 0x2c, 0x74, + 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x58, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7d, 0x2c, 0x74, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x24, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x29, 0x7d, 0x2c, 0x74, 0x2e, 0x63, 0x6f, 0x70, 0x79, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x6f, 0x28, 0x6e, 0x29, + 0x7d, 0x2c, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x75, 0x6f, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x69, 0x6e, 0x6e, 0x65, + 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x6f, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x6f, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x41, 0x6e, 0x67, 0x6c, + 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x63, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x65, 0x6e, 0x64, 0x41, 0x6e, 0x67, 0x6c, + 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6c, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x26, 0x26, 0x6e, 0x2e, 0x70, 0x61, 0x64, 0x41, + 0x6e, 0x67, 0x6c, 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x73, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x2c, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, + 0x6e, 0x2d, 0x65, 0x29, 0x2a, 0x74, 0x2d, 0x28, 0x74, 0x2d, 0x72, + 0x29, 0x2a, 0x6e, 0x3e, 0x30, 0x3f, 0x30, 0x3a, 0x31, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x6f, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2d, + 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x6f, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, + 0x2d, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x61, 0x3d, 0x28, 0x75, 0x3f, + 0x72, 0x3a, 0x2d, 0x72, 0x29, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x73, 0x71, 0x72, 0x74, 0x28, 0x69, 0x2a, 0x69, 0x2b, 0x6f, 0x2a, + 0x6f, 0x29, 0x2c, 0x63, 0x3d, 0x61, 0x2a, 0x6f, 0x2c, 0x6c, 0x3d, + 0x2d, 0x61, 0x2a, 0x69, 0x2c, 0x73, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, + 0x2b, 0x63, 0x2c, 0x66, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x2b, 0x6c, + 0x2c, 0x68, 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x2b, 0x63, 0x2c, 0x67, + 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2b, 0x6c, 0x2c, 0x70, 0x3d, 0x28, + 0x73, 0x2b, 0x68, 0x29, 0x2f, 0x32, 0x2c, 0x76, 0x3d, 0x28, 0x66, + 0x2b, 0x67, 0x29, 0x2f, 0x32, 0x2c, 0x64, 0x3d, 0x68, 0x2d, 0x73, + 0x2c, 0x6d, 0x3d, 0x67, 0x2d, 0x66, 0x2c, 0x79, 0x3d, 0x64, 0x2a, + 0x64, 0x2b, 0x6d, 0x2a, 0x6d, 0x2c, 0x4d, 0x3d, 0x65, 0x2d, 0x72, + 0x2c, 0x78, 0x3d, 0x73, 0x2a, 0x67, 0x2d, 0x68, 0x2a, 0x66, 0x2c, + 0x62, 0x3d, 0x28, 0x30, 0x3e, 0x6d, 0x3f, 0x2d, 0x31, 0x3a, 0x31, + 0x29, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, + 0x28, 0x4d, 0x2a, 0x4d, 0x2a, 0x79, 0x2d, 0x78, 0x2a, 0x78, 0x29, + 0x2c, 0x5f, 0x3d, 0x28, 0x78, 0x2a, 0x6d, 0x2d, 0x64, 0x2a, 0x62, + 0x29, 0x2f, 0x79, 0x2c, 0x77, 0x3d, 0x28, 0x2d, 0x78, 0x2a, 0x64, + 0x2d, 0x6d, 0x2a, 0x62, 0x29, 0x2f, 0x79, 0x2c, 0x53, 0x3d, 0x28, + 0x78, 0x2a, 0x6d, 0x2b, 0x64, 0x2a, 0x62, 0x29, 0x2f, 0x79, 0x2c, + 0x6b, 0x3d, 0x28, 0x2d, 0x78, 0x2a, 0x64, 0x2b, 0x6d, 0x2a, 0x62, + 0x29, 0x2f, 0x79, 0x2c, 0x45, 0x3d, 0x5f, 0x2d, 0x70, 0x2c, 0x41, + 0x3d, 0x77, 0x2d, 0x76, 0x2c, 0x4e, 0x3d, 0x53, 0x2d, 0x70, 0x2c, + 0x43, 0x3d, 0x6b, 0x2d, 0x76, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x45, 0x2a, 0x45, 0x2b, 0x41, 0x2a, 0x41, 0x3e, 0x4e, + 0x2a, 0x4e, 0x2b, 0x43, 0x2a, 0x43, 0x26, 0x26, 0x28, 0x5f, 0x3d, + 0x53, 0x2c, 0x77, 0x3d, 0x6b, 0x29, 0x2c, 0x5b, 0x5b, 0x5f, 0x2d, + 0x63, 0x2c, 0x77, 0x2d, 0x6c, 0x5d, 0x2c, 0x5b, 0x5f, 0x2a, 0x65, + 0x2f, 0x4d, 0x2c, 0x77, 0x2a, 0x65, 0x2f, 0x4d, 0x5d, 0x5d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x6f, + 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x74, 0x28, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x29, 0x7b, 0x6c, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x4d, 0x22, 0x2c, 0x69, 0x28, + 0x6e, 0x28, 0x73, 0x29, 0x2c, 0x61, 0x29, 0x29, 0x7d, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x63, 0x2c, 0x6c, 0x3d, 0x5b, + 0x5d, 0x2c, 0x73, 0x3d, 0x5b, 0x5d, 0x2c, 0x66, 0x3d, 0x2d, 0x31, + 0x2c, 0x68, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2c, 0x67, 0x3d, 0x45, 0x74, 0x28, 0x65, 0x29, 0x2c, 0x70, 0x3d, + 0x45, 0x74, 0x28, 0x72, 0x29, 0x3b, 0x2b, 0x2b, 0x66, 0x3c, 0x68, + 0x3b, 0x29, 0x75, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x63, 0x3d, 0x74, 0x5b, 0x66, 0x5d, 0x2c, 0x66, + 0x29, 0x3f, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x5b, 0x2b, + 0x67, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x63, 0x2c, 0x66, 0x29, 0x2c, 0x2b, 0x70, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x63, 0x2c, 0x66, + 0x29, 0x5d, 0x29, 0x3a, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x26, 0x26, 0x28, 0x6f, 0x28, 0x29, 0x2c, 0x73, 0x3d, 0x5b, + 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x26, 0x26, 0x6f, 0x28, + 0x29, 0x2c, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x6c, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x3a, + 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x41, 0x72, 0x2c, 0x72, 0x3d, 0x4e, 0x72, 0x2c, 0x75, 0x3d, 0x4e, + 0x65, 0x2c, 0x69, 0x3d, 0x67, 0x6f, 0x2c, 0x6f, 0x3d, 0x69, 0x2e, + 0x6b, 0x65, 0x79, 0x2c, 0x61, 0x3d, 0x2e, 0x37, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x78, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x65, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x65, 0x7d, + 0x2c, 0x74, 0x2e, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, 0x3d, + 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x74, 0x2e, 0x64, + 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x75, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x75, 0x7d, 0x2c, 0x74, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6f, 0x3d, 0x22, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x3f, 0x69, 0x3d, 0x6e, 0x3a, + 0x28, 0x69, 0x3d, 0x45, 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x6e, + 0x29, 0x7c, 0x7c, 0x67, 0x6f, 0x29, 0x2e, 0x6b, 0x65, 0x79, 0x2c, + 0x74, 0x29, 0x3a, 0x6f, 0x7d, 0x2c, 0x74, 0x2e, 0x74, 0x65, 0x6e, + 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x61, 0x3d, + 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x61, 0x7d, 0x2c, 0x74, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x67, 0x6f, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x4c, 0x22, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x6f, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x67, 0x6f, 0x28, 0x6e, 0x29, 0x2b, 0x22, 0x5a, 0x22, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, 0x6f, 0x28, + 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x30, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2c, 0x72, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, + 0x75, 0x3d, 0x5b, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x22, 0x2c, 0x22, + 0x2c, 0x72, 0x5b, 0x31, 0x5d, 0x5d, 0x3b, 0x2b, 0x2b, 0x74, 0x3c, + 0x65, 0x3b, 0x29, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, + 0x48, 0x22, 0x2c, 0x28, 0x72, 0x5b, 0x30, 0x5d, 0x2b, 0x28, 0x72, + 0x3d, 0x6e, 0x5b, 0x74, 0x5d, 0x29, 0x5b, 0x30, 0x5d, 0x29, 0x2f, + 0x32, 0x2c, 0x22, 0x56, 0x22, 0x2c, 0x72, 0x5b, 0x31, 0x5d, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3e, 0x31, + 0x26, 0x26, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x48, + 0x22, 0x2c, 0x72, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x75, 0x2e, 0x6a, + 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6f, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x30, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x72, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x3d, + 0x5b, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x72, + 0x5b, 0x31, 0x5d, 0x5d, 0x3b, 0x2b, 0x2b, 0x74, 0x3c, 0x65, 0x3b, + 0x29, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x56, 0x22, + 0x2c, 0x28, 0x72, 0x3d, 0x6e, 0x5b, 0x74, 0x5d, 0x29, 0x5b, 0x31, + 0x5d, 0x2c, 0x22, 0x48, 0x22, 0x2c, 0x72, 0x5b, 0x30, 0x5d, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x2e, 0x6a, + 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x6f, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x30, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x72, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x3d, + 0x5b, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x72, + 0x5b, 0x31, 0x5d, 0x5d, 0x3b, 0x2b, 0x2b, 0x74, 0x3c, 0x65, 0x3b, + 0x29, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x48, 0x22, + 0x2c, 0x28, 0x72, 0x3d, 0x6e, 0x5b, 0x74, 0x5d, 0x29, 0x5b, 0x30, + 0x5d, 0x2c, 0x22, 0x56, 0x22, 0x2c, 0x72, 0x5b, 0x31, 0x5d, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x2e, 0x6a, + 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x6f, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x34, 0x3f, 0x67, + 0x6f, 0x28, 0x6e, 0x29, 0x3a, 0x6e, 0x5b, 0x31, 0x5d, 0x2b, 0x5f, + 0x6f, 0x28, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x31, + 0x2c, 0x2d, 0x31, 0x29, 0x2c, 0x77, 0x6f, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x78, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3c, 0x33, 0x3f, 0x67, 0x6f, 0x28, 0x6e, 0x29, 0x3a, + 0x6e, 0x5b, 0x30, 0x5d, 0x2b, 0x5f, 0x6f, 0x28, 0x28, 0x6e, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x29, 0x2c, + 0x6e, 0x29, 0x2c, 0x77, 0x6f, 0x28, 0x5b, 0x6e, 0x5b, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x32, 0x5d, 0x5d, 0x2e, + 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6e, 0x2c, 0x5b, 0x6e, + 0x5b, 0x31, 0x5d, 0x5d, 0x29, 0x2c, 0x74, 0x29, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x6f, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x33, + 0x3f, 0x67, 0x6f, 0x28, 0x6e, 0x29, 0x3a, 0x6e, 0x5b, 0x30, 0x5d, + 0x2b, 0x5f, 0x6f, 0x28, 0x6e, 0x2c, 0x77, 0x6f, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x5f, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x69, + 0x66, 0x28, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, + 0x31, 0x7c, 0x7c, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x21, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x26, + 0x26, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x21, 0x3d, + 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b, 0x32, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x6f, 0x28, 0x6e, + 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x21, 0x3d, 0x74, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x72, 0x3d, 0x22, 0x22, 0x2c, 0x75, + 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x69, 0x3d, 0x6e, 0x5b, 0x31, + 0x5d, 0x2c, 0x6f, 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x61, 0x3d, + 0x6f, 0x2c, 0x63, 0x3d, 0x31, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x26, + 0x26, 0x28, 0x72, 0x2b, 0x3d, 0x22, 0x51, 0x22, 0x2b, 0x28, 0x69, + 0x5b, 0x30, 0x5d, 0x2d, 0x32, 0x2a, 0x6f, 0x5b, 0x30, 0x5d, 0x2f, + 0x33, 0x29, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x28, 0x69, 0x5b, 0x31, + 0x5d, 0x2d, 0x32, 0x2a, 0x6f, 0x5b, 0x31, 0x5d, 0x2f, 0x33, 0x29, + 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x69, 0x5b, 0x30, 0x5d, 0x2b, 0x22, + 0x2c, 0x22, 0x2b, 0x69, 0x5b, 0x31, 0x5d, 0x2c, 0x75, 0x3d, 0x6e, + 0x5b, 0x31, 0x5d, 0x2c, 0x63, 0x3d, 0x32, 0x29, 0x2c, 0x74, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x31, 0x29, 0x7b, 0x61, + 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x69, 0x3d, 0x6e, 0x5b, 0x63, + 0x5d, 0x2c, 0x63, 0x2b, 0x2b, 0x2c, 0x72, 0x2b, 0x3d, 0x22, 0x43, + 0x22, 0x2b, 0x28, 0x75, 0x5b, 0x30, 0x5d, 0x2b, 0x6f, 0x5b, 0x30, + 0x5d, 0x29, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x28, 0x75, 0x5b, 0x31, + 0x5d, 0x2b, 0x6f, 0x5b, 0x31, 0x5d, 0x29, 0x2b, 0x22, 0x2c, 0x22, + 0x2b, 0x28, 0x69, 0x5b, 0x30, 0x5d, 0x2d, 0x61, 0x5b, 0x30, 0x5d, + 0x29, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x28, 0x69, 0x5b, 0x31, 0x5d, + 0x2d, 0x61, 0x5b, 0x31, 0x5d, 0x29, 0x2b, 0x22, 0x2c, 0x22, 0x2b, + 0x69, 0x5b, 0x30, 0x5d, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x69, 0x5b, + 0x31, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x6c, 0x3d, 0x32, 0x3b, 0x6c, 0x3c, 0x74, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x6c, 0x2b, 0x2b, 0x2c, 0x63, 0x2b, 0x2b, + 0x29, 0x69, 0x3d, 0x6e, 0x5b, 0x63, 0x5d, 0x2c, 0x61, 0x3d, 0x74, + 0x5b, 0x6c, 0x5d, 0x2c, 0x72, 0x2b, 0x3d, 0x22, 0x53, 0x22, 0x2b, + 0x28, 0x69, 0x5b, 0x30, 0x5d, 0x2d, 0x61, 0x5b, 0x30, 0x5d, 0x29, + 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x28, 0x69, 0x5b, 0x31, 0x5d, 0x2d, + 0x61, 0x5b, 0x31, 0x5d, 0x29, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x69, + 0x5b, 0x30, 0x5d, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x69, 0x5b, 0x31, + 0x5d, 0x7d, 0x69, 0x66, 0x28, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x73, 0x3d, 0x6e, 0x5b, 0x63, 0x5d, 0x3b, 0x72, 0x2b, 0x3d, + 0x22, 0x51, 0x22, 0x2b, 0x28, 0x69, 0x5b, 0x30, 0x5d, 0x2b, 0x32, + 0x2a, 0x61, 0x5b, 0x30, 0x5d, 0x2f, 0x33, 0x29, 0x2b, 0x22, 0x2c, + 0x22, 0x2b, 0x28, 0x69, 0x5b, 0x31, 0x5d, 0x2b, 0x32, 0x2a, 0x61, + 0x5b, 0x31, 0x5d, 0x2f, 0x33, 0x29, 0x2b, 0x22, 0x2c, 0x22, 0x2b, + 0x73, 0x5b, 0x30, 0x5d, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x73, 0x5b, + 0x31, 0x5d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, + 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, 0x5b, 0x5d, 0x2c, + 0x75, 0x3d, 0x28, 0x31, 0x2d, 0x74, 0x29, 0x2f, 0x32, 0x2c, 0x69, + 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x6f, 0x3d, 0x6e, 0x5b, 0x31, + 0x5d, 0x2c, 0x61, 0x3d, 0x31, 0x2c, 0x63, 0x3d, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x61, 0x3c, 0x63, + 0x3b, 0x29, 0x65, 0x3d, 0x69, 0x2c, 0x69, 0x3d, 0x6f, 0x2c, 0x6f, + 0x3d, 0x6e, 0x5b, 0x61, 0x5d, 0x2c, 0x72, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x5b, 0x75, 0x2a, 0x28, 0x6f, 0x5b, 0x30, 0x5d, 0x2d, + 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x75, 0x2a, 0x28, 0x6f, 0x5b, + 0x31, 0x5d, 0x2d, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x5d, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x53, 0x6f, 0x28, 0x6e, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3c, 0x33, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x67, 0x6f, 0x28, 0x6e, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x31, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2c, 0x72, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, + 0x75, 0x3d, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x69, 0x3d, 0x72, 0x5b, + 0x31, 0x5d, 0x2c, 0x6f, 0x3d, 0x5b, 0x75, 0x2c, 0x75, 0x2c, 0x75, + 0x2c, 0x28, 0x72, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x29, 0x5b, 0x30, + 0x5d, 0x5d, 0x2c, 0x61, 0x3d, 0x5b, 0x69, 0x2c, 0x69, 0x2c, 0x69, + 0x2c, 0x72, 0x5b, 0x31, 0x5d, 0x5d, 0x2c, 0x63, 0x3d, 0x5b, 0x75, + 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x69, 0x2c, 0x22, 0x4c, 0x22, 0x2c, + 0x4e, 0x6f, 0x28, 0x43, 0x6c, 0x2c, 0x6f, 0x29, 0x2c, 0x22, 0x2c, + 0x22, 0x2c, 0x4e, 0x6f, 0x28, 0x43, 0x6c, 0x2c, 0x61, 0x29, 0x5d, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x6e, 0x5b, 0x65, 0x2d, 0x31, 0x5d, 0x29, 0x3b, 0x2b, 0x2b, + 0x74, 0x3c, 0x3d, 0x65, 0x3b, 0x29, 0x72, 0x3d, 0x6e, 0x5b, 0x74, + 0x5d, 0x2c, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, + 0x2c, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x5b, 0x30, + 0x5d, 0x29, 0x2c, 0x61, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, + 0x29, 0x2c, 0x61, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x5b, + 0x31, 0x5d, 0x29, 0x2c, 0x43, 0x6f, 0x28, 0x63, 0x2c, 0x6f, 0x2c, + 0x61, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2c, 0x63, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x22, 0x4c, 0x22, 0x2c, 0x72, 0x29, 0x2c, 0x63, + 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6b, 0x6f, 0x28, + 0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3c, 0x34, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x67, 0x6f, 0x28, 0x6e, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x5b, 0x5d, + 0x2c, 0x72, 0x3d, 0x2d, 0x31, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x69, 0x3d, 0x5b, 0x30, 0x5d, + 0x2c, 0x6f, 0x3d, 0x5b, 0x30, 0x5d, 0x3b, 0x2b, 0x2b, 0x72, 0x3c, + 0x33, 0x3b, 0x29, 0x74, 0x3d, 0x6e, 0x5b, 0x72, 0x5d, 0x2c, 0x69, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x29, + 0x2c, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x5b, 0x31, + 0x5d, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x4e, 0x6f, 0x28, 0x43, 0x6c, 0x2c, 0x69, 0x29, + 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x4e, 0x6f, 0x28, 0x43, 0x6c, 0x2c, + 0x6f, 0x29, 0x29, 0x2c, 0x2d, 0x2d, 0x72, 0x3b, 0x2b, 0x2b, 0x72, + 0x3c, 0x75, 0x3b, 0x29, 0x74, 0x3d, 0x6e, 0x5b, 0x72, 0x5d, 0x2c, + 0x69, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x2c, 0x69, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x29, + 0x2c, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x2c, + 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x5b, 0x31, 0x5d, + 0x29, 0x2c, 0x43, 0x6f, 0x28, 0x65, 0x2c, 0x69, 0x2c, 0x6f, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x6a, + 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x6f, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, + 0x65, 0x2c, 0x72, 0x3d, 0x2d, 0x31, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x69, 0x3d, 0x75, 0x2b, + 0x34, 0x2c, 0x6f, 0x3d, 0x5b, 0x5d, 0x2c, 0x61, 0x3d, 0x5b, 0x5d, + 0x3b, 0x2b, 0x2b, 0x72, 0x3c, 0x34, 0x3b, 0x29, 0x65, 0x3d, 0x6e, + 0x5b, 0x72, 0x25, 0x75, 0x5d, 0x2c, 0x6f, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x61, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x5b, 0x4e, 0x6f, 0x28, 0x43, 0x6c, + 0x2c, 0x6f, 0x29, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x4e, 0x6f, 0x28, + 0x43, 0x6c, 0x2c, 0x61, 0x29, 0x5d, 0x2c, 0x2d, 0x2d, 0x72, 0x3b, + 0x2b, 0x2b, 0x72, 0x3c, 0x69, 0x3b, 0x29, 0x65, 0x3d, 0x6e, 0x5b, + 0x72, 0x25, 0x75, 0x5d, 0x2c, 0x6f, 0x2e, 0x73, 0x68, 0x69, 0x66, + 0x74, 0x28, 0x29, 0x2c, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x61, 0x2e, 0x73, 0x68, 0x69, + 0x66, 0x74, 0x28, 0x29, 0x2c, 0x61, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x43, 0x6f, 0x28, 0x74, + 0x2c, 0x6f, 0x2c, 0x61, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x41, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2d, 0x31, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x29, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x3d, + 0x6e, 0x5b, 0x30, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x6f, 0x3d, 0x6e, + 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x61, 0x3d, 0x6e, 0x5b, + 0x65, 0x5d, 0x5b, 0x30, 0x5d, 0x2d, 0x69, 0x2c, 0x63, 0x3d, 0x6e, + 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x2d, 0x6f, 0x2c, 0x6c, 0x3d, + 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x6c, 0x3c, 0x3d, 0x65, 0x3b, 0x29, + 0x72, 0x3d, 0x6e, 0x5b, 0x6c, 0x5d, 0x2c, 0x75, 0x3d, 0x6c, 0x2f, + 0x65, 0x2c, 0x72, 0x5b, 0x30, 0x5d, 0x3d, 0x74, 0x2a, 0x72, 0x5b, + 0x30, 0x5d, 0x2b, 0x28, 0x31, 0x2d, 0x74, 0x29, 0x2a, 0x28, 0x69, + 0x2b, 0x75, 0x2a, 0x61, 0x29, 0x2c, 0x72, 0x5b, 0x31, 0x5d, 0x3d, + 0x74, 0x2a, 0x72, 0x5b, 0x31, 0x5d, 0x2b, 0x28, 0x31, 0x2d, 0x74, + 0x29, 0x2a, 0x28, 0x6f, 0x2b, 0x75, 0x2a, 0x63, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x53, 0x6f, 0x28, 0x6e, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, + 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x74, 0x5b, 0x30, + 0x5d, 0x2b, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x74, 0x5b, 0x31, 0x5d, + 0x2b, 0x6e, 0x5b, 0x32, 0x5d, 0x2a, 0x74, 0x5b, 0x32, 0x5d, 0x2b, + 0x6e, 0x5b, 0x33, 0x5d, 0x2a, 0x74, 0x5b, 0x33, 0x5d, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x6f, 0x28, + 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x6e, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x22, 0x43, 0x22, 0x2c, 0x4e, 0x6f, 0x28, 0x41, + 0x6c, 0x2c, 0x74, 0x29, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x4e, 0x6f, + 0x28, 0x41, 0x6c, 0x2c, 0x65, 0x29, 0x2c, 0x22, 0x2c, 0x22, 0x2c, + 0x4e, 0x6f, 0x28, 0x4e, 0x6c, 0x2c, 0x74, 0x29, 0x2c, 0x22, 0x2c, + 0x22, 0x2c, 0x4e, 0x6f, 0x28, 0x4e, 0x6c, 0x2c, 0x65, 0x29, 0x2c, + 0x22, 0x2c, 0x22, 0x2c, 0x4e, 0x6f, 0x28, 0x43, 0x6c, 0x2c, 0x74, + 0x29, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x4e, 0x6f, 0x28, 0x43, 0x6c, + 0x2c, 0x65, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x7a, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x74, 0x5b, 0x31, 0x5d, + 0x2d, 0x6e, 0x5b, 0x31, 0x5d, 0x29, 0x2f, 0x28, 0x74, 0x5b, 0x30, + 0x5d, 0x2d, 0x6e, 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x71, 0x6f, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x30, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2d, 0x31, 0x2c, 0x72, 0x3d, 0x5b, 0x5d, 0x2c, 0x75, 0x3d, + 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x69, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, + 0x2c, 0x6f, 0x3d, 0x72, 0x5b, 0x30, 0x5d, 0x3d, 0x7a, 0x6f, 0x28, + 0x75, 0x2c, 0x69, 0x29, 0x3b, 0x2b, 0x2b, 0x74, 0x3c, 0x65, 0x3b, + 0x29, 0x72, 0x5b, 0x74, 0x5d, 0x3d, 0x28, 0x6f, 0x2b, 0x28, 0x6f, + 0x3d, 0x7a, 0x6f, 0x28, 0x75, 0x3d, 0x69, 0x2c, 0x69, 0x3d, 0x6e, + 0x5b, 0x74, 0x2b, 0x31, 0x5d, 0x29, 0x29, 0x29, 0x2f, 0x32, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x5b, 0x74, 0x5d, + 0x3d, 0x6f, 0x2c, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x4c, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, + 0x2c, 0x75, 0x2c, 0x69, 0x3d, 0x5b, 0x5d, 0x2c, 0x6f, 0x3d, 0x71, + 0x6f, 0x28, 0x6e, 0x29, 0x2c, 0x61, 0x3d, 0x2d, 0x31, 0x2c, 0x63, + 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, + 0x3b, 0x2b, 0x2b, 0x61, 0x3c, 0x63, 0x3b, 0x29, 0x74, 0x3d, 0x7a, + 0x6f, 0x28, 0x6e, 0x5b, 0x61, 0x5d, 0x2c, 0x6e, 0x5b, 0x61, 0x2b, + 0x31, 0x5d, 0x29, 0x2c, 0x67, 0x61, 0x28, 0x74, 0x29, 0x3c, 0x43, + 0x61, 0x3f, 0x6f, 0x5b, 0x61, 0x5d, 0x3d, 0x6f, 0x5b, 0x61, 0x2b, + 0x31, 0x5d, 0x3d, 0x30, 0x3a, 0x28, 0x65, 0x3d, 0x6f, 0x5b, 0x61, + 0x5d, 0x2f, 0x74, 0x2c, 0x72, 0x3d, 0x6f, 0x5b, 0x61, 0x2b, 0x31, + 0x5d, 0x2f, 0x74, 0x2c, 0x75, 0x3d, 0x65, 0x2a, 0x65, 0x2b, 0x72, + 0x2a, 0x72, 0x2c, 0x75, 0x3e, 0x39, 0x26, 0x26, 0x28, 0x75, 0x3d, + 0x33, 0x2a, 0x74, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x75, 0x29, 0x2c, 0x6f, 0x5b, 0x61, 0x5d, 0x3d, + 0x75, 0x2a, 0x65, 0x2c, 0x6f, 0x5b, 0x61, 0x2b, 0x31, 0x5d, 0x3d, + 0x75, 0x2a, 0x72, 0x29, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x61, + 0x3d, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x61, 0x3c, 0x3d, 0x63, 0x3b, + 0x29, 0x75, 0x3d, 0x28, 0x6e, 0x5b, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x6d, 0x69, 0x6e, 0x28, 0x63, 0x2c, 0x61, 0x2b, 0x31, 0x29, 0x5d, + 0x5b, 0x30, 0x5d, 0x2d, 0x6e, 0x5b, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x6d, 0x61, 0x78, 0x28, 0x30, 0x2c, 0x61, 0x2d, 0x31, 0x29, 0x5d, + 0x5b, 0x30, 0x5d, 0x29, 0x2f, 0x28, 0x36, 0x2a, 0x28, 0x31, 0x2b, + 0x6f, 0x5b, 0x61, 0x5d, 0x2a, 0x6f, 0x5b, 0x61, 0x5d, 0x29, 0x29, + 0x2c, 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x5b, 0x75, 0x7c, + 0x7c, 0x30, 0x2c, 0x6f, 0x5b, 0x61, 0x5d, 0x2a, 0x75, 0x7c, 0x7c, + 0x30, 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x69, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x54, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, + 0x33, 0x3f, 0x67, 0x6f, 0x28, 0x6e, 0x29, 0x3a, 0x6e, 0x5b, 0x30, + 0x5d, 0x2b, 0x5f, 0x6f, 0x28, 0x6e, 0x2c, 0x4c, 0x6f, 0x28, 0x6e, + 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x52, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, + 0x3d, 0x2d, 0x31, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, + 0x74, 0x3d, 0x6e, 0x5b, 0x75, 0x5d, 0x2c, 0x65, 0x3d, 0x74, 0x5b, + 0x30, 0x5d, 0x2c, 0x72, 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2d, 0x52, + 0x61, 0x2c, 0x74, 0x5b, 0x30, 0x5d, 0x3d, 0x65, 0x2a, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x72, 0x29, 0x2c, 0x74, + 0x5b, 0x31, 0x5d, 0x3d, 0x65, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x73, 0x69, 0x6e, 0x28, 0x72, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x44, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x74, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, + 0x28, 0x29, 0x7b, 0x76, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, + 0x4d, 0x22, 0x2c, 0x61, 0x28, 0x6e, 0x28, 0x6d, 0x29, 0x2c, 0x66, + 0x29, 0x2c, 0x73, 0x2c, 0x6c, 0x28, 0x6e, 0x28, 0x64, 0x2e, 0x72, + 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, 0x29, 0x2c, 0x66, + 0x29, 0x2c, 0x22, 0x5a, 0x22, 0x29, 0x7d, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x68, 0x2c, 0x67, 0x2c, 0x70, 0x2c, 0x76, + 0x3d, 0x5b, 0x5d, 0x2c, 0x64, 0x3d, 0x5b, 0x5d, 0x2c, 0x6d, 0x3d, + 0x5b, 0x5d, 0x2c, 0x79, 0x3d, 0x2d, 0x31, 0x2c, 0x4d, 0x3d, 0x74, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x78, 0x3d, 0x45, + 0x74, 0x28, 0x65, 0x29, 0x2c, 0x62, 0x3d, 0x45, 0x74, 0x28, 0x75, + 0x29, 0x2c, 0x5f, 0x3d, 0x65, 0x3d, 0x3d, 0x3d, 0x72, 0x3f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x7d, 0x3a, 0x45, 0x74, + 0x28, 0x72, 0x29, 0x2c, 0x77, 0x3d, 0x75, 0x3d, 0x3d, 0x3d, 0x69, + 0x3f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x7d, 0x3a, + 0x45, 0x74, 0x28, 0x69, 0x29, 0x3b, 0x2b, 0x2b, 0x79, 0x3c, 0x4d, + 0x3b, 0x29, 0x6f, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x68, 0x3d, 0x74, 0x5b, 0x79, 0x5d, 0x2c, 0x79, + 0x29, 0x3f, 0x28, 0x64, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x5b, + 0x67, 0x3d, 0x2b, 0x78, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x68, 0x2c, 0x79, 0x29, 0x2c, 0x70, 0x3d, + 0x2b, 0x62, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x68, 0x2c, 0x79, 0x29, 0x5d, 0x29, 0x2c, 0x6d, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x5b, 0x2b, 0x5f, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x68, 0x2c, 0x79, + 0x29, 0x2c, 0x2b, 0x77, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x68, 0x2c, 0x79, 0x29, 0x5d, 0x29, 0x29, + 0x3a, 0x64, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x26, 0x26, + 0x28, 0x63, 0x28, 0x29, 0x2c, 0x64, 0x3d, 0x5b, 0x5d, 0x2c, 0x6d, + 0x3d, 0x5b, 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x64, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x26, 0x26, + 0x63, 0x28, 0x29, 0x2c, 0x76, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x76, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x22, + 0x29, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x41, 0x72, 0x2c, 0x72, 0x3d, 0x41, 0x72, 0x2c, 0x75, + 0x3d, 0x30, 0x2c, 0x69, 0x3d, 0x4e, 0x72, 0x2c, 0x6f, 0x3d, 0x4e, + 0x65, 0x2c, 0x61, 0x3d, 0x67, 0x6f, 0x2c, 0x63, 0x3d, 0x61, 0x2e, + 0x6b, 0x65, 0x79, 0x2c, 0x6c, 0x3d, 0x61, 0x2c, 0x73, 0x3d, 0x22, + 0x4c, 0x22, 0x2c, 0x66, 0x3d, 0x2e, 0x37, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x78, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x65, 0x3d, 0x72, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x72, + 0x7d, 0x2c, 0x74, 0x2e, 0x78, 0x30, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x65, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x74, + 0x2e, 0x78, 0x31, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, 0x3d, 0x6e, + 0x2c, 0x74, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x74, 0x2e, 0x79, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x75, 0x3d, 0x69, 0x3d, 0x6e, 0x2c, 0x74, + 0x29, 0x3a, 0x69, 0x7d, 0x2c, 0x74, 0x2e, 0x79, 0x30, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x75, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x75, + 0x7d, 0x2c, 0x74, 0x2e, 0x79, 0x31, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x69, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x69, 0x7d, 0x2c, 0x74, + 0x2e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x6f, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x6f, 0x7d, + 0x2c, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, + 0x61, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x63, 0x3d, 0x22, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x3f, 0x61, 0x3d, + 0x6e, 0x3a, 0x28, 0x61, 0x3d, 0x45, 0x6c, 0x2e, 0x67, 0x65, 0x74, + 0x28, 0x6e, 0x29, 0x7c, 0x7c, 0x67, 0x6f, 0x29, 0x2e, 0x6b, 0x65, + 0x79, 0x2c, 0x6c, 0x3d, 0x61, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, + 0x73, 0x65, 0x7c, 0x7c, 0x61, 0x2c, 0x73, 0x3d, 0x61, 0x2e, 0x63, + 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x3f, 0x22, 0x4d, 0x22, 0x3a, 0x22, + 0x4c, 0x22, 0x2c, 0x74, 0x29, 0x3a, 0x63, 0x7d, 0x2c, 0x74, 0x2e, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x66, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x66, 0x7d, 0x2c, + 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x50, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x55, 0x6f, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, + 0x6e, 0x2e, 0x78, 0x2c, 0x6e, 0x2e, 0x79, 0x5d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6a, 0x6f, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x2c, 0x65, 0x3d, 0x74, 0x5b, 0x30, + 0x5d, 0x2c, 0x72, 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2d, 0x52, 0x61, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x65, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x72, 0x29, 0x2c, + 0x65, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x72, 0x29, 0x5d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x46, 0x6f, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x36, 0x34, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x48, 0x6f, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x63, 0x69, 0x72, 0x63, 0x6c, + 0x65, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x4f, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, + 0x28, 0x6e, 0x2f, 0x71, 0x61, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x4d, 0x30, 0x2c, 0x22, 0x2b, 0x74, 0x2b, 0x22, + 0x41, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x74, 0x2b, + 0x22, 0x20, 0x30, 0x20, 0x31, 0x2c, 0x31, 0x20, 0x30, 0x2c, 0x22, + 0x2b, 0x2d, 0x74, 0x2b, 0x22, 0x41, 0x22, 0x2b, 0x74, 0x2b, 0x22, + 0x2c, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x20, 0x30, 0x20, 0x31, 0x2c, + 0x31, 0x20, 0x30, 0x2c, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x5a, 0x22, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x49, + 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3b, 0x28, 0x74, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6e, 0x5d, 0x29, 0x26, 0x26, + 0x28, 0x65, 0x3d, 0x74, 0x5b, 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5d, 0x29, 0x26, 0x26, 0x28, 0x2d, 0x2d, 0x74, 0x2e, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3f, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x20, 0x74, 0x5b, 0x74, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x5d, 0x3a, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x5b, 0x6e, 0x5d, 0x2c, 0x74, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x2b, 0x3d, 0x2e, 0x35, 0x2c, 0x65, 0x2e, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x65, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, + 0x70, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x65, 0x2e, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x29, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x59, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, 0x61, + 0x28, 0x6e, 0x2c, 0x50, 0x6c, 0x29, 0x2c, 0x6e, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3d, 0x74, 0x2c, 0x6e, + 0x2e, 0x69, 0x64, 0x3d, 0x65, 0x2c, 0x6e, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5a, 0x6f, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x75, 0x3d, 0x6e, 0x2e, 0x69, 0x64, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x59, 0x28, 0x6e, 0x2c, 0x22, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x3f, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x6f, 0x2c, + 0x61, 0x29, 0x7b, 0x6e, 0x5b, 0x69, 0x5d, 0x5b, 0x75, 0x5d, 0x2e, + 0x74, 0x77, 0x65, 0x65, 0x6e, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x74, + 0x2c, 0x72, 0x28, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, + 0x2c, 0x6e, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, + 0x2c, 0x6f, 0x2c, 0x61, 0x29, 0x29, 0x29, 0x7d, 0x3a, 0x28, 0x65, + 0x3d, 0x72, 0x28, 0x65, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x5b, 0x69, 0x5d, + 0x5b, 0x75, 0x5d, 0x2e, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x2e, 0x73, + 0x65, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7d, 0x29, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x56, 0x6f, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x26, 0x26, 0x28, 0x6e, + 0x3d, 0x22, 0x22, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, + 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, + 0x6e, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x58, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x3f, + 0x22, 0x5f, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x5f, 0x22, 0x3a, 0x22, 0x5f, 0x5f, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x22, 0x2b, + 0x6e, 0x2b, 0x22, 0x5f, 0x5f, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x24, 0x6f, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x3d, 0x6e, 0x5b, 0x65, 0x5d, 0x7c, 0x7c, 0x28, 0x6e, + 0x5b, 0x65, 0x5d, 0x3d, 0x7b, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x3a, 0x30, 0x2c, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3a, 0x30, 0x7d, + 0x29, 0x2c, 0x6f, 0x3d, 0x69, 0x5b, 0x72, 0x5d, 0x3b, 0x69, 0x66, + 0x28, 0x21, 0x6f, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, + 0x75, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x3b, 0x6f, 0x3d, 0x69, 0x5b, + 0x72, 0x5d, 0x3d, 0x7b, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x3a, 0x6e, + 0x65, 0x77, 0x20, 0x6c, 0x2c, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x61, + 0x2c, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x75, 0x2e, 0x64, 0x65, + 0x6c, 0x61, 0x79, 0x2c, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x75, 0x2e, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2c, 0x65, 0x61, 0x73, 0x65, 0x3a, 0x75, 0x2e, 0x65, 0x61, + 0x73, 0x65, 0x2c, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x74, 0x7d, + 0x2c, 0x75, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x2b, 0x2b, 0x69, + 0x2e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, 0x74, 0x61, 0x2e, 0x74, + 0x69, 0x6d, 0x65, 0x72, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x75, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x65, 0x29, 0x7b, 0x69, 0x66, + 0x28, 0x69, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x3e, 0x72, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x28, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x69, 0x5b, 0x69, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5d, 0x3b, 0x75, 0x26, 0x26, + 0x28, 0x2d, 0x2d, 0x69, 0x2e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x2c, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x69, 0x5b, 0x69, 0x2e, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5d, 0x2c, 0x75, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x75, 0x2e, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, + 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, 0x2e, + 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x75, 0x2e, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x29, 0x2c, 0x69, 0x2e, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x3d, 0x72, 0x2c, 0x6f, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x26, 0x26, 0x6f, 0x2e, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, 0x2e, 0x5f, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x74, 0x29, 0x2c, 0x6f, 0x2e, 0x74, + 0x77, 0x65, 0x65, 0x6e, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, + 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x28, 0x72, 0x3d, 0x72, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, 0x2e, 0x5f, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x74, 0x29, 0x29, 0x26, 0x26, + 0x76, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x29, 0x7d, 0x29, + 0x2c, 0x68, 0x3d, 0x6f, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2c, 0x66, + 0x3d, 0x6f, 0x2e, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2c, 0x74, 0x61, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x2e, 0x63, 0x3d, 0x6c, + 0x28, 0x65, 0x7c, 0x7c, 0x31, 0x29, 0x3f, 0x4e, 0x65, 0x3a, 0x6c, + 0x2c, 0x31, 0x7d, 0x2c, 0x30, 0x2c, 0x61, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x28, 0x65, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x69, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x21, 0x3d, 0x3d, 0x72, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x31, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x75, 0x3d, 0x65, 0x2f, 0x66, 0x2c, 0x61, 0x3d, 0x68, 0x28, + 0x75, 0x29, 0x2c, 0x63, 0x3d, 0x76, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x63, 0x3e, 0x30, 0x3b, 0x29, 0x76, 0x5b, 0x2d, + 0x2d, 0x63, 0x5d, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, + 0x61, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, + 0x3e, 0x3d, 0x31, 0x3f, 0x28, 0x6f, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x26, 0x26, 0x6f, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, + 0x65, 0x6e, 0x64, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, + 0x6e, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, + 0x74, 0x29, 0x2c, 0x73, 0x28, 0x29, 0x29, 0x3a, 0x76, 0x6f, 0x69, + 0x64, 0x20, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x73, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x2d, 0x2d, 0x69, 0x2e, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x3f, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x69, 0x5b, 0x72, 0x5d, + 0x3a, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6e, 0x5b, 0x65, + 0x5d, 0x2c, 0x31, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x66, 0x2c, 0x68, + 0x2c, 0x67, 0x3d, 0x6f, 0x2e, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x2c, + 0x70, 0x3d, 0x65, 0x63, 0x2c, 0x76, 0x3d, 0x5b, 0x5d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x70, 0x2e, 0x74, 0x3d, 0x67, + 0x2b, 0x61, 0x2c, 0x75, 0x3e, 0x3d, 0x67, 0x3f, 0x63, 0x28, 0x75, + 0x2d, 0x67, 0x29, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x70, 0x2e, + 0x63, 0x3d, 0x63, 0x29, 0x7d, 0x2c, 0x30, 0x2c, 0x61, 0x29, 0x7d, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x42, + 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x6e, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, + 0x65, 0x28, 0x22, 0x2b, 0x28, 0x69, 0x73, 0x46, 0x69, 0x6e, 0x69, + 0x74, 0x65, 0x28, 0x72, 0x29, 0x3f, 0x72, 0x3a, 0x65, 0x28, 0x6e, + 0x29, 0x29, 0x2b, 0x22, 0x2c, 0x30, 0x29, 0x22, 0x7d, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x57, 0x6f, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x6e, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x3d, 0x74, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, + 0x28, 0x30, 0x2c, 0x22, 0x2b, 0x28, 0x69, 0x73, 0x46, 0x69, 0x6e, + 0x69, 0x74, 0x65, 0x28, 0x72, 0x29, 0x3f, 0x72, 0x3a, 0x65, 0x28, + 0x6e, 0x29, 0x29, 0x2b, 0x22, 0x29, 0x22, 0x7d, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4a, 0x6f, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x74, 0x6f, 0x49, 0x53, 0x4f, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x47, 0x6f, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x28, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x2d, 0x6e, + 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x3d, 0x72, 0x2f, 0x65, 0x2c, 0x69, + 0x3d, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, 0x65, 0x63, 0x74, 0x28, + 0x56, 0x6c, 0x2c, 0x75, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x3d, 0x3d, 0x56, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x5b, 0x74, 0x2e, 0x79, 0x65, 0x61, 0x72, + 0x2c, 0x56, 0x69, 0x28, 0x6e, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2f, 0x33, 0x31, + 0x35, 0x33, 0x36, 0x65, 0x36, 0x7d, 0x29, 0x2c, 0x65, 0x29, 0x5b, + 0x32, 0x5d, 0x5d, 0x3a, 0x69, 0x3f, 0x74, 0x5b, 0x75, 0x2f, 0x56, + 0x6c, 0x5b, 0x69, 0x2d, 0x31, 0x5d, 0x3c, 0x56, 0x6c, 0x5b, 0x69, + 0x5d, 0x2f, 0x75, 0x3f, 0x69, 0x2d, 0x31, 0x3a, 0x69, 0x5d, 0x3a, + 0x5b, 0x42, 0x6c, 0x2c, 0x56, 0x69, 0x28, 0x6e, 0x2c, 0x65, 0x29, + 0x5b, 0x32, 0x5d, 0x5d, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x72, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4b, 0x6f, 0x28, 0x6e, + 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x74, 0x29, 0x29, + 0x7d, 0x2c, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x6e, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x28, 0x74, 0x29, 0x2c, 0x72, 0x29, 0x3a, 0x6e, 0x2e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x4b, 0x6f, 0x29, 0x7d, 0x2c, 0x72, 0x2e, 0x6e, 0x69, 0x63, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x21, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x65, + 0x29, 0x26, 0x26, 0x21, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x28, 0x65, 0x2c, 0x4b, 0x6f, 0x28, 0x2b, 0x65, 0x2b, 0x31, 0x29, + 0x2c, 0x74, 0x29, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x72, 0x2e, 0x64, 0x6f, 0x6d, + 0x61, 0x69, 0x6e, 0x28, 0x29, 0x2c, 0x6f, 0x3d, 0x50, 0x69, 0x28, + 0x69, 0x29, 0x2c, 0x61, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, + 0x6e, 0x3f, 0x75, 0x28, 0x6f, 0x2c, 0x31, 0x30, 0x29, 0x3a, 0x22, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3d, 0x3d, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x26, 0x26, 0x75, 0x28, 0x6f, + 0x2c, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x26, 0x26, 0x28, 0x6e, 0x3d, 0x61, 0x5b, 0x30, 0x5d, 0x2c, + 0x74, 0x3d, 0x61, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x72, 0x2e, 0x64, + 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x46, 0x69, 0x28, 0x69, 0x2c, + 0x74, 0x3e, 0x31, 0x3f, 0x7b, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x65, 0x28, 0x74, 0x3d, 0x6e, + 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x74, 0x29, 0x29, 0x3b, + 0x29, 0x74, 0x3d, 0x4b, 0x6f, 0x28, 0x74, 0x2d, 0x31, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x2c, 0x63, + 0x65, 0x69, 0x6c, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x65, + 0x28, 0x74, 0x3d, 0x6e, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x74, + 0x29, 0x29, 0x3b, 0x29, 0x74, 0x3d, 0x4b, 0x6f, 0x28, 0x2b, 0x74, + 0x2b, 0x31, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x7d, 0x7d, 0x3a, 0x6e, 0x29, 0x29, 0x7d, 0x2c, 0x72, 0x2e, + 0x74, 0x69, 0x63, 0x6b, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x50, 0x69, 0x28, 0x72, 0x2e, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x29, 0x2c, 0x69, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x3f, 0x75, 0x28, 0x65, 0x2c, + 0x31, 0x30, 0x29, 0x3a, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, + 0x3f, 0x75, 0x28, 0x65, 0x2c, 0x6e, 0x29, 0x3a, 0x21, 0x6e, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x26, 0x26, 0x5b, 0x7b, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x3a, 0x6e, 0x7d, 0x2c, 0x74, 0x5d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x26, 0x26, 0x28, 0x6e, + 0x3d, 0x69, 0x5b, 0x30, 0x5d, 0x2c, 0x74, 0x3d, 0x69, 0x5b, 0x31, + 0x5d, 0x29, 0x2c, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, + 0x65, 0x5b, 0x30, 0x5d, 0x2c, 0x4b, 0x6f, 0x28, 0x2b, 0x65, 0x5b, + 0x31, 0x5d, 0x2b, 0x31, 0x29, 0x2c, 0x31, 0x3e, 0x74, 0x3f, 0x31, + 0x3a, 0x74, 0x29, 0x7d, 0x2c, 0x72, 0x2e, 0x74, 0x69, 0x63, 0x6b, + 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x2c, 0x72, 0x2e, 0x63, 0x6f, 0x70, + 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, + 0x28, 0x6e, 0x2e, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x29, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7d, 0x2c, 0x59, 0x69, 0x28, 0x72, 0x2c, 0x6e, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x4b, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x28, + 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x51, 0x6f, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x28, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x54, 0x65, 0x78, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x61, 0x28, 0x6e, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x75, 0x61, 0x2e, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x28, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x28, + 0x75, 0x61, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x29, 0x2c, 0x74, 0x2e, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x75, 0x61, 0x6c, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x28, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x54, 0x65, 0x78, 0x74, 0x29, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x61, 0x3d, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x3a, 0x22, 0x33, 0x2e, 0x35, 0x2e, 0x36, 0x22, 0x7d, 0x2c, + 0x65, 0x61, 0x3d, 0x5b, 0x5d, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, + 0x2c, 0x72, 0x61, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x65, 0x61, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x29, + 0x7d, 0x2c, 0x75, 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x3b, 0x69, 0x66, 0x28, + 0x75, 0x61, 0x29, 0x74, 0x72, 0x79, 0x7b, 0x72, 0x61, 0x28, 0x75, + 0x61, 0x2e, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x45, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x29, 0x5b, 0x30, 0x5d, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x54, 0x79, 0x70, 0x65, 0x7d, 0x63, 0x61, + 0x74, 0x63, 0x68, 0x28, 0x69, 0x61, 0x29, 0x7b, 0x72, 0x61, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x65, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x74, + 0x29, 0x3b, 0x74, 0x2d, 0x2d, 0x3b, 0x29, 0x65, 0x5b, 0x74, 0x5d, + 0x3d, 0x6e, 0x5b, 0x74, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x65, 0x7d, 0x7d, 0x69, 0x66, 0x28, 0x44, 0x61, 0x74, + 0x65, 0x2e, 0x6e, 0x6f, 0x77, 0x7c, 0x7c, 0x28, 0x44, 0x61, 0x74, + 0x65, 0x2e, 0x6e, 0x6f, 0x77, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x2b, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x7d, + 0x29, 0x2c, 0x75, 0x61, 0x29, 0x74, 0x72, 0x79, 0x7b, 0x75, 0x61, + 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x28, 0x22, 0x44, 0x49, 0x56, 0x22, 0x29, 0x2e, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x22, 0x6f, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x22, 0x2c, 0x30, 0x2c, 0x22, 0x22, 0x29, + 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x6f, 0x61, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x61, 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x63, 0x61, 0x3d, + 0x61, 0x61, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x2c, 0x6c, 0x61, 0x3d, 0x61, 0x61, 0x2e, + 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x4e, 0x53, 0x2c, 0x73, 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x43, 0x53, 0x53, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x44, 0x65, + 0x63, 0x6c, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x66, 0x61, + 0x3d, 0x73, 0x61, 0x2e, 0x73, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x79, 0x3b, 0x61, 0x61, 0x2e, 0x73, 0x65, 0x74, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x63, 0x61, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x74, 0x2b, 0x22, 0x22, 0x29, + 0x7d, 0x2c, 0x61, 0x61, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x53, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x29, 0x7b, 0x6c, 0x61, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2b, + 0x22, 0x22, 0x29, 0x7d, 0x2c, 0x73, 0x61, 0x2e, 0x73, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x29, 0x7b, 0x66, 0x61, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x74, 0x2b, 0x22, 0x22, + 0x2c, 0x65, 0x29, 0x7d, 0x7d, 0x74, 0x61, 0x2e, 0x61, 0x73, 0x63, + 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x65, 0x2c, 0x74, 0x61, + 0x2e, 0x64, 0x65, 0x73, 0x63, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x3e, 0x74, 0x3f, 0x2d, 0x31, 0x3a, 0x74, 0x3e, 0x6e, 0x3f, + 0x31, 0x3a, 0x74, 0x3e, 0x3d, 0x6e, 0x3f, 0x30, 0x3a, 0x30, 0x2f, + 0x30, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x6d, 0x69, 0x6e, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, + 0x3d, 0x2d, 0x31, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x69, 0x66, 0x28, 0x31, 0x3d, 0x3d, 0x3d, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, + 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, 0x69, 0x66, 0x28, + 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x72, 0x3d, 0x6e, 0x5b, + 0x75, 0x5d, 0x29, 0x26, 0x26, 0x72, 0x3e, 0x3d, 0x72, 0x29, 0x7b, + 0x65, 0x3d, 0x72, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x66, + 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, + 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x72, 0x3d, 0x6e, 0x5b, + 0x75, 0x5d, 0x29, 0x26, 0x26, 0x65, 0x3e, 0x72, 0x26, 0x26, 0x28, + 0x65, 0x3d, 0x72, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, + 0x69, 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x72, + 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, + 0x5b, 0x75, 0x5d, 0x2c, 0x75, 0x29, 0x29, 0x26, 0x26, 0x72, 0x3e, + 0x3d, 0x72, 0x29, 0x7b, 0x65, 0x3d, 0x72, 0x3b, 0x62, 0x72, 0x65, + 0x61, 0x6b, 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x75, + 0x3c, 0x69, 0x3b, 0x29, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, + 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, + 0x6e, 0x5b, 0x75, 0x5d, 0x2c, 0x75, 0x29, 0x29, 0x26, 0x26, 0x65, + 0x3e, 0x72, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x72, 0x29, 0x7d, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x6d, 0x61, 0x78, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3d, 0x2d, 0x31, 0x2c, 0x69, + 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69, + 0x66, 0x28, 0x31, 0x3d, 0x3d, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, + 0x69, 0x3b, 0x29, 0x69, 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x21, + 0x3d, 0x28, 0x72, 0x3d, 0x6e, 0x5b, 0x75, 0x5d, 0x29, 0x26, 0x26, + 0x72, 0x3e, 0x3d, 0x72, 0x29, 0x7b, 0x65, 0x3d, 0x72, 0x3b, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, + 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, 0x6e, 0x75, 0x6c, 0x6c, 0x21, + 0x3d, 0x28, 0x72, 0x3d, 0x6e, 0x5b, 0x75, 0x5d, 0x29, 0x26, 0x26, + 0x72, 0x3e, 0x65, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x72, 0x29, 0x7d, + 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, + 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, 0x69, 0x66, 0x28, 0x6e, 0x75, + 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, 0x5b, 0x75, 0x5d, 0x2c, 0x75, + 0x29, 0x29, 0x26, 0x26, 0x72, 0x3e, 0x3d, 0x72, 0x29, 0x7b, 0x65, + 0x3d, 0x72, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x66, 0x6f, + 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, 0x6e, + 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x72, 0x3d, 0x74, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, 0x5b, 0x75, 0x5d, 0x2c, + 0x75, 0x29, 0x29, 0x26, 0x26, 0x72, 0x3e, 0x65, 0x26, 0x26, 0x28, + 0x65, 0x3d, 0x72, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x65, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x3d, 0x2d, 0x31, 0x2c, 0x6f, + 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69, + 0x66, 0x28, 0x31, 0x3d, 0x3d, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, + 0x6f, 0x3b, 0x29, 0x69, 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x21, + 0x3d, 0x28, 0x72, 0x3d, 0x6e, 0x5b, 0x69, 0x5d, 0x29, 0x26, 0x26, + 0x72, 0x3e, 0x3d, 0x72, 0x29, 0x7b, 0x65, 0x3d, 0x75, 0x3d, 0x72, + 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x66, 0x6f, 0x72, 0x28, + 0x3b, 0x2b, 0x2b, 0x69, 0x3c, 0x6f, 0x3b, 0x29, 0x6e, 0x75, 0x6c, + 0x6c, 0x21, 0x3d, 0x28, 0x72, 0x3d, 0x6e, 0x5b, 0x69, 0x5d, 0x29, + 0x26, 0x26, 0x28, 0x65, 0x3e, 0x72, 0x26, 0x26, 0x28, 0x65, 0x3d, + 0x72, 0x29, 0x2c, 0x72, 0x3e, 0x75, 0x26, 0x26, 0x28, 0x75, 0x3d, + 0x72, 0x29, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x66, 0x6f, + 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, 0x6f, 0x3b, 0x29, 0x69, + 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x72, 0x3d, + 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, 0x5b, + 0x69, 0x5d, 0x2c, 0x69, 0x29, 0x29, 0x26, 0x26, 0x72, 0x3e, 0x3d, + 0x72, 0x29, 0x7b, 0x65, 0x3d, 0x75, 0x3d, 0x72, 0x3b, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, + 0x69, 0x3c, 0x6f, 0x3b, 0x29, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, + 0x28, 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, + 0x2c, 0x6e, 0x5b, 0x69, 0x5d, 0x2c, 0x69, 0x29, 0x29, 0x26, 0x26, + 0x28, 0x65, 0x3e, 0x72, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x72, 0x29, + 0x2c, 0x72, 0x3e, 0x75, 0x26, 0x26, 0x28, 0x75, 0x3d, 0x72, 0x29, + 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x65, 0x2c, + 0x75, 0x5d, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x75, 0x6d, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, + 0x30, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x6f, 0x3d, 0x2d, 0x31, 0x3b, 0x69, 0x66, 0x28, 0x31, + 0x3d, 0x3d, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x66, 0x6f, + 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x6f, 0x3c, 0x69, 0x3b, 0x29, 0x75, + 0x28, 0x65, 0x3d, 0x2b, 0x6e, 0x5b, 0x6f, 0x5d, 0x29, 0x26, 0x26, + 0x28, 0x72, 0x2b, 0x3d, 0x65, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x6f, 0x3c, 0x69, + 0x3b, 0x29, 0x75, 0x28, 0x65, 0x3d, 0x2b, 0x74, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, 0x5b, 0x6f, 0x5d, 0x2c, 0x6f, + 0x29, 0x29, 0x26, 0x26, 0x28, 0x72, 0x2b, 0x3d, 0x65, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x2c, 0x74, + 0x61, 0x2e, 0x6d, 0x65, 0x61, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x2c, 0x69, 0x3d, 0x30, 0x2c, 0x6f, 0x3d, + 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x61, 0x3d, + 0x2d, 0x31, 0x2c, 0x63, 0x3d, 0x6f, 0x3b, 0x69, 0x66, 0x28, 0x31, + 0x3d, 0x3d, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x66, 0x6f, + 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x61, 0x3c, 0x6f, 0x3b, 0x29, 0x75, + 0x28, 0x65, 0x3d, 0x72, 0x28, 0x6e, 0x5b, 0x61, 0x5d, 0x29, 0x29, + 0x3f, 0x69, 0x2b, 0x3d, 0x65, 0x3a, 0x2d, 0x2d, 0x63, 0x3b, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, + 0x61, 0x3c, 0x6f, 0x3b, 0x29, 0x75, 0x28, 0x65, 0x3d, 0x72, 0x28, + 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6e, 0x5b, + 0x61, 0x5d, 0x2c, 0x61, 0x29, 0x29, 0x29, 0x3f, 0x69, 0x2b, 0x3d, + 0x65, 0x3a, 0x2d, 0x2d, 0x63, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x63, 0x3f, 0x69, 0x2f, 0x63, 0x3a, 0x76, 0x6f, 0x69, + 0x64, 0x20, 0x30, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x71, 0x75, 0x61, + 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2d, 0x31, 0x29, 0x2a, 0x74, 0x2b, 0x31, 0x2c, 0x72, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, + 0x28, 0x65, 0x29, 0x2c, 0x75, 0x3d, 0x2b, 0x6e, 0x5b, 0x72, 0x2d, + 0x31, 0x5d, 0x2c, 0x69, 0x3d, 0x65, 0x2d, 0x72, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x3f, 0x75, 0x2b, 0x69, 0x2a, + 0x28, 0x6e, 0x5b, 0x72, 0x5d, 0x2d, 0x75, 0x29, 0x3a, 0x75, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x2c, 0x6f, 0x3d, + 0x5b, 0x5d, 0x2c, 0x61, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2c, 0x63, 0x3d, 0x2d, 0x31, 0x3b, 0x69, 0x66, 0x28, + 0x31, 0x3d, 0x3d, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x66, + 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x63, 0x3c, 0x61, 0x3b, 0x29, + 0x75, 0x28, 0x69, 0x3d, 0x72, 0x28, 0x6e, 0x5b, 0x63, 0x5d, 0x29, + 0x29, 0x26, 0x26, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x69, + 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, + 0x3b, 0x2b, 0x2b, 0x63, 0x3c, 0x61, 0x3b, 0x29, 0x75, 0x28, 0x69, + 0x3d, 0x72, 0x28, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, + 0x2c, 0x6e, 0x5b, 0x63, 0x5d, 0x2c, 0x63, 0x29, 0x29, 0x29, 0x26, + 0x26, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x69, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x74, 0x61, 0x2e, 0x71, 0x75, 0x61, + 0x6e, 0x74, 0x69, 0x6c, 0x65, 0x28, 0x6f, 0x2e, 0x73, 0x6f, 0x72, + 0x74, 0x28, 0x65, 0x29, 0x2c, 0x2e, 0x35, 0x29, 0x3a, 0x76, 0x6f, + 0x69, 0x64, 0x20, 0x30, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x76, 0x61, + 0x72, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x2c, 0x69, 0x2c, 0x6f, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x61, 0x3d, 0x30, 0x2c, + 0x63, 0x3d, 0x30, 0x2c, 0x6c, 0x3d, 0x2d, 0x31, 0x2c, 0x73, 0x3d, + 0x30, 0x3b, 0x69, 0x66, 0x28, 0x31, 0x3d, 0x3d, 0x3d, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, + 0x6c, 0x3c, 0x6f, 0x3b, 0x29, 0x75, 0x28, 0x65, 0x3d, 0x72, 0x28, + 0x6e, 0x5b, 0x6c, 0x5d, 0x29, 0x29, 0x26, 0x26, 0x28, 0x69, 0x3d, + 0x65, 0x2d, 0x61, 0x2c, 0x61, 0x2b, 0x3d, 0x69, 0x2f, 0x2b, 0x2b, + 0x73, 0x2c, 0x63, 0x2b, 0x3d, 0x69, 0x2a, 0x28, 0x65, 0x2d, 0x61, + 0x29, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, + 0x28, 0x3b, 0x2b, 0x2b, 0x6c, 0x3c, 0x6f, 0x3b, 0x29, 0x75, 0x28, + 0x65, 0x3d, 0x72, 0x28, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x6e, 0x2c, 0x6e, 0x5b, 0x6c, 0x5d, 0x2c, 0x6c, 0x29, 0x29, 0x29, + 0x26, 0x26, 0x28, 0x69, 0x3d, 0x65, 0x2d, 0x61, 0x2c, 0x61, 0x2b, + 0x3d, 0x69, 0x2f, 0x2b, 0x2b, 0x73, 0x2c, 0x63, 0x2b, 0x3d, 0x69, + 0x2a, 0x28, 0x65, 0x2d, 0x61, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x73, 0x3e, 0x31, 0x3f, 0x63, 0x2f, 0x28, + 0x73, 0x2d, 0x31, 0x29, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x30, + 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x69, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x74, + 0x61, 0x2e, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, + 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3f, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x6e, 0x29, 0x3a, + 0x6e, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x68, 0x61, 0x3d, 0x69, + 0x28, 0x65, 0x29, 0x3b, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, 0x65, + 0x63, 0x74, 0x4c, 0x65, 0x66, 0x74, 0x3d, 0x68, 0x61, 0x2e, 0x6c, + 0x65, 0x66, 0x74, 0x2c, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, 0x65, + 0x63, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, 0x65, 0x63, + 0x74, 0x52, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x68, 0x61, 0x2e, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x2c, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x28, 0x31, 0x3d, 0x3d, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x72, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x28, 0x74, + 0x29, 0x2c, 0x72, 0x29, 0x7d, 0x3a, 0x6e, 0x29, 0x7d, 0x2c, 0x74, + 0x61, 0x2e, 0x73, 0x68, 0x75, 0x66, 0x66, 0x6c, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x28, 0x69, 0x3d, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x3c, 0x33, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x32, 0x3e, 0x69, 0x26, + 0x26, 0x28, 0x74, 0x3d, 0x30, 0x29, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x3d, + 0x65, 0x2d, 0x74, 0x3b, 0x69, 0x3b, 0x29, 0x75, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, + 0x2a, 0x69, 0x2d, 0x2d, 0x7c, 0x30, 0x2c, 0x72, 0x3d, 0x6e, 0x5b, + 0x69, 0x2b, 0x74, 0x5d, 0x2c, 0x6e, 0x5b, 0x69, 0x2b, 0x74, 0x5d, + 0x3d, 0x6e, 0x5b, 0x75, 0x2b, 0x74, 0x5d, 0x2c, 0x6e, 0x5b, 0x75, + 0x2b, 0x74, 0x5d, 0x3d, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x70, 0x65, 0x72, + 0x6d, 0x75, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20, + 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x65, 0x29, 0x3b, 0x65, 0x2d, + 0x2d, 0x3b, 0x29, 0x72, 0x5b, 0x65, 0x5d, 0x3d, 0x6e, 0x5b, 0x74, + 0x5b, 0x65, 0x5d, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x72, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x70, 0x61, 0x69, 0x72, + 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x2c, 0x65, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x2c, 0x75, 0x3d, 0x6e, + 0x5b, 0x30, 0x5d, 0x2c, 0x69, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x28, 0x30, 0x3e, 0x72, 0x3f, 0x30, 0x3a, + 0x72, 0x29, 0x3b, 0x72, 0x3e, 0x65, 0x3b, 0x29, 0x69, 0x5b, 0x65, + 0x5d, 0x3d, 0x5b, 0x74, 0x3d, 0x75, 0x2c, 0x75, 0x3d, 0x6e, 0x5b, + 0x2b, 0x2b, 0x65, 0x5d, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x69, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x7a, 0x69, 0x70, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x21, 0x28, 0x72, 0x3d, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, + 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6e, + 0x3d, 0x2d, 0x31, 0x2c, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2c, 0x6f, 0x29, 0x2c, 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x28, 0x74, 0x29, 0x3b, 0x2b, 0x2b, 0x6e, + 0x3c, 0x74, 0x3b, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x72, 0x2c, 0x75, 0x3d, 0x2d, 0x31, 0x2c, 0x69, 0x3d, 0x65, + 0x5b, 0x6e, 0x5d, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, + 0x61, 0x79, 0x28, 0x72, 0x29, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x72, + 0x3b, 0x29, 0x69, 0x5b, 0x75, 0x5d, 0x3d, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5b, 0x75, 0x5d, 0x5b, 0x6e, 0x5d, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x2c, + 0x74, 0x61, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x73, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x61, 0x2e, 0x7a, 0x69, 0x70, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x28, 0x74, 0x61, 0x2c, 0x6e, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x6b, 0x65, 0x79, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x74, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x74, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x6e, 0x5b, 0x65, 0x5d, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x6e, + 0x29, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x6b, 0x65, + 0x79, 0x3a, 0x65, 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x6e, + 0x5b, 0x65, 0x5d, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x6d, 0x65, 0x72, + 0x67, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x69, 0x3d, 0x2d, 0x31, + 0x2c, 0x6f, 0x3d, 0x30, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, 0x75, 0x3b, + 0x29, 0x6f, 0x2b, 0x3d, 0x6e, 0x5b, 0x69, 0x5d, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6f, + 0x29, 0x3b, 0x2d, 0x2d, 0x75, 0x3e, 0x3d, 0x30, 0x3b, 0x29, 0x66, + 0x6f, 0x72, 0x28, 0x72, 0x3d, 0x6e, 0x5b, 0x75, 0x5d, 0x2c, 0x74, + 0x3d, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2d, + 0x2d, 0x74, 0x3e, 0x3d, 0x30, 0x3b, 0x29, 0x65, 0x5b, 0x2d, 0x2d, + 0x6f, 0x5d, 0x3d, 0x72, 0x5b, 0x74, 0x5d, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x67, 0x61, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x62, 0x73, + 0x3b, 0x74, 0x61, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x33, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x31, 0x2c, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x26, 0x26, 0x28, 0x74, 0x3d, + 0x6e, 0x2c, 0x6e, 0x3d, 0x30, 0x29, 0x29, 0x2c, 0x28, 0x74, 0x2d, + 0x6e, 0x29, 0x2f, 0x65, 0x3d, 0x3d, 0x3d, 0x31, 0x2f, 0x30, 0x29, + 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x69, 0x6e, 0x66, 0x69, 0x6e, + 0x69, 0x74, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x3d, 0x5b, 0x5d, + 0x2c, 0x69, 0x3d, 0x61, 0x28, 0x67, 0x61, 0x28, 0x65, 0x29, 0x29, + 0x2c, 0x6f, 0x3d, 0x2d, 0x31, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x2a, + 0x3d, 0x69, 0x2c, 0x74, 0x2a, 0x3d, 0x69, 0x2c, 0x65, 0x2a, 0x3d, + 0x69, 0x2c, 0x30, 0x3e, 0x65, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x3b, + 0x28, 0x72, 0x3d, 0x6e, 0x2b, 0x65, 0x2a, 0x2b, 0x2b, 0x6f, 0x29, + 0x3e, 0x74, 0x3b, 0x29, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x72, 0x2f, 0x69, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, + 0x6f, 0x72, 0x28, 0x3b, 0x28, 0x72, 0x3d, 0x6e, 0x2b, 0x65, 0x2a, + 0x2b, 0x2b, 0x6f, 0x29, 0x3c, 0x74, 0x3b, 0x29, 0x75, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x72, 0x2f, 0x69, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x6d, 0x61, 0x70, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x6c, 0x3b, 0x69, 0x66, 0x28, + 0x6e, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, + 0x66, 0x20, 0x6c, 0x29, 0x6e, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, + 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x65, 0x2e, 0x73, 0x65, 0x74, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x29, 0x3b, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x69, 0x66, 0x28, 0x41, 0x72, 0x72, 0x61, 0x79, 0x2e, + 0x69, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, 0x29, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x3d, 0x2d, 0x31, + 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x69, 0x66, 0x28, 0x31, 0x3d, 0x3d, 0x3d, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x75, + 0x3c, 0x69, 0x3b, 0x29, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x75, + 0x2c, 0x6e, 0x5b, 0x75, 0x5d, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x69, + 0x3b, 0x29, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x74, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x72, 0x3d, 0x6e, 0x5b, 0x75, + 0x5d, 0x2c, 0x75, 0x29, 0x2c, 0x72, 0x29, 0x7d, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6f, + 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x65, 0x2e, 0x73, 0x65, 0x74, + 0x28, 0x6f, 0x2c, 0x6e, 0x5b, 0x6f, 0x5d, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x70, 0x61, 0x3d, 0x22, 0x5f, 0x5f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x5f, 0x5f, 0x22, 0x2c, 0x76, 0x61, 0x3d, 0x22, 0x5c, 0x78, + 0x30, 0x30, 0x22, 0x3b, 0x63, 0x28, 0x6c, 0x2c, 0x7b, 0x68, 0x61, + 0x73, 0x3a, 0x68, 0x2c, 0x67, 0x65, 0x74, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x5b, 0x73, 0x28, 0x6e, 0x29, 0x5d, 0x7d, 0x2c, 0x73, 0x65, 0x74, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x5b, 0x73, 0x28, 0x6e, 0x29, + 0x5d, 0x3d, 0x74, 0x7d, 0x2c, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x3a, 0x67, 0x2c, 0x6b, 0x65, 0x79, 0x73, 0x3a, 0x70, 0x2c, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, + 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x5f, 0x29, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x5f, 0x5b, 0x74, 0x5d, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x2c, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, + 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x29, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x6b, 0x65, + 0x79, 0x3a, 0x66, 0x28, 0x74, 0x29, 0x2c, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x5b, 0x74, 0x5d, + 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x7d, 0x2c, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x76, 0x2c, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x3a, 0x64, 0x2c, 0x66, 0x6f, 0x72, 0x45, 0x61, + 0x63, 0x68, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x5f, 0x29, 0x6e, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x66, 0x28, 0x74, 0x29, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x5f, 0x5b, 0x74, 0x5d, 0x29, 0x7d, 0x7d, 0x29, 0x2c, + 0x74, 0x61, 0x2e, 0x6e, 0x65, 0x73, 0x74, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x74, 0x2c, 0x6f, + 0x2c, 0x61, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x61, 0x3e, 0x3d, 0x69, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x72, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x75, 0x2c, 0x6f, 0x29, 0x3a, 0x65, 0x3f, 0x6f, 0x2e, + 0x73, 0x6f, 0x72, 0x74, 0x28, 0x65, 0x29, 0x3a, 0x6f, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x63, 0x2c, 0x73, 0x2c, + 0x66, 0x2c, 0x68, 0x2c, 0x67, 0x3d, 0x2d, 0x31, 0x2c, 0x70, 0x3d, + 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x76, 0x3d, + 0x69, 0x5b, 0x61, 0x2b, 0x2b, 0x5d, 0x2c, 0x64, 0x3d, 0x6e, 0x65, + 0x77, 0x20, 0x6c, 0x3b, 0x2b, 0x2b, 0x67, 0x3c, 0x70, 0x3b, 0x29, + 0x28, 0x68, 0x3d, 0x64, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x63, 0x3d, + 0x76, 0x28, 0x73, 0x3d, 0x6f, 0x5b, 0x67, 0x5d, 0x29, 0x29, 0x29, + 0x3f, 0x68, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x73, 0x29, 0x3a, + 0x64, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x63, 0x2c, 0x5b, 0x73, 0x5d, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x3f, + 0x28, 0x73, 0x3d, 0x74, 0x28, 0x29, 0x2c, 0x66, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, + 0x7b, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x65, 0x2c, 0x6e, 0x28, + 0x74, 0x2c, 0x72, 0x2c, 0x61, 0x29, 0x29, 0x7d, 0x29, 0x3a, 0x28, + 0x73, 0x3d, 0x7b, 0x7d, 0x2c, 0x66, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x73, + 0x5b, 0x65, 0x5d, 0x3d, 0x6e, 0x28, 0x74, 0x2c, 0x72, 0x2c, 0x61, + 0x29, 0x7d, 0x29, 0x2c, 0x64, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, + 0x63, 0x68, 0x28, 0x66, 0x29, 0x2c, 0x73, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x2c, 0x65, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x3e, 0x3d, 0x69, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x5b, + 0x5d, 0x2c, 0x75, 0x3d, 0x6f, 0x5b, 0x65, 0x2b, 0x2b, 0x5d, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x66, 0x6f, + 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x75, 0x29, 0x7b, 0x72, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x6b, 0x65, 0x79, 0x3a, 0x6e, + 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x3a, 0x74, 0x28, 0x75, + 0x2c, 0x65, 0x29, 0x7d, 0x29, 0x7d, 0x29, 0x2c, 0x75, 0x3f, 0x72, + 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x2e, 0x6b, 0x65, + 0x79, 0x2c, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x29, 0x7d, 0x29, 0x3a, + 0x72, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, + 0x3d, 0x7b, 0x7d, 0x2c, 0x69, 0x3d, 0x5b, 0x5d, 0x2c, 0x6f, 0x3d, + 0x5b, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, + 0x2e, 0x6d, 0x61, 0x70, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x28, 0x65, 0x2c, 0x74, 0x2c, 0x30, + 0x29, 0x7d, 0x2c, 0x75, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x28, 0x6e, 0x28, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x2c, 0x65, + 0x2c, 0x30, 0x29, 0x2c, 0x30, 0x29, 0x7d, 0x2c, 0x75, 0x2e, 0x6b, + 0x65, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x29, 0x2c, 0x75, + 0x7d, 0x2c, 0x75, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, + 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, + 0x5b, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, + 0x5d, 0x3d, 0x6e, 0x2c, 0x75, 0x7d, 0x2c, 0x75, 0x2e, 0x73, 0x6f, + 0x72, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3d, 0x6e, 0x2c, 0x75, + 0x7d, 0x2c, 0x75, 0x2e, 0x72, 0x6f, 0x6c, 0x6c, 0x75, 0x70, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3d, 0x6e, + 0x2c, 0x75, 0x7d, 0x2c, 0x75, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, + 0x65, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, + 0x65, 0x77, 0x20, 0x6d, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x29, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x30, 0x2c, + 0x72, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x72, 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x74, 0x2e, 0x61, + 0x64, 0x64, 0x28, 0x6e, 0x5b, 0x65, 0x5d, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x2c, 0x63, 0x28, 0x6d, + 0x2c, 0x7b, 0x68, 0x61, 0x73, 0x3a, 0x68, 0x2c, 0x61, 0x64, 0x64, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x5f, 0x5b, 0x73, 0x28, 0x6e, 0x2b, 0x3d, 0x22, + 0x22, 0x29, 0x5d, 0x3d, 0x21, 0x30, 0x2c, 0x6e, 0x7d, 0x2c, 0x72, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x3a, 0x67, 0x2c, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x3a, 0x70, 0x2c, 0x73, 0x69, 0x7a, 0x65, 0x3a, + 0x76, 0x2c, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3a, 0x64, 0x2c, 0x66, + 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x29, 0x6e, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x66, 0x28, 0x74, 0x29, + 0x29, 0x7d, 0x7d, 0x29, 0x2c, 0x74, 0x61, 0x2e, 0x62, 0x65, 0x68, + 0x61, 0x76, 0x69, 0x6f, 0x72, 0x3d, 0x7b, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x72, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, + 0x3d, 0x31, 0x2c, 0x75, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x2b, 0x2b, 0x72, 0x3c, 0x75, 0x3b, 0x29, 0x6e, 0x5b, 0x65, 0x3d, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5b, 0x72, + 0x5d, 0x5d, 0x3d, 0x4d, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x74, 0x5b, + 0x65, 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x64, 0x61, 0x3d, 0x5b, + 0x22, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x22, 0x2c, 0x22, 0x6d, + 0x73, 0x22, 0x2c, 0x22, 0x6d, 0x6f, 0x7a, 0x22, 0x2c, 0x22, 0x4d, + 0x6f, 0x7a, 0x22, 0x2c, 0x22, 0x6f, 0x22, 0x2c, 0x22, 0x4f, 0x22, + 0x5d, 0x3b, 0x74, 0x61, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, + 0x63, 0x68, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x5f, 0x2c, 0x74, 0x3d, 0x2d, + 0x31, 0x2c, 0x65, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, + 0x2b, 0x74, 0x3c, 0x65, 0x3b, 0x29, 0x6e, 0x5b, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5b, 0x74, 0x5d, 0x5d, 0x3d, + 0x77, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x7d, 0x2c, 0x5f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x74, 0x79, 0x70, 0x65, 0x2e, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x2e, 0x22, 0x29, 0x2c, 0x72, + 0x3d, 0x22, 0x22, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x3e, 0x3d, 0x30, + 0x26, 0x26, 0x28, 0x72, 0x3d, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x28, 0x65, 0x2b, 0x31, 0x29, 0x2c, 0x6e, 0x3d, 0x6e, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x65, 0x29, 0x29, + 0x2c, 0x6e, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x3f, 0x74, 0x68, 0x69, 0x73, + 0x5b, 0x6e, 0x5d, 0x2e, 0x6f, 0x6e, 0x28, 0x72, 0x29, 0x3a, 0x74, + 0x68, 0x69, 0x73, 0x5b, 0x6e, 0x5d, 0x2e, 0x6f, 0x6e, 0x28, 0x72, + 0x2c, 0x74, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x32, 0x3d, 0x3d, 0x3d, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, 0x29, 0x66, 0x6f, 0x72, 0x28, + 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x29, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x68, 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6e, 0x29, 0x26, + 0x26, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6e, 0x5d, 0x2e, 0x6f, 0x6e, + 0x28, 0x72, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x7d, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x74, 0x61, 0x2e, 0x72, 0x65, 0x71, 0x75, + 0x6f, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, + 0x6d, 0x61, 0x2c, 0x22, 0x5c, 0x5c, 0x24, 0x26, 0x22, 0x29, 0x7d, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x61, 0x3d, 0x2f, 0x5b, 0x5c, + 0x5c, 0x5c, 0x5e, 0x5c, 0x24, 0x5c, 0x2a, 0x5c, 0x2b, 0x5c, 0x3f, + 0x5c, 0x7c, 0x5c, 0x5b, 0x5c, 0x5d, 0x5c, 0x28, 0x5c, 0x29, 0x5c, + 0x2e, 0x5c, 0x7b, 0x5c, 0x7d, 0x5d, 0x2f, 0x67, 0x2c, 0x79, 0x61, + 0x3d, 0x7b, 0x7d, 0x2e, 0x5f, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x5f, 0x5f, 0x3f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x2e, 0x5f, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x5f, 0x3d, 0x74, 0x7d, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x20, 0x69, 0x6e, 0x20, 0x74, 0x29, 0x6e, 0x5b, 0x65, 0x5d, 0x3d, + 0x74, 0x5b, 0x65, 0x5d, 0x7d, 0x2c, 0x4d, 0x61, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x28, 0x6e, 0x29, 0x7d, 0x2c, 0x78, 0x61, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x6e, 0x29, 0x7d, 0x2c, 0x62, 0x61, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, + 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x7c, 0x7c, 0x6e, + 0x5b, 0x78, 0x28, 0x6e, 0x2c, 0x22, 0x6d, 0x61, 0x74, 0x63, 0x68, + 0x65, 0x73, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, + 0x29, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x62, + 0x61, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7d, 0x29, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x3b, 0x22, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x53, 0x69, 0x7a, 0x7a, + 0x6c, 0x65, 0x26, 0x26, 0x28, 0x4d, 0x61, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x53, 0x69, 0x7a, 0x7a, + 0x6c, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x5b, 0x30, 0x5d, 0x7c, + 0x7c, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x78, 0x61, 0x3d, 0x53, + 0x69, 0x7a, 0x7a, 0x6c, 0x65, 0x2c, 0x62, 0x61, 0x3d, 0x53, 0x69, + 0x7a, 0x7a, 0x6c, 0x65, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x29, 0x2c, + 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x75, 0x61, 0x2e, + 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x5f, 0x61, 0x3d, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x5b, 0x5d, 0x3b, 0x5f, 0x61, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x3d, 0x5b, + 0x5d, 0x3b, 0x6e, 0x3d, 0x4e, 0x28, 0x6e, 0x29, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x2d, 0x31, 0x2c, + 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x6f, 0x3c, 0x61, 0x3b, 0x29, 0x7b, + 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x3d, 0x5b, 0x5d, + 0x29, 0x2c, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x3d, 0x28, 0x72, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x5b, 0x6f, 0x5d, 0x29, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x63, 0x3d, 0x2d, 0x31, 0x2c, 0x6c, 0x3d, 0x72, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x63, 0x3c, + 0x6c, 0x3b, 0x29, 0x28, 0x75, 0x3d, 0x72, 0x5b, 0x63, 0x5d, 0x29, + 0x3f, 0x28, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x3d, + 0x6e, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x75, 0x2c, 0x75, 0x2e, + 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x63, 0x2c, + 0x6f, 0x29, 0x29, 0x2c, 0x65, 0x26, 0x26, 0x22, 0x5f, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x22, 0x69, 0x6e, 0x20, 0x75, 0x26, + 0x26, 0x28, 0x65, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x5f, 0x3d, 0x75, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x5f, 0x29, 0x29, 0x3a, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x41, 0x28, 0x69, 0x29, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x3d, 0x5b, + 0x5d, 0x3b, 0x6e, 0x3d, 0x43, 0x28, 0x6e, 0x29, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x2d, 0x31, 0x2c, + 0x69, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x75, 0x5d, 0x2c, 0x61, 0x3d, 0x2d, 0x31, 0x2c, + 0x63, 0x3d, 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x2b, 0x2b, 0x61, 0x3c, 0x63, 0x3b, 0x29, 0x28, 0x65, 0x3d, 0x6f, + 0x5b, 0x61, 0x5d, 0x29, 0x26, 0x26, 0x28, 0x72, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x74, 0x3d, 0x72, 0x61, 0x28, 0x6e, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x65, 0x2c, 0x65, 0x2e, 0x5f, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x61, 0x2c, 0x75, 0x29, 0x29, + 0x29, 0x2c, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, + 0x6f, 0x64, 0x65, 0x3d, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x41, 0x28, 0x72, 0x29, 0x7d, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x77, 0x61, 0x3d, 0x7b, 0x73, 0x76, 0x67, 0x3a, 0x22, + 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, + 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x32, 0x30, 0x30, 0x30, + 0x2f, 0x73, 0x76, 0x67, 0x22, 0x2c, 0x78, 0x68, 0x74, 0x6d, 0x6c, + 0x3a, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, + 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, + 0x39, 0x39, 0x2f, 0x78, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x2c, 0x78, + 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, + 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x78, 0x6c, 0x69, 0x6e, + 0x6b, 0x22, 0x2c, 0x78, 0x6d, 0x6c, 0x3a, 0x22, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, 0x2e, + 0x6f, 0x72, 0x67, 0x2f, 0x58, 0x4d, 0x4c, 0x2f, 0x31, 0x39, 0x39, + 0x38, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x22, 0x2c, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x22, 0x68, 0x74, + 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, 0x33, + 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x32, 0x30, 0x30, 0x30, 0x2f, 0x78, + 0x6d, 0x6c, 0x6e, 0x73, 0x2f, 0x22, 0x7d, 0x3b, 0x74, 0x61, 0x2e, + 0x6e, 0x73, 0x3d, 0x7b, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x3a, + 0x77, 0x61, 0x2c, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x79, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x3a, 0x22, 0x29, 0x2c, + 0x65, 0x3d, 0x6e, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x3e, 0x3d, 0x30, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x6e, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x74, 0x29, 0x2c, + 0x6e, 0x3d, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x74, + 0x2b, 0x31, 0x29, 0x29, 0x2c, 0x77, 0x61, 0x2e, 0x68, 0x61, 0x73, + 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x28, 0x65, 0x29, 0x3f, 0x7b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3a, + 0x77, 0x61, 0x5b, 0x65, 0x5d, 0x2c, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x3a, 0x6e, 0x7d, 0x3a, 0x6e, 0x7d, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x29, 0x7b, 0x69, 0x66, + 0x28, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3d, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x6e, 0x73, 0x2e, 0x71, + 0x75, 0x61, 0x6c, 0x69, 0x66, 0x79, 0x28, 0x6e, 0x29, 0x2c, 0x6e, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x3f, 0x65, 0x2e, 0x67, 0x65, + 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, + 0x53, 0x28, 0x6e, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x6e, + 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3a, 0x65, 0x2e, 0x67, + 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x20, 0x69, + 0x6e, 0x20, 0x6e, 0x29, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, + 0x63, 0x68, 0x28, 0x7a, 0x28, 0x74, 0x2c, 0x6e, 0x5b, 0x74, 0x5d, + 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x7a, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x29, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x64, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x2c, 0x72, 0x3d, + 0x28, 0x6e, 0x3d, 0x54, 0x28, 0x6e, 0x29, 0x29, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x75, 0x3d, 0x2d, 0x31, 0x3b, 0x69, + 0x66, 0x28, 0x74, 0x3d, 0x65, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x4c, 0x69, 0x73, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, + 0x2b, 0x2b, 0x75, 0x3c, 0x72, 0x3b, 0x29, 0x69, 0x66, 0x28, 0x21, + 0x74, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x73, 0x28, + 0x6e, 0x5b, 0x75, 0x5d, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x21, 0x31, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x28, 0x74, 0x3d, 0x65, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x22, 0x29, 0x3b, 0x2b, 0x2b, 0x75, 0x3c, 0x72, + 0x3b, 0x29, 0x69, 0x66, 0x28, 0x21, 0x4c, 0x28, 0x6e, 0x5b, 0x75, + 0x5d, 0x29, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x74, 0x29, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x31, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x21, 0x30, 0x7d, 0x66, 0x6f, 0x72, 0x28, + 0x74, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x52, 0x28, 0x74, 0x2c, 0x6e, + 0x5b, 0x74, 0x5d, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x7d, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, + 0x68, 0x28, 0x52, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x29, 0x7d, 0x2c, + 0x5f, 0x61, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x2c, + 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x69, 0x66, 0x28, 0x33, 0x3e, 0x75, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x22, 0x21, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, + 0x29, 0x7b, 0x32, 0x3e, 0x75, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x22, + 0x22, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x72, 0x20, 0x69, 0x6e, + 0x20, 0x6e, 0x29, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, + 0x68, 0x28, 0x50, 0x28, 0x72, 0x2c, 0x6e, 0x5b, 0x72, 0x5d, 0x2c, + 0x65, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x7d, 0x69, 0x66, 0x28, 0x32, 0x3e, 0x75, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x28, 0x69, 0x29, 0x2e, 0x67, + 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x53, + 0x74, 0x79, 0x6c, 0x65, 0x28, 0x69, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, + 0x29, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x6e, 0x29, 0x7d, + 0x72, 0x3d, 0x22, 0x22, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, + 0x50, 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x29, 0x7d, 0x2c, + 0x5f, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x32, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x22, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, + 0x6f, 0x66, 0x20, 0x6e, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, + 0x29, 0x5b, 0x6e, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x20, + 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, + 0x61, 0x63, 0x68, 0x28, 0x55, 0x28, 0x74, 0x2c, 0x6e, 0x5b, 0x74, + 0x5d, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, + 0x55, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x29, 0x7d, 0x2c, 0x5f, 0x61, + 0x2e, 0x74, 0x65, 0x78, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x22, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x3f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, 0x3f, 0x22, 0x22, 0x3a, 0x74, + 0x7d, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x3f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x22, 0x22, 0x7d, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x6e, 0x7d, 0x29, 0x3a, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x7d, 0x2c, + 0x5f, 0x61, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x22, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x3f, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, 0x3f, 0x22, 0x22, 0x3a, 0x74, + 0x7d, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x3f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, + 0x4d, 0x4c, 0x3d, 0x22, 0x22, 0x7d, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54, 0x4d, 0x4c, 0x3d, + 0x6e, 0x7d, 0x29, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x28, 0x29, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, + 0x54, 0x4d, 0x4c, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x3d, 0x6a, 0x28, 0x6e, 0x29, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, + 0x70, 0x70, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, + 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x29, 0x7d, 0x29, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x69, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x6a, 0x28, 0x6e, 0x29, 0x2c, + 0x74, 0x3d, 0x4e, 0x28, 0x74, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x28, + 0x6e, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x2c, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x29, 0x7c, 0x7c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7d, + 0x29, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x46, 0x29, 0x7d, + 0x2c, 0x5f, 0x61, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, + 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x66, 0x3d, 0x65, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x68, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6f, 0x2c, 0x66, 0x29, 0x2c, 0x67, + 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, + 0x66, 0x29, 0x2c, 0x70, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, + 0x72, 0x61, 0x79, 0x28, 0x66, 0x29, 0x2c, 0x76, 0x3d, 0x6e, 0x65, + 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6f, 0x29, 0x3b, + 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x64, + 0x2c, 0x6d, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x6c, 0x2c, 0x79, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6f, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x72, 0x3d, 0x2d, 0x31, 0x3b, + 0x2b, 0x2b, 0x72, 0x3c, 0x6f, 0x3b, 0x29, 0x6d, 0x2e, 0x68, 0x61, + 0x73, 0x28, 0x64, 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x75, 0x3d, 0x6e, 0x5b, 0x72, 0x5d, 0x2c, 0x75, 0x2e, 0x5f, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x72, 0x29, 0x29, 0x3f, + 0x76, 0x5b, 0x72, 0x5d, 0x3d, 0x75, 0x3a, 0x6d, 0x2e, 0x73, 0x65, + 0x74, 0x28, 0x64, 0x2c, 0x75, 0x29, 0x2c, 0x79, 0x5b, 0x72, 0x5d, + 0x3d, 0x64, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x72, 0x3d, 0x2d, 0x31, + 0x3b, 0x2b, 0x2b, 0x72, 0x3c, 0x66, 0x3b, 0x29, 0x28, 0x75, 0x3d, + 0x6d, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x64, 0x3d, 0x74, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x65, 0x2c, 0x69, 0x3d, 0x65, 0x5b, 0x72, + 0x5d, 0x2c, 0x72, 0x29, 0x29, 0x29, 0x3f, 0x75, 0x21, 0x3d, 0x3d, + 0x21, 0x30, 0x26, 0x26, 0x28, 0x67, 0x5b, 0x72, 0x5d, 0x3d, 0x75, + 0x2c, 0x75, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, + 0x3d, 0x69, 0x29, 0x3a, 0x70, 0x5b, 0x72, 0x5d, 0x3d, 0x48, 0x28, + 0x69, 0x29, 0x2c, 0x6d, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x64, 0x2c, + 0x21, 0x30, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x72, 0x3d, 0x2d, + 0x31, 0x3b, 0x2b, 0x2b, 0x72, 0x3c, 0x6f, 0x3b, 0x29, 0x6d, 0x2e, + 0x67, 0x65, 0x74, 0x28, 0x79, 0x5b, 0x72, 0x5d, 0x29, 0x21, 0x3d, + 0x3d, 0x21, 0x30, 0x26, 0x26, 0x28, 0x76, 0x5b, 0x72, 0x5d, 0x3d, + 0x6e, 0x5b, 0x72, 0x5d, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, + 0x66, 0x6f, 0x72, 0x28, 0x72, 0x3d, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, + 0x72, 0x3c, 0x68, 0x3b, 0x29, 0x75, 0x3d, 0x6e, 0x5b, 0x72, 0x5d, + 0x2c, 0x69, 0x3d, 0x65, 0x5b, 0x72, 0x5d, 0x2c, 0x75, 0x3f, 0x28, + 0x75, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x3d, + 0x69, 0x2c, 0x67, 0x5b, 0x72, 0x5d, 0x3d, 0x75, 0x29, 0x3a, 0x70, + 0x5b, 0x72, 0x5d, 0x3d, 0x48, 0x28, 0x69, 0x29, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x3b, 0x66, 0x3e, 0x72, 0x3b, 0x2b, 0x2b, 0x72, 0x29, + 0x70, 0x5b, 0x72, 0x5d, 0x3d, 0x48, 0x28, 0x65, 0x5b, 0x72, 0x5d, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x6f, 0x3e, 0x72, 0x3b, + 0x2b, 0x2b, 0x72, 0x29, 0x76, 0x5b, 0x72, 0x5d, 0x3d, 0x6e, 0x5b, + 0x72, 0x5d, 0x7d, 0x70, 0x2e, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x3d, 0x67, 0x2c, 0x70, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x3d, 0x67, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3d, 0x76, 0x2e, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3d, 0x6e, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2c, + 0x61, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x70, 0x29, 0x2c, 0x63, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x67, 0x29, 0x2c, 0x73, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x76, 0x29, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x3d, 0x2d, 0x31, 0x2c, 0x6f, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6e, 0x3d, 0x6e, 0x65, 0x77, + 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6f, 0x3d, 0x28, 0x72, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, + 0x6f, 0x3b, 0x29, 0x28, 0x75, 0x3d, 0x72, 0x5b, 0x69, 0x5d, 0x29, + 0x26, 0x26, 0x28, 0x6e, 0x5b, 0x69, 0x5d, 0x3d, 0x75, 0x2e, 0x5f, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x61, 0x3d, 0x5a, 0x28, 0x5b, 0x5d, 0x29, 0x2c, 0x63, 0x3d, 0x41, + 0x28, 0x5b, 0x5d, 0x29, 0x2c, 0x73, 0x3d, 0x41, 0x28, 0x5b, 0x5d, + 0x29, 0x3b, 0x69, 0x66, 0x28, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, + 0x66, 0x20, 0x6e, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, + 0x69, 0x3c, 0x6f, 0x3b, 0x29, 0x65, 0x28, 0x72, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x69, 0x5d, 0x2c, 0x6e, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x72, 0x2c, 0x72, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x5f, 0x5f, 0x2c, 0x69, 0x29, 0x29, 0x3b, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, + 0x6f, 0x3b, 0x29, 0x65, 0x28, 0x72, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x5b, 0x69, 0x5d, 0x2c, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x63, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x7d, 0x2c, 0x63, + 0x2e, 0x65, 0x78, 0x69, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x73, 0x7d, 0x2c, 0x63, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, + 0x64, 0x61, 0x74, 0x75, 0x6d, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, + 0x28, 0x22, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x22, + 0x2c, 0x6e, 0x29, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x22, 0x5f, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x22, 0x29, 0x7d, 0x2c, 0x5f, 0x61, + 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3d, 0x5b, + 0x5d, 0x3b, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x21, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, + 0x26, 0x26, 0x28, 0x6e, 0x3d, 0x4f, 0x28, 0x6e, 0x29, 0x29, 0x3b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x30, + 0x2c, 0x6f, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x6f, 0x3e, 0x69, 0x3b, 0x69, 0x2b, 0x2b, + 0x29, 0x7b, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x3d, + 0x5b, 0x5d, 0x29, 0x2c, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3d, 0x28, 0x65, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x69, 0x5d, 0x29, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x30, 0x2c, 0x63, 0x3d, 0x65, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x63, 0x3e, 0x61, + 0x3b, 0x61, 0x2b, 0x2b, 0x29, 0x28, 0x72, 0x3d, 0x65, 0x5b, 0x61, + 0x5d, 0x29, 0x26, 0x26, 0x6e, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x72, 0x2c, 0x72, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x5f, 0x2c, 0x61, 0x2c, 0x69, 0x29, 0x26, 0x26, 0x74, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x72, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x41, 0x28, 0x75, 0x29, 0x7d, 0x2c, 0x5f, 0x61, + 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x2d, 0x31, 0x2c, 0x74, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x2b, 0x2b, 0x6e, 0x3c, 0x74, 0x3b, 0x29, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x6e, 0x5d, 0x2c, 0x75, 0x3d, 0x72, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x2c, 0x69, 0x3d, 0x72, + 0x5b, 0x75, 0x5d, 0x3b, 0x2d, 0x2d, 0x75, 0x3e, 0x3d, 0x30, 0x3b, + 0x29, 0x28, 0x65, 0x3d, 0x72, 0x5b, 0x75, 0x5d, 0x29, 0x26, 0x26, + 0x28, 0x69, 0x26, 0x26, 0x69, 0x21, 0x3d, 0x3d, 0x65, 0x2e, 0x6e, + 0x65, 0x78, 0x74, 0x53, 0x69, 0x62, 0x6c, 0x69, 0x6e, 0x67, 0x26, + 0x26, 0x69, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, + 0x64, 0x65, 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x28, 0x65, 0x2c, 0x69, 0x29, 0x2c, 0x69, + 0x3d, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x73, 0x6f, + 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x3d, 0x49, 0x2e, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x2d, 0x31, 0x2c, 0x65, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x2b, 0x2b, 0x74, 0x3c, 0x65, 0x3b, 0x29, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x74, 0x5d, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, + 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x28, 0x29, + 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x59, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x6e, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x2c, 0x74, 0x2e, 0x5f, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7d, + 0x29, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x72, 0x61, 0x28, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x74, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x7d, 0x2c, + 0x5f, 0x61, 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x28, 0x29, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x6e, 0x3d, 0x30, 0x2c, 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x74, 0x3e, 0x6e, + 0x3b, 0x6e, 0x2b, 0x2b, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6e, 0x5d, + 0x2c, 0x72, 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x65, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x75, 0x3e, 0x72, 0x3b, 0x72, 0x2b, + 0x2b, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x65, 0x5b, + 0x72, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x69, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, + 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, + 0x30, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x59, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x2b, 0x2b, 0x6e, 0x7d, 0x29, 0x2c, + 0x6e, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x53, 0x61, 0x3d, 0x5b, + 0x5d, 0x3b, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3d, 0x5a, + 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x53, 0x61, 0x2c, + 0x53, 0x61, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x3d, 0x5f, + 0x61, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x2c, 0x53, 0x61, + 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3d, 0x5f, 0x61, 0x2e, 0x65, + 0x6d, 0x70, 0x74, 0x79, 0x2c, 0x53, 0x61, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x3d, 0x5f, 0x61, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x2c, 0x53, + 0x61, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x3d, 0x5f, 0x61, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x2c, 0x53, 0x61, 0x2e, 0x73, 0x69, 0x7a, 0x65, + 0x3d, 0x5f, 0x61, 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x2c, 0x53, 0x61, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, + 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x3d, 0x5b, 0x5d, 0x2c, 0x61, + 0x3d, 0x2d, 0x31, 0x2c, 0x63, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x61, 0x3c, + 0x63, 0x3b, 0x29, 0x7b, 0x72, 0x3d, 0x28, 0x75, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x61, 0x5d, 0x29, 0x2e, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x2c, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, + 0x3d, 0x5b, 0x5d, 0x29, 0x2c, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3d, 0x75, 0x2e, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x2d, 0x31, 0x2c, + 0x73, 0x3d, 0x75, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x2b, 0x2b, 0x6c, 0x3c, 0x73, 0x3b, 0x29, 0x28, 0x69, 0x3d, 0x75, + 0x5b, 0x6c, 0x5d, 0x29, 0x3f, 0x28, 0x74, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x72, 0x5b, 0x6c, 0x5d, 0x3d, 0x65, 0x3d, 0x6e, 0x2e, + 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x75, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2c, 0x69, 0x2e, 0x5f, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x6c, 0x2c, 0x61, 0x29, + 0x29, 0x2c, 0x65, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x5f, 0x3d, 0x69, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x5f, 0x29, 0x3a, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, + 0x75, 0x6c, 0x6c, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x41, 0x28, 0x6f, 0x29, 0x7d, 0x2c, 0x53, 0x61, 0x2e, 0x69, + 0x6e, 0x73, 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, + 0x32, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x56, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x29, 0x29, 0x2c, 0x5f, 0x61, 0x2e, 0x69, 0x6e, 0x73, 0x65, + 0x72, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3f, 0x28, 0x65, 0x3d, 0x5b, 0x4d, + 0x61, 0x28, 0x74, 0x2c, 0x75, 0x61, 0x29, 0x5d, 0x2c, 0x65, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3d, + 0x75, 0x61, 0x2e, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x3a, 0x28, 0x65, + 0x3d, 0x5b, 0x74, 0x5d, 0x2c, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3d, 0x6e, 0x28, 0x74, 0x29, + 0x29, 0x2c, 0x41, 0x28, 0x5b, 0x65, 0x5d, 0x29, 0x7d, 0x2c, 0x74, + 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, + 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x3f, + 0x28, 0x74, 0x3d, 0x72, 0x61, 0x28, 0x78, 0x61, 0x28, 0x6e, 0x2c, + 0x75, 0x61, 0x29, 0x29, 0x2c, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x3d, 0x75, 0x61, 0x2e, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x29, 0x3a, 0x28, 0x74, 0x3d, 0x6e, 0x2c, 0x74, + 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x41, 0x28, 0x5b, 0x74, + 0x5d, 0x29, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x6f, 0x6e, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69, 0x66, 0x28, 0x33, 0x3e, 0x72, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x22, 0x21, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x6e, 0x29, 0x7b, 0x32, 0x3e, 0x72, 0x26, 0x26, 0x28, 0x74, 0x3d, + 0x21, 0x31, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x6e, 0x29, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, + 0x63, 0x68, 0x28, 0x58, 0x28, 0x65, 0x2c, 0x6e, 0x5b, 0x65, 0x5d, + 0x2c, 0x74, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x7d, 0x69, 0x66, 0x28, 0x32, 0x3e, + 0x72, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x72, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x29, + 0x5b, 0x22, 0x5f, 0x5f, 0x6f, 0x6e, 0x22, 0x2b, 0x6e, 0x5d, 0x29, + 0x26, 0x26, 0x72, 0x2e, 0x5f, 0x3b, 0x65, 0x3d, 0x21, 0x31, 0x7d, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x58, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6b, + 0x61, 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x7b, 0x6d, + 0x6f, 0x75, 0x73, 0x65, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3a, 0x22, + 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x22, 0x2c, + 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x3a, + 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x7d, + 0x29, 0x3b, 0x75, 0x61, 0x26, 0x26, 0x6b, 0x61, 0x2e, 0x66, 0x6f, + 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x22, 0x6f, 0x6e, 0x22, + 0x2b, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x75, 0x61, 0x26, 0x26, 0x6b, + 0x61, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x6e, 0x29, + 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x45, 0x61, 0x2c, 0x41, + 0x61, 0x3d, 0x30, 0x3b, 0x74, 0x61, 0x2e, 0x6d, 0x6f, 0x75, 0x73, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4a, + 0x28, 0x6e, 0x2c, 0x6b, 0x28, 0x29, 0x29, 0x7d, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x4e, 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, + 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x6f, 0x72, 0x26, 0x26, 0x2f, + 0x57, 0x65, 0x62, 0x4b, 0x69, 0x74, 0x2f, 0x2e, 0x74, 0x65, 0x73, + 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x76, 0x69, + 0x67, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x29, 0x3f, 0x2d, 0x31, 0x3a, 0x30, 0x3b, + 0x74, 0x61, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3c, 0x33, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x74, 0x2c, 0x74, 0x3d, + 0x6b, 0x28, 0x29, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, + 0x54, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x29, 0x2c, 0x74, 0x29, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, + 0x3d, 0x30, 0x2c, 0x69, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x69, 0x3e, 0x75, 0x3b, 0x2b, 0x2b, 0x75, 0x29, + 0x69, 0x66, 0x28, 0x28, 0x72, 0x3d, 0x74, 0x5b, 0x75, 0x5d, 0x29, + 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x3d, 0x3d, 0x3d, 0x65, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x4a, 0x28, 0x6e, 0x2c, 0x72, 0x29, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, 0x64, + 0x72, 0x61, 0x67, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x6f, 0x6e, 0x28, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x64, 0x6f, + 0x77, 0x6e, 0x2e, 0x64, 0x72, 0x61, 0x67, 0x22, 0x2c, 0x69, 0x29, + 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x2e, 0x64, 0x72, 0x61, 0x67, 0x22, 0x2c, + 0x6f, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x69, 0x2c, + 0x6f, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x28, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x2c, 0x65, 0x2c, 0x72, 0x3d, + 0x74, 0x28, 0x68, 0x2c, 0x76, 0x29, 0x3b, 0x72, 0x26, 0x26, 0x28, + 0x6e, 0x3d, 0x72, 0x5b, 0x30, 0x5d, 0x2d, 0x4d, 0x5b, 0x30, 0x5d, + 0x2c, 0x65, 0x3d, 0x72, 0x5b, 0x31, 0x5d, 0x2d, 0x4d, 0x5b, 0x31, + 0x5d, 0x2c, 0x70, 0x7c, 0x3d, 0x6e, 0x7c, 0x65, 0x2c, 0x4d, 0x3d, + 0x72, 0x2c, 0x67, 0x28, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, + 0x64, 0x72, 0x61, 0x67, 0x22, 0x2c, 0x78, 0x3a, 0x72, 0x5b, 0x30, + 0x5d, 0x2b, 0x6c, 0x5b, 0x30, 0x5d, 0x2c, 0x79, 0x3a, 0x72, 0x5b, + 0x31, 0x5d, 0x2b, 0x6c, 0x5b, 0x31, 0x5d, 0x2c, 0x64, 0x78, 0x3a, + 0x6e, 0x2c, 0x64, 0x79, 0x3a, 0x65, 0x7d, 0x29, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x29, + 0x7b, 0x74, 0x28, 0x68, 0x2c, 0x76, 0x29, 0x26, 0x26, 0x28, 0x6d, + 0x2e, 0x6f, 0x6e, 0x28, 0x69, 0x2b, 0x64, 0x2c, 0x6e, 0x75, 0x6c, + 0x6c, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x6f, 0x2b, 0x64, 0x2c, 0x6e, + 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x79, 0x28, 0x70, 0x26, 0x26, 0x74, + 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x3d, 0x3d, 0x3d, 0x66, 0x29, 0x2c, 0x67, 0x28, + 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x64, 0x72, 0x61, 0x67, + 0x65, 0x6e, 0x64, 0x22, 0x7d, 0x29, 0x29, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x6c, 0x2c, 0x73, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x66, + 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x2c, 0x68, 0x3d, 0x73, 0x2e, 0x70, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x2c, 0x67, + 0x3d, 0x72, 0x2e, 0x6f, 0x66, 0x28, 0x73, 0x2c, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x2c, 0x70, 0x3d, 0x30, + 0x2c, 0x76, 0x3d, 0x6e, 0x28, 0x29, 0x2c, 0x64, 0x3d, 0x22, 0x2e, + 0x64, 0x72, 0x61, 0x67, 0x22, 0x2b, 0x28, 0x6e, 0x75, 0x6c, 0x6c, + 0x3d, 0x3d, 0x76, 0x3f, 0x22, 0x22, 0x3a, 0x22, 0x2d, 0x22, 0x2b, + 0x76, 0x29, 0x2c, 0x6d, 0x3d, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x28, 0x65, 0x28, 0x66, 0x29, 0x29, 0x2e, 0x6f, + 0x6e, 0x28, 0x69, 0x2b, 0x64, 0x2c, 0x61, 0x29, 0x2e, 0x6f, 0x6e, + 0x28, 0x6f, 0x2b, 0x64, 0x2c, 0x63, 0x29, 0x2c, 0x79, 0x3d, 0x57, + 0x28, 0x66, 0x29, 0x2c, 0x4d, 0x3d, 0x74, 0x28, 0x68, 0x2c, 0x76, + 0x29, 0x3b, 0x75, 0x3f, 0x28, 0x6c, 0x3d, 0x75, 0x2e, 0x61, 0x70, + 0x70, 0x6c, 0x79, 0x28, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x2c, 0x6c, 0x3d, 0x5b, 0x6c, 0x2e, + 0x78, 0x2d, 0x4d, 0x5b, 0x30, 0x5d, 0x2c, 0x6c, 0x2e, 0x79, 0x2d, + 0x4d, 0x5b, 0x31, 0x5d, 0x5d, 0x29, 0x3a, 0x6c, 0x3d, 0x5b, 0x30, + 0x2c, 0x30, 0x5d, 0x2c, 0x67, 0x28, 0x7b, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x22, 0x64, 0x72, 0x61, 0x67, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x22, 0x7d, 0x29, 0x7d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, + 0x45, 0x28, 0x6e, 0x2c, 0x22, 0x64, 0x72, 0x61, 0x67, 0x22, 0x2c, + 0x22, 0x64, 0x72, 0x61, 0x67, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, + 0x2c, 0x22, 0x64, 0x72, 0x61, 0x67, 0x65, 0x6e, 0x64, 0x22, 0x29, + 0x2c, 0x75, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x69, 0x3d, 0x65, + 0x28, 0x62, 0x2c, 0x74, 0x61, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x2c, 0x74, 0x2c, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x22, 0x2c, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x75, + 0x70, 0x22, 0x29, 0x2c, 0x6f, 0x3d, 0x65, 0x28, 0x47, 0x2c, 0x74, + 0x61, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x2c, 0x79, 0x2c, 0x22, + 0x74, 0x6f, 0x75, 0x63, 0x68, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x2c, + 0x22, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x6e, 0x64, 0x22, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x75, + 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x75, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x72, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x6e, 0x2c, 0x72, + 0x2c, 0x22, 0x6f, 0x6e, 0x22, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x32, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x6b, 0x28, 0x29, + 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x29, 0x2c, 0x74, + 0x3f, 0x72, 0x61, 0x28, 0x74, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x4a, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, + 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, + 0x3d, 0x74, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x2c, 0x65, 0x7d, 0x29, 0x3a, 0x5b, 0x5d, 0x7d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x43, 0x61, 0x3d, 0x31, 0x65, 0x2d, 0x36, + 0x2c, 0x7a, 0x61, 0x3d, 0x43, 0x61, 0x2a, 0x43, 0x61, 0x2c, 0x71, + 0x61, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x50, 0x49, 0x2c, 0x4c, + 0x61, 0x3d, 0x32, 0x2a, 0x71, 0x61, 0x2c, 0x54, 0x61, 0x3d, 0x4c, + 0x61, 0x2d, 0x43, 0x61, 0x2c, 0x52, 0x61, 0x3d, 0x71, 0x61, 0x2f, + 0x32, 0x2c, 0x44, 0x61, 0x3d, 0x71, 0x61, 0x2f, 0x31, 0x38, 0x30, + 0x2c, 0x50, 0x61, 0x3d, 0x31, 0x38, 0x30, 0x2f, 0x71, 0x61, 0x2c, + 0x55, 0x61, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x51, 0x52, + 0x54, 0x32, 0x2c, 0x6a, 0x61, 0x3d, 0x32, 0x2c, 0x46, 0x61, 0x3d, + 0x34, 0x3b, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, + 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x5a, 0x6f, 0x6f, 0x6d, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x6e, 0x2a, 0x79, 0x3b, 0x69, 0x66, 0x28, 0x6d, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x3d, 0x72, 0x74, 0x28, 0x76, 0x29, 0x2c, + 0x6f, 0x3d, 0x69, 0x2f, 0x28, 0x6a, 0x61, 0x2a, 0x68, 0x29, 0x2a, + 0x28, 0x65, 0x2a, 0x75, 0x74, 0x28, 0x55, 0x61, 0x2a, 0x74, 0x2b, + 0x76, 0x29, 0x2d, 0x65, 0x74, 0x28, 0x76, 0x29, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x72, 0x2b, 0x6f, 0x2a, 0x6c, + 0x2c, 0x75, 0x2b, 0x6f, 0x2a, 0x73, 0x2c, 0x69, 0x2a, 0x65, 0x2f, + 0x72, 0x74, 0x28, 0x55, 0x61, 0x2a, 0x74, 0x2b, 0x76, 0x29, 0x5d, + 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x72, 0x2b, 0x6e, + 0x2a, 0x6c, 0x2c, 0x75, 0x2b, 0x6e, 0x2a, 0x73, 0x2c, 0x69, 0x2a, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x65, 0x78, 0x70, 0x28, 0x55, 0x61, + 0x2a, 0x74, 0x29, 0x5d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, + 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, + 0x2c, 0x69, 0x3d, 0x6e, 0x5b, 0x32, 0x5d, 0x2c, 0x6f, 0x3d, 0x74, + 0x5b, 0x30, 0x5d, 0x2c, 0x61, 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2c, + 0x63, 0x3d, 0x74, 0x5b, 0x32, 0x5d, 0x2c, 0x6c, 0x3d, 0x6f, 0x2d, + 0x72, 0x2c, 0x73, 0x3d, 0x61, 0x2d, 0x75, 0x2c, 0x66, 0x3d, 0x6c, + 0x2a, 0x6c, 0x2b, 0x73, 0x2a, 0x73, 0x2c, 0x68, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x66, 0x29, 0x2c, + 0x67, 0x3d, 0x28, 0x63, 0x2a, 0x63, 0x2d, 0x69, 0x2a, 0x69, 0x2b, + 0x46, 0x61, 0x2a, 0x66, 0x29, 0x2f, 0x28, 0x32, 0x2a, 0x69, 0x2a, + 0x6a, 0x61, 0x2a, 0x68, 0x29, 0x2c, 0x70, 0x3d, 0x28, 0x63, 0x2a, + 0x63, 0x2d, 0x69, 0x2a, 0x69, 0x2d, 0x46, 0x61, 0x2a, 0x66, 0x29, + 0x2f, 0x28, 0x32, 0x2a, 0x63, 0x2a, 0x6a, 0x61, 0x2a, 0x68, 0x29, + 0x2c, 0x76, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, + 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, + 0x67, 0x2a, 0x67, 0x2b, 0x31, 0x29, 0x2d, 0x67, 0x29, 0x2c, 0x64, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x70, 0x2a, + 0x70, 0x2b, 0x31, 0x29, 0x2d, 0x70, 0x29, 0x2c, 0x6d, 0x3d, 0x64, + 0x2d, 0x76, 0x2c, 0x79, 0x3d, 0x28, 0x6d, 0x7c, 0x7c, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x63, 0x2f, 0x69, 0x29, + 0x29, 0x2f, 0x55, 0x61, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x65, 0x2e, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3d, 0x31, 0x65, 0x33, 0x2a, 0x79, 0x2c, 0x65, 0x7d, 0x2c, 0x74, + 0x61, 0x2e, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x2e, + 0x7a, 0x6f, 0x6f, 0x6d, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x6f, + 0x6e, 0x28, 0x71, 0x2c, 0x66, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x4f, + 0x61, 0x2b, 0x22, 0x2e, 0x7a, 0x6f, 0x6f, 0x6d, 0x22, 0x2c, 0x67, + 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x64, 0x62, 0x6c, 0x63, 0x6c, + 0x69, 0x63, 0x6b, 0x2e, 0x7a, 0x6f, 0x6f, 0x6d, 0x22, 0x2c, 0x70, + 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x52, 0x2c, 0x68, 0x29, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x28, 0x6e, + 0x5b, 0x30, 0x5d, 0x2d, 0x6b, 0x2e, 0x78, 0x29, 0x2f, 0x6b, 0x2e, + 0x6b, 0x2c, 0x28, 0x6e, 0x5b, 0x31, 0x5d, 0x2d, 0x6b, 0x2e, 0x79, + 0x29, 0x2f, 0x6b, 0x2e, 0x6b, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, + 0x6b, 0x2e, 0x6b, 0x2b, 0x6b, 0x2e, 0x78, 0x2c, 0x6e, 0x5b, 0x31, + 0x5d, 0x2a, 0x6b, 0x2e, 0x6b, 0x2b, 0x6b, 0x2e, 0x79, 0x5d, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, + 0x6e, 0x29, 0x7b, 0x6b, 0x2e, 0x6b, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x4e, 0x5b, 0x30, 0x5d, 0x2c, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x4e, 0x5b, 0x31, + 0x5d, 0x2c, 0x6e, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x74, 0x3d, 0x72, 0x28, 0x74, 0x29, 0x2c, 0x6b, 0x2e, 0x78, 0x2b, + 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2d, 0x74, 0x5b, 0x30, 0x5d, 0x2c, + 0x6b, 0x2e, 0x79, 0x2b, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x2d, 0x74, + 0x5b, 0x31, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6f, 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x6f, + 0x29, 0x7b, 0x74, 0x2e, 0x5f, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x74, + 0x5f, 0x5f, 0x3d, 0x7b, 0x78, 0x3a, 0x6b, 0x2e, 0x78, 0x2c, 0x79, + 0x3a, 0x6b, 0x2e, 0x79, 0x2c, 0x6b, 0x3a, 0x6b, 0x2e, 0x6b, 0x7d, + 0x2c, 0x75, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, + 0x28, 0x32, 0x2c, 0x6f, 0x29, 0x29, 0x2c, 0x69, 0x28, 0x64, 0x3d, + 0x65, 0x2c, 0x72, 0x29, 0x2c, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x43, 0x3e, + 0x30, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x74, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x2e, 0x64, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x43, 0x29, 0x29, + 0x2c, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x28, 0x29, 0x7b, 0x62, 0x26, 0x26, + 0x62, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x78, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x29, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x6e, 0x2d, + 0x6b, 0x2e, 0x78, 0x29, 0x2f, 0x6b, 0x2e, 0x6b, 0x7d, 0x29, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x78, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, + 0x74, 0x29, 0x29, 0x2c, 0x77, 0x26, 0x26, 0x77, 0x2e, 0x64, 0x6f, + 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x5f, 0x2e, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x28, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x28, 0x6e, 0x2d, 0x6b, 0x2e, 0x79, 0x29, + 0x2f, 0x6b, 0x2e, 0x6b, 0x7d, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, + 0x5f, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x29, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, + 0x6e, 0x29, 0x7b, 0x7a, 0x2b, 0x2b, 0x7c, 0x7c, 0x6e, 0x28, 0x7b, + 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x7a, 0x6f, 0x6f, 0x6d, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x22, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x28, 0x6e, 0x29, 0x7b, + 0x61, 0x28, 0x29, 0x2c, 0x6e, 0x28, 0x7b, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x22, 0x7a, 0x6f, 0x6f, 0x6d, 0x22, 0x2c, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x3a, 0x6b, 0x2e, 0x6b, 0x2c, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x6c, 0x61, 0x74, 0x65, 0x3a, 0x5b, 0x6b, 0x2e, 0x78, 0x2c, + 0x6b, 0x2e, 0x79, 0x5d, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x28, 0x6e, 0x29, 0x7b, 0x2d, + 0x2d, 0x7a, 0x7c, 0x7c, 0x28, 0x6e, 0x28, 0x7b, 0x74, 0x79, 0x70, + 0x65, 0x3a, 0x22, 0x7a, 0x6f, 0x6f, 0x6d, 0x65, 0x6e, 0x64, 0x22, + 0x7d, 0x29, 0x2c, 0x64, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x28, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x3d, 0x31, 0x2c, 0x69, 0x28, 0x74, + 0x61, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x28, 0x75, 0x29, 0x2c, + 0x67, 0x29, 0x2c, 0x6c, 0x28, 0x61, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, 0x7b, 0x68, + 0x2e, 0x6f, 0x6e, 0x28, 0x4c, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x2e, 0x6f, 0x6e, 0x28, 0x54, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x2c, 0x70, 0x28, 0x66, 0x26, 0x26, 0x74, 0x61, 0x2e, 0x65, 0x76, + 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, + 0x3d, 0x3d, 0x6f, 0x29, 0x2c, 0x73, 0x28, 0x61, 0x29, 0x7d, 0x76, + 0x61, 0x72, 0x20, 0x75, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6f, + 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x2c, 0x61, 0x3d, 0x44, 0x2e, 0x6f, + 0x66, 0x28, 0x75, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x29, 0x2c, 0x66, 0x3d, 0x30, 0x2c, 0x68, 0x3d, 0x74, + 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, 0x28, + 0x75, 0x29, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x4c, 0x2c, 0x6e, 0x29, + 0x2e, 0x6f, 0x6e, 0x28, 0x54, 0x2c, 0x72, 0x29, 0x2c, 0x67, 0x3d, + 0x65, 0x28, 0x74, 0x61, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x28, + 0x75, 0x29, 0x29, 0x2c, 0x70, 0x3d, 0x57, 0x28, 0x75, 0x29, 0x3b, + 0x44, 0x6c, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x75, 0x29, 0x2c, + 0x63, 0x28, 0x61, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x68, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x74, 0x6f, 0x75, 0x63, + 0x68, 0x65, 0x73, 0x28, 0x70, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x67, 0x3d, 0x6b, 0x2e, 0x6b, 0x2c, 0x6e, 0x2e, + 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x20, + 0x69, 0x6e, 0x20, 0x64, 0x26, 0x26, 0x28, 0x64, 0x5b, 0x6e, 0x2e, + 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5d, + 0x3d, 0x65, 0x28, 0x6e, 0x29, 0x29, 0x7d, 0x29, 0x2c, 0x6e, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x61, 0x2e, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x3b, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x28, 0x74, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x78, 0x2c, 0x72, 0x29, + 0x2e, 0x6f, 0x6e, 0x28, 0x62, 0x2c, 0x61, 0x29, 0x2c, 0x5f, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, 0x61, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x64, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x2c, 0x75, 0x3d, + 0x30, 0x2c, 0x69, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x69, 0x3e, 0x75, 0x3b, 0x2b, 0x2b, 0x75, 0x29, 0x64, + 0x5b, 0x65, 0x5b, 0x75, 0x5d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x5d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, 0x6e, 0x28, 0x29, 0x2c, + 0x6c, 0x3d, 0x44, 0x61, 0x74, 0x65, 0x2e, 0x6e, 0x6f, 0x77, 0x28, + 0x29, 0x3b, 0x69, 0x66, 0x28, 0x31, 0x3d, 0x3d, 0x3d, 0x63, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x69, 0x66, 0x28, + 0x35, 0x30, 0x30, 0x3e, 0x6c, 0x2d, 0x4d, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x73, 0x3d, 0x63, 0x5b, 0x30, 0x5d, 0x3b, 0x6f, 0x28, + 0x70, 0x2c, 0x73, 0x2c, 0x64, 0x5b, 0x73, 0x2e, 0x69, 0x64, 0x65, + 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x5d, 0x2c, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x6b, 0x2e, 0x6b, 0x29, + 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x4e, 0x32, 0x29, 0x2b, + 0x31, 0x29, 0x2c, 0x53, 0x28, 0x29, 0x7d, 0x4d, 0x3d, 0x6c, 0x7d, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x63, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x31, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x73, 0x3d, 0x63, 0x5b, 0x30, 0x5d, 0x2c, 0x66, 0x3d, + 0x63, 0x5b, 0x31, 0x5d, 0x2c, 0x68, 0x3d, 0x73, 0x5b, 0x30, 0x5d, + 0x2d, 0x66, 0x5b, 0x30, 0x5d, 0x2c, 0x67, 0x3d, 0x73, 0x5b, 0x31, + 0x5d, 0x2d, 0x66, 0x5b, 0x31, 0x5d, 0x3b, 0x6d, 0x3d, 0x68, 0x2a, + 0x68, 0x2b, 0x67, 0x2a, 0x67, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x6f, + 0x3d, 0x74, 0x61, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, + 0x28, 0x70, 0x29, 0x3b, 0x44, 0x6c, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x70, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x61, 0x3d, 0x30, 0x2c, 0x63, 0x3d, 0x6f, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x63, 0x3e, 0x61, 0x3b, 0x2b, 0x2b, + 0x61, 0x2c, 0x72, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x69, 0x66, + 0x28, 0x65, 0x3d, 0x6f, 0x5b, 0x61, 0x5d, 0x2c, 0x72, 0x3d, 0x64, + 0x5b, 0x65, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, + 0x65, 0x72, 0x5d, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x62, + 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x6e, 0x3d, 0x65, 0x2c, 0x74, 0x3d, + 0x72, 0x7d, 0x69, 0x66, 0x28, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x73, 0x3d, 0x28, 0x73, 0x3d, 0x65, 0x5b, 0x30, 0x5d, 0x2d, + 0x6e, 0x5b, 0x30, 0x5d, 0x29, 0x2a, 0x73, 0x2b, 0x28, 0x73, 0x3d, + 0x65, 0x5b, 0x31, 0x5d, 0x2d, 0x6e, 0x5b, 0x31, 0x5d, 0x29, 0x2a, + 0x73, 0x2c, 0x66, 0x3d, 0x6d, 0x26, 0x26, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x73, 0x2f, 0x6d, 0x29, 0x3b, + 0x6e, 0x3d, 0x5b, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2b, 0x65, 0x5b, + 0x30, 0x5d, 0x29, 0x2f, 0x32, 0x2c, 0x28, 0x6e, 0x5b, 0x31, 0x5d, + 0x2b, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x2f, 0x32, 0x5d, 0x2c, 0x74, + 0x3d, 0x5b, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x2b, 0x72, 0x5b, 0x30, + 0x5d, 0x29, 0x2f, 0x32, 0x2c, 0x28, 0x74, 0x5b, 0x31, 0x5d, 0x2b, + 0x72, 0x5b, 0x31, 0x5d, 0x29, 0x2f, 0x32, 0x5d, 0x2c, 0x75, 0x28, + 0x66, 0x2a, 0x67, 0x29, 0x7d, 0x4d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x2c, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x2c, 0x6c, 0x28, 0x76, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x61, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x61, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x61, + 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x2c, + 0x65, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x72, 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, + 0x29, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x64, 0x5b, 0x74, + 0x5b, 0x65, 0x5d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, + 0x69, 0x65, 0x72, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x75, 0x20, 0x69, 0x6e, 0x20, 0x64, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6e, + 0x28, 0x29, 0x7d, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x5f, 0x29, 0x2e, 0x6f, 0x6e, 0x28, + 0x79, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x77, 0x2e, 0x6f, + 0x6e, 0x28, 0x71, 0x2c, 0x66, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x52, + 0x2c, 0x68, 0x29, 0x2c, 0x45, 0x28, 0x29, 0x2c, 0x73, 0x28, 0x76, + 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x67, 0x2c, 0x70, 0x3d, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x76, 0x3d, 0x44, 0x2e, 0x6f, 0x66, 0x28, + 0x70, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x2c, 0x64, 0x3d, 0x7b, 0x7d, 0x2c, 0x6d, 0x3d, 0x30, 0x2c, + 0x79, 0x3d, 0x22, 0x2e, 0x7a, 0x6f, 0x6f, 0x6d, 0x2d, 0x22, 0x2b, + 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x68, + 0x61, 0x6e, 0x67, 0x65, 0x64, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x65, + 0x73, 0x5b, 0x30, 0x5d, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x2c, 0x78, 0x3d, 0x22, 0x74, 0x6f, 0x75, + 0x63, 0x68, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x2b, 0x79, 0x2c, 0x62, + 0x3d, 0x22, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x6e, 0x64, 0x22, + 0x2b, 0x79, 0x2c, 0x5f, 0x3d, 0x5b, 0x5d, 0x2c, 0x77, 0x3d, 0x74, + 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x70, 0x29, + 0x2c, 0x45, 0x3d, 0x57, 0x28, 0x70, 0x29, 0x3b, 0x74, 0x28, 0x29, + 0x2c, 0x63, 0x28, 0x76, 0x29, 0x2c, 0x77, 0x2e, 0x6f, 0x6e, 0x28, + 0x71, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2e, 0x6f, 0x6e, 0x28, + 0x52, 0x2c, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x67, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x3d, 0x44, 0x2e, 0x6f, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, + 0x3b, 0x79, 0x3f, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x28, 0x79, 0x29, 0x3a, 0x28, 0x44, 0x6c, + 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x2c, 0x76, 0x3d, 0x65, 0x28, 0x64, 0x3d, 0x6d, 0x7c, 0x7c, 0x74, + 0x61, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x29, 0x29, 0x2c, 0x63, 0x28, 0x6e, 0x29, 0x29, 0x2c, 0x79, + 0x3d, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x79, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x73, 0x28, 0x6e, + 0x29, 0x7d, 0x2c, 0x35, 0x30, 0x29, 0x2c, 0x53, 0x28, 0x29, 0x2c, + 0x75, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, + 0x32, 0x2c, 0x2e, 0x30, 0x30, 0x32, 0x2a, 0x48, 0x61, 0x28, 0x29, + 0x29, 0x2a, 0x6b, 0x2e, 0x6b, 0x29, 0x2c, 0x69, 0x28, 0x64, 0x2c, + 0x76, 0x29, 0x2c, 0x6c, 0x28, 0x6e, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x6f, 0x75, + 0x73, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x2c, 0x74, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x6b, 0x2e, + 0x6b, 0x29, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x4c, 0x4e, 0x32, + 0x3b, 0x6f, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x65, + 0x28, 0x6e, 0x29, 0x2c, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x4b, 0x65, 0x79, 0x3f, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x74, + 0x29, 0x2d, 0x31, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, + 0x6f, 0x6f, 0x72, 0x28, 0x74, 0x29, 0x2b, 0x31, 0x29, 0x7d, 0x76, + 0x61, 0x72, 0x20, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x79, 0x2c, + 0x4d, 0x2c, 0x78, 0x2c, 0x62, 0x2c, 0x5f, 0x2c, 0x77, 0x2c, 0x6b, + 0x3d, 0x7b, 0x78, 0x3a, 0x30, 0x2c, 0x79, 0x3a, 0x30, 0x2c, 0x6b, + 0x3a, 0x31, 0x7d, 0x2c, 0x41, 0x3d, 0x5b, 0x39, 0x36, 0x30, 0x2c, + 0x35, 0x30, 0x30, 0x5d, 0x2c, 0x4e, 0x3d, 0x49, 0x61, 0x2c, 0x43, + 0x3d, 0x32, 0x35, 0x30, 0x2c, 0x7a, 0x3d, 0x30, 0x2c, 0x71, 0x3d, + 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x2e, + 0x7a, 0x6f, 0x6f, 0x6d, 0x22, 0x2c, 0x4c, 0x3d, 0x22, 0x6d, 0x6f, + 0x75, 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2e, 0x7a, 0x6f, 0x6f, + 0x6d, 0x22, 0x2c, 0x54, 0x3d, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x75, 0x70, 0x2e, 0x7a, 0x6f, 0x6f, 0x6d, 0x22, 0x2c, 0x52, 0x3d, + 0x22, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x2e, 0x7a, 0x6f, 0x6f, 0x6d, 0x22, 0x2c, 0x44, 0x3d, 0x45, 0x28, + 0x6e, 0x2c, 0x22, 0x7a, 0x6f, 0x6f, 0x6d, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x22, 0x2c, 0x22, 0x7a, 0x6f, 0x6f, 0x6d, 0x22, 0x2c, 0x22, + 0x7a, 0x6f, 0x6f, 0x6d, 0x65, 0x6e, 0x64, 0x22, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4f, 0x61, 0x7c, 0x7c, 0x28, + 0x4f, 0x61, 0x3d, 0x22, 0x6f, 0x6e, 0x77, 0x68, 0x65, 0x65, 0x6c, + 0x22, 0x69, 0x6e, 0x20, 0x75, 0x61, 0x3f, 0x28, 0x48, 0x61, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x74, 0x61, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x59, + 0x2a, 0x28, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, + 0x64, 0x65, 0x6c, 0x74, 0x61, 0x4d, 0x6f, 0x64, 0x65, 0x3f, 0x31, + 0x32, 0x30, 0x3a, 0x31, 0x29, 0x7d, 0x2c, 0x22, 0x77, 0x68, 0x65, + 0x65, 0x6c, 0x22, 0x29, 0x3a, 0x22, 0x6f, 0x6e, 0x6d, 0x6f, 0x75, + 0x73, 0x65, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x22, 0x69, 0x6e, 0x20, + 0x75, 0x61, 0x3f, 0x28, 0x48, 0x61, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x2e, 0x77, 0x68, 0x65, 0x65, 0x6c, 0x44, 0x65, 0x6c, 0x74, 0x61, + 0x7d, 0x2c, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x77, 0x68, 0x65, + 0x65, 0x6c, 0x22, 0x29, 0x3a, 0x28, 0x48, 0x61, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x2e, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x7d, 0x2c, + 0x22, 0x4d, 0x6f, 0x7a, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x50, 0x69, + 0x78, 0x65, 0x6c, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x22, 0x29, + 0x29, 0x2c, 0x6e, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x6e, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x3d, 0x44, 0x2e, 0x6f, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, + 0x2c, 0x74, 0x3d, 0x6b, 0x3b, 0x54, 0x6c, 0x3f, 0x74, 0x61, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x29, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x22, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x2e, 0x7a, 0x6f, 0x6f, 0x6d, 0x22, 0x2c, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x6b, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x5f, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x5f, 0x5f, 0x7c, 0x7c, 0x7b, 0x78, 0x3a, 0x30, + 0x2c, 0x79, 0x3a, 0x30, 0x2c, 0x6b, 0x3a, 0x31, 0x7d, 0x2c, 0x63, + 0x28, 0x6e, 0x29, 0x7d, 0x29, 0x2e, 0x74, 0x77, 0x65, 0x65, 0x6e, + 0x28, 0x22, 0x7a, 0x6f, 0x6f, 0x6d, 0x3a, 0x7a, 0x6f, 0x6f, 0x6d, + 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x41, 0x5b, 0x30, + 0x5d, 0x2c, 0x72, 0x3d, 0x41, 0x5b, 0x31, 0x5d, 0x2c, 0x75, 0x3d, + 0x64, 0x3f, 0x64, 0x5b, 0x30, 0x5d, 0x3a, 0x65, 0x2f, 0x32, 0x2c, + 0x69, 0x3d, 0x64, 0x3f, 0x64, 0x5b, 0x31, 0x5d, 0x3a, 0x72, 0x2f, + 0x32, 0x2c, 0x6f, 0x3d, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, 0x65, + 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x5a, 0x6f, 0x6f, 0x6d, + 0x28, 0x5b, 0x28, 0x75, 0x2d, 0x6b, 0x2e, 0x78, 0x29, 0x2f, 0x6b, + 0x2e, 0x6b, 0x2c, 0x28, 0x69, 0x2d, 0x6b, 0x2e, 0x79, 0x29, 0x2f, + 0x6b, 0x2e, 0x6b, 0x2c, 0x65, 0x2f, 0x6b, 0x2e, 0x6b, 0x5d, 0x2c, + 0x5b, 0x28, 0x75, 0x2d, 0x74, 0x2e, 0x78, 0x29, 0x2f, 0x74, 0x2e, + 0x6b, 0x2c, 0x28, 0x69, 0x2d, 0x74, 0x2e, 0x79, 0x29, 0x2f, 0x74, + 0x2e, 0x6b, 0x2c, 0x65, 0x2f, 0x74, 0x2e, 0x6b, 0x5d, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x72, 0x3d, 0x6f, 0x28, 0x74, 0x29, 0x2c, 0x61, 0x3d, 0x65, + 0x2f, 0x72, 0x5b, 0x32, 0x5d, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x5f, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x74, 0x5f, 0x5f, 0x3d, 0x6b, + 0x3d, 0x7b, 0x78, 0x3a, 0x75, 0x2d, 0x72, 0x5b, 0x30, 0x5d, 0x2a, + 0x61, 0x2c, 0x79, 0x3a, 0x69, 0x2d, 0x72, 0x5b, 0x31, 0x5d, 0x2a, + 0x61, 0x2c, 0x6b, 0x3a, 0x61, 0x7d, 0x2c, 0x6c, 0x28, 0x6e, 0x29, + 0x7d, 0x7d, 0x29, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x22, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x2e, 0x7a, 0x6f, + 0x6f, 0x6d, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x73, 0x28, 0x6e, 0x29, 0x7d, 0x29, 0x2e, + 0x65, 0x61, 0x63, 0x68, 0x28, 0x22, 0x65, 0x6e, 0x64, 0x2e, 0x7a, + 0x6f, 0x6f, 0x6d, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x73, 0x28, 0x6e, 0x29, 0x7d, 0x29, + 0x3a, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x5f, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x5f, 0x5f, 0x3d, 0x6b, 0x2c, 0x63, 0x28, 0x6e, + 0x29, 0x2c, 0x6c, 0x28, 0x6e, 0x29, 0x2c, 0x73, 0x28, 0x6e, 0x29, + 0x29, 0x7d, 0x29, 0x7d, 0x2c, 0x6e, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6b, + 0x3d, 0x7b, 0x78, 0x3a, 0x2b, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x79, + 0x3a, 0x2b, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x6b, 0x3a, 0x6b, 0x2e, + 0x6b, 0x7d, 0x2c, 0x61, 0x28, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x5b, + 0x6b, 0x2e, 0x78, 0x2c, 0x6b, 0x2e, 0x79, 0x5d, 0x7d, 0x2c, 0x6e, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x6b, 0x3d, 0x7b, 0x78, 0x3a, 0x6b, 0x2e, 0x78, 0x2c, 0x79, 0x3a, + 0x6b, 0x2e, 0x79, 0x2c, 0x6b, 0x3a, 0x2b, 0x74, 0x7d, 0x2c, 0x61, + 0x28, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x6b, 0x2e, 0x6b, 0x7d, 0x2c, + 0x6e, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x4e, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x3d, 0x3d, 0x74, 0x3f, 0x49, 0x61, 0x3a, 0x5b, 0x2b, + 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x2b, 0x74, 0x5b, 0x31, 0x5d, 0x5d, + 0x2c, 0x6e, 0x29, 0x3a, 0x4e, 0x7d, 0x2c, 0x6e, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6d, 0x3d, + 0x74, 0x26, 0x26, 0x5b, 0x2b, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x2b, + 0x74, 0x5b, 0x31, 0x5d, 0x5d, 0x2c, 0x6e, 0x29, 0x3a, 0x6d, 0x7d, + 0x2c, 0x6e, 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x41, 0x3d, 0x74, 0x26, 0x26, 0x5b, 0x2b, 0x74, 0x5b, 0x30, + 0x5d, 0x2c, 0x2b, 0x74, 0x5b, 0x31, 0x5d, 0x5d, 0x2c, 0x6e, 0x29, + 0x3a, 0x41, 0x7d, 0x2c, 0x6e, 0x2e, 0x64, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x43, 0x3d, 0x2b, + 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x43, 0x7d, 0x2c, 0x6e, 0x2e, 0x78, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x62, 0x3d, 0x74, 0x2c, 0x78, 0x3d, + 0x74, 0x2e, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x29, 0x2c, 0x6b, 0x3d, + 0x7b, 0x78, 0x3a, 0x30, 0x2c, 0x79, 0x3a, 0x30, 0x2c, 0x6b, 0x3a, + 0x31, 0x7d, 0x2c, 0x6e, 0x29, 0x3a, 0x62, 0x7d, 0x2c, 0x6e, 0x2e, + 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x77, 0x3d, 0x74, 0x2c, 0x5f, + 0x3d, 0x74, 0x2e, 0x63, 0x6f, 0x70, 0x79, 0x28, 0x29, 0x2c, 0x6b, + 0x3d, 0x7b, 0x78, 0x3a, 0x30, 0x2c, 0x79, 0x3a, 0x30, 0x2c, 0x6b, + 0x3a, 0x31, 0x7d, 0x2c, 0x6e, 0x29, 0x3a, 0x77, 0x7d, 0x2c, 0x74, + 0x61, 0x2e, 0x72, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x6e, 0x2c, + 0x44, 0x2c, 0x22, 0x6f, 0x6e, 0x22, 0x29, 0x7d, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x48, 0x61, 0x2c, 0x4f, 0x61, 0x2c, 0x49, 0x61, 0x3d, + 0x5b, 0x30, 0x2c, 0x31, 0x2f, 0x30, 0x5d, 0x3b, 0x74, 0x61, 0x2e, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3d, 0x6f, 0x74, 0x2c, 0x6f, 0x74, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x2e, + 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, + 0x67, 0x62, 0x28, 0x29, 0x2b, 0x22, 0x22, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x68, 0x73, 0x6c, 0x3d, 0x61, 0x74, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x59, 0x61, 0x3d, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x6f, + 0x74, 0x3b, 0x59, 0x61, 0x2e, 0x62, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, + 0x2e, 0x37, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x3a, + 0x31, 0x29, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x61, 0x74, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x68, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x73, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x2f, 0x6e, 0x29, + 0x7d, 0x2c, 0x59, 0x61, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x65, 0x72, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x2e, 0x37, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x3a, 0x31, 0x29, + 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x61, 0x74, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x68, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x2c, + 0x6e, 0x2a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x29, 0x7d, 0x2c, + 0x59, 0x61, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x63, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x68, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6c, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x68, + 0x63, 0x6c, 0x3d, 0x6c, 0x74, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x5a, + 0x61, 0x3d, 0x6c, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x6f, 0x74, 0x3b, + 0x5a, 0x61, 0x2e, 0x62, 0x72, 0x69, 0x67, 0x68, 0x74, 0x65, 0x72, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, + 0x77, 0x20, 0x6c, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x68, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x2c, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x31, 0x30, 0x30, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x2b, 0x56, 0x61, 0x2a, 0x28, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x3a, 0x31, 0x29, 0x29, 0x29, + 0x7d, 0x2c, 0x5a, 0x61, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x65, 0x72, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, + 0x77, 0x20, 0x6c, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x68, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x2c, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x30, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x6c, 0x2d, 0x56, 0x61, 0x2a, 0x28, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x6e, 0x3a, 0x31, 0x29, 0x29, 0x29, 0x7d, 0x2c, + 0x5a, 0x61, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x73, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x68, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6c, 0x29, 0x2e, 0x72, 0x67, 0x62, 0x28, 0x29, + 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x62, 0x3d, 0x66, 0x74, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x56, 0x61, 0x3d, 0x31, 0x38, 0x2c, + 0x58, 0x61, 0x3d, 0x2e, 0x39, 0x35, 0x30, 0x34, 0x37, 0x2c, 0x24, + 0x61, 0x3d, 0x31, 0x2c, 0x42, 0x61, 0x3d, 0x31, 0x2e, 0x30, 0x38, + 0x38, 0x38, 0x33, 0x2c, 0x57, 0x61, 0x3d, 0x66, 0x74, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x6e, 0x65, + 0x77, 0x20, 0x6f, 0x74, 0x3b, 0x57, 0x61, 0x2e, 0x62, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x66, 0x74, 0x28, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x31, 0x30, 0x30, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x2b, 0x56, 0x61, 0x2a, + 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x3a, 0x31, 0x29, + 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x62, 0x29, 0x7d, 0x2c, 0x57, 0x61, 0x2e, 0x64, + 0x61, 0x72, 0x6b, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x66, 0x74, 0x28, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x30, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x2d, 0x56, 0x61, 0x2a, 0x28, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x3a, 0x31, 0x29, 0x29, 0x2c, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x62, 0x29, 0x7d, 0x2c, 0x57, 0x61, 0x2e, 0x72, 0x67, 0x62, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x74, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x61, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x62, 0x29, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x72, 0x67, 0x62, 0x3d, 0x6d, 0x74, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x4a, 0x61, 0x3d, 0x6d, 0x74, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x6e, 0x65, + 0x77, 0x20, 0x6f, 0x74, 0x3b, 0x4a, 0x61, 0x2e, 0x62, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x2e, 0x37, 0x2c, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x3a, 0x31, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, + 0x2c, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x2c, 0x72, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x62, 0x2c, 0x75, 0x3d, 0x33, + 0x30, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7c, + 0x7c, 0x65, 0x7c, 0x7c, 0x72, 0x3f, 0x28, 0x74, 0x26, 0x26, 0x75, + 0x3e, 0x74, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x75, 0x29, 0x2c, 0x65, + 0x26, 0x26, 0x75, 0x3e, 0x65, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x75, + 0x29, 0x2c, 0x72, 0x26, 0x26, 0x75, 0x3e, 0x72, 0x26, 0x26, 0x28, + 0x72, 0x3d, 0x75, 0x29, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x6d, 0x74, + 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x32, + 0x35, 0x35, 0x2c, 0x74, 0x2f, 0x6e, 0x29, 0x2c, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x65, + 0x2f, 0x6e, 0x29, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x32, 0x35, 0x35, 0x2c, 0x72, 0x2f, 0x6e, 0x29, 0x29, + 0x29, 0x3a, 0x6e, 0x65, 0x77, 0x20, 0x6d, 0x74, 0x28, 0x75, 0x2c, + 0x75, 0x2c, 0x75, 0x29, 0x7d, 0x2c, 0x4a, 0x61, 0x2e, 0x64, 0x61, + 0x72, 0x6b, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x6f, + 0x77, 0x28, 0x2e, 0x37, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x6e, 0x3a, 0x31, 0x29, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x6d, 0x74, + 0x28, 0x6e, 0x2a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x2c, 0x6e, + 0x2a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x2c, 0x6e, 0x2a, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x62, 0x29, 0x7d, 0x2c, 0x4a, 0x61, 0x2e, + 0x68, 0x73, 0x6c, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x5f, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x67, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x62, 0x29, 0x7d, 0x2c, 0x4a, 0x61, 0x2e, 0x74, 0x6f, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x22, 0x23, 0x22, 0x2b, 0x78, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x29, 0x2b, 0x78, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x67, 0x29, 0x2b, 0x78, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x62, 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x47, 0x61, + 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x7b, 0x61, 0x6c, + 0x69, 0x63, 0x65, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x31, 0x35, 0x37, + 0x39, 0x32, 0x33, 0x38, 0x33, 0x2c, 0x61, 0x6e, 0x74, 0x69, 0x71, + 0x75, 0x65, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3a, 0x31, 0x36, 0x34, + 0x34, 0x34, 0x33, 0x37, 0x35, 0x2c, 0x61, 0x71, 0x75, 0x61, 0x3a, + 0x36, 0x35, 0x35, 0x33, 0x35, 0x2c, 0x61, 0x71, 0x75, 0x61, 0x6d, + 0x61, 0x72, 0x69, 0x6e, 0x65, 0x3a, 0x38, 0x33, 0x38, 0x38, 0x35, + 0x36, 0x34, 0x2c, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x3a, 0x31, 0x35, + 0x37, 0x39, 0x34, 0x31, 0x37, 0x35, 0x2c, 0x62, 0x65, 0x69, 0x67, + 0x65, 0x3a, 0x31, 0x36, 0x31, 0x31, 0x39, 0x32, 0x36, 0x30, 0x2c, + 0x62, 0x69, 0x73, 0x71, 0x75, 0x65, 0x3a, 0x31, 0x36, 0x37, 0x37, + 0x30, 0x32, 0x34, 0x34, 0x2c, 0x62, 0x6c, 0x61, 0x63, 0x6b, 0x3a, + 0x30, 0x2c, 0x62, 0x6c, 0x61, 0x6e, 0x63, 0x68, 0x65, 0x64, 0x61, + 0x6c, 0x6d, 0x6f, 0x6e, 0x64, 0x3a, 0x31, 0x36, 0x37, 0x37, 0x32, + 0x30, 0x34, 0x35, 0x2c, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x32, 0x35, + 0x35, 0x2c, 0x62, 0x6c, 0x75, 0x65, 0x76, 0x69, 0x6f, 0x6c, 0x65, + 0x74, 0x3a, 0x39, 0x30, 0x35, 0x35, 0x32, 0x30, 0x32, 0x2c, 0x62, + 0x72, 0x6f, 0x77, 0x6e, 0x3a, 0x31, 0x30, 0x38, 0x32, 0x34, 0x32, + 0x33, 0x34, 0x2c, 0x62, 0x75, 0x72, 0x6c, 0x79, 0x77, 0x6f, 0x6f, + 0x64, 0x3a, 0x31, 0x34, 0x35, 0x39, 0x36, 0x32, 0x33, 0x31, 0x2c, + 0x63, 0x61, 0x64, 0x65, 0x74, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x36, + 0x32, 0x36, 0x36, 0x35, 0x32, 0x38, 0x2c, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x72, 0x65, 0x75, 0x73, 0x65, 0x3a, 0x38, 0x33, 0x38, 0x38, + 0x33, 0x35, 0x32, 0x2c, 0x63, 0x68, 0x6f, 0x63, 0x6f, 0x6c, 0x61, + 0x74, 0x65, 0x3a, 0x31, 0x33, 0x37, 0x38, 0x39, 0x34, 0x37, 0x30, + 0x2c, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x3a, 0x31, 0x36, 0x37, 0x34, + 0x34, 0x32, 0x37, 0x32, 0x2c, 0x63, 0x6f, 0x72, 0x6e, 0x66, 0x6c, + 0x6f, 0x77, 0x65, 0x72, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x36, 0x35, + 0x39, 0x31, 0x39, 0x38, 0x31, 0x2c, 0x63, 0x6f, 0x72, 0x6e, 0x73, + 0x69, 0x6c, 0x6b, 0x3a, 0x31, 0x36, 0x37, 0x37, 0x35, 0x33, 0x38, + 0x38, 0x2c, 0x63, 0x72, 0x69, 0x6d, 0x73, 0x6f, 0x6e, 0x3a, 0x31, + 0x34, 0x34, 0x32, 0x33, 0x31, 0x30, 0x30, 0x2c, 0x63, 0x79, 0x61, + 0x6e, 0x3a, 0x36, 0x35, 0x35, 0x33, 0x35, 0x2c, 0x64, 0x61, 0x72, + 0x6b, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x31, 0x33, 0x39, 0x2c, 0x64, + 0x61, 0x72, 0x6b, 0x63, 0x79, 0x61, 0x6e, 0x3a, 0x33, 0x35, 0x37, + 0x32, 0x33, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x67, 0x6f, 0x6c, 0x64, + 0x65, 0x6e, 0x72, 0x6f, 0x64, 0x3a, 0x31, 0x32, 0x30, 0x39, 0x32, + 0x39, 0x33, 0x39, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x67, 0x72, 0x61, + 0x79, 0x3a, 0x31, 0x31, 0x31, 0x31, 0x39, 0x30, 0x31, 0x37, 0x2c, + 0x64, 0x61, 0x72, 0x6b, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x3a, 0x32, + 0x35, 0x36, 0x30, 0x30, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x67, 0x72, + 0x65, 0x79, 0x3a, 0x31, 0x31, 0x31, 0x31, 0x39, 0x30, 0x31, 0x37, + 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x6b, 0x68, 0x61, 0x6b, 0x69, 0x3a, + 0x31, 0x32, 0x34, 0x33, 0x33, 0x32, 0x35, 0x39, 0x2c, 0x64, 0x61, + 0x72, 0x6b, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x61, 0x3a, 0x39, + 0x31, 0x30, 0x39, 0x36, 0x34, 0x33, 0x2c, 0x64, 0x61, 0x72, 0x6b, + 0x6f, 0x6c, 0x69, 0x76, 0x65, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x3a, + 0x35, 0x35, 0x39, 0x37, 0x39, 0x39, 0x39, 0x2c, 0x64, 0x61, 0x72, + 0x6b, 0x6f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3a, 0x31, 0x36, 0x37, + 0x34, 0x37, 0x35, 0x32, 0x30, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x6f, + 0x72, 0x63, 0x68, 0x69, 0x64, 0x3a, 0x31, 0x30, 0x30, 0x34, 0x30, + 0x30, 0x31, 0x32, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x72, 0x65, 0x64, + 0x3a, 0x39, 0x31, 0x30, 0x39, 0x35, 0x30, 0x34, 0x2c, 0x64, 0x61, + 0x72, 0x6b, 0x73, 0x61, 0x6c, 0x6d, 0x6f, 0x6e, 0x3a, 0x31, 0x35, + 0x33, 0x30, 0x38, 0x34, 0x31, 0x30, 0x2c, 0x64, 0x61, 0x72, 0x6b, + 0x73, 0x65, 0x61, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x3a, 0x39, 0x34, + 0x31, 0x39, 0x39, 0x31, 0x39, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x73, + 0x6c, 0x61, 0x74, 0x65, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x34, 0x37, + 0x33, 0x34, 0x33, 0x34, 0x37, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x73, + 0x6c, 0x61, 0x74, 0x65, 0x67, 0x72, 0x61, 0x79, 0x3a, 0x33, 0x31, + 0x30, 0x30, 0x34, 0x39, 0x35, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x73, + 0x6c, 0x61, 0x74, 0x65, 0x67, 0x72, 0x65, 0x79, 0x3a, 0x33, 0x31, + 0x30, 0x30, 0x34, 0x39, 0x35, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x74, + 0x75, 0x72, 0x71, 0x75, 0x6f, 0x69, 0x73, 0x65, 0x3a, 0x35, 0x32, + 0x39, 0x34, 0x35, 0x2c, 0x64, 0x61, 0x72, 0x6b, 0x76, 0x69, 0x6f, + 0x6c, 0x65, 0x74, 0x3a, 0x39, 0x36, 0x39, 0x39, 0x35, 0x33, 0x39, + 0x2c, 0x64, 0x65, 0x65, 0x70, 0x70, 0x69, 0x6e, 0x6b, 0x3a, 0x31, + 0x36, 0x37, 0x31, 0x36, 0x39, 0x34, 0x37, 0x2c, 0x64, 0x65, 0x65, + 0x70, 0x73, 0x6b, 0x79, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x34, 0x39, + 0x31, 0x35, 0x31, 0x2c, 0x64, 0x69, 0x6d, 0x67, 0x72, 0x61, 0x79, + 0x3a, 0x36, 0x39, 0x30, 0x38, 0x32, 0x36, 0x35, 0x2c, 0x64, 0x69, + 0x6d, 0x67, 0x72, 0x65, 0x79, 0x3a, 0x36, 0x39, 0x30, 0x38, 0x32, + 0x36, 0x35, 0x2c, 0x64, 0x6f, 0x64, 0x67, 0x65, 0x72, 0x62, 0x6c, + 0x75, 0x65, 0x3a, 0x32, 0x30, 0x30, 0x33, 0x31, 0x39, 0x39, 0x2c, + 0x66, 0x69, 0x72, 0x65, 0x62, 0x72, 0x69, 0x63, 0x6b, 0x3a, 0x31, + 0x31, 0x36, 0x37, 0x34, 0x31, 0x34, 0x36, 0x2c, 0x66, 0x6c, 0x6f, + 0x72, 0x61, 0x6c, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3a, 0x31, 0x36, + 0x37, 0x37, 0x35, 0x39, 0x32, 0x30, 0x2c, 0x66, 0x6f, 0x72, 0x65, + 0x73, 0x74, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x3a, 0x32, 0x32, 0x36, + 0x33, 0x38, 0x34, 0x32, 0x2c, 0x66, 0x75, 0x63, 0x68, 0x73, 0x69, + 0x61, 0x3a, 0x31, 0x36, 0x37, 0x31, 0x31, 0x39, 0x33, 0x35, 0x2c, + 0x67, 0x61, 0x69, 0x6e, 0x73, 0x62, 0x6f, 0x72, 0x6f, 0x3a, 0x31, + 0x34, 0x34, 0x37, 0x34, 0x34, 0x36, 0x30, 0x2c, 0x67, 0x68, 0x6f, + 0x73, 0x74, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3a, 0x31, 0x36, 0x33, + 0x31, 0x36, 0x36, 0x37, 0x31, 0x2c, 0x67, 0x6f, 0x6c, 0x64, 0x3a, + 0x31, 0x36, 0x37, 0x36, 0x36, 0x37, 0x32, 0x30, 0x2c, 0x67, 0x6f, + 0x6c, 0x64, 0x65, 0x6e, 0x72, 0x6f, 0x64, 0x3a, 0x31, 0x34, 0x33, + 0x32, 0x39, 0x31, 0x32, 0x30, 0x2c, 0x67, 0x72, 0x61, 0x79, 0x3a, + 0x38, 0x34, 0x32, 0x31, 0x35, 0x30, 0x34, 0x2c, 0x67, 0x72, 0x65, + 0x65, 0x6e, 0x3a, 0x33, 0x32, 0x37, 0x36, 0x38, 0x2c, 0x67, 0x72, + 0x65, 0x65, 0x6e, 0x79, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x3a, 0x31, + 0x31, 0x34, 0x30, 0x33, 0x30, 0x35, 0x35, 0x2c, 0x67, 0x72, 0x65, + 0x79, 0x3a, 0x38, 0x34, 0x32, 0x31, 0x35, 0x30, 0x34, 0x2c, 0x68, + 0x6f, 0x6e, 0x65, 0x79, 0x64, 0x65, 0x77, 0x3a, 0x31, 0x35, 0x37, + 0x39, 0x34, 0x31, 0x36, 0x30, 0x2c, 0x68, 0x6f, 0x74, 0x70, 0x69, + 0x6e, 0x6b, 0x3a, 0x31, 0x36, 0x37, 0x33, 0x38, 0x37, 0x34, 0x30, + 0x2c, 0x69, 0x6e, 0x64, 0x69, 0x61, 0x6e, 0x72, 0x65, 0x64, 0x3a, + 0x31, 0x33, 0x34, 0x35, 0x38, 0x35, 0x32, 0x34, 0x2c, 0x69, 0x6e, + 0x64, 0x69, 0x67, 0x6f, 0x3a, 0x34, 0x39, 0x31, 0x35, 0x33, 0x33, + 0x30, 0x2c, 0x69, 0x76, 0x6f, 0x72, 0x79, 0x3a, 0x31, 0x36, 0x37, + 0x37, 0x37, 0x32, 0x30, 0x30, 0x2c, 0x6b, 0x68, 0x61, 0x6b, 0x69, + 0x3a, 0x31, 0x35, 0x37, 0x38, 0x37, 0x36, 0x36, 0x30, 0x2c, 0x6c, + 0x61, 0x76, 0x65, 0x6e, 0x64, 0x65, 0x72, 0x3a, 0x31, 0x35, 0x31, + 0x33, 0x32, 0x34, 0x31, 0x30, 0x2c, 0x6c, 0x61, 0x76, 0x65, 0x6e, + 0x64, 0x65, 0x72, 0x62, 0x6c, 0x75, 0x73, 0x68, 0x3a, 0x31, 0x36, + 0x37, 0x37, 0x33, 0x33, 0x36, 0x35, 0x2c, 0x6c, 0x61, 0x77, 0x6e, + 0x67, 0x72, 0x65, 0x65, 0x6e, 0x3a, 0x38, 0x31, 0x39, 0x30, 0x39, + 0x37, 0x36, 0x2c, 0x6c, 0x65, 0x6d, 0x6f, 0x6e, 0x63, 0x68, 0x69, + 0x66, 0x66, 0x6f, 0x6e, 0x3a, 0x31, 0x36, 0x37, 0x37, 0x35, 0x38, + 0x38, 0x35, 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x62, 0x6c, 0x75, + 0x65, 0x3a, 0x31, 0x31, 0x33, 0x39, 0x33, 0x32, 0x35, 0x34, 0x2c, + 0x6c, 0x69, 0x67, 0x68, 0x74, 0x63, 0x6f, 0x72, 0x61, 0x6c, 0x3a, + 0x31, 0x35, 0x37, 0x36, 0x31, 0x35, 0x33, 0x36, 0x2c, 0x6c, 0x69, + 0x67, 0x68, 0x74, 0x63, 0x79, 0x61, 0x6e, 0x3a, 0x31, 0x34, 0x37, + 0x34, 0x35, 0x35, 0x39, 0x39, 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x67, 0x6f, 0x6c, 0x64, 0x65, 0x6e, 0x72, 0x6f, 0x64, 0x79, 0x65, + 0x6c, 0x6c, 0x6f, 0x77, 0x3a, 0x31, 0x36, 0x34, 0x34, 0x38, 0x32, + 0x31, 0x30, 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x67, 0x72, 0x61, + 0x79, 0x3a, 0x31, 0x33, 0x38, 0x38, 0x32, 0x33, 0x32, 0x33, 0x2c, + 0x6c, 0x69, 0x67, 0x68, 0x74, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x3a, + 0x39, 0x34, 0x39, 0x38, 0x32, 0x35, 0x36, 0x2c, 0x6c, 0x69, 0x67, + 0x68, 0x74, 0x67, 0x72, 0x65, 0x79, 0x3a, 0x31, 0x33, 0x38, 0x38, + 0x32, 0x33, 0x32, 0x33, 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x70, + 0x69, 0x6e, 0x6b, 0x3a, 0x31, 0x36, 0x37, 0x35, 0x38, 0x34, 0x36, + 0x35, 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x61, 0x6c, 0x6d, + 0x6f, 0x6e, 0x3a, 0x31, 0x36, 0x37, 0x35, 0x32, 0x37, 0x36, 0x32, + 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x65, 0x61, 0x67, 0x72, + 0x65, 0x65, 0x6e, 0x3a, 0x32, 0x31, 0x34, 0x32, 0x38, 0x39, 0x30, + 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6b, 0x79, 0x62, 0x6c, + 0x75, 0x65, 0x3a, 0x38, 0x39, 0x30, 0x30, 0x33, 0x34, 0x36, 0x2c, + 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x67, + 0x72, 0x61, 0x79, 0x3a, 0x37, 0x38, 0x33, 0x33, 0x37, 0x35, 0x33, + 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x6c, 0x61, 0x74, 0x65, + 0x67, 0x72, 0x65, 0x79, 0x3a, 0x37, 0x38, 0x33, 0x33, 0x37, 0x35, + 0x33, 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x74, 0x65, 0x65, + 0x6c, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x31, 0x31, 0x35, 0x38, 0x34, + 0x37, 0x33, 0x34, 0x2c, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x79, 0x65, + 0x6c, 0x6c, 0x6f, 0x77, 0x3a, 0x31, 0x36, 0x37, 0x37, 0x37, 0x31, + 0x38, 0x34, 0x2c, 0x6c, 0x69, 0x6d, 0x65, 0x3a, 0x36, 0x35, 0x32, + 0x38, 0x30, 0x2c, 0x6c, 0x69, 0x6d, 0x65, 0x67, 0x72, 0x65, 0x65, + 0x6e, 0x3a, 0x33, 0x33, 0x32, 0x39, 0x33, 0x33, 0x30, 0x2c, 0x6c, + 0x69, 0x6e, 0x65, 0x6e, 0x3a, 0x31, 0x36, 0x34, 0x34, 0x35, 0x36, + 0x37, 0x30, 0x2c, 0x6d, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x61, 0x3a, + 0x31, 0x36, 0x37, 0x31, 0x31, 0x39, 0x33, 0x35, 0x2c, 0x6d, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x3a, 0x38, 0x33, 0x38, 0x38, 0x36, 0x30, + 0x38, 0x2c, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x61, 0x71, 0x75, + 0x61, 0x6d, 0x61, 0x72, 0x69, 0x6e, 0x65, 0x3a, 0x36, 0x37, 0x33, + 0x37, 0x33, 0x32, 0x32, 0x2c, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, + 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x32, 0x30, 0x35, 0x2c, 0x6d, 0x65, + 0x64, 0x69, 0x75, 0x6d, 0x6f, 0x72, 0x63, 0x68, 0x69, 0x64, 0x3a, + 0x31, 0x32, 0x32, 0x31, 0x31, 0x36, 0x36, 0x37, 0x2c, 0x6d, 0x65, + 0x64, 0x69, 0x75, 0x6d, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x3a, + 0x39, 0x36, 0x36, 0x32, 0x36, 0x38, 0x33, 0x2c, 0x6d, 0x65, 0x64, + 0x69, 0x75, 0x6d, 0x73, 0x65, 0x61, 0x67, 0x72, 0x65, 0x65, 0x6e, + 0x3a, 0x33, 0x39, 0x37, 0x38, 0x30, 0x39, 0x37, 0x2c, 0x6d, 0x65, + 0x64, 0x69, 0x75, 0x6d, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x62, 0x6c, + 0x75, 0x65, 0x3a, 0x38, 0x30, 0x38, 0x37, 0x37, 0x39, 0x30, 0x2c, + 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x73, 0x70, 0x72, 0x69, 0x6e, + 0x67, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x3a, 0x36, 0x34, 0x31, 0x35, + 0x34, 0x2c, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x74, 0x75, 0x72, + 0x71, 0x75, 0x6f, 0x69, 0x73, 0x65, 0x3a, 0x34, 0x37, 0x37, 0x32, + 0x33, 0x30, 0x30, 0x2c, 0x6d, 0x65, 0x64, 0x69, 0x75, 0x6d, 0x76, + 0x69, 0x6f, 0x6c, 0x65, 0x74, 0x72, 0x65, 0x64, 0x3a, 0x31, 0x33, + 0x30, 0x34, 0x37, 0x31, 0x37, 0x33, 0x2c, 0x6d, 0x69, 0x64, 0x6e, + 0x69, 0x67, 0x68, 0x74, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x31, 0x36, + 0x34, 0x34, 0x39, 0x31, 0x32, 0x2c, 0x6d, 0x69, 0x6e, 0x74, 0x63, + 0x72, 0x65, 0x61, 0x6d, 0x3a, 0x31, 0x36, 0x31, 0x32, 0x31, 0x38, + 0x35, 0x30, 0x2c, 0x6d, 0x69, 0x73, 0x74, 0x79, 0x72, 0x6f, 0x73, + 0x65, 0x3a, 0x31, 0x36, 0x37, 0x37, 0x30, 0x32, 0x37, 0x33, 0x2c, + 0x6d, 0x6f, 0x63, 0x63, 0x61, 0x73, 0x69, 0x6e, 0x3a, 0x31, 0x36, + 0x37, 0x37, 0x30, 0x32, 0x32, 0x39, 0x2c, 0x6e, 0x61, 0x76, 0x61, + 0x6a, 0x6f, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3a, 0x31, 0x36, 0x37, + 0x36, 0x38, 0x36, 0x38, 0x35, 0x2c, 0x6e, 0x61, 0x76, 0x79, 0x3a, + 0x31, 0x32, 0x38, 0x2c, 0x6f, 0x6c, 0x64, 0x6c, 0x61, 0x63, 0x65, + 0x3a, 0x31, 0x36, 0x36, 0x34, 0x33, 0x35, 0x35, 0x38, 0x2c, 0x6f, + 0x6c, 0x69, 0x76, 0x65, 0x3a, 0x38, 0x34, 0x32, 0x31, 0x33, 0x37, + 0x36, 0x2c, 0x6f, 0x6c, 0x69, 0x76, 0x65, 0x64, 0x72, 0x61, 0x62, + 0x3a, 0x37, 0x30, 0x34, 0x38, 0x37, 0x33, 0x39, 0x2c, 0x6f, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x3a, 0x31, 0x36, 0x37, 0x35, 0x33, 0x39, + 0x32, 0x30, 0x2c, 0x6f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x72, 0x65, + 0x64, 0x3a, 0x31, 0x36, 0x37, 0x32, 0x39, 0x33, 0x34, 0x34, 0x2c, + 0x6f, 0x72, 0x63, 0x68, 0x69, 0x64, 0x3a, 0x31, 0x34, 0x33, 0x31, + 0x35, 0x37, 0x33, 0x34, 0x2c, 0x70, 0x61, 0x6c, 0x65, 0x67, 0x6f, + 0x6c, 0x64, 0x65, 0x6e, 0x72, 0x6f, 0x64, 0x3a, 0x31, 0x35, 0x36, + 0x35, 0x37, 0x31, 0x33, 0x30, 0x2c, 0x70, 0x61, 0x6c, 0x65, 0x67, + 0x72, 0x65, 0x65, 0x6e, 0x3a, 0x31, 0x30, 0x30, 0x32, 0x35, 0x38, + 0x38, 0x30, 0x2c, 0x70, 0x61, 0x6c, 0x65, 0x74, 0x75, 0x72, 0x71, + 0x75, 0x6f, 0x69, 0x73, 0x65, 0x3a, 0x31, 0x31, 0x35, 0x32, 0x39, + 0x39, 0x36, 0x36, 0x2c, 0x70, 0x61, 0x6c, 0x65, 0x76, 0x69, 0x6f, + 0x6c, 0x65, 0x74, 0x72, 0x65, 0x64, 0x3a, 0x31, 0x34, 0x33, 0x38, + 0x31, 0x32, 0x30, 0x33, 0x2c, 0x70, 0x61, 0x70, 0x61, 0x79, 0x61, + 0x77, 0x68, 0x69, 0x70, 0x3a, 0x31, 0x36, 0x37, 0x37, 0x33, 0x30, + 0x37, 0x37, 0x2c, 0x70, 0x65, 0x61, 0x63, 0x68, 0x70, 0x75, 0x66, + 0x66, 0x3a, 0x31, 0x36, 0x37, 0x36, 0x37, 0x36, 0x37, 0x33, 0x2c, + 0x70, 0x65, 0x72, 0x75, 0x3a, 0x31, 0x33, 0x34, 0x36, 0x38, 0x39, + 0x39, 0x31, 0x2c, 0x70, 0x69, 0x6e, 0x6b, 0x3a, 0x31, 0x36, 0x37, + 0x36, 0x31, 0x30, 0x33, 0x35, 0x2c, 0x70, 0x6c, 0x75, 0x6d, 0x3a, + 0x31, 0x34, 0x35, 0x32, 0x34, 0x36, 0x33, 0x37, 0x2c, 0x70, 0x6f, + 0x77, 0x64, 0x65, 0x72, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x31, 0x31, + 0x35, 0x39, 0x31, 0x39, 0x31, 0x30, 0x2c, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x3a, 0x38, 0x33, 0x38, 0x38, 0x37, 0x33, 0x36, 0x2c, + 0x72, 0x65, 0x62, 0x65, 0x63, 0x63, 0x61, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x3a, 0x36, 0x36, 0x39, 0x37, 0x38, 0x38, 0x31, 0x2c, + 0x72, 0x65, 0x64, 0x3a, 0x31, 0x36, 0x37, 0x31, 0x31, 0x36, 0x38, + 0x30, 0x2c, 0x72, 0x6f, 0x73, 0x79, 0x62, 0x72, 0x6f, 0x77, 0x6e, + 0x3a, 0x31, 0x32, 0x33, 0x35, 0x37, 0x35, 0x31, 0x39, 0x2c, 0x72, + 0x6f, 0x79, 0x61, 0x6c, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x34, 0x32, + 0x38, 0x36, 0x39, 0x34, 0x35, 0x2c, 0x73, 0x61, 0x64, 0x64, 0x6c, + 0x65, 0x62, 0x72, 0x6f, 0x77, 0x6e, 0x3a, 0x39, 0x31, 0x32, 0x37, + 0x31, 0x38, 0x37, 0x2c, 0x73, 0x61, 0x6c, 0x6d, 0x6f, 0x6e, 0x3a, + 0x31, 0x36, 0x34, 0x31, 0x36, 0x38, 0x38, 0x32, 0x2c, 0x73, 0x61, + 0x6e, 0x64, 0x79, 0x62, 0x72, 0x6f, 0x77, 0x6e, 0x3a, 0x31, 0x36, + 0x30, 0x33, 0x32, 0x38, 0x36, 0x34, 0x2c, 0x73, 0x65, 0x61, 0x67, + 0x72, 0x65, 0x65, 0x6e, 0x3a, 0x33, 0x30, 0x35, 0x30, 0x33, 0x32, + 0x37, 0x2c, 0x73, 0x65, 0x61, 0x73, 0x68, 0x65, 0x6c, 0x6c, 0x3a, + 0x31, 0x36, 0x37, 0x37, 0x34, 0x36, 0x33, 0x38, 0x2c, 0x73, 0x69, + 0x65, 0x6e, 0x6e, 0x61, 0x3a, 0x31, 0x30, 0x35, 0x30, 0x36, 0x37, + 0x39, 0x37, 0x2c, 0x73, 0x69, 0x6c, 0x76, 0x65, 0x72, 0x3a, 0x31, + 0x32, 0x36, 0x33, 0x32, 0x32, 0x35, 0x36, 0x2c, 0x73, 0x6b, 0x79, + 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x38, 0x39, 0x30, 0x30, 0x33, 0x33, + 0x31, 0x2c, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x62, 0x6c, 0x75, 0x65, + 0x3a, 0x36, 0x39, 0x37, 0x30, 0x30, 0x36, 0x31, 0x2c, 0x73, 0x6c, + 0x61, 0x74, 0x65, 0x67, 0x72, 0x61, 0x79, 0x3a, 0x37, 0x33, 0x37, + 0x32, 0x39, 0x34, 0x34, 0x2c, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x67, + 0x72, 0x65, 0x79, 0x3a, 0x37, 0x33, 0x37, 0x32, 0x39, 0x34, 0x34, + 0x2c, 0x73, 0x6e, 0x6f, 0x77, 0x3a, 0x31, 0x36, 0x37, 0x37, 0x35, + 0x39, 0x33, 0x30, 0x2c, 0x73, 0x70, 0x72, 0x69, 0x6e, 0x67, 0x67, + 0x72, 0x65, 0x65, 0x6e, 0x3a, 0x36, 0x35, 0x34, 0x30, 0x37, 0x2c, + 0x73, 0x74, 0x65, 0x65, 0x6c, 0x62, 0x6c, 0x75, 0x65, 0x3a, 0x34, + 0x36, 0x32, 0x30, 0x39, 0x38, 0x30, 0x2c, 0x74, 0x61, 0x6e, 0x3a, + 0x31, 0x33, 0x38, 0x30, 0x38, 0x37, 0x38, 0x30, 0x2c, 0x74, 0x65, + 0x61, 0x6c, 0x3a, 0x33, 0x32, 0x38, 0x39, 0x36, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x74, 0x6c, 0x65, 0x3a, 0x31, 0x34, 0x32, 0x30, 0x34, + 0x38, 0x38, 0x38, 0x2c, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x6f, 0x3a, + 0x31, 0x36, 0x37, 0x33, 0x37, 0x30, 0x39, 0x35, 0x2c, 0x74, 0x75, + 0x72, 0x71, 0x75, 0x6f, 0x69, 0x73, 0x65, 0x3a, 0x34, 0x32, 0x35, + 0x31, 0x38, 0x35, 0x36, 0x2c, 0x76, 0x69, 0x6f, 0x6c, 0x65, 0x74, + 0x3a, 0x31, 0x35, 0x36, 0x33, 0x31, 0x30, 0x38, 0x36, 0x2c, 0x77, + 0x68, 0x65, 0x61, 0x74, 0x3a, 0x31, 0x36, 0x31, 0x31, 0x33, 0x33, + 0x33, 0x31, 0x2c, 0x77, 0x68, 0x69, 0x74, 0x65, 0x3a, 0x31, 0x36, + 0x37, 0x37, 0x37, 0x32, 0x31, 0x35, 0x2c, 0x77, 0x68, 0x69, 0x74, + 0x65, 0x73, 0x6d, 0x6f, 0x6b, 0x65, 0x3a, 0x31, 0x36, 0x31, 0x31, + 0x39, 0x32, 0x38, 0x35, 0x2c, 0x79, 0x65, 0x6c, 0x6c, 0x6f, 0x77, + 0x3a, 0x31, 0x36, 0x37, 0x37, 0x36, 0x39, 0x36, 0x30, 0x2c, 0x79, + 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x67, 0x72, 0x65, 0x65, 0x6e, 0x3a, + 0x31, 0x30, 0x31, 0x34, 0x35, 0x30, 0x37, 0x34, 0x7d, 0x29, 0x3b, + 0x47, 0x61, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x47, 0x61, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x6e, + 0x2c, 0x79, 0x74, 0x28, 0x74, 0x29, 0x29, 0x7d, 0x29, 0x2c, 0x74, + 0x61, 0x2e, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x6f, 0x72, 0x3d, 0x45, + 0x74, 0x2c, 0x74, 0x61, 0x2e, 0x78, 0x68, 0x72, 0x3d, 0x41, 0x74, + 0x28, 0x79, 0x29, 0x2c, 0x74, 0x61, 0x2e, 0x64, 0x73, 0x76, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x69, 0x29, 0x7b, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x33, 0x26, 0x26, 0x28, 0x69, 0x3d, + 0x65, 0x2c, 0x65, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x4e, 0x74, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x65, 0x3f, 0x72, 0x3a, + 0x75, 0x28, 0x65, 0x29, 0x2c, 0x69, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x2e, 0x72, 0x6f, 0x77, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x6f, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x28, 0x65, 0x3d, + 0x6e, 0x29, 0x3f, 0x72, 0x3a, 0x75, 0x28, 0x6e, 0x29, 0x29, 0x3a, + 0x65, 0x7d, 0x2c, 0x6f, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, + 0x28, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x54, 0x65, 0x78, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x74, + 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x65, + 0x78, 0x74, 0x2c, 0x6e, 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x6f, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x6e, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x6e, 0x29, 0x3f, 0x27, + 0x22, 0x27, 0x2b, 0x6e, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x28, 0x2f, 0x5c, 0x22, 0x2f, 0x67, 0x2c, 0x27, 0x22, 0x22, + 0x27, 0x29, 0x2b, 0x27, 0x22, 0x27, 0x3a, 0x6e, 0x7d, 0x76, 0x61, + 0x72, 0x20, 0x61, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x52, 0x65, 0x67, + 0x45, 0x78, 0x70, 0x28, 0x27, 0x5b, 0x22, 0x27, 0x2b, 0x6e, 0x2b, + 0x22, 0x5c, 0x6e, 0x5d, 0x22, 0x29, 0x2c, 0x63, 0x3d, 0x6e, 0x2e, + 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28, + 0x30, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, + 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x52, 0x6f, 0x77, + 0x73, 0x28, 0x6e, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x72, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x28, 0x6e, + 0x2c, 0x65, 0x2d, 0x31, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x75, + 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x22, 0x64, 0x22, 0x2c, 0x22, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x7b, 0x22, 0x2b, 0x6e, 0x2e, 0x6d, 0x61, + 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x69, 0x66, 0x79, 0x28, 0x6e, 0x29, 0x2b, 0x22, 0x3a, 0x20, + 0x64, 0x5b, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x5d, 0x22, 0x7d, 0x29, + 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x2b, + 0x22, 0x7d, 0x22, 0x29, 0x3b, 0x72, 0x3d, 0x74, 0x3f, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x28, 0x75, + 0x28, 0x6e, 0x29, 0x2c, 0x65, 0x29, 0x7d, 0x3a, 0x75, 0x7d, 0x29, + 0x7d, 0x2c, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x52, 0x6f, + 0x77, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28, + 0x73, 0x3e, 0x3d, 0x6c, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6f, 0x3b, 0x69, 0x66, 0x28, 0x75, 0x29, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x75, 0x3d, 0x21, 0x31, 0x2c, 0x69, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x73, 0x3b, 0x69, 0x66, 0x28, + 0x33, 0x34, 0x3d, 0x3d, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, + 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28, 0x74, 0x29, 0x29, 0x7b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, + 0x3b, 0x65, 0x2b, 0x2b, 0x3c, 0x6c, 0x3b, 0x29, 0x69, 0x66, 0x28, + 0x33, 0x34, 0x3d, 0x3d, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, + 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28, 0x65, 0x29, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x33, 0x34, 0x21, 0x3d, 0x3d, 0x6e, 0x2e, 0x63, + 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28, 0x65, + 0x2b, 0x31, 0x29, 0x29, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x2b, + 0x2b, 0x65, 0x7d, 0x73, 0x3d, 0x65, 0x2b, 0x32, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x43, + 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28, 0x65, 0x2b, 0x31, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x33, 0x3d, 0x3d, + 0x3d, 0x72, 0x3f, 0x28, 0x75, 0x3d, 0x21, 0x30, 0x2c, 0x31, 0x30, + 0x3d, 0x3d, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, + 0x64, 0x65, 0x41, 0x74, 0x28, 0x65, 0x2b, 0x32, 0x29, 0x26, 0x26, + 0x2b, 0x2b, 0x73, 0x29, 0x3a, 0x31, 0x30, 0x3d, 0x3d, 0x3d, 0x72, + 0x26, 0x26, 0x28, 0x75, 0x3d, 0x21, 0x30, 0x29, 0x2c, 0x6e, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x74, 0x2b, 0x31, 0x2c, 0x65, + 0x29, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, + 0x22, 0x22, 0x2f, 0x67, 0x2c, 0x27, 0x22, 0x27, 0x29, 0x7d, 0x66, + 0x6f, 0x72, 0x28, 0x3b, 0x6c, 0x3e, 0x73, 0x3b, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, + 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x28, 0x73, 0x2b, 0x2b, 0x29, + 0x2c, 0x61, 0x3d, 0x31, 0x3b, 0x69, 0x66, 0x28, 0x31, 0x30, 0x3d, + 0x3d, 0x3d, 0x72, 0x29, 0x75, 0x3d, 0x21, 0x30, 0x3b, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x31, 0x33, 0x3d, 0x3d, 0x3d, + 0x72, 0x29, 0x75, 0x3d, 0x21, 0x30, 0x2c, 0x31, 0x30, 0x3d, 0x3d, + 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x43, 0x6f, 0x64, 0x65, + 0x41, 0x74, 0x28, 0x73, 0x29, 0x26, 0x26, 0x28, 0x2b, 0x2b, 0x73, + 0x2c, 0x2b, 0x2b, 0x61, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x69, 0x66, 0x28, 0x72, 0x21, 0x3d, 0x3d, 0x63, 0x29, 0x63, 0x6f, + 0x6e, 0x74, 0x69, 0x6e, 0x75, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, + 0x74, 0x2c, 0x73, 0x2d, 0x61, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, + 0x74, 0x29, 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x3d, 0x7b, 0x7d, 0x2c, 0x6f, 0x3d, + 0x7b, 0x7d, 0x2c, 0x61, 0x3d, 0x5b, 0x5d, 0x2c, 0x6c, 0x3d, 0x6e, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x73, 0x3d, 0x30, + 0x2c, 0x66, 0x3d, 0x30, 0x3b, 0x28, 0x72, 0x3d, 0x65, 0x28, 0x29, + 0x29, 0x21, 0x3d, 0x3d, 0x6f, 0x3b, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x68, 0x3d, 0x5b, 0x5d, 0x3b, 0x72, + 0x21, 0x3d, 0x3d, 0x69, 0x26, 0x26, 0x72, 0x21, 0x3d, 0x3d, 0x6f, + 0x3b, 0x29, 0x68, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x29, + 0x2c, 0x72, 0x3d, 0x65, 0x28, 0x29, 0x3b, 0x74, 0x26, 0x26, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x28, 0x68, 0x3d, 0x74, 0x28, 0x68, + 0x2c, 0x66, 0x2b, 0x2b, 0x29, 0x29, 0x7c, 0x7c, 0x61, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x68, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x7d, 0x2c, 0x65, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x41, 0x72, 0x72, + 0x61, 0x79, 0x2e, 0x69, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, + 0x74, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x65, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, + 0x6f, 0x77, 0x73, 0x28, 0x74, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x6d, 0x2c, 0x75, 0x3d, 0x5b, + 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, + 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x20, 0x69, 0x6e, 0x20, + 0x6e, 0x29, 0x72, 0x2e, 0x68, 0x61, 0x73, 0x28, 0x74, 0x29, 0x7c, + 0x7c, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x2e, 0x61, + 0x64, 0x64, 0x28, 0x74, 0x29, 0x29, 0x7d, 0x29, 0x2c, 0x5b, 0x75, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x6f, 0x29, 0x2e, 0x6a, 0x6f, 0x69, + 0x6e, 0x28, 0x6e, 0x29, 0x5d, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, + 0x74, 0x28, 0x74, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x2e, 0x6d, 0x61, 0x70, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x28, 0x74, + 0x5b, 0x6e, 0x5d, 0x29, 0x7d, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, + 0x28, 0x6e, 0x29, 0x7d, 0x29, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, + 0x28, 0x22, 0x5c, 0x6e, 0x22, 0x29, 0x7d, 0x2c, 0x65, 0x2e, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x6f, 0x77, 0x73, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6d, 0x61, + 0x70, 0x28, 0x69, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, + 0x5c, 0x6e, 0x22, 0x29, 0x7d, 0x2c, 0x65, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x63, 0x73, 0x76, 0x3d, 0x74, 0x61, 0x2e, 0x64, 0x73, 0x76, + 0x28, 0x22, 0x2c, 0x22, 0x2c, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x63, 0x73, 0x76, 0x22, 0x29, 0x2c, 0x74, 0x61, 0x2e, 0x74, 0x73, + 0x76, 0x3d, 0x74, 0x61, 0x2e, 0x64, 0x73, 0x76, 0x28, 0x22, 0x09, + 0x22, 0x2c, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x61, 0x62, + 0x2d, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2d, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x4b, 0x61, 0x2c, 0x51, 0x61, 0x2c, 0x6e, 0x63, 0x2c, + 0x74, 0x63, 0x2c, 0x65, 0x63, 0x2c, 0x72, 0x63, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x78, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x22, + 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x6e, 0x69, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x22, + 0x29, 0x5d, 0x7c, 0x7c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x6f, 0x75, 0x74, 0x28, 0x6e, 0x2c, 0x31, 0x37, 0x29, 0x7d, + 0x3b, 0x74, 0x61, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x32, 0x3e, 0x72, 0x26, 0x26, 0x28, + 0x74, 0x3d, 0x30, 0x29, 0x2c, 0x33, 0x3e, 0x72, 0x26, 0x26, 0x28, + 0x65, 0x3d, 0x44, 0x61, 0x74, 0x65, 0x2e, 0x6e, 0x6f, 0x77, 0x28, + 0x29, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x65, 0x2b, + 0x74, 0x2c, 0x69, 0x3d, 0x7b, 0x63, 0x3a, 0x6e, 0x2c, 0x74, 0x3a, + 0x75, 0x2c, 0x66, 0x3a, 0x21, 0x31, 0x2c, 0x6e, 0x3a, 0x6e, 0x75, + 0x6c, 0x6c, 0x7d, 0x3b, 0x51, 0x61, 0x3f, 0x51, 0x61, 0x2e, 0x6e, + 0x3d, 0x69, 0x3a, 0x4b, 0x61, 0x3d, 0x69, 0x2c, 0x51, 0x61, 0x3d, + 0x69, 0x2c, 0x6e, 0x63, 0x7c, 0x7c, 0x28, 0x74, 0x63, 0x3d, 0x63, + 0x6c, 0x65, 0x61, 0x72, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x28, 0x74, 0x63, 0x29, 0x2c, 0x6e, 0x63, 0x3d, 0x31, 0x2c, 0x72, + 0x63, 0x28, 0x71, 0x74, 0x29, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x74, 0x69, 0x6d, 0x65, 0x72, 0x2e, 0x66, 0x6c, 0x75, 0x73, 0x68, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x4c, 0x74, 0x28, 0x29, 0x2c, 0x54, 0x74, 0x28, 0x29, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x3f, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, + 0x6e, 0x2a, 0x28, 0x74, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x70, + 0x6f, 0x77, 0x28, 0x31, 0x30, 0x2c, 0x74, 0x29, 0x29, 0x29, 0x2f, + 0x74, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x28, 0x6e, 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x75, + 0x63, 0x3d, 0x5b, 0x22, 0x79, 0x22, 0x2c, 0x22, 0x7a, 0x22, 0x2c, + 0x22, 0x61, 0x22, 0x2c, 0x22, 0x66, 0x22, 0x2c, 0x22, 0x70, 0x22, + 0x2c, 0x22, 0x6e, 0x22, 0x2c, 0x22, 0x5c, 0x78, 0x62, 0x35, 0x22, + 0x2c, 0x22, 0x6d, 0x22, 0x2c, 0x22, 0x22, 0x2c, 0x22, 0x6b, 0x22, + 0x2c, 0x22, 0x4d, 0x22, 0x2c, 0x22, 0x47, 0x22, 0x2c, 0x22, 0x54, + 0x22, 0x2c, 0x22, 0x50, 0x22, 0x2c, 0x22, 0x45, 0x22, 0x2c, 0x22, + 0x5a, 0x22, 0x2c, 0x22, 0x59, 0x22, 0x5d, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x44, 0x74, 0x29, 0x3b, 0x74, 0x61, 0x2e, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x30, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x26, 0x26, 0x28, 0x30, + 0x3e, 0x6e, 0x26, 0x26, 0x28, 0x6e, 0x2a, 0x3d, 0x2d, 0x31, 0x29, + 0x2c, 0x74, 0x26, 0x26, 0x28, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x6e, 0x2c, 0x52, 0x74, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x29, 0x29, 0x2c, 0x65, 0x3d, 0x31, 0x2b, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x31, + 0x65, 0x2d, 0x31, 0x32, 0x2b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6c, + 0x6f, 0x67, 0x28, 0x6e, 0x29, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x4c, 0x4e, 0x31, 0x30, 0x29, 0x2c, 0x65, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x2d, 0x32, 0x34, 0x2c, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x32, 0x34, 0x2c, + 0x33, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, + 0x72, 0x28, 0x28, 0x65, 0x2d, 0x31, 0x29, 0x2f, 0x33, 0x29, 0x29, + 0x29, 0x29, 0x2c, 0x75, 0x63, 0x5b, 0x38, 0x2b, 0x65, 0x2f, 0x33, + 0x5d, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x63, 0x3d, 0x2f, + 0x28, 0x3f, 0x3a, 0x28, 0x5b, 0x5e, 0x7b, 0x5d, 0x29, 0x3f, 0x28, + 0x5b, 0x3c, 0x3e, 0x3d, 0x5e, 0x5d, 0x29, 0x29, 0x3f, 0x28, 0x5b, + 0x2b, 0x5c, 0x2d, 0x20, 0x5d, 0x29, 0x3f, 0x28, 0x5b, 0x24, 0x23, + 0x5d, 0x29, 0x3f, 0x28, 0x30, 0x29, 0x3f, 0x28, 0x5c, 0x64, 0x2b, + 0x29, 0x3f, 0x28, 0x2c, 0x29, 0x3f, 0x28, 0x5c, 0x2e, 0x2d, 0x3f, + 0x5c, 0x64, 0x2b, 0x29, 0x3f, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x25, + 0x5d, 0x29, 0x3f, 0x2f, 0x69, 0x2c, 0x6f, 0x63, 0x3d, 0x74, 0x61, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x7b, 0x62, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x74, 0x6f, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x28, 0x32, 0x29, 0x7d, 0x2c, 0x63, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, + 0x72, 0x43, 0x6f, 0x64, 0x65, 0x28, 0x6e, 0x29, 0x7d, 0x2c, 0x6f, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, + 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x38, 0x29, + 0x7d, 0x2c, 0x78, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x28, 0x31, 0x36, 0x29, 0x7d, 0x2c, 0x58, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x74, 0x6f, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x36, 0x29, 0x2e, 0x74, 0x6f, + 0x55, 0x70, 0x70, 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, + 0x7d, 0x2c, 0x67, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x74, 0x6f, 0x50, 0x72, 0x65, 0x63, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7d, 0x2c, 0x65, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x2e, 0x74, 0x6f, 0x45, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, + 0x74, 0x69, 0x61, 0x6c, 0x28, 0x74, 0x29, 0x7d, 0x2c, 0x66, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x74, 0x6f, 0x46, 0x69, 0x78, 0x65, 0x64, 0x28, 0x74, 0x29, + 0x7d, 0x2c, 0x72, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x28, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x28, 0x6e, 0x2c, 0x52, 0x74, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x29, 0x29, 0x2e, 0x74, 0x6f, 0x46, 0x69, 0x78, 0x65, 0x64, + 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x30, + 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x32, + 0x30, 0x2c, 0x52, 0x74, 0x28, 0x6e, 0x2a, 0x28, 0x31, 0x2b, 0x31, + 0x65, 0x2d, 0x31, 0x35, 0x29, 0x2c, 0x74, 0x29, 0x29, 0x29, 0x29, + 0x7d, 0x7d, 0x29, 0x2c, 0x61, 0x63, 0x3d, 0x74, 0x61, 0x2e, 0x74, + 0x69, 0x6d, 0x65, 0x3d, 0x7b, 0x7d, 0x2c, 0x63, 0x63, 0x3d, 0x44, + 0x61, 0x74, 0x65, 0x3b, 0x6a, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x7b, 0x67, 0x65, 0x74, 0x44, + 0x61, 0x74, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x2e, 0x67, 0x65, 0x74, 0x55, + 0x54, 0x43, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x7d, 0x2c, 0x67, + 0x65, 0x74, 0x44, 0x61, 0x79, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x2e, 0x67, 0x65, + 0x74, 0x55, 0x54, 0x43, 0x44, 0x61, 0x79, 0x28, 0x29, 0x7d, 0x2c, + 0x67, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, 0x65, 0x61, 0x72, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x5f, 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x46, + 0x75, 0x6c, 0x6c, 0x59, 0x65, 0x61, 0x72, 0x28, 0x29, 0x7d, 0x2c, + 0x67, 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x48, 0x6f, 0x75, 0x72, + 0x73, 0x28, 0x29, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x4d, 0x69, 0x6c, + 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x5f, 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x4d, 0x69, 0x6c, + 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x28, 0x29, + 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x75, 0x74, 0x65, + 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x5f, 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, + 0x4d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x28, 0x29, 0x7d, 0x2c, + 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x4d, 0x6f, 0x6e, 0x74, + 0x68, 0x28, 0x29, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x53, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x2e, 0x67, 0x65, 0x74, + 0x55, 0x54, 0x43, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x28, + 0x29, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x5f, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, + 0x29, 0x7d, 0x2c, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x7a, + 0x6f, 0x6e, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x7d, 0x2c, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x4f, 0x66, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x2e, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x4f, 0x66, 0x28, 0x29, 0x7d, 0x2c, 0x73, 0x65, + 0x74, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6c, 0x63, 0x2e, 0x73, 0x65, + 0x74, 0x55, 0x54, 0x43, 0x44, 0x61, 0x74, 0x65, 0x2e, 0x61, 0x70, + 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x2c, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x7d, + 0x2c, 0x73, 0x65, 0x74, 0x44, 0x61, 0x79, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6c, 0x63, 0x2e, + 0x73, 0x65, 0x74, 0x55, 0x54, 0x43, 0x44, 0x61, 0x79, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, + 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, 0x65, + 0x61, 0x72, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x6c, 0x63, 0x2e, 0x73, 0x65, 0x74, 0x55, 0x54, + 0x43, 0x46, 0x75, 0x6c, 0x6c, 0x59, 0x65, 0x61, 0x72, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, + 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x6c, 0x63, 0x2e, 0x73, 0x65, 0x74, 0x55, 0x54, 0x43, 0x48, 0x6f, + 0x75, 0x72, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x4d, + 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x6c, 0x63, 0x2e, 0x73, 0x65, 0x74, 0x55, 0x54, 0x43, 0x4d, + 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x5f, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x29, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x4d, 0x69, 0x6e, 0x75, + 0x74, 0x65, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x6c, 0x63, 0x2e, 0x73, 0x65, 0x74, 0x55, + 0x54, 0x43, 0x4d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, + 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x6c, 0x63, 0x2e, 0x73, 0x65, 0x74, 0x55, 0x54, 0x43, 0x4d, 0x6f, + 0x6e, 0x74, 0x68, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x53, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6c, 0x63, 0x2e, 0x73, + 0x65, 0x74, 0x55, 0x54, 0x43, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x73, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x5f, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x29, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x6c, 0x63, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x5f, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x29, 0x7d, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6c, + 0x63, 0x3d, 0x44, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3b, 0x61, 0x63, 0x2e, 0x79, 0x65, + 0x61, 0x72, 0x3d, 0x46, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x61, 0x63, 0x2e, 0x64, 0x61, 0x79, + 0x28, 0x6e, 0x29, 0x2c, 0x6e, 0x2e, 0x73, 0x65, 0x74, 0x4d, 0x6f, + 0x6e, 0x74, 0x68, 0x28, 0x30, 0x2c, 0x31, 0x29, 0x2c, 0x6e, 0x7d, + 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x2e, 0x73, 0x65, 0x74, 0x46, 0x75, + 0x6c, 0x6c, 0x59, 0x65, 0x61, 0x72, 0x28, 0x6e, 0x2e, 0x67, 0x65, + 0x74, 0x46, 0x75, 0x6c, 0x6c, 0x59, 0x65, 0x61, 0x72, 0x28, 0x29, + 0x2b, 0x74, 0x29, 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, + 0x59, 0x65, 0x61, 0x72, 0x28, 0x29, 0x7d, 0x29, 0x2c, 0x61, 0x63, + 0x2e, 0x79, 0x65, 0x61, 0x72, 0x73, 0x3d, 0x61, 0x63, 0x2e, 0x79, + 0x65, 0x61, 0x72, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, + 0x63, 0x2e, 0x79, 0x65, 0x61, 0x72, 0x73, 0x2e, 0x75, 0x74, 0x63, + 0x3d, 0x61, 0x63, 0x2e, 0x79, 0x65, 0x61, 0x72, 0x2e, 0x75, 0x74, + 0x63, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, 0x63, 0x2e, + 0x64, 0x61, 0x79, 0x3d, 0x46, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x63, 0x63, 0x28, 0x32, + 0x65, 0x33, 0x2c, 0x30, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x46, 0x75, 0x6c, 0x6c, + 0x59, 0x65, 0x61, 0x72, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x46, + 0x75, 0x6c, 0x6c, 0x59, 0x65, 0x61, 0x72, 0x28, 0x29, 0x2c, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x28, 0x29, + 0x2c, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, + 0x29, 0x29, 0x2c, 0x74, 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x2e, + 0x73, 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x6e, 0x2e, 0x67, + 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x2b, 0x74, 0x29, + 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x2d, + 0x31, 0x7d, 0x29, 0x2c, 0x61, 0x63, 0x2e, 0x64, 0x61, 0x79, 0x73, + 0x3d, 0x61, 0x63, 0x2e, 0x64, 0x61, 0x79, 0x2e, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x2c, 0x61, 0x63, 0x2e, 0x64, 0x61, 0x79, 0x73, 0x2e, + 0x75, 0x74, 0x63, 0x3d, 0x61, 0x63, 0x2e, 0x64, 0x61, 0x79, 0x2e, + 0x75, 0x74, 0x63, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, + 0x63, 0x2e, 0x64, 0x61, 0x79, 0x4f, 0x66, 0x59, 0x65, 0x61, 0x72, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x61, 0x63, 0x2e, + 0x79, 0x65, 0x61, 0x72, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, + 0x6f, 0x6f, 0x72, 0x28, 0x28, 0x6e, 0x2d, 0x74, 0x2d, 0x36, 0x65, + 0x34, 0x2a, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x28, 0x29, 0x2d, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x28, 0x29, 0x29, 0x29, 0x2f, 0x38, 0x36, 0x34, 0x65, 0x35, 0x29, + 0x7d, 0x2c, 0x5b, 0x22, 0x73, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x22, + 0x2c, 0x22, 0x6d, 0x6f, 0x6e, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, + 0x74, 0x75, 0x65, 0x73, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, 0x77, + 0x65, 0x64, 0x6e, 0x65, 0x73, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, + 0x74, 0x68, 0x75, 0x72, 0x73, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, + 0x66, 0x72, 0x69, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, 0x73, 0x61, + 0x74, 0x75, 0x72, 0x64, 0x61, 0x79, 0x22, 0x5d, 0x2e, 0x66, 0x6f, + 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x74, 0x3d, + 0x37, 0x2d, 0x74, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x61, + 0x63, 0x5b, 0x6e, 0x5d, 0x3d, 0x46, 0x74, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x28, 0x6e, 0x3d, 0x61, 0x63, 0x2e, 0x64, + 0x61, 0x79, 0x28, 0x6e, 0x29, 0x29, 0x2e, 0x73, 0x65, 0x74, 0x44, + 0x61, 0x74, 0x65, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x44, 0x61, + 0x74, 0x65, 0x28, 0x29, 0x2d, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, + 0x44, 0x61, 0x79, 0x28, 0x29, 0x2b, 0x74, 0x29, 0x25, 0x37, 0x29, + 0x2c, 0x6e, 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x2e, 0x73, 0x65, + 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, + 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x2b, 0x37, 0x2a, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x74, 0x29, + 0x29, 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x61, + 0x63, 0x2e, 0x79, 0x65, 0x61, 0x72, 0x28, 0x6e, 0x29, 0x2e, 0x67, + 0x65, 0x74, 0x44, 0x61, 0x79, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, + 0x6f, 0x6f, 0x72, 0x28, 0x28, 0x61, 0x63, 0x2e, 0x64, 0x61, 0x79, + 0x4f, 0x66, 0x59, 0x65, 0x61, 0x72, 0x28, 0x6e, 0x29, 0x2b, 0x28, + 0x65, 0x2b, 0x74, 0x29, 0x25, 0x37, 0x29, 0x2f, 0x37, 0x29, 0x2d, + 0x28, 0x65, 0x21, 0x3d, 0x3d, 0x74, 0x29, 0x7d, 0x29, 0x3b, 0x61, + 0x63, 0x5b, 0x6e, 0x2b, 0x22, 0x73, 0x22, 0x5d, 0x3d, 0x65, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, 0x63, 0x5b, 0x6e, 0x2b, + 0x22, 0x73, 0x22, 0x5d, 0x2e, 0x75, 0x74, 0x63, 0x3d, 0x65, 0x2e, + 0x75, 0x74, 0x63, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, + 0x63, 0x5b, 0x6e, 0x2b, 0x22, 0x4f, 0x66, 0x59, 0x65, 0x61, 0x72, + 0x22, 0x5d, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x61, + 0x63, 0x2e, 0x79, 0x65, 0x61, 0x72, 0x28, 0x6e, 0x29, 0x2e, 0x67, + 0x65, 0x74, 0x44, 0x61, 0x79, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, + 0x6f, 0x6f, 0x72, 0x28, 0x28, 0x61, 0x63, 0x2e, 0x64, 0x61, 0x79, + 0x4f, 0x66, 0x59, 0x65, 0x61, 0x72, 0x28, 0x6e, 0x29, 0x2b, 0x28, + 0x65, 0x2b, 0x74, 0x29, 0x25, 0x37, 0x29, 0x2f, 0x37, 0x29, 0x7d, + 0x7d, 0x29, 0x2c, 0x61, 0x63, 0x2e, 0x77, 0x65, 0x65, 0x6b, 0x3d, + 0x61, 0x63, 0x2e, 0x73, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x2c, 0x61, + 0x63, 0x2e, 0x77, 0x65, 0x65, 0x6b, 0x73, 0x3d, 0x61, 0x63, 0x2e, + 0x73, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x2e, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x2c, 0x61, 0x63, 0x2e, 0x77, 0x65, 0x65, 0x6b, 0x73, 0x2e, + 0x75, 0x74, 0x63, 0x3d, 0x61, 0x63, 0x2e, 0x73, 0x75, 0x6e, 0x64, + 0x61, 0x79, 0x2e, 0x75, 0x74, 0x63, 0x2e, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x2c, 0x61, 0x63, 0x2e, 0x77, 0x65, 0x65, 0x6b, 0x4f, 0x66, + 0x59, 0x65, 0x61, 0x72, 0x3d, 0x61, 0x63, 0x2e, 0x73, 0x75, 0x6e, + 0x64, 0x61, 0x79, 0x4f, 0x66, 0x59, 0x65, 0x61, 0x72, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x73, 0x63, 0x3d, 0x7b, 0x22, 0x2d, 0x22, 0x3a, + 0x22, 0x22, 0x2c, 0x5f, 0x3a, 0x22, 0x20, 0x22, 0x2c, 0x30, 0x3a, + 0x22, 0x30, 0x22, 0x7d, 0x2c, 0x66, 0x63, 0x3d, 0x2f, 0x5e, 0x5c, + 0x73, 0x2a, 0x5c, 0x64, 0x2b, 0x2f, 0x2c, 0x68, 0x63, 0x3d, 0x2f, + 0x5e, 0x25, 0x2f, 0x3b, 0x74, 0x61, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x46, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x3a, 0x50, 0x74, 0x28, 0x6e, 0x29, 0x2c, 0x74, 0x69, 0x6d, + 0x65, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x3a, 0x4f, 0x74, 0x28, + 0x6e, 0x29, 0x7d, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x67, 0x63, + 0x3d, 0x74, 0x61, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x65, 0x28, + 0x7b, 0x64, 0x65, 0x63, 0x69, 0x6d, 0x61, 0x6c, 0x3a, 0x22, 0x2e, + 0x22, 0x2c, 0x74, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x73, + 0x3a, 0x22, 0x2c, 0x22, 0x2c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x69, + 0x6e, 0x67, 0x3a, 0x5b, 0x33, 0x5d, 0x2c, 0x63, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x3a, 0x5b, 0x22, 0x24, 0x22, 0x2c, 0x22, + 0x22, 0x5d, 0x2c, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, + 0x3a, 0x22, 0x25, 0x61, 0x20, 0x25, 0x62, 0x20, 0x25, 0x65, 0x20, + 0x25, 0x58, 0x20, 0x25, 0x59, 0x22, 0x2c, 0x64, 0x61, 0x74, 0x65, + 0x3a, 0x22, 0x25, 0x6d, 0x2f, 0x25, 0x64, 0x2f, 0x25, 0x59, 0x22, + 0x2c, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x22, 0x25, 0x48, 0x3a, 0x25, + 0x4d, 0x3a, 0x25, 0x53, 0x22, 0x2c, 0x70, 0x65, 0x72, 0x69, 0x6f, + 0x64, 0x73, 0x3a, 0x5b, 0x22, 0x41, 0x4d, 0x22, 0x2c, 0x22, 0x50, + 0x4d, 0x22, 0x5d, 0x2c, 0x64, 0x61, 0x79, 0x73, 0x3a, 0x5b, 0x22, + 0x53, 0x75, 0x6e, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, 0x4d, 0x6f, + 0x6e, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, 0x54, 0x75, 0x65, 0x73, + 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, 0x57, 0x65, 0x64, 0x6e, 0x65, + 0x73, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, 0x54, 0x68, 0x75, 0x72, + 0x73, 0x64, 0x61, 0x79, 0x22, 0x2c, 0x22, 0x46, 0x72, 0x69, 0x64, + 0x61, 0x79, 0x22, 0x2c, 0x22, 0x53, 0x61, 0x74, 0x75, 0x72, 0x64, + 0x61, 0x79, 0x22, 0x5d, 0x2c, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x44, + 0x61, 0x79, 0x73, 0x3a, 0x5b, 0x22, 0x53, 0x75, 0x6e, 0x22, 0x2c, + 0x22, 0x4d, 0x6f, 0x6e, 0x22, 0x2c, 0x22, 0x54, 0x75, 0x65, 0x22, + 0x2c, 0x22, 0x57, 0x65, 0x64, 0x22, 0x2c, 0x22, 0x54, 0x68, 0x75, + 0x22, 0x2c, 0x22, 0x46, 0x72, 0x69, 0x22, 0x2c, 0x22, 0x53, 0x61, + 0x74, 0x22, 0x5d, 0x2c, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x3a, + 0x5b, 0x22, 0x4a, 0x61, 0x6e, 0x75, 0x61, 0x72, 0x79, 0x22, 0x2c, + 0x22, 0x46, 0x65, 0x62, 0x72, 0x75, 0x61, 0x72, 0x79, 0x22, 0x2c, + 0x22, 0x4d, 0x61, 0x72, 0x63, 0x68, 0x22, 0x2c, 0x22, 0x41, 0x70, + 0x72, 0x69, 0x6c, 0x22, 0x2c, 0x22, 0x4d, 0x61, 0x79, 0x22, 0x2c, + 0x22, 0x4a, 0x75, 0x6e, 0x65, 0x22, 0x2c, 0x22, 0x4a, 0x75, 0x6c, + 0x79, 0x22, 0x2c, 0x22, 0x41, 0x75, 0x67, 0x75, 0x73, 0x74, 0x22, + 0x2c, 0x22, 0x53, 0x65, 0x70, 0x74, 0x65, 0x6d, 0x62, 0x65, 0x72, + 0x22, 0x2c, 0x22, 0x4f, 0x63, 0x74, 0x6f, 0x62, 0x65, 0x72, 0x22, + 0x2c, 0x22, 0x4e, 0x6f, 0x76, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x22, + 0x2c, 0x22, 0x44, 0x65, 0x63, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x22, + 0x5d, 0x2c, 0x73, 0x68, 0x6f, 0x72, 0x74, 0x4d, 0x6f, 0x6e, 0x74, + 0x68, 0x73, 0x3a, 0x5b, 0x22, 0x4a, 0x61, 0x6e, 0x22, 0x2c, 0x22, + 0x46, 0x65, 0x62, 0x22, 0x2c, 0x22, 0x4d, 0x61, 0x72, 0x22, 0x2c, + 0x22, 0x41, 0x70, 0x72, 0x22, 0x2c, 0x22, 0x4d, 0x61, 0x79, 0x22, + 0x2c, 0x22, 0x4a, 0x75, 0x6e, 0x22, 0x2c, 0x22, 0x4a, 0x75, 0x6c, + 0x22, 0x2c, 0x22, 0x41, 0x75, 0x67, 0x22, 0x2c, 0x22, 0x53, 0x65, + 0x70, 0x22, 0x2c, 0x22, 0x4f, 0x63, 0x74, 0x22, 0x2c, 0x22, 0x4e, + 0x6f, 0x76, 0x22, 0x2c, 0x22, 0x44, 0x65, 0x63, 0x22, 0x5d, 0x7d, + 0x29, 0x3b, 0x74, 0x61, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x3d, 0x67, 0x63, 0x2e, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x46, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, + 0x6f, 0x3d, 0x7b, 0x7d, 0x2c, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x7b, 0x73, 0x3a, 0x30, + 0x2c, 0x74, 0x3a, 0x30, 0x2c, 0x61, 0x64, 0x64, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6c, + 0x65, 0x28, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x2c, + 0x70, 0x63, 0x29, 0x2c, 0x6c, 0x65, 0x28, 0x70, 0x63, 0x2e, 0x73, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x3f, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x74, 0x2b, 0x3d, 0x70, 0x63, 0x2e, 0x74, + 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x3d, 0x70, 0x63, 0x2e, + 0x74, 0x7d, 0x2c, 0x72, 0x65, 0x73, 0x65, 0x74, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x73, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, + 0x3d, 0x30, 0x7d, 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x66, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x7d, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x70, + 0x63, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x63, 0x65, 0x3b, 0x74, 0x61, + 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x26, 0x26, 0x76, 0x63, 0x2e, 0x68, + 0x61, 0x73, 0x4f, 0x77, 0x6e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x79, 0x28, 0x6e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x29, 0x3f, + 0x76, 0x63, 0x5b, 0x6e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x5d, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x73, 0x65, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x76, 0x63, 0x3d, 0x7b, + 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x73, 0x65, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x6f, 0x6d, 0x65, 0x74, + 0x72, 0x79, 0x2c, 0x74, 0x29, 0x7d, 0x2c, 0x46, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x66, 0x65, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x73, 0x2c, 0x72, 0x3d, 0x2d, 0x31, 0x2c, 0x75, + 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, + 0x2b, 0x72, 0x3c, 0x75, 0x3b, 0x29, 0x73, 0x65, 0x28, 0x65, 0x5b, + 0x72, 0x5d, 0x2e, 0x67, 0x65, 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x79, + 0x2c, 0x74, 0x29, 0x7d, 0x7d, 0x2c, 0x64, 0x63, 0x3d, 0x7b, 0x53, + 0x70, 0x68, 0x65, 0x72, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x74, 0x2e, + 0x73, 0x70, 0x68, 0x65, 0x72, 0x65, 0x28, 0x29, 0x7d, 0x2c, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x3d, 0x6e, + 0x2e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, + 0x73, 0x2c, 0x74, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x6e, + 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, 0x5b, + 0x32, 0x5d, 0x29, 0x7d, 0x2c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, 0x63, 0x6f, + 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x72, + 0x3d, 0x2d, 0x31, 0x2c, 0x75, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x72, 0x3c, 0x75, 0x3b, 0x29, + 0x6e, 0x3d, 0x65, 0x5b, 0x72, 0x5d, 0x2c, 0x74, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, + 0x31, 0x5d, 0x2c, 0x6e, 0x5b, 0x32, 0x5d, 0x29, 0x7d, 0x2c, 0x4c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x66, 0x65, 0x28, 0x6e, 0x2e, 0x63, 0x6f, 0x6f, 0x72, + 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x2c, 0x74, 0x2c, 0x30, + 0x29, 0x7d, 0x2c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x4c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, + 0x2e, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, + 0x73, 0x2c, 0x72, 0x3d, 0x2d, 0x31, 0x2c, 0x75, 0x3d, 0x65, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x72, 0x3c, + 0x75, 0x3b, 0x29, 0x66, 0x65, 0x28, 0x65, 0x5b, 0x72, 0x5d, 0x2c, + 0x74, 0x2c, 0x30, 0x29, 0x7d, 0x2c, 0x50, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x68, 0x65, 0x28, 0x6e, 0x2e, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, + 0x2c, 0x74, 0x29, 0x7d, 0x2c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x50, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x2e, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, + 0x2c, 0x72, 0x3d, 0x2d, 0x31, 0x2c, 0x75, 0x3d, 0x65, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x72, 0x3c, 0x75, + 0x3b, 0x29, 0x68, 0x65, 0x28, 0x65, 0x5b, 0x72, 0x5d, 0x2c, 0x74, + 0x29, 0x7d, 0x2c, 0x47, 0x65, 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x79, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x6f, 0x6d, 0x65, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x2c, 0x72, 0x3d, 0x2d, 0x31, 0x2c, 0x75, 0x3d, + 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, + 0x72, 0x3c, 0x75, 0x3b, 0x29, 0x73, 0x65, 0x28, 0x65, 0x5b, 0x72, + 0x5d, 0x2c, 0x74, 0x29, 0x7d, 0x7d, 0x3b, 0x74, 0x61, 0x2e, 0x67, + 0x65, 0x6f, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x63, 0x3d, 0x30, 0x2c, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x28, 0x6e, 0x2c, 0x4d, 0x63, 0x29, 0x2c, 0x6d, 0x63, 0x7d, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x63, 0x2c, 0x79, 0x63, 0x3d, + 0x6e, 0x65, 0x77, 0x20, 0x63, 0x65, 0x2c, 0x4d, 0x63, 0x3d, 0x7b, + 0x73, 0x70, 0x68, 0x65, 0x72, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x6d, 0x63, 0x2b, 0x3d, + 0x34, 0x2a, 0x71, 0x61, 0x7d, 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x3a, 0x62, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x3a, 0x62, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x3a, 0x62, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x79, 0x63, 0x2e, 0x72, 0x65, 0x73, + 0x65, 0x74, 0x28, 0x29, 0x2c, 0x4d, 0x63, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x67, 0x65, 0x7d, 0x2c, + 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x32, 0x2a, 0x79, 0x63, 0x3b, + 0x6d, 0x63, 0x2b, 0x3d, 0x30, 0x3e, 0x6e, 0x3f, 0x34, 0x2a, 0x71, + 0x61, 0x2b, 0x6e, 0x3a, 0x6e, 0x2c, 0x4d, 0x63, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x4d, 0x63, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x4d, 0x63, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x62, 0x7d, 0x7d, 0x3b, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x4d, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x78, 0x3d, 0x5b, 0x73, 0x3d, 0x6e, 0x2c, 0x68, + 0x3d, 0x6e, 0x5d, 0x29, 0x2c, 0x66, 0x3e, 0x74, 0x26, 0x26, 0x28, + 0x66, 0x3d, 0x74, 0x29, 0x2c, 0x74, 0x3e, 0x67, 0x26, 0x26, 0x28, + 0x67, 0x3d, 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x70, 0x65, 0x28, 0x5b, 0x74, 0x2a, + 0x44, 0x61, 0x2c, 0x65, 0x2a, 0x44, 0x61, 0x5d, 0x29, 0x3b, 0x69, + 0x66, 0x28, 0x6d, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, + 0x64, 0x65, 0x28, 0x6d, 0x2c, 0x72, 0x29, 0x2c, 0x69, 0x3d, 0x5b, + 0x75, 0x5b, 0x31, 0x5d, 0x2c, 0x2d, 0x75, 0x5b, 0x30, 0x5d, 0x2c, + 0x30, 0x5d, 0x2c, 0x6f, 0x3d, 0x64, 0x65, 0x28, 0x69, 0x2c, 0x75, + 0x29, 0x3b, 0x4d, 0x65, 0x28, 0x6f, 0x29, 0x2c, 0x6f, 0x3d, 0x78, + 0x65, 0x28, 0x6f, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, + 0x74, 0x2d, 0x70, 0x2c, 0x6c, 0x3d, 0x63, 0x3e, 0x30, 0x3f, 0x31, + 0x3a, 0x2d, 0x31, 0x2c, 0x76, 0x3d, 0x6f, 0x5b, 0x30, 0x5d, 0x2a, + 0x50, 0x61, 0x2a, 0x6c, 0x2c, 0x64, 0x3d, 0x67, 0x61, 0x28, 0x63, + 0x29, 0x3e, 0x31, 0x38, 0x30, 0x3b, 0x69, 0x66, 0x28, 0x64, 0x5e, + 0x28, 0x76, 0x3e, 0x6c, 0x2a, 0x70, 0x26, 0x26, 0x6c, 0x2a, 0x74, + 0x3e, 0x76, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x79, 0x3d, + 0x6f, 0x5b, 0x31, 0x5d, 0x2a, 0x50, 0x61, 0x3b, 0x79, 0x3e, 0x67, + 0x26, 0x26, 0x28, 0x67, 0x3d, 0x79, 0x29, 0x7d, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x69, 0x66, 0x28, 0x76, 0x3d, 0x28, 0x76, 0x2b, 0x33, + 0x36, 0x30, 0x29, 0x25, 0x33, 0x36, 0x30, 0x2d, 0x31, 0x38, 0x30, + 0x2c, 0x64, 0x5e, 0x28, 0x76, 0x3e, 0x6c, 0x2a, 0x70, 0x26, 0x26, + 0x6c, 0x2a, 0x74, 0x3e, 0x76, 0x29, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x79, 0x3d, 0x2d, 0x6f, 0x5b, 0x31, 0x5d, 0x2a, 0x50, 0x61, + 0x3b, 0x66, 0x3e, 0x79, 0x26, 0x26, 0x28, 0x66, 0x3d, 0x79, 0x29, + 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x3e, 0x65, 0x26, 0x26, + 0x28, 0x66, 0x3d, 0x65, 0x29, 0x2c, 0x65, 0x3e, 0x67, 0x26, 0x26, + 0x28, 0x67, 0x3d, 0x65, 0x29, 0x3b, 0x64, 0x3f, 0x70, 0x3e, 0x74, + 0x3f, 0x61, 0x28, 0x73, 0x2c, 0x74, 0x29, 0x3e, 0x61, 0x28, 0x73, + 0x2c, 0x68, 0x29, 0x26, 0x26, 0x28, 0x68, 0x3d, 0x74, 0x29, 0x3a, + 0x61, 0x28, 0x74, 0x2c, 0x68, 0x29, 0x3e, 0x61, 0x28, 0x73, 0x2c, + 0x68, 0x29, 0x26, 0x26, 0x28, 0x73, 0x3d, 0x74, 0x29, 0x3a, 0x68, + 0x3e, 0x3d, 0x73, 0x3f, 0x28, 0x73, 0x3e, 0x74, 0x26, 0x26, 0x28, + 0x73, 0x3d, 0x74, 0x29, 0x2c, 0x74, 0x3e, 0x68, 0x26, 0x26, 0x28, + 0x68, 0x3d, 0x74, 0x29, 0x29, 0x3a, 0x74, 0x3e, 0x70, 0x3f, 0x61, + 0x28, 0x73, 0x2c, 0x74, 0x29, 0x3e, 0x61, 0x28, 0x73, 0x2c, 0x68, + 0x29, 0x26, 0x26, 0x28, 0x68, 0x3d, 0x74, 0x29, 0x3a, 0x61, 0x28, + 0x74, 0x2c, 0x68, 0x29, 0x3e, 0x61, 0x28, 0x73, 0x2c, 0x68, 0x29, + 0x26, 0x26, 0x28, 0x73, 0x3d, 0x74, 0x29, 0x7d, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x3b, 0x6d, 0x3d, + 0x72, 0x2c, 0x70, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x29, 0x7b, 0x62, 0x2e, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x29, 0x7b, 0x78, 0x5b, + 0x30, 0x5d, 0x3d, 0x73, 0x2c, 0x78, 0x5b, 0x31, 0x5d, 0x3d, 0x68, + 0x2c, 0x62, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, 0x2c, + 0x6d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x2c, 0x65, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x6d, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x6e, 0x2d, 0x70, 0x3b, 0x79, 0x2b, 0x3d, 0x67, 0x61, + 0x28, 0x72, 0x29, 0x3e, 0x31, 0x38, 0x30, 0x3f, 0x72, 0x2b, 0x28, + 0x72, 0x3e, 0x30, 0x3f, 0x33, 0x36, 0x30, 0x3a, 0x2d, 0x33, 0x36, + 0x30, 0x29, 0x3a, 0x72, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x76, + 0x3d, 0x6e, 0x2c, 0x64, 0x3d, 0x65, 0x3b, 0x4d, 0x63, 0x2e, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x2c, 0x74, + 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x29, 0x7b, 0x4d, 0x63, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, + 0x28, 0x29, 0x7b, 0x75, 0x28, 0x76, 0x2c, 0x64, 0x29, 0x2c, 0x4d, + 0x63, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, + 0x2c, 0x67, 0x61, 0x28, 0x79, 0x29, 0x3e, 0x43, 0x61, 0x26, 0x26, + 0x28, 0x73, 0x3d, 0x2d, 0x28, 0x68, 0x3d, 0x31, 0x38, 0x30, 0x29, + 0x29, 0x2c, 0x78, 0x5b, 0x30, 0x5d, 0x3d, 0x73, 0x2c, 0x78, 0x5b, + 0x31, 0x5d, 0x3d, 0x68, 0x2c, 0x6d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x28, 0x74, 0x2d, 0x3d, 0x6e, 0x29, 0x3c, 0x30, 0x3f, 0x74, + 0x2b, 0x33, 0x36, 0x30, 0x3a, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x5b, 0x30, + 0x5d, 0x2d, 0x74, 0x5b, 0x30, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x5b, 0x30, + 0x5d, 0x3c, 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x3f, 0x74, 0x5b, 0x30, + 0x5d, 0x3c, 0x3d, 0x6e, 0x26, 0x26, 0x6e, 0x3c, 0x3d, 0x74, 0x5b, + 0x31, 0x5d, 0x3a, 0x6e, 0x3c, 0x74, 0x5b, 0x30, 0x5d, 0x7c, 0x7c, + 0x74, 0x5b, 0x31, 0x5d, 0x3c, 0x6e, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x73, 0x2c, 0x66, 0x2c, 0x68, 0x2c, 0x67, 0x2c, 0x70, 0x2c, 0x76, + 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x79, 0x2c, 0x4d, 0x2c, 0x78, 0x2c, + 0x62, 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x6e, 0x2c, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x65, + 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x72, 0x2c, + 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x62, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x75, + 0x2c, 0x62, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x3d, 0x69, 0x2c, 0x62, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, + 0x6e, 0x64, 0x3d, 0x6f, 0x2c, 0x79, 0x3d, 0x30, 0x2c, 0x4d, 0x63, + 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x28, 0x29, 0x7d, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x4d, 0x63, 0x2e, 0x70, 0x6f, + 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x2c, + 0x62, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, 0x2c, 0x62, + 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, + 0x65, 0x2c, 0x62, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x3d, 0x72, 0x2c, 0x30, 0x3e, 0x79, 0x63, 0x3f, 0x28, 0x73, 0x3d, + 0x2d, 0x28, 0x68, 0x3d, 0x31, 0x38, 0x30, 0x29, 0x2c, 0x66, 0x3d, + 0x2d, 0x28, 0x67, 0x3d, 0x39, 0x30, 0x29, 0x29, 0x3a, 0x79, 0x3e, + 0x43, 0x61, 0x3f, 0x67, 0x3d, 0x39, 0x30, 0x3a, 0x2d, 0x43, 0x61, + 0x3e, 0x79, 0x26, 0x26, 0x28, 0x66, 0x3d, 0x2d, 0x39, 0x30, 0x29, + 0x2c, 0x78, 0x5b, 0x30, 0x5d, 0x3d, 0x73, 0x2c, 0x78, 0x5b, 0x31, + 0x5d, 0x3d, 0x68, 0x7d, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x67, 0x3d, 0x68, 0x3d, 0x2d, 0x28, 0x73, 0x3d, + 0x66, 0x3d, 0x31, 0x2f, 0x30, 0x29, 0x2c, 0x4d, 0x3d, 0x5b, 0x5d, + 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x28, 0x6e, 0x2c, 0x62, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x4d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x4d, 0x2e, 0x73, + 0x6f, 0x72, 0x74, 0x28, 0x63, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, 0x31, 0x2c, 0x75, + 0x3d, 0x4d, 0x5b, 0x30, 0x5d, 0x2c, 0x69, 0x3d, 0x5b, 0x75, 0x5d, + 0x3b, 0x74, 0x3e, 0x72, 0x3b, 0x2b, 0x2b, 0x72, 0x29, 0x65, 0x3d, + 0x4d, 0x5b, 0x72, 0x5d, 0x2c, 0x6c, 0x28, 0x65, 0x5b, 0x30, 0x5d, + 0x2c, 0x75, 0x29, 0x7c, 0x7c, 0x6c, 0x28, 0x65, 0x5b, 0x31, 0x5d, + 0x2c, 0x75, 0x29, 0x3f, 0x28, 0x61, 0x28, 0x75, 0x5b, 0x30, 0x5d, + 0x2c, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x3e, 0x61, 0x28, 0x75, 0x5b, + 0x30, 0x5d, 0x2c, 0x75, 0x5b, 0x31, 0x5d, 0x29, 0x26, 0x26, 0x28, + 0x75, 0x5b, 0x31, 0x5d, 0x3d, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x2c, + 0x61, 0x28, 0x65, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x5b, 0x31, 0x5d, + 0x29, 0x3e, 0x61, 0x28, 0x75, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x5b, + 0x31, 0x5d, 0x29, 0x26, 0x26, 0x28, 0x75, 0x5b, 0x30, 0x5d, 0x3d, + 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x3a, 0x69, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x75, 0x3d, 0x65, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x2c, 0x65, 0x2c, 0x70, 0x3d, + 0x2d, 0x31, 0x2f, 0x30, 0x2c, 0x74, 0x3d, 0x69, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x2c, 0x72, 0x3d, 0x30, 0x2c, + 0x75, 0x3d, 0x69, 0x5b, 0x74, 0x5d, 0x3b, 0x74, 0x3e, 0x3d, 0x72, + 0x3b, 0x75, 0x3d, 0x65, 0x2c, 0x2b, 0x2b, 0x72, 0x29, 0x65, 0x3d, + 0x69, 0x5b, 0x72, 0x5d, 0x2c, 0x28, 0x6f, 0x3d, 0x61, 0x28, 0x75, + 0x5b, 0x31, 0x5d, 0x2c, 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x3e, + 0x70, 0x26, 0x26, 0x28, 0x70, 0x3d, 0x6f, 0x2c, 0x73, 0x3d, 0x65, + 0x5b, 0x30, 0x5d, 0x2c, 0x68, 0x3d, 0x75, 0x5b, 0x31, 0x5d, 0x29, + 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x3d, 0x78, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x31, 0x2f, 0x30, 0x3d, 0x3d, + 0x3d, 0x73, 0x7c, 0x7c, 0x31, 0x2f, 0x30, 0x3d, 0x3d, 0x3d, 0x66, + 0x3f, 0x5b, 0x5b, 0x30, 0x2f, 0x30, 0x2c, 0x30, 0x2f, 0x30, 0x5d, + 0x2c, 0x5b, 0x30, 0x2f, 0x30, 0x2c, 0x30, 0x2f, 0x30, 0x5d, 0x5d, + 0x3a, 0x5b, 0x5b, 0x73, 0x2c, 0x66, 0x5d, 0x2c, 0x5b, 0x68, 0x2c, + 0x67, 0x5d, 0x5d, 0x7d, 0x7d, 0x28, 0x29, 0x2c, 0x74, 0x61, 0x2e, + 0x67, 0x65, 0x6f, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x69, + 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x78, 0x63, 0x3d, 0x62, 0x63, 0x3d, 0x5f, 0x63, + 0x3d, 0x77, 0x63, 0x3d, 0x53, 0x63, 0x3d, 0x6b, 0x63, 0x3d, 0x45, + 0x63, 0x3d, 0x41, 0x63, 0x3d, 0x4e, 0x63, 0x3d, 0x43, 0x63, 0x3d, + 0x7a, 0x63, 0x3d, 0x30, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x6e, 0x2c, 0x71, + 0x63, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x4e, 0x63, + 0x2c, 0x65, 0x3d, 0x43, 0x63, 0x2c, 0x72, 0x3d, 0x7a, 0x63, 0x2c, + 0x75, 0x3d, 0x74, 0x2a, 0x74, 0x2b, 0x65, 0x2a, 0x65, 0x2b, 0x72, + 0x2a, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x7a, + 0x61, 0x3e, 0x75, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x6b, 0x63, 0x2c, + 0x65, 0x3d, 0x45, 0x63, 0x2c, 0x72, 0x3d, 0x41, 0x63, 0x2c, 0x43, + 0x61, 0x3e, 0x62, 0x63, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x5f, 0x63, + 0x2c, 0x65, 0x3d, 0x77, 0x63, 0x2c, 0x72, 0x3d, 0x53, 0x63, 0x29, + 0x2c, 0x75, 0x3d, 0x74, 0x2a, 0x74, 0x2b, 0x65, 0x2a, 0x65, 0x2b, + 0x72, 0x2a, 0x72, 0x2c, 0x7a, 0x61, 0x3e, 0x75, 0x29, 0x3f, 0x5b, + 0x30, 0x2f, 0x30, 0x2c, 0x30, 0x2f, 0x30, 0x5d, 0x3a, 0x5b, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x32, 0x28, 0x65, + 0x2c, 0x74, 0x29, 0x2a, 0x50, 0x61, 0x2c, 0x74, 0x74, 0x28, 0x72, + 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, + 0x75, 0x29, 0x29, 0x2a, 0x50, 0x61, 0x5d, 0x7d, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x78, 0x63, 0x2c, 0x62, 0x63, 0x2c, 0x5f, 0x63, 0x2c, + 0x77, 0x63, 0x2c, 0x53, 0x63, 0x2c, 0x6b, 0x63, 0x2c, 0x45, 0x63, + 0x2c, 0x41, 0x63, 0x2c, 0x4e, 0x63, 0x2c, 0x43, 0x63, 0x2c, 0x7a, + 0x63, 0x2c, 0x71, 0x63, 0x3d, 0x7b, 0x73, 0x70, 0x68, 0x65, 0x72, + 0x65, 0x3a, 0x62, 0x2c, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x5f, + 0x65, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x3a, 0x53, 0x65, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x3a, 0x6b, 0x65, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x71, 0x63, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x45, 0x65, 0x7d, + 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x71, 0x63, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x3d, 0x53, 0x65, 0x7d, 0x7d, 0x2c, 0x4c, 0x63, 0x3d, + 0x4c, 0x65, 0x28, 0x4e, 0x65, 0x2c, 0x50, 0x65, 0x2c, 0x6a, 0x65, + 0x2c, 0x5b, 0x2d, 0x71, 0x61, 0x2c, 0x2d, 0x71, 0x61, 0x2f, 0x32, + 0x5d, 0x29, 0x2c, 0x54, 0x63, 0x3d, 0x31, 0x65, 0x39, 0x3b, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, + 0x6f, 0x3d, 0x7b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x26, 0x26, 0x28, + 0x75, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x3d, 0x21, 0x31, 0x29, + 0x2c, 0x75, 0x3d, 0x69, 0x28, 0x6e, 0x29, 0x2c, 0x75, 0x2e, 0x76, + 0x61, 0x6c, 0x69, 0x64, 0x3d, 0x21, 0x30, 0x2c, 0x75, 0x7d, 0x2c, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x61, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x69, 0x3d, 0x49, 0x65, 0x28, 0x6e, 0x3d, 0x2b, 0x61, 0x5b, 0x30, + 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x74, 0x3d, 0x2b, 0x61, 0x5b, 0x30, + 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x65, 0x3d, 0x2b, 0x61, 0x5b, 0x31, + 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x72, 0x3d, 0x2b, 0x61, 0x5b, 0x31, + 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x75, 0x26, 0x26, 0x28, 0x75, + 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x3d, 0x21, 0x31, 0x2c, 0x75, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x6f, 0x29, 0x3a, 0x5b, + 0x5b, 0x6e, 0x2c, 0x74, 0x5d, 0x2c, 0x5b, 0x65, 0x2c, 0x72, 0x5d, + 0x5d, 0x7d, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6f, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x28, 0x5b, 0x5b, + 0x30, 0x2c, 0x30, 0x5d, 0x2c, 0x5b, 0x39, 0x36, 0x30, 0x2c, 0x35, + 0x30, 0x30, 0x5d, 0x5d, 0x29, 0x7d, 0x2c, 0x28, 0x74, 0x61, 0x2e, + 0x67, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x45, 0x71, + 0x75, 0x61, 0x6c, 0x41, 0x72, 0x65, 0x61, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x59, 0x65, 0x28, 0x5a, 0x65, 0x29, 0x7d, + 0x29, 0x2e, 0x72, 0x61, 0x77, 0x3d, 0x5a, 0x65, 0x2c, 0x74, 0x61, + 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x61, 0x6c, 0x62, 0x65, 0x72, 0x73, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, + 0x67, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x45, 0x71, + 0x75, 0x61, 0x6c, 0x41, 0x72, 0x65, 0x61, 0x28, 0x29, 0x2e, 0x72, + 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x5b, 0x39, 0x36, 0x2c, 0x30, + 0x5d, 0x29, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x5b, + 0x2d, 0x2e, 0x36, 0x2c, 0x33, 0x38, 0x2e, 0x37, 0x5d, 0x29, 0x2e, + 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x73, 0x28, 0x5b, + 0x32, 0x39, 0x2e, 0x35, 0x2c, 0x34, 0x35, 0x2e, 0x35, 0x5d, 0x29, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x31, 0x30, 0x37, 0x30, + 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x61, + 0x6c, 0x62, 0x65, 0x72, 0x73, 0x55, 0x73, 0x61, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, + 0x2c, 0x6f, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, + 0x65, 0x28, 0x69, 0x2c, 0x6f, 0x29, 0x2c, 0x74, 0x7c, 0x7c, 0x28, + 0x72, 0x28, 0x69, 0x2c, 0x6f, 0x29, 0x2c, 0x74, 0x29, 0x7c, 0x7c, + 0x75, 0x28, 0x69, 0x2c, 0x6f, 0x29, 0x2c, 0x74, 0x7d, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, + 0x3d, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x61, 0x6c, 0x62, + 0x65, 0x72, 0x73, 0x28, 0x29, 0x2c, 0x6f, 0x3d, 0x74, 0x61, 0x2e, + 0x67, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x45, 0x71, + 0x75, 0x61, 0x6c, 0x41, 0x72, 0x65, 0x61, 0x28, 0x29, 0x2e, 0x72, + 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x5b, 0x31, 0x35, 0x34, 0x2c, + 0x30, 0x5d, 0x29, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, + 0x5b, 0x2d, 0x32, 0x2c, 0x35, 0x38, 0x2e, 0x35, 0x5d, 0x29, 0x2e, + 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x73, 0x28, 0x5b, + 0x35, 0x35, 0x2c, 0x36, 0x35, 0x5d, 0x29, 0x2c, 0x61, 0x3d, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x69, 0x63, + 0x45, 0x71, 0x75, 0x61, 0x6c, 0x41, 0x72, 0x65, 0x61, 0x28, 0x29, + 0x2e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x5b, 0x31, 0x35, + 0x37, 0x2c, 0x30, 0x5d, 0x29, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x28, 0x5b, 0x2d, 0x33, 0x2c, 0x31, 0x39, 0x2e, 0x39, 0x5d, + 0x29, 0x2e, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x73, + 0x28, 0x5b, 0x38, 0x2c, 0x31, 0x38, 0x5d, 0x29, 0x2c, 0x63, 0x3d, + 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x74, + 0x3d, 0x5b, 0x6e, 0x2c, 0x65, 0x5d, 0x7d, 0x7d, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x69, 0x6e, 0x76, 0x65, + 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x69, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x29, 0x2c, 0x65, 0x3d, + 0x69, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, + 0x28, 0x29, 0x2c, 0x72, 0x3d, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2d, + 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x2f, 0x74, 0x2c, 0x75, 0x3d, 0x28, + 0x6e, 0x5b, 0x31, 0x5d, 0x2d, 0x65, 0x5b, 0x31, 0x5d, 0x29, 0x2f, + 0x74, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x75, 0x3e, + 0x3d, 0x2e, 0x31, 0x32, 0x26, 0x26, 0x2e, 0x32, 0x33, 0x34, 0x3e, + 0x75, 0x26, 0x26, 0x72, 0x3e, 0x3d, 0x2d, 0x2e, 0x34, 0x32, 0x35, + 0x26, 0x26, 0x2d, 0x2e, 0x32, 0x31, 0x34, 0x3e, 0x72, 0x3f, 0x6f, + 0x3a, 0x75, 0x3e, 0x3d, 0x2e, 0x31, 0x36, 0x36, 0x26, 0x26, 0x2e, + 0x32, 0x33, 0x34, 0x3e, 0x75, 0x26, 0x26, 0x72, 0x3e, 0x3d, 0x2d, + 0x2e, 0x32, 0x31, 0x34, 0x26, 0x26, 0x2d, 0x2e, 0x31, 0x31, 0x35, + 0x3e, 0x72, 0x3f, 0x61, 0x3a, 0x69, 0x29, 0x2e, 0x69, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x28, 0x6e, 0x29, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x69, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, + 0x6e, 0x29, 0x2c, 0x65, 0x3d, 0x6f, 0x2e, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x28, 0x6e, 0x29, 0x2c, 0x72, 0x3d, 0x61, 0x2e, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x6e, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x75, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, + 0x6e, 0x2c, 0x75, 0x29, 0x2c, 0x65, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x28, 0x6e, 0x2c, 0x75, 0x29, 0x2c, 0x72, 0x2e, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x28, 0x6e, 0x2c, 0x75, 0x29, 0x7d, 0x2c, 0x73, + 0x70, 0x68, 0x65, 0x72, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x2e, 0x73, 0x70, 0x68, + 0x65, 0x72, 0x65, 0x28, 0x29, 0x2c, 0x65, 0x2e, 0x73, 0x70, 0x68, + 0x65, 0x72, 0x65, 0x28, 0x29, 0x2c, 0x72, 0x2e, 0x73, 0x70, 0x68, + 0x65, 0x72, 0x65, 0x28, 0x29, 0x7d, 0x2c, 0x6c, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x65, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, + 0x2c, 0x72, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x28, 0x29, 0x7d, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, + 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x74, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x28, 0x29, 0x2c, 0x65, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, + 0x64, 0x28, 0x29, 0x2c, 0x72, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x45, + 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x2e, 0x70, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x28, 0x29, 0x2c, 0x65, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, + 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x2c, 0x72, 0x2e, + 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x28, 0x29, 0x7d, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, + 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x79, + 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x2c, 0x65, 0x2e, + 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, + 0x29, 0x2c, 0x72, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, + 0x45, 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x7d, 0x7d, 0x2c, 0x6e, 0x2e, + 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x69, 0x2e, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x2c, 0x6f, 0x2e, 0x70, 0x72, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x2c, + 0x61, 0x2e, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x69, 0x2e, 0x70, 0x72, + 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7d, 0x2c, + 0x6e, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x69, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x74, 0x29, + 0x2c, 0x6f, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x2e, 0x33, + 0x35, 0x2a, 0x74, 0x29, 0x2c, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x69, 0x2e, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x29, 0x29, 0x29, 0x3a, + 0x69, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x29, 0x7d, 0x2c, + 0x6e, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x69, 0x2e, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x28, 0x29, 0x2c, 0x73, 0x3d, 0x2b, 0x74, 0x5b, 0x30, + 0x5d, 0x2c, 0x66, 0x3d, 0x2b, 0x74, 0x5b, 0x31, 0x5d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3d, 0x69, 0x2e, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x74, 0x29, + 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, + 0x28, 0x5b, 0x5b, 0x73, 0x2d, 0x2e, 0x34, 0x35, 0x35, 0x2a, 0x6c, + 0x2c, 0x66, 0x2d, 0x2e, 0x32, 0x33, 0x38, 0x2a, 0x6c, 0x5d, 0x2c, + 0x5b, 0x73, 0x2b, 0x2e, 0x34, 0x35, 0x35, 0x2a, 0x6c, 0x2c, 0x66, + 0x2b, 0x2e, 0x32, 0x33, 0x38, 0x2a, 0x6c, 0x5d, 0x5d, 0x29, 0x2e, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x63, 0x29, 0x2e, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x72, 0x3d, 0x6f, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x5b, 0x73, 0x2d, + 0x2e, 0x33, 0x30, 0x37, 0x2a, 0x6c, 0x2c, 0x66, 0x2b, 0x2e, 0x32, + 0x30, 0x31, 0x2a, 0x6c, 0x5d, 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x70, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x28, 0x5b, 0x5b, 0x73, 0x2d, + 0x2e, 0x34, 0x32, 0x35, 0x2a, 0x6c, 0x2b, 0x43, 0x61, 0x2c, 0x66, + 0x2b, 0x2e, 0x31, 0x32, 0x2a, 0x6c, 0x2b, 0x43, 0x61, 0x5d, 0x2c, + 0x5b, 0x73, 0x2d, 0x2e, 0x32, 0x31, 0x34, 0x2a, 0x6c, 0x2d, 0x43, + 0x61, 0x2c, 0x66, 0x2b, 0x2e, 0x32, 0x33, 0x34, 0x2a, 0x6c, 0x2d, + 0x43, 0x61, 0x5d, 0x5d, 0x29, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x28, 0x63, 0x29, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, + 0x75, 0x3d, 0x61, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, + 0x74, 0x65, 0x28, 0x5b, 0x73, 0x2d, 0x2e, 0x32, 0x30, 0x35, 0x2a, + 0x6c, 0x2c, 0x66, 0x2b, 0x2e, 0x32, 0x31, 0x32, 0x2a, 0x6c, 0x5d, + 0x29, 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x28, 0x5b, 0x5b, 0x73, 0x2d, 0x2e, 0x32, 0x31, 0x34, 0x2a, + 0x6c, 0x2b, 0x43, 0x61, 0x2c, 0x66, 0x2b, 0x2e, 0x31, 0x36, 0x36, + 0x2a, 0x6c, 0x2b, 0x43, 0x61, 0x5d, 0x2c, 0x5b, 0x73, 0x2d, 0x2e, + 0x31, 0x31, 0x35, 0x2a, 0x6c, 0x2d, 0x43, 0x61, 0x2c, 0x66, 0x2b, + 0x2e, 0x32, 0x33, 0x34, 0x2a, 0x6c, 0x2d, 0x43, 0x61, 0x5d, 0x5d, + 0x29, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x63, 0x29, + 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x6e, 0x7d, 0x2c, 0x6e, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x28, 0x31, 0x30, 0x37, 0x30, + 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x52, 0x63, 0x2c, 0x44, + 0x63, 0x2c, 0x50, 0x63, 0x2c, 0x55, 0x63, 0x2c, 0x6a, 0x63, 0x2c, + 0x46, 0x63, 0x2c, 0x48, 0x63, 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x3a, 0x62, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x3a, 0x62, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, + 0x64, 0x3a, 0x62, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x44, 0x63, 0x3d, 0x30, 0x2c, + 0x48, 0x63, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x3d, 0x56, 0x65, 0x7d, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, + 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x48, 0x63, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x48, 0x63, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x48, 0x63, 0x2e, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x62, 0x2c, 0x52, 0x63, 0x2b, + 0x3d, 0x67, 0x61, 0x28, 0x44, 0x63, 0x2f, 0x32, 0x29, 0x7d, 0x7d, + 0x2c, 0x4f, 0x63, 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, + 0x58, 0x65, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, + 0x74, 0x3a, 0x62, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, + 0x3a, 0x62, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x3a, 0x62, 0x2c, 0x70, 0x6f, 0x6c, 0x79, + 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x62, 0x7d, 0x2c, 0x49, + 0x63, 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x57, 0x65, + 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, + 0x4a, 0x65, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3a, + 0x47, 0x65, 0x2c, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x49, 0x63, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x4b, 0x65, 0x7d, 0x2c, + 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x49, 0x63, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x57, 0x65, + 0x2c, 0x49, 0x63, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, + 0x72, 0x74, 0x3d, 0x4a, 0x65, 0x2c, 0x49, 0x63, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3d, 0x47, 0x65, 0x7d, 0x7d, 0x3b, + 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x70, 0x61, 0x74, 0x68, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x26, 0x26, 0x28, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, + 0x20, 0x61, 0x26, 0x26, 0x69, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x28, 0x2b, 0x61, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x29, 0x2c, + 0x6f, 0x26, 0x26, 0x6f, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x7c, + 0x7c, 0x28, 0x6f, 0x3d, 0x75, 0x28, 0x69, 0x29, 0x29, 0x2c, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x28, 0x6e, 0x2c, 0x6f, 0x29, 0x29, 0x2c, 0x69, 0x2e, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x2c, 0x6e, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, + 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, 0x3d, 0x34, 0x2e, + 0x35, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, + 0x61, 0x72, 0x65, 0x61, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x52, 0x63, 0x3d, 0x30, 0x2c, 0x74, 0x61, 0x2e, 0x67, + 0x65, 0x6f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x6e, + 0x2c, 0x75, 0x28, 0x48, 0x63, 0x29, 0x29, 0x2c, 0x52, 0x63, 0x7d, + 0x2c, 0x6e, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x6f, 0x69, 0x64, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x63, + 0x3d, 0x77, 0x63, 0x3d, 0x53, 0x63, 0x3d, 0x6b, 0x63, 0x3d, 0x45, + 0x63, 0x3d, 0x41, 0x63, 0x3d, 0x4e, 0x63, 0x3d, 0x43, 0x63, 0x3d, + 0x7a, 0x63, 0x3d, 0x30, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x6e, 0x2c, 0x75, + 0x28, 0x49, 0x63, 0x29, 0x29, 0x2c, 0x7a, 0x63, 0x3f, 0x5b, 0x4e, + 0x63, 0x2f, 0x7a, 0x63, 0x2c, 0x43, 0x63, 0x2f, 0x7a, 0x63, 0x5d, + 0x3a, 0x41, 0x63, 0x3f, 0x5b, 0x6b, 0x63, 0x2f, 0x41, 0x63, 0x2c, + 0x45, 0x63, 0x2f, 0x41, 0x63, 0x5d, 0x3a, 0x53, 0x63, 0x3f, 0x5b, + 0x5f, 0x63, 0x2f, 0x53, 0x63, 0x2c, 0x77, 0x63, 0x2f, 0x53, 0x63, + 0x5d, 0x3a, 0x5b, 0x30, 0x2f, 0x30, 0x2c, 0x30, 0x2f, 0x30, 0x5d, + 0x7d, 0x2c, 0x6e, 0x2e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6a, 0x63, 0x3d, + 0x46, 0x63, 0x3d, 0x2d, 0x28, 0x50, 0x63, 0x3d, 0x55, 0x63, 0x3d, + 0x31, 0x2f, 0x30, 0x29, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x28, 0x6e, 0x2c, 0x75, + 0x28, 0x4f, 0x63, 0x29, 0x29, 0x2c, 0x5b, 0x5b, 0x50, 0x63, 0x2c, + 0x55, 0x63, 0x5d, 0x2c, 0x5b, 0x6a, 0x63, 0x2c, 0x46, 0x63, 0x5d, + 0x5d, 0x7d, 0x2c, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x75, 0x3d, + 0x28, 0x65, 0x3d, 0x6e, 0x29, 0x3f, 0x6e, 0x2e, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x7c, 0x7c, 0x74, 0x72, 0x28, 0x6e, 0x29, 0x3a, + 0x79, 0x2c, 0x74, 0x28, 0x29, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x6e, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x69, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x28, + 0x72, 0x3d, 0x6e, 0x29, 0x3f, 0x6e, 0x65, 0x77, 0x20, 0x24, 0x65, + 0x3a, 0x6e, 0x65, 0x77, 0x20, 0x51, 0x65, 0x28, 0x6e, 0x29, 0x2c, + 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x21, + 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x61, 0x26, 0x26, + 0x69, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x28, 0x61, 0x29, 0x2c, 0x74, 0x28, 0x29, 0x29, 0x3a, + 0x72, 0x7d, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x61, + 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3f, + 0x74, 0x3a, 0x28, 0x69, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x28, 0x2b, 0x74, 0x29, 0x2c, 0x2b, + 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x61, 0x7d, 0x2c, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x61, 0x6c, 0x62, 0x65, + 0x72, 0x73, 0x55, 0x73, 0x61, 0x28, 0x29, 0x29, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x6e, 0x65, 0x77, + 0x20, 0x65, 0x72, 0x28, 0x74, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, + 0x65, 0x5b, 0x72, 0x5d, 0x3d, 0x6e, 0x5b, 0x72, 0x5d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, 0x7d, 0x7d, 0x2c, + 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x7b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7d, 0x2c, 0x73, 0x70, 0x68, 0x65, 0x72, 0x65, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, + 0x73, 0x70, 0x68, 0x65, 0x72, 0x65, 0x28, 0x29, 0x7d, 0x2c, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x7d, + 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x6c, + 0x69, 0x6e, 0x65, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x2c, 0x70, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x28, 0x29, 0x7d, 0x2c, 0x70, 0x6f, 0x6c, 0x79, + 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, + 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x28, 0x29, 0x7d, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x75, 0x72, 0x2c, + 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x75, 0x74, 0x61, 0x74, + 0x6f, 0x72, 0x3d, 0x69, 0x72, 0x2c, 0x28, 0x74, 0x61, 0x2e, 0x67, + 0x65, 0x6f, 0x2e, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x61, 0x6e, 0x67, 0x75, 0x6c, 0x61, 0x72, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x75, 0x72, 0x28, 0x61, 0x72, 0x29, 0x7d, + 0x29, 0x2e, 0x72, 0x61, 0x77, 0x3d, 0x61, 0x72, 0x2e, 0x69, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x3d, 0x61, 0x72, 0x2c, 0x74, 0x61, 0x2e, + 0x67, 0x65, 0x6f, 0x2e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x3d, 0x6e, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x2a, + 0x44, 0x61, 0x2c, 0x74, 0x5b, 0x31, 0x5d, 0x2a, 0x44, 0x61, 0x29, + 0x2c, 0x74, 0x5b, 0x30, 0x5d, 0x2a, 0x3d, 0x50, 0x61, 0x2c, 0x74, + 0x5b, 0x31, 0x5d, 0x2a, 0x3d, 0x50, 0x61, 0x2c, 0x74, 0x7d, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, 0x6c, 0x72, 0x28, + 0x6e, 0x5b, 0x30, 0x5d, 0x25, 0x33, 0x36, 0x30, 0x2a, 0x44, 0x61, + 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x44, 0x61, 0x2c, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x32, 0x3f, 0x6e, 0x5b, + 0x32, 0x5d, 0x2a, 0x44, 0x61, 0x3a, 0x30, 0x29, 0x2c, 0x74, 0x2e, + 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x69, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x2a, 0x44, 0x61, + 0x2c, 0x74, 0x5b, 0x31, 0x5d, 0x2a, 0x44, 0x61, 0x29, 0x2c, 0x74, + 0x5b, 0x30, 0x5d, 0x2a, 0x3d, 0x50, 0x61, 0x2c, 0x74, 0x5b, 0x31, + 0x5d, 0x2a, 0x3d, 0x50, 0x61, 0x2c, 0x74, 0x7d, 0x2c, 0x74, 0x7d, + 0x2c, 0x63, 0x72, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, + 0x61, 0x72, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x63, + 0x69, 0x72, 0x63, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6e, 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x72, 0x3f, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x29, 0x3a, 0x72, 0x2c, 0x74, 0x3d, 0x6c, 0x72, 0x28, + 0x2d, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x44, 0x61, 0x2c, 0x2d, 0x6e, + 0x5b, 0x31, 0x5d, 0x2a, 0x44, 0x61, 0x2c, 0x30, 0x29, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x2c, 0x75, 0x3d, 0x5b, 0x5d, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x75, + 0x6c, 0x6c, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x31, 0x2c, 0x7b, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x75, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x3d, 0x74, 0x28, 0x6e, 0x2c, + 0x65, 0x29, 0x29, 0x2c, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x3d, 0x50, + 0x61, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x3d, 0x50, 0x61, 0x7d, + 0x7d, 0x29, 0x2c, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x50, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x22, 0x2c, 0x63, 0x6f, 0x6f, + 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x3a, 0x5b, 0x75, + 0x5d, 0x7d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x3d, 0x5b, 0x30, 0x2c, 0x30, 0x5d, 0x2c, 0x75, 0x3d, 0x36, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6f, + 0x72, 0x69, 0x67, 0x69, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, + 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x2e, + 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, + 0x3d, 0x67, 0x72, 0x28, 0x28, 0x74, 0x3d, 0x2b, 0x72, 0x29, 0x2a, + 0x44, 0x61, 0x2c, 0x75, 0x2a, 0x44, 0x61, 0x29, 0x2c, 0x6e, 0x29, + 0x3a, 0x74, 0x7d, 0x2c, 0x6e, 0x2e, 0x70, 0x72, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, + 0x67, 0x72, 0x28, 0x74, 0x2a, 0x44, 0x61, 0x2c, 0x28, 0x75, 0x3d, + 0x2b, 0x72, 0x29, 0x2a, 0x44, 0x61, 0x29, 0x2c, 0x6e, 0x29, 0x3a, + 0x75, 0x7d, 0x2c, 0x6e, 0x2e, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x28, + 0x39, 0x30, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, + 0x2e, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, 0x28, + 0x74, 0x5b, 0x30, 0x5d, 0x2d, 0x6e, 0x5b, 0x30, 0x5d, 0x29, 0x2a, + 0x44, 0x61, 0x2c, 0x75, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x44, + 0x61, 0x2c, 0x69, 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2a, 0x44, 0x61, + 0x2c, 0x6f, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, + 0x28, 0x72, 0x29, 0x2c, 0x61, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x63, 0x6f, 0x73, 0x28, 0x72, 0x29, 0x2c, 0x63, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x75, 0x29, 0x2c, 0x6c, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x75, + 0x29, 0x2c, 0x73, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, + 0x6e, 0x28, 0x69, 0x29, 0x2c, 0x66, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x69, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, + 0x61, 0x6e, 0x32, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x28, 0x65, 0x3d, 0x66, 0x2a, 0x6f, 0x29, 0x2a, + 0x65, 0x2b, 0x28, 0x65, 0x3d, 0x6c, 0x2a, 0x73, 0x2d, 0x63, 0x2a, + 0x66, 0x2a, 0x61, 0x29, 0x2a, 0x65, 0x29, 0x2c, 0x63, 0x2a, 0x73, + 0x2b, 0x6c, 0x2a, 0x66, 0x2a, 0x61, 0x29, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x67, 0x72, 0x61, 0x74, 0x69, 0x63, + 0x75, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x4d, 0x75, 0x6c, + 0x74, 0x69, 0x4c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x22, 0x2c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, + 0x74, 0x65, 0x73, 0x3a, 0x74, 0x28, 0x29, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, + 0x65, 0x69, 0x6c, 0x28, 0x69, 0x2f, 0x64, 0x29, 0x2a, 0x64, 0x2c, + 0x75, 0x2c, 0x64, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x68, 0x29, + 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x61, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x63, 0x65, 0x69, 0x6c, 0x28, 0x6c, 0x2f, 0x6d, 0x29, 0x2a, 0x6d, + 0x2c, 0x63, 0x2c, 0x6d, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x67, + 0x29, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, + 0x61, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x72, 0x2f, 0x70, 0x29, + 0x2a, 0x70, 0x2c, 0x65, 0x2c, 0x70, 0x29, 0x2e, 0x66, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x67, 0x61, 0x28, 0x6e, 0x25, 0x64, 0x29, 0x3e, 0x43, 0x61, + 0x7d, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x73, 0x29, 0x29, 0x2e, + 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x74, 0x61, 0x2e, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, + 0x65, 0x69, 0x6c, 0x28, 0x61, 0x2f, 0x76, 0x29, 0x2a, 0x76, 0x2c, + 0x6f, 0x2c, 0x76, 0x29, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x67, 0x61, + 0x28, 0x6e, 0x25, 0x6d, 0x29, 0x3e, 0x43, 0x61, 0x7d, 0x29, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x66, 0x29, 0x29, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, + 0x61, 0x2c, 0x63, 0x2c, 0x6c, 0x2c, 0x73, 0x2c, 0x66, 0x2c, 0x68, + 0x2c, 0x67, 0x2c, 0x70, 0x3d, 0x31, 0x30, 0x2c, 0x76, 0x3d, 0x70, + 0x2c, 0x64, 0x3d, 0x39, 0x30, 0x2c, 0x6d, 0x3d, 0x33, 0x36, 0x30, + 0x2c, 0x79, 0x3d, 0x32, 0x2e, 0x35, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x28, 0x29, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x4c, 0x69, 0x6e, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, 0x63, 0x6f, 0x6f, + 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, 0x3a, 0x6e, 0x7d, + 0x7d, 0x29, 0x7d, 0x2c, 0x6e, 0x2e, 0x6f, 0x75, 0x74, 0x6c, 0x69, + 0x6e, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x22, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, + 0x6e, 0x22, 0x2c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, + 0x74, 0x65, 0x73, 0x3a, 0x5b, 0x68, 0x28, 0x69, 0x29, 0x2e, 0x63, + 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x67, 0x28, 0x63, 0x29, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x31, 0x29, 0x2c, 0x68, 0x28, + 0x75, 0x29, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, + 0x29, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x31, 0x29, 0x2c, + 0x67, 0x28, 0x6c, 0x29, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x28, 0x29, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x31, + 0x29, 0x29, 0x5d, 0x7d, 0x7d, 0x2c, 0x6e, 0x2e, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x2e, 0x6d, 0x61, + 0x6a, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x28, 0x74, + 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x28, 0x74, 0x29, 0x3a, 0x6e, 0x2e, 0x6d, 0x69, 0x6e, + 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x28, 0x29, 0x7d, + 0x2c, 0x6e, 0x2e, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x69, 0x3d, 0x2b, + 0x74, 0x5b, 0x30, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x3d, 0x2b, + 0x74, 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x6c, 0x3d, 0x2b, + 0x74, 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x63, 0x3d, 0x2b, + 0x74, 0x5b, 0x31, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x69, 0x3e, 0x75, + 0x26, 0x26, 0x28, 0x74, 0x3d, 0x69, 0x2c, 0x69, 0x3d, 0x75, 0x2c, + 0x75, 0x3d, 0x74, 0x29, 0x2c, 0x6c, 0x3e, 0x63, 0x26, 0x26, 0x28, + 0x74, 0x3d, 0x6c, 0x2c, 0x6c, 0x3d, 0x63, 0x2c, 0x63, 0x3d, 0x74, + 0x29, 0x2c, 0x6e, 0x2e, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x28, 0x79, 0x29, 0x29, 0x3a, 0x5b, 0x5b, 0x69, 0x2c, + 0x6c, 0x5d, 0x2c, 0x5b, 0x75, 0x2c, 0x63, 0x5d, 0x5d, 0x7d, 0x2c, + 0x6e, 0x2e, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x45, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, 0x3d, 0x2b, 0x74, + 0x5b, 0x30, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x3d, 0x2b, 0x74, + 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x61, 0x3d, 0x2b, 0x74, + 0x5b, 0x30, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x6f, 0x3d, 0x2b, 0x74, + 0x5b, 0x31, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x72, 0x3e, 0x65, 0x26, + 0x26, 0x28, 0x74, 0x3d, 0x72, 0x2c, 0x72, 0x3d, 0x65, 0x2c, 0x65, + 0x3d, 0x74, 0x29, 0x2c, 0x61, 0x3e, 0x6f, 0x26, 0x26, 0x28, 0x74, + 0x3d, 0x61, 0x2c, 0x61, 0x3d, 0x6f, 0x2c, 0x6f, 0x3d, 0x74, 0x29, + 0x2c, 0x6e, 0x2e, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x28, 0x79, 0x29, 0x29, 0x3a, 0x5b, 0x5b, 0x72, 0x2c, 0x61, + 0x5d, 0x2c, 0x5b, 0x65, 0x2c, 0x6f, 0x5d, 0x5d, 0x7d, 0x2c, 0x6e, + 0x2e, 0x73, 0x74, 0x65, 0x70, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x2e, + 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x53, 0x74, 0x65, 0x70, 0x28, 0x74, + 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x53, 0x74, 0x65, 0x70, + 0x28, 0x74, 0x29, 0x3a, 0x6e, 0x2e, 0x6d, 0x69, 0x6e, 0x6f, 0x72, + 0x53, 0x74, 0x65, 0x70, 0x28, 0x29, 0x7d, 0x2c, 0x6e, 0x2e, 0x6d, + 0x61, 0x6a, 0x6f, 0x72, 0x53, 0x74, 0x65, 0x70, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x64, 0x3d, 0x2b, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x6d, + 0x3d, 0x2b, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, 0x29, 0x3a, 0x5b, + 0x64, 0x2c, 0x6d, 0x5d, 0x7d, 0x2c, 0x6e, 0x2e, 0x6d, 0x69, 0x6e, + 0x6f, 0x72, 0x53, 0x74, 0x65, 0x70, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x70, 0x3d, 0x2b, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x76, 0x3d, 0x2b, + 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, 0x29, 0x3a, 0x5b, 0x70, 0x2c, + 0x76, 0x5d, 0x7d, 0x2c, 0x6e, 0x2e, 0x70, 0x72, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x79, 0x3d, + 0x2b, 0x74, 0x2c, 0x73, 0x3d, 0x76, 0x72, 0x28, 0x61, 0x2c, 0x6f, + 0x2c, 0x39, 0x30, 0x29, 0x2c, 0x66, 0x3d, 0x64, 0x72, 0x28, 0x72, + 0x2c, 0x65, 0x2c, 0x79, 0x29, 0x2c, 0x68, 0x3d, 0x76, 0x72, 0x28, + 0x6c, 0x2c, 0x63, 0x2c, 0x39, 0x30, 0x29, 0x2c, 0x67, 0x3d, 0x64, + 0x72, 0x28, 0x69, 0x2c, 0x75, 0x2c, 0x79, 0x29, 0x2c, 0x6e, 0x29, + 0x3a, 0x79, 0x7d, 0x2c, 0x6e, 0x2e, 0x6d, 0x61, 0x6a, 0x6f, 0x72, + 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x28, 0x5b, 0x5b, 0x2d, 0x31, + 0x38, 0x30, 0x2c, 0x2d, 0x39, 0x30, 0x2b, 0x43, 0x61, 0x5d, 0x2c, + 0x5b, 0x31, 0x38, 0x30, 0x2c, 0x39, 0x30, 0x2d, 0x43, 0x61, 0x5d, + 0x5d, 0x29, 0x2e, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x45, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x28, 0x5b, 0x5b, 0x2d, 0x31, 0x38, 0x30, 0x2c, + 0x2d, 0x38, 0x30, 0x2d, 0x43, 0x61, 0x5d, 0x2c, 0x5b, 0x31, 0x38, + 0x30, 0x2c, 0x38, 0x30, 0x2b, 0x43, 0x61, 0x5d, 0x5d, 0x29, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x67, 0x72, 0x65, + 0x61, 0x74, 0x41, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x4c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x2c, + 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x73, + 0x3a, 0x5b, 0x74, 0x7c, 0x7c, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x2c, 0x65, 0x7c, 0x7c, 0x75, + 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, + 0x5d, 0x7d, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x3d, 0x6d, 0x72, 0x2c, 0x75, 0x3d, 0x79, 0x72, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x64, 0x69, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x64, 0x69, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x28, 0x74, 0x7c, 0x7c, 0x72, + 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, + 0x2c, 0x65, 0x7c, 0x7c, 0x75, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x29, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, + 0x3d, 0x65, 0x2c, 0x74, 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, + 0x66, 0x20, 0x65, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x65, 0x2c, + 0x6e, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x2e, 0x74, 0x61, 0x72, + 0x67, 0x65, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x75, 0x3d, 0x74, + 0x2c, 0x65, 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x74, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x74, 0x2c, 0x6e, 0x29, + 0x3a, 0x75, 0x7d, 0x2c, 0x6e, 0x2e, 0x70, 0x72, 0x65, 0x63, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x6e, 0x3a, 0x30, 0x7d, + 0x2c, 0x6e, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x4d, 0x72, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x44, 0x61, 0x2c, + 0x6e, 0x5b, 0x31, 0x5d, 0x2a, 0x44, 0x61, 0x2c, 0x74, 0x5b, 0x30, + 0x5d, 0x2a, 0x44, 0x61, 0x2c, 0x74, 0x5b, 0x31, 0x5d, 0x2a, 0x44, + 0x61, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x59, 0x63, 0x3d, 0x30, 0x2c, 0x74, 0x61, + 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x28, 0x6e, 0x2c, 0x5a, 0x63, 0x29, 0x2c, 0x59, 0x63, 0x7d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x59, 0x63, 0x2c, 0x5a, 0x63, 0x3d, 0x7b, + 0x73, 0x70, 0x68, 0x65, 0x72, 0x65, 0x3a, 0x62, 0x2c, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x3a, 0x62, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x3a, 0x78, 0x72, 0x2c, 0x6c, 0x69, 0x6e, + 0x65, 0x45, 0x6e, 0x64, 0x3a, 0x62, 0x2c, 0x70, 0x6f, 0x6c, 0x79, + 0x67, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x3a, 0x62, 0x2c, + 0x70, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x3a, + 0x62, 0x7d, 0x2c, 0x56, 0x63, 0x3d, 0x62, 0x72, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x73, 0x71, 0x72, 0x74, 0x28, 0x32, 0x2f, 0x28, 0x31, 0x2b, 0x6e, + 0x29, 0x29, 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x32, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x73, 0x69, + 0x6e, 0x28, 0x6e, 0x2f, 0x32, 0x29, 0x7d, 0x29, 0x3b, 0x28, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x61, 0x7a, 0x69, 0x6d, 0x75, + 0x74, 0x68, 0x61, 0x6c, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x41, 0x72, + 0x65, 0x61, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, + 0x72, 0x28, 0x56, 0x63, 0x29, 0x7d, 0x29, 0x2e, 0x72, 0x61, 0x77, + 0x3d, 0x56, 0x63, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x58, 0x63, 0x3d, + 0x62, 0x72, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x61, 0x63, 0x6f, 0x73, 0x28, 0x6e, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x26, 0x26, + 0x74, 0x2f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x74, 0x29, 0x7d, 0x2c, 0x79, 0x29, 0x3b, 0x28, 0x74, 0x61, 0x2e, + 0x67, 0x65, 0x6f, 0x2e, 0x61, 0x7a, 0x69, 0x6d, 0x75, 0x74, 0x68, + 0x61, 0x6c, 0x45, 0x71, 0x75, 0x69, 0x64, 0x69, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, + 0x72, 0x28, 0x58, 0x63, 0x29, 0x7d, 0x29, 0x2e, 0x72, 0x61, 0x77, + 0x3d, 0x58, 0x63, 0x2c, 0x28, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, + 0x2e, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x59, 0x65, 0x28, 0x5f, 0x72, 0x29, 0x7d, 0x29, 0x2e, 0x72, + 0x61, 0x77, 0x3d, 0x5f, 0x72, 0x2c, 0x28, 0x74, 0x61, 0x2e, 0x67, + 0x65, 0x6f, 0x2e, 0x63, 0x6f, 0x6e, 0x69, 0x63, 0x45, 0x71, 0x75, + 0x69, 0x64, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x59, 0x65, 0x28, 0x77, 0x72, 0x29, + 0x7d, 0x29, 0x2e, 0x72, 0x61, 0x77, 0x3d, 0x77, 0x72, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x24, 0x63, 0x3d, 0x62, 0x72, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x2f, 0x6e, 0x7d, 0x2c, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x29, 0x3b, + 0x28, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x67, 0x6e, 0x6f, + 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x75, 0x72, 0x28, 0x24, 0x63, 0x29, 0x7d, 0x29, 0x2e, + 0x72, 0x61, 0x77, 0x3d, 0x24, 0x63, 0x2c, 0x53, 0x72, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x2c, 0x32, 0x2a, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x28, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x65, 0x78, 0x70, 0x28, 0x74, 0x29, 0x29, 0x2d, 0x52, + 0x61, 0x5d, 0x7d, 0x2c, 0x28, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, + 0x2e, 0x6d, 0x65, 0x72, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6b, 0x72, 0x28, 0x53, 0x72, + 0x29, 0x7d, 0x29, 0x2e, 0x72, 0x61, 0x77, 0x3d, 0x53, 0x72, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x42, 0x63, 0x3d, 0x62, 0x72, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x7d, 0x2c, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x61, 0x73, 0x69, 0x6e, 0x29, 0x3b, 0x28, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x2e, 0x6f, 0x72, 0x74, 0x68, 0x6f, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x69, 0x63, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x75, 0x72, 0x28, 0x42, 0x63, 0x29, 0x7d, + 0x29, 0x2e, 0x72, 0x61, 0x77, 0x3d, 0x42, 0x63, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x57, 0x63, 0x3d, 0x62, 0x72, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x2f, 0x28, 0x31, 0x2b, 0x6e, + 0x29, 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x32, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, + 0x28, 0x6e, 0x29, 0x7d, 0x29, 0x3b, 0x28, 0x74, 0x61, 0x2e, 0x67, + 0x65, 0x6f, 0x2e, 0x73, 0x74, 0x65, 0x72, 0x65, 0x6f, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x69, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x75, 0x72, 0x28, 0x57, 0x63, 0x29, 0x7d, 0x29, 0x2e, + 0x72, 0x61, 0x77, 0x3d, 0x57, 0x63, 0x2c, 0x45, 0x72, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x2d, 0x74, 0x2c, 0x32, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x61, 0x74, 0x61, 0x6e, 0x28, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x65, 0x78, 0x70, 0x28, 0x6e, 0x29, 0x29, 0x2d, + 0x52, 0x61, 0x5d, 0x7d, 0x2c, 0x28, 0x74, 0x61, 0x2e, 0x67, 0x65, + 0x6f, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x76, 0x65, 0x72, 0x73, + 0x65, 0x4d, 0x65, 0x72, 0x63, 0x61, 0x74, 0x6f, 0x72, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x6b, 0x72, 0x28, 0x45, 0x72, 0x29, + 0x2c, 0x74, 0x3d, 0x6e, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x3f, 0x74, 0x28, 0x5b, 0x2d, 0x6e, 0x5b, + 0x31, 0x5d, 0x2c, 0x6e, 0x5b, 0x30, 0x5d, 0x5d, 0x29, 0x3a, 0x28, + 0x6e, 0x3d, 0x74, 0x28, 0x29, 0x2c, 0x5b, 0x6e, 0x5b, 0x31, 0x5d, + 0x2c, 0x2d, 0x6e, 0x5b, 0x30, 0x5d, 0x5d, 0x29, 0x7d, 0x2c, 0x6e, + 0x2e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3f, 0x65, 0x28, 0x5b, 0x6e, + 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x32, 0x3f, 0x6e, 0x5b, + 0x32, 0x5d, 0x2b, 0x39, 0x30, 0x3a, 0x39, 0x30, 0x5d, 0x29, 0x3a, + 0x28, 0x6e, 0x3d, 0x65, 0x28, 0x29, 0x2c, 0x5b, 0x6e, 0x5b, 0x30, + 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2c, 0x6e, 0x5b, 0x32, 0x5d, + 0x2d, 0x39, 0x30, 0x5d, 0x29, 0x7d, 0x2c, 0x65, 0x28, 0x5b, 0x30, + 0x2c, 0x30, 0x2c, 0x39, 0x30, 0x5d, 0x29, 0x7d, 0x29, 0x2e, 0x72, + 0x61, 0x77, 0x3d, 0x45, 0x72, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, + 0x6f, 0x6d, 0x3d, 0x7b, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, + 0x6f, 0x6d, 0x2e, 0x68, 0x75, 0x6c, 0x6c, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x33, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, + 0x5d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x75, 0x3d, 0x45, + 0x74, 0x28, 0x65, 0x29, 0x2c, 0x69, 0x3d, 0x45, 0x74, 0x28, 0x72, + 0x29, 0x2c, 0x6f, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x61, 0x3d, 0x5b, 0x5d, 0x2c, 0x63, 0x3d, 0x5b, 0x5d, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x3b, 0x6f, 0x3e, + 0x74, 0x3b, 0x74, 0x2b, 0x2b, 0x29, 0x61, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x5b, 0x2b, 0x75, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x5b, 0x74, 0x5d, 0x2c, 0x74, + 0x29, 0x2c, 0x2b, 0x69, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x5b, 0x74, 0x5d, 0x2c, 0x74, 0x29, + 0x2c, 0x74, 0x5d, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x61, 0x2e, + 0x73, 0x6f, 0x72, 0x74, 0x28, 0x7a, 0x72, 0x29, 0x2c, 0x74, 0x3d, + 0x30, 0x3b, 0x6f, 0x3e, 0x74, 0x3b, 0x74, 0x2b, 0x2b, 0x29, 0x63, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x5b, 0x61, 0x5b, 0x74, 0x5d, + 0x5b, 0x30, 0x5d, 0x2c, 0x2d, 0x61, 0x5b, 0x74, 0x5d, 0x5b, 0x31, + 0x5d, 0x5d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x43, + 0x72, 0x28, 0x61, 0x29, 0x2c, 0x73, 0x3d, 0x43, 0x72, 0x28, 0x63, + 0x29, 0x2c, 0x66, 0x3d, 0x73, 0x5b, 0x30, 0x5d, 0x3d, 0x3d, 0x3d, + 0x6c, 0x5b, 0x30, 0x5d, 0x2c, 0x68, 0x3d, 0x73, 0x5b, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x3d, 0x3d, + 0x3d, 0x6c, 0x5b, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2d, 0x31, 0x5d, 0x2c, 0x67, 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x74, 0x3d, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2d, 0x31, 0x3b, 0x74, 0x3e, 0x3d, 0x30, 0x3b, 0x2d, 0x2d, + 0x74, 0x29, 0x67, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x5b, + 0x61, 0x5b, 0x6c, 0x5b, 0x74, 0x5d, 0x5d, 0x5b, 0x32, 0x5d, 0x5d, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x2b, 0x66, 0x3b, + 0x74, 0x3c, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, + 0x68, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x67, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x6e, 0x5b, 0x61, 0x5b, 0x73, 0x5b, 0x74, 0x5d, 0x5d, + 0x5b, 0x32, 0x5d, 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x67, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x41, + 0x72, 0x2c, 0x72, 0x3d, 0x4e, 0x72, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x74, 0x28, + 0x6e, 0x29, 0x3a, 0x28, 0x74, 0x2e, 0x78, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x65, 0x3d, 0x6e, 0x2c, 0x74, 0x29, 0x3a, 0x65, 0x7d, 0x2c, + 0x74, 0x2e, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, 0x3d, 0x6e, + 0x2c, 0x74, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x74, 0x29, 0x7d, 0x2c, + 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, + 0x79, 0x67, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x79, 0x61, 0x28, 0x6e, 0x2c, 0x4a, 0x63, 0x29, 0x2c, + 0x6e, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x4a, 0x63, 0x3d, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x79, + 0x67, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x5b, 0x5d, 0x3b, 0x4a, 0x63, 0x2e, 0x61, 0x72, + 0x65, 0x61, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x2c, 0x74, 0x3d, 0x2d, 0x31, 0x2c, 0x65, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x72, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x65, 0x2d, 0x31, 0x5d, 0x2c, + 0x75, 0x3d, 0x30, 0x3b, 0x2b, 0x2b, 0x74, 0x3c, 0x65, 0x3b, 0x29, + 0x6e, 0x3d, 0x72, 0x2c, 0x72, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, + 0x74, 0x5d, 0x2c, 0x75, 0x2b, 0x3d, 0x6e, 0x5b, 0x31, 0x5d, 0x2a, + 0x72, 0x5b, 0x30, 0x5d, 0x2d, 0x6e, 0x5b, 0x30, 0x5d, 0x2a, 0x72, + 0x5b, 0x31, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2e, + 0x35, 0x2a, 0x75, 0x7d, 0x2c, 0x4a, 0x63, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x6f, 0x69, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x3d, 0x2d, 0x31, 0x2c, 0x75, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2c, 0x69, 0x3d, 0x30, 0x2c, 0x6f, 0x3d, 0x30, 0x2c, 0x61, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x5b, 0x75, 0x2d, 0x31, 0x5d, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7c, 0x7c, 0x28, + 0x6e, 0x3d, 0x2d, 0x31, 0x2f, 0x28, 0x36, 0x2a, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x28, 0x29, 0x29, 0x29, 0x3b, + 0x2b, 0x2b, 0x72, 0x3c, 0x75, 0x3b, 0x29, 0x74, 0x3d, 0x61, 0x2c, + 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x72, 0x5d, 0x2c, 0x65, + 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x2a, 0x61, 0x5b, 0x31, 0x5d, 0x2d, + 0x61, 0x5b, 0x30, 0x5d, 0x2a, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x69, + 0x2b, 0x3d, 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x2b, 0x61, 0x5b, 0x30, + 0x5d, 0x29, 0x2a, 0x65, 0x2c, 0x6f, 0x2b, 0x3d, 0x28, 0x74, 0x5b, + 0x31, 0x5d, 0x2b, 0x61, 0x5b, 0x31, 0x5d, 0x29, 0x2a, 0x65, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x69, 0x2a, 0x6e, 0x2c, + 0x6f, 0x2a, 0x6e, 0x5d, 0x7d, 0x2c, 0x4a, 0x63, 0x2e, 0x63, 0x6c, + 0x69, 0x70, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, + 0x6f, 0x2c, 0x61, 0x3d, 0x54, 0x72, 0x28, 0x6e, 0x29, 0x2c, 0x63, + 0x3d, 0x2d, 0x31, 0x2c, 0x6c, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x54, 0x72, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x2c, 0x73, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x5b, 0x6c, 0x2d, 0x31, 0x5d, 0x3b, 0x2b, 0x2b, 0x63, 0x3c, 0x6c, + 0x3b, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x6e, 0x2e, + 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x29, 0x2c, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x74, + 0x68, 0x69, 0x73, 0x5b, 0x63, 0x5d, 0x2c, 0x69, 0x3d, 0x74, 0x5b, + 0x28, 0x72, 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2d, 0x61, 0x29, 0x2d, 0x31, 0x5d, 0x2c, 0x65, 0x3d, 0x2d, 0x31, + 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x72, 0x3b, 0x29, 0x6f, 0x3d, 0x74, + 0x5b, 0x65, 0x5d, 0x2c, 0x71, 0x72, 0x28, 0x6f, 0x2c, 0x73, 0x2c, + 0x75, 0x29, 0x3f, 0x28, 0x71, 0x72, 0x28, 0x69, 0x2c, 0x73, 0x2c, + 0x75, 0x29, 0x7c, 0x7c, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x4c, 0x72, 0x28, 0x69, 0x2c, 0x6f, 0x2c, 0x73, 0x2c, 0x75, 0x29, + 0x29, 0x2c, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6f, 0x29, + 0x29, 0x3a, 0x71, 0x72, 0x28, 0x69, 0x2c, 0x73, 0x2c, 0x75, 0x29, + 0x26, 0x26, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x4c, 0x72, + 0x28, 0x69, 0x2c, 0x6f, 0x2c, 0x73, 0x2c, 0x75, 0x29, 0x29, 0x2c, + 0x69, 0x3d, 0x6f, 0x3b, 0x61, 0x26, 0x26, 0x6e, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x73, 0x3d, + 0x75, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x47, 0x63, 0x2c, 0x4b, 0x63, 0x2c, + 0x51, 0x63, 0x2c, 0x6e, 0x6c, 0x2c, 0x74, 0x6c, 0x2c, 0x65, 0x6c, + 0x3d, 0x5b, 0x5d, 0x2c, 0x72, 0x6c, 0x3d, 0x5b, 0x5d, 0x3b, 0x4f, + 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, + 0x2e, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x2c, 0x74, 0x3d, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x73, 0x2c, 0x65, + 0x3d, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, + 0x2d, 0x2d, 0x3b, 0x29, 0x6e, 0x3d, 0x74, 0x5b, 0x65, 0x5d, 0x2e, + 0x65, 0x64, 0x67, 0x65, 0x2c, 0x6e, 0x2e, 0x62, 0x26, 0x26, 0x6e, + 0x2e, 0x61, 0x7c, 0x7c, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x63, + 0x65, 0x28, 0x65, 0x2c, 0x31, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, 0x59, + 0x72, 0x29, 0x2c, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x7d, 0x2c, 0x51, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x7b, 0x73, 0x74, 0x61, 0x72, 0x74, 0x3a, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x65, 0x64, 0x67, 0x65, 0x2e, 0x6c, 0x3d, 0x3d, 0x3d, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x3f, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x2e, 0x61, 0x3a, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x2e, 0x62, 0x7d, + 0x2c, 0x65, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x2e, + 0x6c, 0x3d, 0x3d, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x69, + 0x74, 0x65, 0x3f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x64, 0x67, + 0x65, 0x2e, 0x62, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x64, + 0x67, 0x65, 0x2e, 0x61, 0x7d, 0x7d, 0x2c, 0x6e, 0x75, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x7b, 0x69, + 0x6e, 0x73, 0x65, 0x72, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3b, 0x69, 0x66, 0x28, + 0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x50, 0x3d, 0x6e, + 0x2c, 0x74, 0x2e, 0x4e, 0x3d, 0x6e, 0x2e, 0x4e, 0x2c, 0x6e, 0x2e, + 0x4e, 0x26, 0x26, 0x28, 0x6e, 0x2e, 0x4e, 0x2e, 0x50, 0x3d, 0x74, + 0x29, 0x2c, 0x6e, 0x2e, 0x4e, 0x3d, 0x74, 0x2c, 0x6e, 0x2e, 0x52, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6e, 0x3d, 0x6e, 0x2e, 0x52, + 0x3b, 0x6e, 0x2e, 0x4c, 0x3b, 0x29, 0x6e, 0x3d, 0x6e, 0x2e, 0x4c, + 0x3b, 0x6e, 0x2e, 0x4c, 0x3d, 0x74, 0x7d, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x6e, 0x2e, 0x52, 0x3d, 0x74, 0x3b, 0x65, 0x3d, 0x6e, 0x7d, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x3f, 0x28, 0x6e, 0x3d, 0x75, 0x75, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x5f, 0x29, 0x2c, 0x74, 0x2e, 0x50, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x2c, 0x74, 0x2e, 0x4e, 0x3d, 0x6e, 0x2c, 0x6e, 0x2e, 0x50, + 0x3d, 0x6e, 0x2e, 0x4c, 0x3d, 0x74, 0x2c, 0x65, 0x3d, 0x6e, 0x29, + 0x3a, 0x28, 0x74, 0x2e, 0x50, 0x3d, 0x74, 0x2e, 0x4e, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x3d, + 0x74, 0x2c, 0x65, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x74, 0x2e, 0x4c, 0x3d, 0x74, 0x2e, 0x52, 0x3d, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x74, 0x2e, 0x55, 0x3d, 0x65, 0x2c, + 0x74, 0x2e, 0x43, 0x3d, 0x21, 0x30, 0x2c, 0x6e, 0x3d, 0x74, 0x3b, + 0x65, 0x26, 0x26, 0x65, 0x2e, 0x43, 0x3b, 0x29, 0x72, 0x3d, 0x65, + 0x2e, 0x55, 0x2c, 0x65, 0x3d, 0x3d, 0x3d, 0x72, 0x2e, 0x4c, 0x3f, + 0x28, 0x75, 0x3d, 0x72, 0x2e, 0x52, 0x2c, 0x75, 0x26, 0x26, 0x75, + 0x2e, 0x43, 0x3f, 0x28, 0x65, 0x2e, 0x43, 0x3d, 0x75, 0x2e, 0x43, + 0x3d, 0x21, 0x31, 0x2c, 0x72, 0x2e, 0x43, 0x3d, 0x21, 0x30, 0x2c, + 0x6e, 0x3d, 0x72, 0x29, 0x3a, 0x28, 0x6e, 0x3d, 0x3d, 0x3d, 0x65, + 0x2e, 0x52, 0x26, 0x26, 0x28, 0x65, 0x75, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x65, 0x29, 0x2c, 0x6e, 0x3d, 0x65, 0x2c, 0x65, 0x3d, + 0x6e, 0x2e, 0x55, 0x29, 0x2c, 0x65, 0x2e, 0x43, 0x3d, 0x21, 0x31, + 0x2c, 0x72, 0x2e, 0x43, 0x3d, 0x21, 0x30, 0x2c, 0x72, 0x75, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x72, 0x29, 0x29, 0x29, 0x3a, 0x28, + 0x75, 0x3d, 0x72, 0x2e, 0x4c, 0x2c, 0x75, 0x26, 0x26, 0x75, 0x2e, + 0x43, 0x3f, 0x28, 0x65, 0x2e, 0x43, 0x3d, 0x75, 0x2e, 0x43, 0x3d, + 0x21, 0x31, 0x2c, 0x72, 0x2e, 0x43, 0x3d, 0x21, 0x30, 0x2c, 0x6e, + 0x3d, 0x72, 0x29, 0x3a, 0x28, 0x6e, 0x3d, 0x3d, 0x3d, 0x65, 0x2e, + 0x4c, 0x26, 0x26, 0x28, 0x72, 0x75, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2c, 0x65, 0x29, 0x2c, 0x6e, 0x3d, 0x65, 0x2c, 0x65, 0x3d, 0x6e, + 0x2e, 0x55, 0x29, 0x2c, 0x65, 0x2e, 0x43, 0x3d, 0x21, 0x31, 0x2c, + 0x72, 0x2e, 0x43, 0x3d, 0x21, 0x30, 0x2c, 0x65, 0x75, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x72, 0x29, 0x29, 0x29, 0x2c, 0x65, 0x3d, + 0x6e, 0x2e, 0x55, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x2e, + 0x43, 0x3d, 0x21, 0x31, 0x7d, 0x2c, 0x72, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x4e, 0x26, 0x26, 0x28, 0x6e, 0x2e, + 0x4e, 0x2e, 0x50, 0x3d, 0x6e, 0x2e, 0x50, 0x29, 0x2c, 0x6e, 0x2e, + 0x50, 0x26, 0x26, 0x28, 0x6e, 0x2e, 0x50, 0x2e, 0x4e, 0x3d, 0x6e, + 0x2e, 0x4e, 0x29, 0x2c, 0x6e, 0x2e, 0x4e, 0x3d, 0x6e, 0x2e, 0x50, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, 0x55, 0x2c, + 0x69, 0x3d, 0x6e, 0x2e, 0x4c, 0x2c, 0x6f, 0x3d, 0x6e, 0x2e, 0x52, + 0x3b, 0x69, 0x66, 0x28, 0x65, 0x3d, 0x69, 0x3f, 0x6f, 0x3f, 0x75, + 0x75, 0x28, 0x6f, 0x29, 0x3a, 0x69, 0x3a, 0x6f, 0x2c, 0x75, 0x3f, + 0x75, 0x2e, 0x4c, 0x3d, 0x3d, 0x3d, 0x6e, 0x3f, 0x75, 0x2e, 0x4c, + 0x3d, 0x65, 0x3a, 0x75, 0x2e, 0x52, 0x3d, 0x65, 0x3a, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x5f, 0x3d, 0x65, 0x2c, 0x69, 0x26, 0x26, 0x6f, + 0x3f, 0x28, 0x72, 0x3d, 0x65, 0x2e, 0x43, 0x2c, 0x65, 0x2e, 0x43, + 0x3d, 0x6e, 0x2e, 0x43, 0x2c, 0x65, 0x2e, 0x4c, 0x3d, 0x69, 0x2c, + 0x69, 0x2e, 0x55, 0x3d, 0x65, 0x2c, 0x65, 0x21, 0x3d, 0x3d, 0x6f, + 0x3f, 0x28, 0x75, 0x3d, 0x65, 0x2e, 0x55, 0x2c, 0x65, 0x2e, 0x55, + 0x3d, 0x6e, 0x2e, 0x55, 0x2c, 0x6e, 0x3d, 0x65, 0x2e, 0x52, 0x2c, + 0x75, 0x2e, 0x4c, 0x3d, 0x6e, 0x2c, 0x65, 0x2e, 0x52, 0x3d, 0x6f, + 0x2c, 0x6f, 0x2e, 0x55, 0x3d, 0x65, 0x29, 0x3a, 0x28, 0x65, 0x2e, + 0x55, 0x3d, 0x75, 0x2c, 0x75, 0x3d, 0x65, 0x2c, 0x6e, 0x3d, 0x65, + 0x2e, 0x52, 0x29, 0x29, 0x3a, 0x28, 0x72, 0x3d, 0x6e, 0x2e, 0x43, + 0x2c, 0x6e, 0x3d, 0x65, 0x29, 0x2c, 0x6e, 0x26, 0x26, 0x28, 0x6e, + 0x2e, 0x55, 0x3d, 0x75, 0x29, 0x2c, 0x21, 0x72, 0x29, 0x7b, 0x69, + 0x66, 0x28, 0x6e, 0x26, 0x26, 0x6e, 0x2e, 0x43, 0x29, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x6e, + 0x2e, 0x43, 0x3d, 0x21, 0x31, 0x29, 0x3b, 0x64, 0x6f, 0x7b, 0x69, + 0x66, 0x28, 0x6e, 0x3d, 0x3d, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x5f, 0x29, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x69, 0x66, 0x28, + 0x6e, 0x3d, 0x3d, 0x3d, 0x75, 0x2e, 0x4c, 0x29, 0x7b, 0x69, 0x66, + 0x28, 0x74, 0x3d, 0x75, 0x2e, 0x52, 0x2c, 0x74, 0x2e, 0x43, 0x26, + 0x26, 0x28, 0x74, 0x2e, 0x43, 0x3d, 0x21, 0x31, 0x2c, 0x75, 0x2e, + 0x43, 0x3d, 0x21, 0x30, 0x2c, 0x65, 0x75, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x75, 0x29, 0x2c, 0x74, 0x3d, 0x75, 0x2e, 0x52, 0x29, + 0x2c, 0x74, 0x2e, 0x4c, 0x26, 0x26, 0x74, 0x2e, 0x4c, 0x2e, 0x43, + 0x7c, 0x7c, 0x74, 0x2e, 0x52, 0x26, 0x26, 0x74, 0x2e, 0x52, 0x2e, + 0x43, 0x29, 0x7b, 0x74, 0x2e, 0x52, 0x26, 0x26, 0x74, 0x2e, 0x52, + 0x2e, 0x43, 0x7c, 0x7c, 0x28, 0x74, 0x2e, 0x4c, 0x2e, 0x43, 0x3d, + 0x21, 0x31, 0x2c, 0x74, 0x2e, 0x43, 0x3d, 0x21, 0x30, 0x2c, 0x72, + 0x75, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x74, 0x29, 0x2c, 0x74, + 0x3d, 0x75, 0x2e, 0x52, 0x29, 0x2c, 0x74, 0x2e, 0x43, 0x3d, 0x75, + 0x2e, 0x43, 0x2c, 0x75, 0x2e, 0x43, 0x3d, 0x74, 0x2e, 0x52, 0x2e, + 0x43, 0x3d, 0x21, 0x31, 0x2c, 0x65, 0x75, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x75, 0x29, 0x2c, 0x6e, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x5f, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x7d, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x75, 0x2e, + 0x4c, 0x2c, 0x74, 0x2e, 0x43, 0x26, 0x26, 0x28, 0x74, 0x2e, 0x43, + 0x3d, 0x21, 0x31, 0x2c, 0x75, 0x2e, 0x43, 0x3d, 0x21, 0x30, 0x2c, + 0x72, 0x75, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x75, 0x29, 0x2c, + 0x74, 0x3d, 0x75, 0x2e, 0x4c, 0x29, 0x2c, 0x74, 0x2e, 0x4c, 0x26, + 0x26, 0x74, 0x2e, 0x4c, 0x2e, 0x43, 0x7c, 0x7c, 0x74, 0x2e, 0x52, + 0x26, 0x26, 0x74, 0x2e, 0x52, 0x2e, 0x43, 0x29, 0x7b, 0x74, 0x2e, + 0x4c, 0x26, 0x26, 0x74, 0x2e, 0x4c, 0x2e, 0x43, 0x7c, 0x7c, 0x28, + 0x74, 0x2e, 0x52, 0x2e, 0x43, 0x3d, 0x21, 0x31, 0x2c, 0x74, 0x2e, + 0x43, 0x3d, 0x21, 0x30, 0x2c, 0x65, 0x75, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x74, 0x29, 0x2c, 0x74, 0x3d, 0x75, 0x2e, 0x4c, 0x29, + 0x2c, 0x74, 0x2e, 0x43, 0x3d, 0x75, 0x2e, 0x43, 0x2c, 0x75, 0x2e, + 0x43, 0x3d, 0x74, 0x2e, 0x4c, 0x2e, 0x43, 0x3d, 0x21, 0x31, 0x2c, + 0x72, 0x75, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x75, 0x29, 0x2c, + 0x6e, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x3b, 0x62, 0x72, + 0x65, 0x61, 0x6b, 0x7d, 0x74, 0x2e, 0x43, 0x3d, 0x21, 0x30, 0x2c, + 0x6e, 0x3d, 0x75, 0x2c, 0x75, 0x3d, 0x75, 0x2e, 0x55, 0x7d, 0x77, + 0x68, 0x69, 0x6c, 0x65, 0x28, 0x21, 0x6e, 0x2e, 0x43, 0x29, 0x3b, + 0x6e, 0x26, 0x26, 0x28, 0x6e, 0x2e, 0x43, 0x3d, 0x21, 0x31, 0x29, + 0x7d, 0x7d, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x6d, + 0x2e, 0x76, 0x6f, 0x72, 0x6f, 0x6e, 0x6f, 0x69, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x65, 0x77, + 0x20, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x6e, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x29, 0x2c, 0x72, 0x3d, 0x61, 0x5b, 0x30, + 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x3d, 0x61, 0x5b, 0x30, 0x5d, + 0x5b, 0x31, 0x5d, 0x2c, 0x69, 0x3d, 0x61, 0x5b, 0x31, 0x5d, 0x5b, + 0x30, 0x5d, 0x2c, 0x6f, 0x3d, 0x61, 0x5b, 0x31, 0x5d, 0x5b, 0x31, + 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x75, + 0x28, 0x65, 0x28, 0x6e, 0x29, 0x2c, 0x61, 0x29, 0x2e, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, + 0x2c, 0x61, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, 0x65, + 0x2e, 0x65, 0x64, 0x67, 0x65, 0x73, 0x2c, 0x6c, 0x3d, 0x65, 0x2e, + 0x73, 0x69, 0x74, 0x65, 0x2c, 0x73, 0x3d, 0x74, 0x5b, 0x61, 0x5d, + 0x3d, 0x63, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x63, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x3d, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x74, 0x2e, 0x78, 0x2c, + 0x74, 0x2e, 0x79, 0x5d, 0x7d, 0x29, 0x3a, 0x6c, 0x2e, 0x78, 0x3e, + 0x3d, 0x72, 0x26, 0x26, 0x6c, 0x2e, 0x78, 0x3c, 0x3d, 0x69, 0x26, + 0x26, 0x6c, 0x2e, 0x79, 0x3e, 0x3d, 0x75, 0x26, 0x26, 0x6c, 0x2e, + 0x79, 0x3c, 0x3d, 0x6f, 0x3f, 0x5b, 0x5b, 0x72, 0x2c, 0x6f, 0x5d, + 0x2c, 0x5b, 0x69, 0x2c, 0x6f, 0x5d, 0x2c, 0x5b, 0x69, 0x2c, 0x75, + 0x5d, 0x2c, 0x5b, 0x72, 0x2c, 0x75, 0x5d, 0x5d, 0x3a, 0x5b, 0x5d, + 0x3b, 0x73, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, 0x5b, + 0x61, 0x5d, 0x7d, 0x29, 0x2c, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, + 0x78, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x28, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x2f, 0x43, 0x61, + 0x29, 0x2a, 0x43, 0x61, 0x2c, 0x79, 0x3a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x28, 0x6f, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x2f, 0x43, 0x61, 0x29, 0x2a, 0x43, 0x61, 0x2c, 0x69, + 0x3a, 0x74, 0x7d, 0x7d, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x3d, 0x41, 0x72, 0x2c, 0x75, 0x3d, 0x4e, 0x72, 0x2c, 0x69, 0x3d, + 0x72, 0x2c, 0x6f, 0x3d, 0x75, 0x2c, 0x61, 0x3d, 0x75, 0x6c, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3f, 0x74, 0x28, + 0x6e, 0x29, 0x3a, 0x28, 0x74, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x73, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x75, + 0x28, 0x65, 0x28, 0x6e, 0x29, 0x29, 0x2e, 0x65, 0x64, 0x67, 0x65, + 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x6c, 0x26, 0x26, + 0x6e, 0x2e, 0x72, 0x7d, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x3a, 0x6e, 0x5b, 0x74, 0x2e, 0x6c, 0x2e, 0x69, 0x5d, + 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x6e, 0x5b, 0x74, + 0x2e, 0x72, 0x2e, 0x69, 0x5d, 0x7d, 0x7d, 0x29, 0x7d, 0x2c, 0x74, + 0x2e, 0x74, 0x72, 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x73, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x5b, 0x5d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x75, 0x28, 0x65, 0x28, + 0x6e, 0x29, 0x29, 0x2e, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x2e, 0x66, + 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, 0x69, 0x2c, + 0x6f, 0x3d, 0x65, 0x2e, 0x73, 0x69, 0x74, 0x65, 0x2c, 0x61, 0x3d, + 0x65, 0x2e, 0x65, 0x64, 0x67, 0x65, 0x73, 0x2e, 0x73, 0x6f, 0x72, + 0x74, 0x28, 0x59, 0x72, 0x29, 0x2c, 0x63, 0x3d, 0x2d, 0x31, 0x2c, + 0x6c, 0x3d, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, + 0x73, 0x3d, 0x61, 0x5b, 0x6c, 0x2d, 0x31, 0x5d, 0x2e, 0x65, 0x64, + 0x67, 0x65, 0x2c, 0x66, 0x3d, 0x73, 0x2e, 0x6c, 0x3d, 0x3d, 0x3d, + 0x6f, 0x3f, 0x73, 0x2e, 0x72, 0x3a, 0x73, 0x2e, 0x6c, 0x3b, 0x2b, + 0x2b, 0x63, 0x3c, 0x6c, 0x3b, 0x29, 0x75, 0x3d, 0x73, 0x2c, 0x69, + 0x3d, 0x66, 0x2c, 0x73, 0x3d, 0x61, 0x5b, 0x63, 0x5d, 0x2e, 0x65, + 0x64, 0x67, 0x65, 0x2c, 0x66, 0x3d, 0x73, 0x2e, 0x6c, 0x3d, 0x3d, + 0x3d, 0x6f, 0x3f, 0x73, 0x2e, 0x72, 0x3a, 0x73, 0x2e, 0x6c, 0x2c, + 0x72, 0x3c, 0x69, 0x2e, 0x69, 0x26, 0x26, 0x72, 0x3c, 0x66, 0x2e, + 0x69, 0x26, 0x26, 0x61, 0x75, 0x28, 0x6f, 0x2c, 0x69, 0x2c, 0x66, + 0x29, 0x3c, 0x30, 0x26, 0x26, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x5b, 0x6e, 0x5b, 0x72, 0x5d, 0x2c, 0x6e, 0x5b, 0x69, 0x2e, + 0x69, 0x5d, 0x2c, 0x6e, 0x5b, 0x66, 0x2e, 0x69, 0x5d, 0x5d, 0x29, + 0x7d, 0x29, 0x2c, 0x74, 0x7d, 0x2c, 0x74, 0x2e, 0x78, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x69, 0x3d, 0x45, 0x74, 0x28, 0x72, 0x3d, 0x6e, + 0x29, 0x2c, 0x74, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x74, 0x2e, 0x79, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6f, 0x3d, 0x45, 0x74, 0x28, 0x75, + 0x3d, 0x6e, 0x29, 0x2c, 0x74, 0x29, 0x3a, 0x75, 0x7d, 0x2c, 0x74, + 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x74, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x61, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x3d, 0x3d, 0x6e, 0x3f, 0x75, 0x6c, 0x3a, 0x6e, 0x2c, 0x74, 0x29, + 0x3a, 0x61, 0x3d, 0x3d, 0x3d, 0x75, 0x6c, 0x3f, 0x6e, 0x75, 0x6c, + 0x6c, 0x3a, 0x61, 0x7d, 0x2c, 0x74, 0x2e, 0x73, 0x69, 0x7a, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x74, 0x2e, 0x63, 0x6c, 0x69, 0x70, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x74, 0x28, 0x6e, 0x26, 0x26, 0x5b, 0x5b, + 0x30, 0x2c, 0x30, 0x5d, 0x2c, 0x6e, 0x5d, 0x29, 0x3a, 0x61, 0x3d, + 0x3d, 0x3d, 0x75, 0x6c, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x61, + 0x26, 0x26, 0x61, 0x5b, 0x31, 0x5d, 0x7d, 0x2c, 0x74, 0x29, 0x7d, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x6c, 0x3d, 0x5b, 0x5b, 0x2d, + 0x31, 0x65, 0x36, 0x2c, 0x2d, 0x31, 0x65, 0x36, 0x5d, 0x2c, 0x5b, + 0x31, 0x65, 0x36, 0x2c, 0x31, 0x65, 0x36, 0x5d, 0x5d, 0x3b, 0x74, + 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x6d, 0x2e, 0x64, 0x65, 0x6c, 0x61, + 0x75, 0x6e, 0x61, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x6d, 0x2e, 0x76, + 0x6f, 0x72, 0x6f, 0x6e, 0x6f, 0x69, 0x28, 0x29, 0x2e, 0x74, 0x72, + 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x73, 0x28, 0x6e, 0x29, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x6d, 0x2e, 0x71, 0x75, + 0x61, 0x64, 0x74, 0x72, 0x65, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x2c, 0x75, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x6e, 0x2c, 0x74, + 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, + 0x61, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x69, 0x73, 0x4e, 0x61, + 0x4e, 0x28, 0x65, 0x29, 0x26, 0x26, 0x21, 0x69, 0x73, 0x4e, 0x61, + 0x4e, 0x28, 0x72, 0x29, 0x29, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x6c, + 0x65, 0x61, 0x66, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x3d, + 0x6e, 0x2e, 0x78, 0x2c, 0x73, 0x3d, 0x6e, 0x2e, 0x79, 0x3b, 0x69, + 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x63, 0x29, 0x69, + 0x66, 0x28, 0x67, 0x61, 0x28, 0x63, 0x2d, 0x65, 0x29, 0x2b, 0x67, + 0x61, 0x28, 0x73, 0x2d, 0x72, 0x29, 0x3c, 0x2e, 0x30, 0x31, 0x29, + 0x6c, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, + 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, 0x29, 0x3b, 0x65, 0x6c, 0x73, + 0x65, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x66, 0x3d, 0x6e, 0x2e, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x3b, 0x6e, 0x2e, 0x78, 0x3d, 0x6e, 0x2e, + 0x79, 0x3d, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x6c, 0x28, 0x6e, 0x2c, 0x66, 0x2c, 0x63, + 0x2c, 0x73, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, 0x29, + 0x2c, 0x6c, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, + 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, 0x29, 0x7d, 0x65, 0x6c, + 0x73, 0x65, 0x20, 0x6e, 0x2e, 0x78, 0x3d, 0x65, 0x2c, 0x6e, 0x2e, + 0x79, 0x3d, 0x72, 0x2c, 0x6e, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x3d, 0x74, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6c, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, + 0x6f, 0x2c, 0x61, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6c, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x2c, 0x75, 0x2c, 0x6f, 0x2c, 0x61, 0x2c, 0x63, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x2e, 0x35, 0x2a, 0x28, 0x75, + 0x2b, 0x61, 0x29, 0x2c, 0x73, 0x3d, 0x2e, 0x35, 0x2a, 0x28, 0x6f, + 0x2b, 0x63, 0x29, 0x2c, 0x66, 0x3d, 0x65, 0x3e, 0x3d, 0x6c, 0x2c, + 0x68, 0x3d, 0x72, 0x3e, 0x3d, 0x73, 0x2c, 0x67, 0x3d, 0x68, 0x3c, + 0x3c, 0x31, 0x7c, 0x66, 0x3b, 0x6e, 0x2e, 0x6c, 0x65, 0x61, 0x66, + 0x3d, 0x21, 0x31, 0x2c, 0x6e, 0x3d, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x73, 0x5b, 0x67, 0x5d, 0x7c, 0x7c, 0x28, 0x6e, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x73, 0x5b, 0x67, 0x5d, 0x3d, 0x73, 0x75, 0x28, + 0x29, 0x29, 0x2c, 0x66, 0x3f, 0x75, 0x3d, 0x6c, 0x3a, 0x61, 0x3d, + 0x6c, 0x2c, 0x68, 0x3f, 0x6f, 0x3d, 0x73, 0x3a, 0x63, 0x3d, 0x73, + 0x2c, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, + 0x75, 0x2c, 0x6f, 0x2c, 0x61, 0x2c, 0x63, 0x29, 0x7d, 0x76, 0x61, + 0x72, 0x20, 0x73, 0x2c, 0x66, 0x2c, 0x68, 0x2c, 0x67, 0x2c, 0x70, + 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x79, 0x2c, 0x4d, 0x3d, + 0x45, 0x74, 0x28, 0x61, 0x29, 0x2c, 0x78, 0x3d, 0x45, 0x74, 0x28, + 0x63, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x21, + 0x3d, 0x74, 0x29, 0x76, 0x3d, 0x74, 0x2c, 0x64, 0x3d, 0x65, 0x2c, + 0x6d, 0x3d, 0x72, 0x2c, 0x79, 0x3d, 0x75, 0x3b, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x69, 0x66, 0x28, 0x6d, 0x3d, 0x79, 0x3d, 0x2d, 0x28, + 0x76, 0x3d, 0x64, 0x3d, 0x31, 0x2f, 0x30, 0x29, 0x2c, 0x66, 0x3d, + 0x5b, 0x5d, 0x2c, 0x68, 0x3d, 0x5b, 0x5d, 0x2c, 0x70, 0x3d, 0x6e, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x6f, 0x29, 0x66, + 0x6f, 0x72, 0x28, 0x67, 0x3d, 0x30, 0x3b, 0x70, 0x3e, 0x67, 0x3b, + 0x2b, 0x2b, 0x67, 0x29, 0x73, 0x3d, 0x6e, 0x5b, 0x67, 0x5d, 0x2c, + 0x73, 0x2e, 0x78, 0x3c, 0x76, 0x26, 0x26, 0x28, 0x76, 0x3d, 0x73, + 0x2e, 0x78, 0x29, 0x2c, 0x73, 0x2e, 0x79, 0x3c, 0x64, 0x26, 0x26, + 0x28, 0x64, 0x3d, 0x73, 0x2e, 0x79, 0x29, 0x2c, 0x73, 0x2e, 0x78, + 0x3e, 0x6d, 0x26, 0x26, 0x28, 0x6d, 0x3d, 0x73, 0x2e, 0x78, 0x29, + 0x2c, 0x73, 0x2e, 0x79, 0x3e, 0x79, 0x26, 0x26, 0x28, 0x79, 0x3d, + 0x73, 0x2e, 0x79, 0x29, 0x2c, 0x66, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x73, 0x2e, 0x78, 0x29, 0x2c, 0x68, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x73, 0x2e, 0x79, 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x28, 0x67, 0x3d, 0x30, 0x3b, 0x70, 0x3e, + 0x67, 0x3b, 0x2b, 0x2b, 0x67, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x62, 0x3d, 0x2b, 0x4d, 0x28, 0x73, 0x3d, 0x6e, 0x5b, 0x67, 0x5d, + 0x2c, 0x67, 0x29, 0x2c, 0x5f, 0x3d, 0x2b, 0x78, 0x28, 0x73, 0x2c, + 0x67, 0x29, 0x3b, 0x76, 0x3e, 0x62, 0x26, 0x26, 0x28, 0x76, 0x3d, + 0x62, 0x29, 0x2c, 0x64, 0x3e, 0x5f, 0x26, 0x26, 0x28, 0x64, 0x3d, + 0x5f, 0x29, 0x2c, 0x62, 0x3e, 0x6d, 0x26, 0x26, 0x28, 0x6d, 0x3d, + 0x62, 0x29, 0x2c, 0x5f, 0x3e, 0x79, 0x26, 0x26, 0x28, 0x79, 0x3d, + 0x5f, 0x29, 0x2c, 0x66, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x62, + 0x29, 0x2c, 0x68, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x5f, 0x29, + 0x7d, 0x76, 0x61, 0x72, 0x20, 0x77, 0x3d, 0x6d, 0x2d, 0x76, 0x2c, + 0x53, 0x3d, 0x79, 0x2d, 0x64, 0x3b, 0x77, 0x3e, 0x53, 0x3f, 0x79, + 0x3d, 0x64, 0x2b, 0x77, 0x3a, 0x6d, 0x3d, 0x76, 0x2b, 0x53, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x6b, 0x3d, 0x73, 0x75, 0x28, 0x29, 0x3b, + 0x69, 0x66, 0x28, 0x6b, 0x2e, 0x61, 0x64, 0x64, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x69, + 0x28, 0x6b, 0x2c, 0x6e, 0x2c, 0x2b, 0x4d, 0x28, 0x6e, 0x2c, 0x2b, + 0x2b, 0x67, 0x29, 0x2c, 0x2b, 0x78, 0x28, 0x6e, 0x2c, 0x67, 0x29, + 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x79, 0x29, 0x7d, 0x2c, + 0x6b, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x74, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x75, + 0x28, 0x6e, 0x2c, 0x6b, 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x2c, + 0x79, 0x29, 0x7d, 0x2c, 0x6b, 0x2e, 0x66, 0x69, 0x6e, 0x64, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, 0x75, 0x28, + 0x6b, 0x2c, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, + 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x79, 0x29, 0x7d, 0x2c, + 0x67, 0x3d, 0x2d, 0x31, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, + 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x2b, 0x2b, 0x67, + 0x3c, 0x70, 0x3b, 0x29, 0x69, 0x28, 0x6b, 0x2c, 0x6e, 0x5b, 0x67, + 0x5d, 0x2c, 0x66, 0x5b, 0x67, 0x5d, 0x2c, 0x68, 0x5b, 0x67, 0x5d, + 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x79, 0x29, 0x3b, 0x2d, + 0x2d, 0x67, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x2e, 0x66, + 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x6b, 0x2e, 0x61, 0x64, + 0x64, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x3d, 0x68, 0x3d, 0x6e, 0x3d, 0x73, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x2c, 0x6b, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x2c, 0x61, 0x3d, + 0x41, 0x72, 0x2c, 0x63, 0x3d, 0x4e, 0x72, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x28, 0x6f, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x3f, 0x28, 0x61, 0x3d, 0x63, 0x75, 0x2c, 0x63, 0x3d, 0x6c, + 0x75, 0x2c, 0x33, 0x3d, 0x3d, 0x3d, 0x6f, 0x26, 0x26, 0x28, 0x75, + 0x3d, 0x65, 0x2c, 0x72, 0x3d, 0x74, 0x2c, 0x65, 0x3d, 0x74, 0x3d, + 0x30, 0x29, 0x2c, 0x69, 0x28, 0x6e, 0x29, 0x29, 0x3a, 0x28, 0x69, + 0x2e, 0x78, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x61, 0x3d, 0x6e, 0x2c, + 0x69, 0x29, 0x3a, 0x61, 0x7d, 0x2c, 0x69, 0x2e, 0x79, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x63, 0x3d, 0x6e, 0x2c, 0x69, 0x29, 0x3a, 0x63, + 0x7d, 0x2c, 0x69, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, + 0x3f, 0x74, 0x3d, 0x65, 0x3d, 0x72, 0x3d, 0x75, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x3a, 0x28, 0x74, 0x3d, 0x2b, 0x6e, 0x5b, 0x30, 0x5d, + 0x5b, 0x30, 0x5d, 0x2c, 0x65, 0x3d, 0x2b, 0x6e, 0x5b, 0x30, 0x5d, + 0x5b, 0x31, 0x5d, 0x2c, 0x72, 0x3d, 0x2b, 0x6e, 0x5b, 0x31, 0x5d, + 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x3d, 0x2b, 0x6e, 0x5b, 0x31, 0x5d, + 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x69, 0x29, 0x3a, 0x6e, 0x75, 0x6c, + 0x6c, 0x3d, 0x3d, 0x74, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x5b, + 0x5b, 0x74, 0x2c, 0x65, 0x5d, 0x2c, 0x5b, 0x72, 0x2c, 0x75, 0x5d, + 0x5d, 0x7d, 0x2c, 0x69, 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x3f, + 0x74, 0x3d, 0x65, 0x3d, 0x72, 0x3d, 0x75, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x3a, 0x28, 0x74, 0x3d, 0x65, 0x3d, 0x30, 0x2c, 0x72, 0x3d, + 0x2b, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x3d, 0x2b, 0x6e, 0x5b, + 0x31, 0x5d, 0x29, 0x2c, 0x69, 0x29, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, + 0x3d, 0x3d, 0x74, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x5b, 0x72, + 0x2d, 0x74, 0x2c, 0x75, 0x2d, 0x65, 0x5d, 0x7d, 0x2c, 0x69, 0x29, + 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, + 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x67, 0x62, 0x3d, 0x67, 0x75, + 0x2c, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, + 0x6c, 0x61, 0x74, 0x65, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3d, + 0x70, 0x75, 0x2c, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x3d, 0x76, 0x75, 0x2c, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x3d, 0x64, 0x75, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x69, 0x6c, 0x3d, 0x2f, 0x5b, 0x2d, 0x2b, 0x5d, 0x3f, 0x28, 0x3f, + 0x3a, 0x5c, 0x64, 0x2b, 0x5c, 0x2e, 0x3f, 0x5c, 0x64, 0x2a, 0x7c, + 0x5c, 0x2e, 0x3f, 0x5c, 0x64, 0x2b, 0x29, 0x28, 0x3f, 0x3a, 0x5b, + 0x65, 0x45, 0x5d, 0x5b, 0x2d, 0x2b, 0x5d, 0x3f, 0x5c, 0x64, 0x2b, + 0x29, 0x3f, 0x2f, 0x67, 0x2c, 0x6f, 0x6c, 0x3d, 0x6e, 0x65, 0x77, + 0x20, 0x52, 0x65, 0x67, 0x45, 0x78, 0x70, 0x28, 0x69, 0x6c, 0x2e, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2c, 0x22, 0x67, 0x22, 0x29, + 0x3b, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, + 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x6d, 0x75, 0x2c, 0x74, 0x61, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x6f, + 0x72, 0x73, 0x3d, 0x5b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x22, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x22, 0x3d, 0x3d, 0x3d, 0x65, 0x3f, 0x47, 0x61, + 0x2e, 0x68, 0x61, 0x73, 0x28, 0x74, 0x2e, 0x74, 0x6f, 0x4c, 0x6f, + 0x77, 0x65, 0x72, 0x43, 0x61, 0x73, 0x65, 0x28, 0x29, 0x29, 0x7c, + 0x7c, 0x2f, 0x5e, 0x28, 0x23, 0x7c, 0x72, 0x67, 0x62, 0x5c, 0x28, + 0x7c, 0x68, 0x73, 0x6c, 0x5c, 0x28, 0x29, 0x2f, 0x69, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x28, 0x74, 0x29, 0x3f, 0x67, 0x75, 0x3a, 0x64, + 0x75, 0x3a, 0x74, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, + 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x74, 0x3f, 0x67, 0x75, 0x3a, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x2e, 0x69, 0x73, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x28, 0x74, 0x29, 0x3f, 0x79, 0x75, 0x3a, 0x22, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3d, 0x3d, 0x3d, 0x65, 0x26, 0x26, + 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x74, 0x29, 0x3f, 0x70, 0x75, + 0x3a, 0x76, 0x75, 0x29, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x5d, + 0x2c, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, + 0x6c, 0x61, 0x74, 0x65, 0x41, 0x72, 0x72, 0x61, 0x79, 0x3d, 0x79, + 0x75, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x6c, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x79, 0x7d, 0x2c, 0x63, 0x6c, 0x3d, + 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x7b, 0x6c, 0x69, 0x6e, + 0x65, 0x61, 0x72, 0x3a, 0x61, 0x6c, 0x2c, 0x70, 0x6f, 0x6c, 0x79, + 0x3a, 0x6b, 0x75, 0x2c, 0x71, 0x75, 0x61, 0x64, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5f, 0x75, 0x7d, 0x2c, 0x63, 0x75, + 0x62, 0x69, 0x63, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x77, 0x75, 0x7d, 0x2c, 0x73, 0x69, 0x6e, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x45, 0x75, 0x7d, 0x2c, 0x65, 0x78, 0x70, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x41, 0x75, 0x7d, + 0x2c, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x4e, 0x75, 0x7d, 0x2c, 0x65, 0x6c, 0x61, + 0x73, 0x74, 0x69, 0x63, 0x3a, 0x43, 0x75, 0x2c, 0x62, 0x61, 0x63, + 0x6b, 0x3a, 0x7a, 0x75, 0x2c, 0x62, 0x6f, 0x75, 0x6e, 0x63, 0x65, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x71, 0x75, 0x7d, + 0x7d, 0x29, 0x2c, 0x6c, 0x6c, 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x61, + 0x70, 0x28, 0x7b, 0x22, 0x69, 0x6e, 0x22, 0x3a, 0x79, 0x2c, 0x6f, + 0x75, 0x74, 0x3a, 0x78, 0x75, 0x2c, 0x22, 0x69, 0x6e, 0x2d, 0x6f, + 0x75, 0x74, 0x22, 0x3a, 0x62, 0x75, 0x2c, 0x22, 0x6f, 0x75, 0x74, + 0x2d, 0x69, 0x6e, 0x22, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x62, 0x75, 0x28, 0x78, 0x75, 0x28, 0x6e, 0x29, 0x29, + 0x7d, 0x7d, 0x29, 0x3b, 0x74, 0x61, 0x2e, 0x65, 0x61, 0x73, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x2d, 0x22, 0x29, + 0x2c, 0x65, 0x3d, 0x74, 0x3e, 0x3d, 0x30, 0x3f, 0x6e, 0x2e, 0x73, + 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x74, 0x29, 0x3a, 0x6e, + 0x2c, 0x72, 0x3d, 0x74, 0x3e, 0x3d, 0x30, 0x3f, 0x6e, 0x2e, 0x73, + 0x6c, 0x69, 0x63, 0x65, 0x28, 0x74, 0x2b, 0x31, 0x29, 0x3a, 0x22, + 0x69, 0x6e, 0x22, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x3d, 0x63, 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x65, 0x29, + 0x7c, 0x7c, 0x61, 0x6c, 0x2c, 0x72, 0x3d, 0x6c, 0x6c, 0x2e, 0x67, + 0x65, 0x74, 0x28, 0x72, 0x29, 0x7c, 0x7c, 0x79, 0x2c, 0x4d, 0x75, + 0x28, 0x72, 0x28, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x65, 0x61, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2c, 0x31, 0x29, 0x29, 0x29, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, + 0x48, 0x63, 0x6c, 0x3d, 0x4c, 0x75, 0x2c, 0x74, 0x61, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x48, + 0x73, 0x6c, 0x3d, 0x54, 0x75, 0x2c, 0x74, 0x61, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x4c, 0x61, + 0x62, 0x3d, 0x52, 0x75, 0x2c, 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x70, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x75, + 0x6e, 0x64, 0x3d, 0x44, 0x75, 0x2c, 0x74, 0x61, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x75, 0x61, 0x2e, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x53, + 0x28, 0x74, 0x61, 0x2e, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x2e, 0x73, 0x76, 0x67, 0x2c, 0x22, 0x67, 0x22, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x74, 0x61, 0x2e, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x69, 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x6e, 0x29, + 0x7b, 0x74, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x28, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x2c, 0x6e, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x74, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x56, 0x61, + 0x6c, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x69, 0x64, 0x61, + 0x74, 0x65, 0x28, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6e, 0x65, 0x77, 0x20, 0x50, 0x75, 0x28, 0x65, 0x3f, 0x65, + 0x2e, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x3a, 0x73, 0x6c, 0x29, + 0x7d, 0x29, 0x28, 0x6e, 0x29, 0x7d, 0x2c, 0x50, 0x75, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x2e, 0x74, 0x6f, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, + 0x65, 0x28, 0x22, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, 0x2b, 0x22, 0x29, 0x72, + 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x22, 0x2b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x2b, 0x22, 0x29, + 0x73, 0x6b, 0x65, 0x77, 0x58, 0x28, 0x22, 0x2b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x6b, 0x65, 0x77, 0x2b, 0x22, 0x29, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x28, 0x22, 0x2b, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2b, 0x22, 0x29, 0x22, 0x7d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x73, 0x6c, 0x3d, 0x7b, 0x61, 0x3a, 0x31, + 0x2c, 0x62, 0x3a, 0x30, 0x2c, 0x63, 0x3a, 0x30, 0x2c, 0x64, 0x3a, + 0x31, 0x2c, 0x65, 0x3a, 0x30, 0x2c, 0x66, 0x3a, 0x30, 0x7d, 0x3b, + 0x74, 0x61, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x6f, 0x6c, + 0x61, 0x74, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, + 0x6d, 0x3d, 0x48, 0x75, 0x2c, 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x79, + 0x6f, 0x75, 0x74, 0x3d, 0x7b, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x6c, + 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x62, 0x75, 0x6e, 0x64, 0x6c, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x5b, 0x5d, + 0x2c, 0x65, 0x3d, 0x2d, 0x31, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x72, + 0x3b, 0x29, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x59, 0x75, + 0x28, 0x6e, 0x5b, 0x65, 0x5d, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x63, 0x68, 0x6f, 0x72, + 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x2c, 0x6c, + 0x2c, 0x66, 0x2c, 0x68, 0x2c, 0x67, 0x2c, 0x70, 0x3d, 0x7b, 0x7d, + 0x2c, 0x76, 0x3d, 0x5b, 0x5d, 0x2c, 0x64, 0x3d, 0x74, 0x61, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x69, 0x29, 0x2c, 0x6d, 0x3d, + 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x5b, 0x5d, + 0x2c, 0x72, 0x3d, 0x5b, 0x5d, 0x2c, 0x6e, 0x3d, 0x30, 0x2c, 0x68, + 0x3d, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x68, 0x3c, 0x69, 0x3b, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x3d, 0x30, 0x2c, 0x67, 0x3d, + 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x67, 0x3c, 0x69, 0x3b, 0x29, 0x6c, + 0x2b, 0x3d, 0x75, 0x5b, 0x68, 0x5d, 0x5b, 0x67, 0x5d, 0x3b, 0x76, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6c, 0x29, 0x2c, 0x6d, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x61, 0x2e, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x28, 0x69, 0x29, 0x29, 0x2c, 0x6e, 0x2b, 0x3d, 0x6c, + 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x6f, 0x26, 0x26, 0x64, 0x2e, 0x73, + 0x6f, 0x72, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6f, 0x28, 0x76, 0x5b, 0x6e, 0x5d, 0x2c, 0x76, + 0x5b, 0x74, 0x5d, 0x29, 0x7d, 0x29, 0x2c, 0x61, 0x26, 0x26, 0x6d, + 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x6e, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x28, 0x75, 0x5b, + 0x74, 0x5d, 0x5b, 0x6e, 0x5d, 0x2c, 0x75, 0x5b, 0x74, 0x5d, 0x5b, + 0x65, 0x5d, 0x29, 0x7d, 0x29, 0x7d, 0x29, 0x2c, 0x6e, 0x3d, 0x28, + 0x4c, 0x61, 0x2d, 0x73, 0x2a, 0x69, 0x29, 0x2f, 0x6e, 0x2c, 0x6c, + 0x3d, 0x30, 0x2c, 0x68, 0x3d, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x68, + 0x3c, 0x69, 0x3b, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x66, 0x3d, + 0x6c, 0x2c, 0x67, 0x3d, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x67, 0x3c, + 0x69, 0x3b, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x79, 0x3d, 0x64, + 0x5b, 0x68, 0x5d, 0x2c, 0x4d, 0x3d, 0x6d, 0x5b, 0x79, 0x5d, 0x5b, + 0x67, 0x5d, 0x2c, 0x78, 0x3d, 0x75, 0x5b, 0x79, 0x5d, 0x5b, 0x4d, + 0x5d, 0x2c, 0x62, 0x3d, 0x6c, 0x2c, 0x5f, 0x3d, 0x6c, 0x2b, 0x3d, + 0x78, 0x2a, 0x6e, 0x3b, 0x70, 0x5b, 0x79, 0x2b, 0x22, 0x2d, 0x22, + 0x2b, 0x4d, 0x5d, 0x3d, 0x7b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, + 0x79, 0x2c, 0x73, 0x75, 0x62, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3a, + 0x4d, 0x2c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x41, 0x6e, 0x67, 0x6c, + 0x65, 0x3a, 0x62, 0x2c, 0x65, 0x6e, 0x64, 0x41, 0x6e, 0x67, 0x6c, + 0x65, 0x3a, 0x5f, 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x78, + 0x7d, 0x7d, 0x72, 0x5b, 0x79, 0x5d, 0x3d, 0x7b, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x3a, 0x79, 0x2c, 0x73, 0x74, 0x61, 0x72, 0x74, 0x41, + 0x6e, 0x67, 0x6c, 0x65, 0x3a, 0x66, 0x2c, 0x65, 0x6e, 0x64, 0x41, + 0x6e, 0x67, 0x6c, 0x65, 0x3a, 0x6c, 0x2c, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x28, 0x6c, 0x2d, 0x66, 0x29, 0x2f, 0x6e, 0x7d, 0x2c, + 0x6c, 0x2b, 0x3d, 0x73, 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x68, 0x3d, + 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x68, 0x3c, 0x69, 0x3b, 0x29, 0x66, + 0x6f, 0x72, 0x28, 0x67, 0x3d, 0x68, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, + 0x67, 0x3c, 0x69, 0x3b, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x77, + 0x3d, 0x70, 0x5b, 0x68, 0x2b, 0x22, 0x2d, 0x22, 0x2b, 0x67, 0x5d, + 0x2c, 0x53, 0x3d, 0x70, 0x5b, 0x67, 0x2b, 0x22, 0x2d, 0x22, 0x2b, + 0x68, 0x5d, 0x3b, 0x28, 0x77, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x7c, 0x7c, 0x53, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x26, + 0x26, 0x65, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x77, 0x2e, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3c, 0x53, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3f, 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x53, + 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x77, 0x7d, 0x3a, + 0x7b, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3a, 0x77, 0x2c, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x3a, 0x53, 0x7d, 0x29, 0x7d, 0x63, + 0x26, 0x26, 0x74, 0x28, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x29, 0x7b, 0x65, 0x2e, 0x73, + 0x6f, 0x72, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x63, 0x28, 0x28, 0x6e, 0x2e, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2b, 0x6e, + 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x29, 0x2f, 0x32, 0x2c, 0x28, 0x74, 0x2e, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2b, + 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x29, 0x2f, 0x32, 0x29, 0x7d, 0x29, 0x7d, 0x76, + 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, + 0x6f, 0x2c, 0x61, 0x2c, 0x63, 0x2c, 0x6c, 0x3d, 0x7b, 0x7d, 0x2c, + 0x73, 0x3d, 0x30, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6c, 0x2e, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x69, 0x3d, 0x28, 0x75, 0x3d, 0x6e, 0x29, 0x26, 0x26, + 0x75, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x65, 0x3d, + 0x72, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6c, 0x29, 0x3a, 0x75, + 0x7d, 0x2c, 0x6c, 0x2e, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x73, 0x3d, 0x6e, 0x2c, 0x65, 0x3d, + 0x72, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6c, 0x29, 0x3a, 0x73, + 0x7d, 0x2c, 0x6c, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6f, 0x3d, 0x6e, + 0x2c, 0x65, 0x3d, 0x72, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6c, + 0x29, 0x3a, 0x6f, 0x7d, 0x2c, 0x6c, 0x2e, 0x73, 0x6f, 0x72, 0x74, + 0x53, 0x75, 0x62, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x61, 0x3d, 0x6e, 0x2c, 0x65, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x2c, 0x6c, 0x29, 0x3a, 0x61, 0x7d, 0x2c, 0x6c, 0x2e, + 0x73, 0x6f, 0x72, 0x74, 0x43, 0x68, 0x6f, 0x72, 0x64, 0x73, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x63, 0x3d, 0x6e, 0x2c, 0x65, 0x26, 0x26, + 0x74, 0x28, 0x29, 0x2c, 0x6c, 0x29, 0x3a, 0x63, 0x7d, 0x2c, 0x6c, + 0x2e, 0x63, 0x68, 0x6f, 0x72, 0x64, 0x73, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7c, 0x7c, 0x6e, 0x28, 0x29, 0x2c, + 0x65, 0x7d, 0x2c, 0x6c, 0x2e, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7c, 0x7c, + 0x6e, 0x28, 0x29, 0x2c, 0x72, 0x7d, 0x2c, 0x6c, 0x7d, 0x2c, 0x74, + 0x61, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x29, 0x7b, 0x69, + 0x66, 0x28, 0x74, 0x2e, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x21, 0x3d, + 0x3d, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x74, + 0x2e, 0x63, 0x78, 0x2d, 0x6e, 0x2e, 0x78, 0x2c, 0x6f, 0x3d, 0x74, + 0x2e, 0x63, 0x79, 0x2d, 0x6e, 0x2e, 0x79, 0x2c, 0x61, 0x3d, 0x75, + 0x2d, 0x65, 0x2c, 0x63, 0x3d, 0x69, 0x2a, 0x69, 0x2b, 0x6f, 0x2a, + 0x6f, 0x3b, 0x69, 0x66, 0x28, 0x63, 0x3e, 0x61, 0x2a, 0x61, 0x2f, + 0x64, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x70, 0x3e, 0x63, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x74, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x67, 0x65, 0x2f, 0x63, 0x3b, 0x6e, 0x2e, 0x70, 0x78, 0x2d, + 0x3d, 0x69, 0x2a, 0x6c, 0x2c, 0x6e, 0x2e, 0x70, 0x79, 0x2d, 0x3d, + 0x6f, 0x2a, 0x6c, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, + 0x30, 0x7d, 0x69, 0x66, 0x28, 0x74, 0x2e, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x26, 0x26, 0x63, 0x26, 0x26, 0x70, 0x3e, 0x63, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x74, 0x2e, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x2f, 0x63, 0x3b, + 0x6e, 0x2e, 0x70, 0x78, 0x2d, 0x3d, 0x69, 0x2a, 0x6c, 0x2c, 0x6e, + 0x2e, 0x70, 0x79, 0x2d, 0x3d, 0x6f, 0x2a, 0x6c, 0x7d, 0x7d, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x74, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x67, 0x65, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x70, + 0x78, 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, + 0x78, 0x2c, 0x6e, 0x2e, 0x70, 0x79, 0x3d, 0x74, 0x61, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x79, 0x2c, 0x61, 0x2e, 0x72, 0x65, + 0x73, 0x75, 0x6d, 0x65, 0x28, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, + 0x3d, 0x7b, 0x7d, 0x2c, 0x63, 0x3d, 0x74, 0x61, 0x2e, 0x64, 0x69, + 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x22, 0x2c, 0x22, 0x74, 0x69, 0x63, 0x6b, 0x22, 0x2c, + 0x22, 0x65, 0x6e, 0x64, 0x22, 0x29, 0x2c, 0x6c, 0x3d, 0x5b, 0x31, + 0x2c, 0x31, 0x5d, 0x2c, 0x73, 0x3d, 0x2e, 0x39, 0x2c, 0x66, 0x3d, + 0x66, 0x6c, 0x2c, 0x68, 0x3d, 0x68, 0x6c, 0x2c, 0x67, 0x3d, 0x2d, + 0x33, 0x30, 0x2c, 0x70, 0x3d, 0x67, 0x6c, 0x2c, 0x76, 0x3d, 0x2e, + 0x31, 0x2c, 0x64, 0x3d, 0x2e, 0x36, 0x34, 0x2c, 0x6d, 0x3d, 0x5b, + 0x5d, 0x2c, 0x4d, 0x3d, 0x5b, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x69, + 0x66, 0x28, 0x28, 0x72, 0x2a, 0x3d, 0x2e, 0x39, 0x39, 0x29, 0x3c, + 0x2e, 0x30, 0x30, 0x35, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x63, 0x2e, 0x65, 0x6e, 0x64, 0x28, 0x7b, 0x74, 0x79, 0x70, + 0x65, 0x3a, 0x22, 0x65, 0x6e, 0x64, 0x22, 0x2c, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x3a, 0x72, 0x3d, 0x30, 0x7d, 0x29, 0x2c, 0x21, 0x30, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x61, 0x2c, + 0x66, 0x2c, 0x68, 0x2c, 0x70, 0x2c, 0x64, 0x2c, 0x79, 0x2c, 0x78, + 0x2c, 0x62, 0x3d, 0x6d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x2c, 0x5f, 0x3d, 0x4d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x30, 0x3b, 0x5f, 0x3e, + 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x61, 0x3d, 0x4d, 0x5b, 0x65, + 0x5d, 0x2c, 0x66, 0x3d, 0x61, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2c, 0x68, 0x3d, 0x61, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x2c, 0x79, 0x3d, 0x68, 0x2e, 0x78, 0x2d, 0x66, 0x2e, 0x78, + 0x2c, 0x78, 0x3d, 0x68, 0x2e, 0x79, 0x2d, 0x66, 0x2e, 0x79, 0x2c, + 0x28, 0x70, 0x3d, 0x79, 0x2a, 0x79, 0x2b, 0x78, 0x2a, 0x78, 0x29, + 0x26, 0x26, 0x28, 0x70, 0x3d, 0x72, 0x2a, 0x69, 0x5b, 0x65, 0x5d, + 0x2a, 0x28, 0x28, 0x70, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x71, 0x72, 0x74, 0x28, 0x70, 0x29, 0x29, 0x2d, 0x75, 0x5b, 0x65, + 0x5d, 0x29, 0x2f, 0x70, 0x2c, 0x79, 0x2a, 0x3d, 0x70, 0x2c, 0x78, + 0x2a, 0x3d, 0x70, 0x2c, 0x68, 0x2e, 0x78, 0x2d, 0x3d, 0x79, 0x2a, + 0x28, 0x64, 0x3d, 0x66, 0x2e, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x2f, 0x28, 0x68, 0x2e, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2b, + 0x66, 0x2e, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x29, 0x29, 0x2c, + 0x68, 0x2e, 0x79, 0x2d, 0x3d, 0x78, 0x2a, 0x64, 0x2c, 0x66, 0x2e, + 0x78, 0x2b, 0x3d, 0x79, 0x2a, 0x28, 0x64, 0x3d, 0x31, 0x2d, 0x64, + 0x29, 0x2c, 0x66, 0x2e, 0x79, 0x2b, 0x3d, 0x78, 0x2a, 0x64, 0x29, + 0x3b, 0x69, 0x66, 0x28, 0x28, 0x64, 0x3d, 0x72, 0x2a, 0x76, 0x29, + 0x26, 0x26, 0x28, 0x79, 0x3d, 0x6c, 0x5b, 0x30, 0x5d, 0x2f, 0x32, + 0x2c, 0x78, 0x3d, 0x6c, 0x5b, 0x31, 0x5d, 0x2f, 0x32, 0x2c, 0x65, + 0x3d, 0x2d, 0x31, 0x2c, 0x64, 0x29, 0x29, 0x66, 0x6f, 0x72, 0x28, + 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x62, 0x3b, 0x29, 0x61, 0x3d, 0x6d, + 0x5b, 0x65, 0x5d, 0x2c, 0x61, 0x2e, 0x78, 0x2b, 0x3d, 0x28, 0x79, + 0x2d, 0x61, 0x2e, 0x78, 0x29, 0x2a, 0x64, 0x2c, 0x61, 0x2e, 0x79, + 0x2b, 0x3d, 0x28, 0x78, 0x2d, 0x61, 0x2e, 0x79, 0x29, 0x2a, 0x64, + 0x3b, 0x69, 0x66, 0x28, 0x67, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x4a, + 0x75, 0x28, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x67, 0x65, 0x6f, 0x6d, + 0x2e, 0x71, 0x75, 0x61, 0x64, 0x74, 0x72, 0x65, 0x65, 0x28, 0x6d, + 0x29, 0x2c, 0x72, 0x2c, 0x6f, 0x29, 0x2c, 0x65, 0x3d, 0x2d, 0x31, + 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x62, 0x3b, 0x29, 0x28, 0x61, 0x3d, + 0x6d, 0x5b, 0x65, 0x5d, 0x29, 0x2e, 0x66, 0x69, 0x78, 0x65, 0x64, + 0x7c, 0x7c, 0x74, 0x2e, 0x76, 0x69, 0x73, 0x69, 0x74, 0x28, 0x6e, + 0x28, 0x61, 0x29, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, + 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x65, 0x3c, 0x62, 0x3b, 0x29, 0x61, + 0x3d, 0x6d, 0x5b, 0x65, 0x5d, 0x2c, 0x61, 0x2e, 0x66, 0x69, 0x78, + 0x65, 0x64, 0x3f, 0x28, 0x61, 0x2e, 0x78, 0x3d, 0x61, 0x2e, 0x70, + 0x78, 0x2c, 0x61, 0x2e, 0x79, 0x3d, 0x61, 0x2e, 0x70, 0x79, 0x29, + 0x3a, 0x28, 0x61, 0x2e, 0x78, 0x2d, 0x3d, 0x28, 0x61, 0x2e, 0x70, + 0x78, 0x2d, 0x28, 0x61, 0x2e, 0x70, 0x78, 0x3d, 0x61, 0x2e, 0x78, + 0x29, 0x29, 0x2a, 0x73, 0x2c, 0x61, 0x2e, 0x79, 0x2d, 0x3d, 0x28, + 0x61, 0x2e, 0x70, 0x79, 0x2d, 0x28, 0x61, 0x2e, 0x70, 0x79, 0x3d, + 0x61, 0x2e, 0x79, 0x29, 0x29, 0x2a, 0x73, 0x29, 0x3b, 0x63, 0x2e, + 0x74, 0x69, 0x63, 0x6b, 0x28, 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, + 0x22, 0x74, 0x69, 0x63, 0x6b, 0x22, 0x2c, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x3a, 0x72, 0x7d, 0x29, 0x7d, 0x2c, 0x61, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6d, 0x3d, 0x6e, + 0x2c, 0x61, 0x29, 0x3a, 0x6d, 0x7d, 0x2c, 0x61, 0x2e, 0x6c, 0x69, + 0x6e, 0x6b, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x4d, 0x3d, 0x6e, + 0x2c, 0x61, 0x29, 0x3a, 0x4d, 0x7d, 0x2c, 0x61, 0x2e, 0x73, 0x69, + 0x7a, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6c, 0x3d, 0x6e, 0x2c, + 0x61, 0x29, 0x3a, 0x6c, 0x7d, 0x2c, 0x61, 0x2e, 0x6c, 0x69, 0x6e, + 0x6b, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x66, 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, + 0x66, 0x20, 0x6e, 0x3f, 0x6e, 0x3a, 0x2b, 0x6e, 0x2c, 0x61, 0x29, + 0x3a, 0x66, 0x7d, 0x2c, 0x61, 0x2e, 0x64, 0x69, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x3d, 0x61, 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x44, + 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x2c, 0x61, 0x2e, 0x6c, + 0x69, 0x6e, 0x6b, 0x53, 0x74, 0x72, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x68, 0x3d, 0x22, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x3f, 0x6e, 0x3a, 0x2b, 0x6e, 0x2c, + 0x61, 0x29, 0x3a, 0x68, 0x7d, 0x2c, 0x61, 0x2e, 0x66, 0x72, 0x69, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x73, + 0x3d, 0x2b, 0x6e, 0x2c, 0x61, 0x29, 0x3a, 0x73, 0x7d, 0x2c, 0x61, + 0x2e, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x67, 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x6e, 0x3f, 0x6e, 0x3a, 0x2b, 0x6e, 0x2c, 0x61, 0x29, 0x3a, 0x67, + 0x7d, 0x2c, 0x61, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x44, + 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x70, 0x3d, 0x6e, 0x2a, 0x6e, 0x2c, 0x61, 0x29, 0x3a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x70, 0x29, + 0x7d, 0x2c, 0x61, 0x2e, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x79, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x76, 0x3d, 0x2b, 0x6e, 0x2c, 0x61, + 0x29, 0x3a, 0x76, 0x7d, 0x2c, 0x61, 0x2e, 0x74, 0x68, 0x65, 0x74, + 0x61, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x64, 0x3d, 0x6e, 0x2a, 0x6e, + 0x2c, 0x61, 0x29, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x64, 0x29, 0x7d, 0x2c, 0x61, 0x2e, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6e, 0x3d, 0x2b, + 0x6e, 0x2c, 0x72, 0x3f, 0x72, 0x3d, 0x6e, 0x3e, 0x30, 0x3f, 0x6e, + 0x3a, 0x30, 0x3a, 0x6e, 0x3e, 0x30, 0x26, 0x26, 0x28, 0x63, 0x2e, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x28, 0x7b, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x22, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x2c, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x3a, 0x72, 0x3d, 0x6e, 0x7d, 0x29, 0x2c, 0x74, + 0x61, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x72, 0x28, 0x61, 0x2e, 0x74, + 0x69, 0x63, 0x6b, 0x29, 0x29, 0x2c, 0x61, 0x29, 0x3a, 0x72, 0x7d, + 0x2c, 0x61, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x2c, + 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x65, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x41, 0x72, + 0x72, 0x61, 0x79, 0x28, 0x63, 0x29, 0x2c, 0x61, 0x3d, 0x30, 0x3b, + 0x63, 0x3e, 0x61, 0x3b, 0x2b, 0x2b, 0x61, 0x29, 0x65, 0x5b, 0x61, + 0x5d, 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x61, 0x3d, + 0x30, 0x3b, 0x73, 0x3e, 0x61, 0x3b, 0x2b, 0x2b, 0x61, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x4d, 0x5b, 0x61, 0x5d, 0x3b, + 0x65, 0x5b, 0x75, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x75, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x2c, + 0x65, 0x5b, 0x75, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x75, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x29, 0x7d, + 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x2c, + 0x6f, 0x3d, 0x65, 0x5b, 0x74, 0x5d, 0x2c, 0x61, 0x3d, 0x2d, 0x31, + 0x2c, 0x6c, 0x3d, 0x6f, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x2b, 0x2b, 0x61, 0x3c, 0x6c, 0x3b, 0x29, 0x69, 0x66, 0x28, + 0x21, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x69, 0x3d, 0x6f, 0x5b, + 0x61, 0x5d, 0x5b, 0x6e, 0x5d, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, + 0x6d, 0x28, 0x29, 0x2a, 0x72, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x63, 0x3d, 0x6d, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x73, 0x3d, 0x4d, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x70, 0x3d, 0x6c, 0x5b, 0x30, 0x5d, + 0x2c, 0x76, 0x3d, 0x6c, 0x5b, 0x31, 0x5d, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x74, 0x3d, 0x30, 0x3b, 0x63, 0x3e, 0x74, 0x3b, 0x2b, 0x2b, + 0x74, 0x29, 0x28, 0x72, 0x3d, 0x6d, 0x5b, 0x74, 0x5d, 0x29, 0x2e, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x74, 0x2c, 0x72, 0x2e, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x3d, 0x30, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x74, 0x3d, 0x30, 0x3b, 0x73, 0x3e, 0x74, 0x3b, 0x2b, 0x2b, + 0x74, 0x29, 0x72, 0x3d, 0x4d, 0x5b, 0x74, 0x5d, 0x2c, 0x22, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x20, 0x72, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x26, 0x26, 0x28, 0x72, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x3d, 0x6d, 0x5b, 0x72, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5d, 0x29, 0x2c, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x72, + 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x26, 0x26, 0x28, 0x72, + 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x6d, 0x5b, 0x72, + 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5d, 0x29, 0x2c, 0x2b, + 0x2b, 0x72, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x77, + 0x65, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x2b, 0x2b, 0x72, 0x2e, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x77, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x3b, 0x63, + 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x72, 0x3d, 0x6d, 0x5b, + 0x74, 0x5d, 0x2c, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x72, 0x2e, + 0x78, 0x29, 0x26, 0x26, 0x28, 0x72, 0x2e, 0x78, 0x3d, 0x6e, 0x28, + 0x22, 0x78, 0x22, 0x2c, 0x70, 0x29, 0x29, 0x2c, 0x69, 0x73, 0x4e, + 0x61, 0x4e, 0x28, 0x72, 0x2e, 0x79, 0x29, 0x26, 0x26, 0x28, 0x72, + 0x2e, 0x79, 0x3d, 0x6e, 0x28, 0x22, 0x79, 0x22, 0x2c, 0x76, 0x29, + 0x29, 0x2c, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x72, 0x2e, 0x70, + 0x78, 0x29, 0x26, 0x26, 0x28, 0x72, 0x2e, 0x70, 0x78, 0x3d, 0x72, + 0x2e, 0x78, 0x29, 0x2c, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x28, 0x72, + 0x2e, 0x70, 0x79, 0x29, 0x26, 0x26, 0x28, 0x72, 0x2e, 0x70, 0x79, + 0x3d, 0x72, 0x2e, 0x79, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x75, 0x3d, + 0x5b, 0x5d, 0x2c, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x66, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x3b, 0x73, + 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x75, 0x5b, 0x74, 0x5d, + 0x3d, 0x2b, 0x66, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x4d, 0x5b, 0x74, 0x5d, 0x2c, 0x74, 0x29, 0x3b, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, + 0x30, 0x3b, 0x73, 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x75, + 0x5b, 0x74, 0x5d, 0x3d, 0x66, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x3d, + 0x5b, 0x5d, 0x2c, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x68, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x3b, 0x73, + 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x69, 0x5b, 0x74, 0x5d, + 0x3d, 0x2b, 0x68, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x4d, 0x5b, 0x74, 0x5d, 0x2c, 0x74, 0x29, 0x3b, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, + 0x30, 0x3b, 0x73, 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x69, + 0x5b, 0x74, 0x5d, 0x3d, 0x68, 0x3b, 0x69, 0x66, 0x28, 0x6f, 0x3d, + 0x5b, 0x5d, 0x2c, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x67, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x3b, 0x63, + 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x6f, 0x5b, 0x74, 0x5d, + 0x3d, 0x2b, 0x67, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x6d, 0x5b, 0x74, 0x5d, 0x2c, 0x74, 0x29, 0x3b, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, + 0x30, 0x3b, 0x63, 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x6f, + 0x5b, 0x74, 0x5d, 0x3d, 0x67, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x2e, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x28, + 0x29, 0x7d, 0x2c, 0x61, 0x2e, 0x72, 0x65, 0x73, 0x75, 0x6d, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x2e, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x28, 0x2e, 0x31, 0x29, 0x7d, 0x2c, 0x61, + 0x2e, 0x73, 0x74, 0x6f, 0x70, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x2e, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x28, 0x30, + 0x29, 0x7d, 0x2c, 0x61, 0x2e, 0x64, 0x72, 0x61, 0x67, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7c, 0x7c, 0x28, 0x65, + 0x3d, 0x74, 0x61, 0x2e, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, + 0x72, 0x2e, 0x64, 0x72, 0x61, 0x67, 0x28, 0x29, 0x2e, 0x6f, 0x72, + 0x69, 0x67, 0x69, 0x6e, 0x28, 0x79, 0x29, 0x2e, 0x6f, 0x6e, 0x28, + 0x22, 0x64, 0x72, 0x61, 0x67, 0x73, 0x74, 0x61, 0x72, 0x74, 0x2e, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x22, 0x2c, 0x58, 0x75, 0x29, 0x2e, + 0x6f, 0x6e, 0x28, 0x22, 0x64, 0x72, 0x61, 0x67, 0x2e, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x22, 0x2c, 0x74, 0x29, 0x2e, 0x6f, 0x6e, 0x28, + 0x22, 0x64, 0x72, 0x61, 0x67, 0x65, 0x6e, 0x64, 0x2e, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x22, 0x2c, 0x24, 0x75, 0x29, 0x29, 0x2c, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x6d, 0x6f, 0x75, + 0x73, 0x65, 0x6f, 0x76, 0x65, 0x72, 0x2e, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x22, 0x2c, 0x42, 0x75, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, + 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x6f, 0x75, 0x74, 0x2e, 0x66, 0x6f, + 0x72, 0x63, 0x65, 0x22, 0x2c, 0x57, 0x75, 0x29, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x65, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x72, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x61, 0x2c, 0x63, + 0x2c, 0x22, 0x6f, 0x6e, 0x22, 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x66, 0x6c, 0x3d, 0x32, 0x30, 0x2c, 0x68, 0x6c, 0x3d, 0x31, + 0x2c, 0x67, 0x6c, 0x3d, 0x31, 0x2f, 0x30, 0x3b, 0x74, 0x61, 0x2e, + 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x68, 0x69, 0x65, 0x72, + 0x61, 0x72, 0x63, 0x68, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x75, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x69, 0x2c, 0x6f, 0x3d, 0x5b, 0x75, 0x5d, 0x2c, 0x61, + 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x75, 0x2e, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x3d, 0x30, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, + 0x21, 0x3d, 0x28, 0x69, 0x3d, 0x6f, 0x2e, 0x70, 0x6f, 0x70, 0x28, + 0x29, 0x29, 0x3b, 0x29, 0x69, 0x66, 0x28, 0x61, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x69, 0x29, 0x2c, 0x28, 0x6c, 0x3d, 0x65, 0x2e, + 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x69, 0x2c, 0x69, 0x2e, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x29, 0x29, 0x26, 0x26, 0x28, 0x63, + 0x3d, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x63, 0x2c, + 0x6c, 0x2c, 0x73, 0x3b, 0x2d, 0x2d, 0x63, 0x3e, 0x3d, 0x30, 0x3b, + 0x29, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x73, 0x3d, 0x6c, + 0x5b, 0x63, 0x5d, 0x29, 0x2c, 0x73, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x3d, 0x69, 0x2c, 0x73, 0x2e, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x3d, 0x69, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x2b, 0x31, + 0x3b, 0x72, 0x26, 0x26, 0x28, 0x69, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3d, 0x30, 0x29, 0x2c, 0x69, 0x2e, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x3d, 0x6c, 0x7d, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x72, 0x26, 0x26, 0x28, 0x69, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3d, 0x2b, 0x72, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, + 0x2c, 0x69, 0x2c, 0x69, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x29, + 0x7c, 0x7c, 0x30, 0x29, 0x2c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x20, 0x69, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x51, 0x75, 0x28, + 0x75, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x75, 0x3b, + 0x74, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x29, 0x26, 0x26, 0x65, 0x2e, 0x73, + 0x6f, 0x72, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x72, 0x26, 0x26, 0x28, + 0x75, 0x3d, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x29, + 0x26, 0x26, 0x28, 0x75, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2b, + 0x3d, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x7d, 0x29, + 0x2c, 0x61, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x65, 0x69, + 0x2c, 0x65, 0x3d, 0x6e, 0x69, 0x2c, 0x72, 0x3d, 0x74, 0x69, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x73, 0x6f, + 0x72, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x65, 0x2c, + 0x6e, 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6e, 0x2e, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, + 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x6e, 0x2e, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, + 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x2e, + 0x72, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x26, 0x26, 0x28, 0x4b, 0x75, + 0x28, 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x26, 0x26, 0x28, 0x6e, 0x2e, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3d, 0x30, 0x29, 0x7d, 0x29, 0x2c, 0x51, 0x75, 0x28, + 0x74, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3b, 0x74, 0x2e, + 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x7c, 0x7c, 0x28, + 0x74, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x2b, 0x72, 0x2e, + 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x74, 0x2e, + 0x64, 0x65, 0x70, 0x74, 0x68, 0x29, 0x7c, 0x7c, 0x30, 0x29, 0x2c, + 0x28, 0x65, 0x3d, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x29, 0x26, 0x26, 0x28, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x2b, 0x3d, 0x74, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x7d, + 0x29, 0x29, 0x2c, 0x74, 0x7d, 0x2c, 0x6e, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x2c, 0x75, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, + 0x74, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x3b, + 0x69, 0x66, 0x28, 0x74, 0x2e, 0x78, 0x3d, 0x65, 0x2c, 0x74, 0x2e, + 0x79, 0x3d, 0x74, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x2a, 0x75, + 0x2c, 0x74, 0x2e, 0x64, 0x78, 0x3d, 0x72, 0x2c, 0x74, 0x2e, 0x64, + 0x79, 0x3d, 0x75, 0x2c, 0x69, 0x26, 0x26, 0x28, 0x6f, 0x3d, 0x69, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6f, 0x2c, 0x61, 0x2c, 0x63, 0x2c, 0x6c, 0x3d, + 0x2d, 0x31, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x72, 0x3d, 0x74, 0x2e, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3f, 0x72, 0x2f, 0x74, 0x2e, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x30, 0x3b, 0x2b, 0x2b, 0x6c, 0x3c, + 0x6f, 0x3b, 0x29, 0x6e, 0x28, 0x61, 0x3d, 0x69, 0x5b, 0x6c, 0x5d, + 0x2c, 0x65, 0x2c, 0x63, 0x3d, 0x61, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x2a, 0x72, 0x2c, 0x75, 0x29, 0x2c, 0x65, 0x2b, 0x3d, 0x63, + 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x2c, + 0x72, 0x3d, 0x30, 0x3b, 0x69, 0x66, 0x28, 0x65, 0x26, 0x26, 0x28, + 0x75, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, + 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, + 0x69, 0x3d, 0x2d, 0x31, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, 0x75, 0x3b, + 0x29, 0x72, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, + 0x28, 0x72, 0x2c, 0x74, 0x28, 0x65, 0x5b, 0x69, 0x5d, 0x29, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x2b, 0x72, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, + 0x28, 0x65, 0x2c, 0x69, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, + 0x3d, 0x72, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x65, 0x2c, 0x69, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x28, 0x6f, 0x5b, 0x30, 0x5d, 0x2c, 0x30, + 0x2c, 0x75, 0x5b, 0x30, 0x5d, 0x2c, 0x75, 0x5b, 0x31, 0x5d, 0x2f, + 0x74, 0x28, 0x6f, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x2c, 0x6f, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x61, 0x2e, 0x6c, 0x61, + 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, + 0x63, 0x68, 0x79, 0x28, 0x29, 0x2c, 0x75, 0x3d, 0x5b, 0x31, 0x2c, + 0x31, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, + 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x75, + 0x3d, 0x6e, 0x2c, 0x65, 0x29, 0x3a, 0x75, 0x7d, 0x2c, 0x47, 0x75, + 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x6c, + 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x70, 0x69, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6f, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x2c, 0x63, 0x3d, 0x6f, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x6c, 0x3d, 0x6f, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x2b, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x6e, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7d, 0x29, 0x2c, 0x73, 0x3d, + 0x2b, 0x28, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x72, + 0x3f, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x29, 0x3a, 0x72, 0x29, 0x2c, 0x66, 0x3d, 0x28, 0x22, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, + 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x75, 0x3f, 0x75, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3a, 0x75, + 0x29, 0x2d, 0x73, 0x2c, 0x68, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x6d, 0x69, 0x6e, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x62, + 0x73, 0x28, 0x66, 0x29, 0x2f, 0x63, 0x2c, 0x2b, 0x28, 0x22, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, + 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x69, 0x3f, 0x69, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x3a, 0x69, + 0x29, 0x29, 0x2c, 0x67, 0x3d, 0x68, 0x2a, 0x28, 0x30, 0x3e, 0x66, + 0x3f, 0x2d, 0x31, 0x3a, 0x31, 0x29, 0x2c, 0x70, 0x3d, 0x28, 0x66, + 0x2d, 0x63, 0x2a, 0x67, 0x29, 0x2f, 0x74, 0x61, 0x2e, 0x73, 0x75, + 0x6d, 0x28, 0x6c, 0x29, 0x2c, 0x76, 0x3d, 0x74, 0x61, 0x2e, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x28, 0x63, 0x29, 0x2c, 0x64, 0x3d, 0x5b, + 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, + 0x6c, 0x6c, 0x21, 0x3d, 0x65, 0x26, 0x26, 0x76, 0x2e, 0x73, 0x6f, + 0x72, 0x74, 0x28, 0x65, 0x3d, 0x3d, 0x3d, 0x70, 0x6c, 0x3f, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x5b, + 0x74, 0x5d, 0x2d, 0x6c, 0x5b, 0x6e, 0x5d, 0x7d, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x28, 0x6f, + 0x5b, 0x6e, 0x5d, 0x2c, 0x6f, 0x5b, 0x74, 0x5d, 0x29, 0x7d, 0x29, + 0x2c, 0x76, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x64, 0x5b, 0x6e, 0x5d, 0x3d, 0x7b, 0x64, 0x61, 0x74, 0x61, + 0x3a, 0x6f, 0x5b, 0x6e, 0x5d, 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x61, 0x3d, 0x6c, 0x5b, 0x6e, 0x5d, 0x2c, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x3a, 0x73, 0x2c, 0x65, + 0x6e, 0x64, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x3a, 0x73, 0x2b, 0x3d, + 0x61, 0x2a, 0x70, 0x2b, 0x67, 0x2c, 0x70, 0x61, 0x64, 0x41, 0x6e, + 0x67, 0x6c, 0x65, 0x3a, 0x68, 0x7d, 0x7d, 0x29, 0x2c, 0x64, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x2c, 0x65, 0x3d, 0x70, 0x6c, 0x2c, 0x72, 0x3d, 0x30, 0x2c, + 0x75, 0x3d, 0x4c, 0x61, 0x2c, 0x69, 0x3d, 0x30, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x65, 0x2c, 0x6e, + 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, 0x6f, 0x72, 0x74, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, 0x74, 0x2c, 0x6e, 0x29, + 0x3a, 0x65, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, + 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x2e, + 0x65, 0x6e, 0x64, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x75, 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x75, 0x7d, + 0x2c, 0x6e, 0x2e, 0x70, 0x61, 0x64, 0x41, 0x6e, 0x67, 0x6c, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x69, 0x3d, 0x74, 0x2c, 0x6e, 0x29, + 0x3a, 0x69, 0x7d, 0x2c, 0x6e, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x70, 0x6c, 0x3d, 0x7b, 0x7d, 0x3b, 0x74, 0x61, 0x2e, 0x6c, 0x61, + 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, + 0x61, 0x2c, 0x63, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x28, 0x68, + 0x3d, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x6c, 0x3d, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x72, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, + 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x72, 0x29, + 0x7d, 0x29, 0x2c, 0x73, 0x3d, 0x6c, 0x2e, 0x6d, 0x61, 0x70, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x6d, + 0x61, 0x70, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x5b, 0x69, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, + 0x74, 0x2c, 0x65, 0x29, 0x2c, 0x6f, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x5d, 0x7d, 0x29, 0x7d, + 0x29, 0x2c, 0x66, 0x3d, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x6e, 0x2c, 0x73, 0x2c, 0x63, 0x29, 0x3b, 0x6c, 0x3d, 0x74, 0x61, + 0x2e, 0x70, 0x65, 0x72, 0x6d, 0x75, 0x74, 0x65, 0x28, 0x6c, 0x2c, + 0x66, 0x29, 0x2c, 0x73, 0x3d, 0x74, 0x61, 0x2e, 0x70, 0x65, 0x72, + 0x6d, 0x75, 0x74, 0x65, 0x28, 0x73, 0x2c, 0x66, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x68, 0x2c, 0x67, 0x2c, 0x70, 0x2c, 0x76, 0x2c, + 0x64, 0x3d, 0x72, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, + 0x73, 0x2c, 0x63, 0x29, 0x2c, 0x6d, 0x3d, 0x6c, 0x5b, 0x30, 0x5d, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x70, 0x3d, 0x30, 0x3b, 0x6d, 0x3e, 0x70, 0x3b, 0x2b, 0x2b, + 0x70, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x75, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x6e, 0x2c, 0x6c, 0x5b, 0x30, 0x5d, 0x5b, 0x70, 0x5d, + 0x2c, 0x76, 0x3d, 0x64, 0x5b, 0x70, 0x5d, 0x2c, 0x73, 0x5b, 0x30, + 0x5d, 0x5b, 0x70, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x67, 0x3d, + 0x31, 0x3b, 0x68, 0x3e, 0x67, 0x3b, 0x2b, 0x2b, 0x67, 0x29, 0x75, + 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x6c, 0x5b, 0x67, + 0x5d, 0x5b, 0x70, 0x5d, 0x2c, 0x76, 0x2b, 0x3d, 0x73, 0x5b, 0x67, + 0x2d, 0x31, 0x5d, 0x5b, 0x70, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x73, + 0x5b, 0x67, 0x5d, 0x5b, 0x70, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x7d, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x79, 0x2c, 0x65, 0x3d, 0x61, 0x69, 0x2c, + 0x72, 0x3d, 0x63, 0x69, 0x2c, 0x75, 0x3d, 0x6f, 0x69, 0x2c, 0x69, + 0x3d, 0x75, 0x69, 0x2c, 0x6f, 0x3d, 0x69, 0x69, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x65, 0x2c, + 0x6e, 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6e, 0x2e, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, 0x22, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, + 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3f, 0x74, 0x3a, 0x76, + 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x74, 0x29, 0x7c, 0x7c, 0x61, + 0x69, 0x2c, 0x6e, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x6e, 0x2e, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, + 0x3d, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3f, + 0x74, 0x3a, 0x64, 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x74, 0x29, + 0x7c, 0x7c, 0x63, 0x69, 0x2c, 0x6e, 0x29, 0x3a, 0x72, 0x7d, 0x2c, + 0x6e, 0x2e, 0x78, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x69, 0x3d, 0x74, + 0x2c, 0x6e, 0x29, 0x3a, 0x69, 0x7d, 0x2c, 0x6e, 0x2e, 0x79, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x6f, 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, + 0x6f, 0x7d, 0x2c, 0x6e, 0x2e, 0x6f, 0x75, 0x74, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x75, 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x75, 0x7d, + 0x2c, 0x6e, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x76, 0x6c, 0x3d, + 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x7b, 0x22, 0x69, 0x6e, + 0x73, 0x69, 0x64, 0x65, 0x2d, 0x6f, 0x75, 0x74, 0x22, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x3d, 0x6e, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x75, 0x3d, 0x6e, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x6c, 0x69, 0x29, 0x2c, 0x69, 0x3d, + 0x6e, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x73, 0x69, 0x29, 0x2c, 0x6f, + 0x3d, 0x74, 0x61, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x72, + 0x29, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x5b, 0x6e, 0x5d, 0x2d, + 0x75, 0x5b, 0x74, 0x5d, 0x7d, 0x29, 0x2c, 0x61, 0x3d, 0x30, 0x2c, + 0x63, 0x3d, 0x30, 0x2c, 0x6c, 0x3d, 0x5b, 0x5d, 0x2c, 0x73, 0x3d, + 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x3b, + 0x72, 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x65, 0x3d, 0x6f, + 0x5b, 0x74, 0x5d, 0x2c, 0x63, 0x3e, 0x61, 0x3f, 0x28, 0x61, 0x2b, + 0x3d, 0x69, 0x5b, 0x65, 0x5d, 0x2c, 0x6c, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x65, 0x29, 0x29, 0x3a, 0x28, 0x63, 0x2b, 0x3d, 0x69, + 0x5b, 0x65, 0x5d, 0x2c, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x65, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x73, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, 0x29, + 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x61, 0x74, 0x28, 0x6c, 0x29, 0x7d, + 0x2c, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x28, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x28, + 0x29, 0x7d, 0x2c, 0x22, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x22, 0x3a, 0x61, 0x69, 0x7d, 0x29, 0x2c, 0x64, 0x6c, 0x3d, 0x74, + 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x7b, 0x73, 0x69, 0x6c, 0x68, + 0x6f, 0x75, 0x65, 0x74, 0x74, 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x69, 0x3d, 0x6e, 0x5b, + 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x6f, + 0x3d, 0x5b, 0x5d, 0x2c, 0x61, 0x3d, 0x30, 0x2c, 0x63, 0x3d, 0x5b, + 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x30, 0x3b, 0x69, + 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x74, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x30, 0x3b, 0x75, 0x3e, + 0x74, 0x3b, 0x74, 0x2b, 0x2b, 0x29, 0x72, 0x2b, 0x3d, 0x6e, 0x5b, + 0x74, 0x5d, 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x3b, 0x72, 0x3e, + 0x61, 0x26, 0x26, 0x28, 0x61, 0x3d, 0x72, 0x29, 0x2c, 0x6f, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, 0x29, 0x7d, 0x66, 0x6f, 0x72, + 0x28, 0x65, 0x3d, 0x30, 0x3b, 0x69, 0x3e, 0x65, 0x3b, 0x2b, 0x2b, + 0x65, 0x29, 0x63, 0x5b, 0x65, 0x5d, 0x3d, 0x28, 0x61, 0x2d, 0x6f, + 0x5b, 0x65, 0x5d, 0x29, 0x2f, 0x32, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x63, 0x7d, 0x2c, 0x77, 0x69, 0x67, 0x67, 0x6c, + 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x6f, 0x2c, 0x61, 0x2c, 0x63, + 0x2c, 0x6c, 0x2c, 0x73, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2c, 0x66, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x68, + 0x3d, 0x66, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x67, + 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x67, 0x5b, 0x30, + 0x5d, 0x3d, 0x63, 0x3d, 0x6c, 0x3d, 0x30, 0x2c, 0x65, 0x3d, 0x31, + 0x3b, 0x68, 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x30, 0x3b, + 0x73, 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x75, 0x2b, 0x3d, + 0x6e, 0x5b, 0x74, 0x5d, 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x3b, + 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x2c, 0x69, 0x3d, 0x30, + 0x2c, 0x61, 0x3d, 0x66, 0x5b, 0x65, 0x5d, 0x5b, 0x30, 0x5d, 0x2d, + 0x66, 0x5b, 0x65, 0x2d, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x3b, 0x73, + 0x3e, 0x74, 0x3b, 0x2b, 0x2b, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x72, 0x3d, 0x30, 0x2c, 0x6f, 0x3d, 0x28, 0x6e, 0x5b, 0x74, + 0x5d, 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x2d, 0x6e, 0x5b, 0x74, + 0x5d, 0x5b, 0x65, 0x2d, 0x31, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x2f, + 0x28, 0x32, 0x2a, 0x61, 0x29, 0x3b, 0x74, 0x3e, 0x72, 0x3b, 0x2b, + 0x2b, 0x72, 0x29, 0x6f, 0x2b, 0x3d, 0x28, 0x6e, 0x5b, 0x72, 0x5d, + 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x2d, 0x6e, 0x5b, 0x72, 0x5d, + 0x5b, 0x65, 0x2d, 0x31, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x2f, 0x61, + 0x3b, 0x69, 0x2b, 0x3d, 0x6f, 0x2a, 0x6e, 0x5b, 0x74, 0x5d, 0x5b, + 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x7d, 0x67, 0x5b, 0x65, 0x5d, 0x3d, + 0x63, 0x2d, 0x3d, 0x75, 0x3f, 0x69, 0x2f, 0x75, 0x2a, 0x61, 0x3a, + 0x30, 0x2c, 0x6c, 0x3e, 0x63, 0x26, 0x26, 0x28, 0x6c, 0x3d, 0x63, + 0x29, 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x30, 0x3b, 0x68, + 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x67, 0x5b, 0x65, 0x5d, + 0x2d, 0x3d, 0x6c, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x67, 0x7d, 0x2c, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, + 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x69, + 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2c, 0x6f, 0x3d, 0x31, 0x2f, 0x75, 0x2c, 0x61, 0x3d, 0x5b, + 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x30, 0x3b, 0x69, + 0x3e, 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x74, 0x3d, 0x30, 0x2c, 0x72, 0x3d, 0x30, 0x3b, 0x75, 0x3e, + 0x74, 0x3b, 0x74, 0x2b, 0x2b, 0x29, 0x72, 0x2b, 0x3d, 0x6e, 0x5b, + 0x74, 0x5d, 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x3b, 0x69, 0x66, + 0x28, 0x72, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, 0x30, 0x3b, + 0x75, 0x3e, 0x74, 0x3b, 0x74, 0x2b, 0x2b, 0x29, 0x6e, 0x5b, 0x74, + 0x5d, 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x2f, 0x3d, 0x72, 0x3b, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x3d, + 0x30, 0x3b, 0x75, 0x3e, 0x74, 0x3b, 0x74, 0x2b, 0x2b, 0x29, 0x6e, + 0x5b, 0x74, 0x5d, 0x5b, 0x65, 0x5d, 0x5b, 0x31, 0x5d, 0x3d, 0x6f, + 0x7d, 0x66, 0x6f, 0x72, 0x28, 0x65, 0x3d, 0x30, 0x3b, 0x69, 0x3e, + 0x65, 0x3b, 0x2b, 0x2b, 0x65, 0x29, 0x61, 0x5b, 0x65, 0x5d, 0x3d, + 0x30, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x7d, + 0x2c, 0x7a, 0x65, 0x72, 0x6f, 0x3a, 0x63, 0x69, 0x7d, 0x29, 0x3b, + 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x68, + 0x69, 0x73, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x2c, + 0x69, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x6f, 0x2c, 0x61, 0x2c, 0x63, 0x3d, 0x5b, 0x5d, 0x2c, 0x6c, 0x3d, + 0x6e, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x65, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x29, 0x2c, 0x73, 0x3d, 0x72, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6c, 0x2c, 0x69, 0x29, 0x2c, + 0x66, 0x3d, 0x75, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x73, 0x2c, 0x6c, 0x2c, 0x69, 0x29, 0x2c, 0x69, + 0x3d, 0x2d, 0x31, 0x2c, 0x68, 0x3d, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2c, 0x67, 0x3d, 0x66, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2d, 0x31, 0x2c, 0x70, 0x3d, 0x74, 0x3f, 0x31, + 0x3a, 0x31, 0x2f, 0x68, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, 0x67, 0x3b, + 0x29, 0x6f, 0x3d, 0x63, 0x5b, 0x69, 0x5d, 0x3d, 0x5b, 0x5d, 0x2c, + 0x6f, 0x2e, 0x64, 0x78, 0x3d, 0x66, 0x5b, 0x69, 0x2b, 0x31, 0x5d, + 0x2d, 0x28, 0x6f, 0x2e, 0x78, 0x3d, 0x66, 0x5b, 0x69, 0x5d, 0x29, + 0x2c, 0x6f, 0x2e, 0x79, 0x3d, 0x30, 0x3b, 0x69, 0x66, 0x28, 0x67, + 0x3e, 0x30, 0x29, 0x66, 0x6f, 0x72, 0x28, 0x69, 0x3d, 0x2d, 0x31, + 0x3b, 0x2b, 0x2b, 0x69, 0x3c, 0x68, 0x3b, 0x29, 0x61, 0x3d, 0x6c, + 0x5b, 0x69, 0x5d, 0x2c, 0x61, 0x3e, 0x3d, 0x73, 0x5b, 0x30, 0x5d, + 0x26, 0x26, 0x61, 0x3c, 0x3d, 0x73, 0x5b, 0x31, 0x5d, 0x26, 0x26, + 0x28, 0x6f, 0x3d, 0x63, 0x5b, 0x74, 0x61, 0x2e, 0x62, 0x69, 0x73, + 0x65, 0x63, 0x74, 0x28, 0x66, 0x2c, 0x61, 0x2c, 0x31, 0x2c, 0x67, + 0x29, 0x2d, 0x31, 0x5d, 0x2c, 0x6f, 0x2e, 0x79, 0x2b, 0x3d, 0x70, + 0x2c, 0x6f, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x5b, 0x69, + 0x5d, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x63, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x21, 0x30, 0x2c, + 0x65, 0x3d, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x72, 0x3d, + 0x70, 0x69, 0x2c, 0x75, 0x3d, 0x68, 0x69, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, 0x74, 0x2c, 0x6e, 0x29, + 0x3a, 0x65, 0x7d, 0x2c, 0x6e, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, 0x3d, 0x45, 0x74, 0x28, 0x74, + 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x2e, 0x62, + 0x69, 0x6e, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x75, 0x3d, 0x22, + 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3d, 0x3d, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3f, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x67, 0x69, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7d, 0x3a, 0x45, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, + 0x75, 0x7d, 0x2c, 0x6e, 0x2e, 0x66, 0x72, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x21, + 0x21, 0x65, 0x2c, 0x6e, 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6e, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, + 0x70, 0x61, 0x63, 0x6b, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x2c, 0x69, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x69, 0x29, 0x2c, + 0x61, 0x3d, 0x6f, 0x5b, 0x30, 0x5d, 0x2c, 0x63, 0x3d, 0x75, 0x5b, + 0x30, 0x5d, 0x2c, 0x6c, 0x3d, 0x75, 0x5b, 0x31, 0x5d, 0x2c, 0x73, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, 0x3f, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x3a, 0x22, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x3f, 0x74, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x3b, 0x69, 0x66, 0x28, + 0x61, 0x2e, 0x78, 0x3d, 0x61, 0x2e, 0x79, 0x3d, 0x30, 0x2c, 0x51, + 0x75, 0x28, 0x61, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x72, 0x3d, 0x2b, 0x73, + 0x28, 0x6e, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x7d, 0x29, + 0x2c, 0x51, 0x75, 0x28, 0x61, 0x2c, 0x4d, 0x69, 0x29, 0x2c, 0x72, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x66, 0x3d, 0x72, 0x2a, 0x28, + 0x74, 0x3f, 0x31, 0x3a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, + 0x78, 0x28, 0x32, 0x2a, 0x61, 0x2e, 0x72, 0x2f, 0x63, 0x2c, 0x32, + 0x2a, 0x61, 0x2e, 0x72, 0x2f, 0x6c, 0x29, 0x29, 0x2f, 0x32, 0x3b, + 0x51, 0x75, 0x28, 0x61, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x72, 0x2b, 0x3d, + 0x66, 0x7d, 0x29, 0x2c, 0x51, 0x75, 0x28, 0x61, 0x2c, 0x4d, 0x69, + 0x29, 0x2c, 0x51, 0x75, 0x28, 0x61, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x72, + 0x2d, 0x3d, 0x66, 0x7d, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x5f, 0x69, 0x28, 0x61, 0x2c, 0x63, 0x2f, 0x32, 0x2c, + 0x6c, 0x2f, 0x32, 0x2c, 0x74, 0x3f, 0x31, 0x3a, 0x31, 0x2f, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x32, 0x2a, 0x61, + 0x2e, 0x72, 0x2f, 0x63, 0x2c, 0x32, 0x2a, 0x61, 0x2e, 0x72, 0x2f, + 0x6c, 0x29, 0x29, 0x2c, 0x6f, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x2c, 0x65, 0x3d, 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, + 0x74, 0x2e, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, + 0x28, 0x29, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, 0x76, 0x69, 0x29, + 0x2c, 0x72, 0x3d, 0x30, 0x2c, 0x75, 0x3d, 0x5b, 0x31, 0x2c, 0x31, + 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, + 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x75, 0x3d, + 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x75, 0x7d, 0x2c, 0x6e, 0x2e, 0x72, + 0x61, 0x64, 0x69, 0x75, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x74, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x65, 0x7c, 0x7c, 0x22, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x3f, 0x65, 0x3a, + 0x2b, 0x65, 0x2c, 0x6e, 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6e, 0x2e, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x72, 0x3d, 0x2b, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x72, 0x7d, + 0x2c, 0x47, 0x75, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7d, 0x2c, 0x74, + 0x61, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x74, 0x72, + 0x65, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6e, 0x28, 0x6e, 0x2c, 0x75, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x73, 0x3d, 0x6f, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x75, 0x29, 0x2c, 0x66, 0x3d, + 0x73, 0x5b, 0x30, 0x5d, 0x2c, 0x68, 0x3d, 0x74, 0x28, 0x66, 0x29, + 0x3b, 0x69, 0x66, 0x28, 0x51, 0x75, 0x28, 0x68, 0x2c, 0x65, 0x29, + 0x2c, 0x68, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6d, + 0x3d, 0x2d, 0x68, 0x2e, 0x7a, 0x2c, 0x4b, 0x75, 0x28, 0x68, 0x2c, + 0x72, 0x29, 0x2c, 0x6c, 0x29, 0x4b, 0x75, 0x28, 0x66, 0x2c, 0x69, + 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x67, 0x3d, 0x66, 0x2c, 0x70, 0x3d, 0x66, 0x2c, 0x76, 0x3d, 0x66, + 0x3b, 0x4b, 0x75, 0x28, 0x66, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x78, 0x3c, + 0x67, 0x2e, 0x78, 0x26, 0x26, 0x28, 0x67, 0x3d, 0x6e, 0x29, 0x2c, + 0x6e, 0x2e, 0x78, 0x3e, 0x70, 0x2e, 0x78, 0x26, 0x26, 0x28, 0x70, + 0x3d, 0x6e, 0x29, 0x2c, 0x6e, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, + 0x3e, 0x76, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x26, 0x26, 0x28, + 0x76, 0x3d, 0x6e, 0x29, 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x64, 0x3d, 0x61, 0x28, 0x67, 0x2c, 0x70, 0x29, 0x2f, 0x32, 0x2d, + 0x67, 0x2e, 0x78, 0x2c, 0x6d, 0x3d, 0x63, 0x5b, 0x30, 0x5d, 0x2f, + 0x28, 0x70, 0x2e, 0x78, 0x2b, 0x61, 0x28, 0x70, 0x2c, 0x67, 0x29, + 0x2f, 0x32, 0x2b, 0x64, 0x29, 0x2c, 0x79, 0x3d, 0x63, 0x5b, 0x31, + 0x5d, 0x2f, 0x28, 0x76, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x7c, + 0x7c, 0x31, 0x29, 0x3b, 0x4b, 0x75, 0x28, 0x66, 0x2c, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, + 0x2e, 0x78, 0x3d, 0x28, 0x6e, 0x2e, 0x78, 0x2b, 0x64, 0x29, 0x2a, + 0x6d, 0x2c, 0x6e, 0x2e, 0x79, 0x3d, 0x6e, 0x2e, 0x64, 0x65, 0x70, + 0x74, 0x68, 0x2a, 0x79, 0x7d, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x73, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x7b, 0x41, + 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x72, 0x65, 0x6e, 0x3a, 0x5b, 0x6e, 0x5d, 0x7d, 0x2c, 0x72, 0x3d, + 0x5b, 0x65, 0x5d, 0x3b, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, + 0x74, 0x3d, 0x72, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x29, 0x3b, + 0x29, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, + 0x69, 0x3d, 0x74, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, + 0x6e, 0x2c, 0x6f, 0x3d, 0x30, 0x2c, 0x61, 0x3d, 0x69, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x61, 0x3e, 0x6f, 0x3b, 0x2b, + 0x2b, 0x6f, 0x29, 0x72, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x28, + 0x69, 0x5b, 0x6f, 0x5d, 0x3d, 0x75, 0x3d, 0x7b, 0x5f, 0x3a, 0x69, + 0x5b, 0x6f, 0x5d, 0x2c, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3a, + 0x74, 0x2c, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x3a, + 0x28, 0x75, 0x3d, 0x69, 0x5b, 0x6f, 0x5d, 0x2e, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x29, 0x26, 0x26, 0x75, 0x2e, 0x73, + 0x6c, 0x69, 0x63, 0x65, 0x28, 0x29, 0x7c, 0x7c, 0x5b, 0x5d, 0x2c, + 0x41, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x61, 0x3a, 0x6e, 0x75, + 0x6c, 0x6c, 0x2c, 0x7a, 0x3a, 0x30, 0x2c, 0x6d, 0x3a, 0x30, 0x2c, + 0x63, 0x3a, 0x30, 0x2c, 0x73, 0x3a, 0x30, 0x2c, 0x74, 0x3a, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x69, 0x3a, 0x6f, 0x7d, 0x29, 0x2e, 0x61, + 0x3d, 0x75, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x5b, + 0x30, 0x5d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, + 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x2c, 0x72, + 0x3d, 0x6e, 0x2e, 0x69, 0x3f, 0x65, 0x5b, 0x6e, 0x2e, 0x69, 0x2d, + 0x31, 0x5d, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69, 0x66, 0x28, + 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x4e, + 0x69, 0x28, 0x6e, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, + 0x28, 0x74, 0x5b, 0x30, 0x5d, 0x2e, 0x7a, 0x2b, 0x74, 0x5b, 0x74, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x2e, + 0x7a, 0x29, 0x2f, 0x32, 0x3b, 0x72, 0x3f, 0x28, 0x6e, 0x2e, 0x7a, + 0x3d, 0x72, 0x2e, 0x7a, 0x2b, 0x61, 0x28, 0x6e, 0x2e, 0x5f, 0x2c, + 0x72, 0x2e, 0x5f, 0x29, 0x2c, 0x6e, 0x2e, 0x6d, 0x3d, 0x6e, 0x2e, + 0x7a, 0x2d, 0x69, 0x29, 0x3a, 0x6e, 0x2e, 0x7a, 0x3d, 0x69, 0x7d, + 0x65, 0x6c, 0x73, 0x65, 0x20, 0x72, 0x26, 0x26, 0x28, 0x6e, 0x2e, + 0x7a, 0x3d, 0x72, 0x2e, 0x7a, 0x2b, 0x61, 0x28, 0x6e, 0x2e, 0x5f, + 0x2c, 0x72, 0x2e, 0x5f, 0x29, 0x29, 0x3b, 0x6e, 0x2e, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x3d, 0x75, 0x28, 0x6e, 0x2c, + 0x72, 0x2c, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, + 0x41, 0x7c, 0x7c, 0x65, 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x6e, 0x29, + 0x7b, 0x6e, 0x2e, 0x5f, 0x2e, 0x78, 0x3d, 0x6e, 0x2e, 0x7a, 0x2b, + 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x6d, 0x2c, + 0x6e, 0x2e, 0x6d, 0x2b, 0x3d, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x2e, 0x6d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x3d, 0x6e, 0x2c, 0x69, + 0x3d, 0x6e, 0x2c, 0x6f, 0x3d, 0x74, 0x2c, 0x63, 0x3d, 0x75, 0x2e, + 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x5b, 0x30, 0x5d, 0x2c, 0x6c, 0x3d, 0x75, + 0x2e, 0x6d, 0x2c, 0x73, 0x3d, 0x69, 0x2e, 0x6d, 0x2c, 0x66, 0x3d, + 0x6f, 0x2e, 0x6d, 0x2c, 0x68, 0x3d, 0x63, 0x2e, 0x6d, 0x3b, 0x6f, + 0x3d, 0x45, 0x69, 0x28, 0x6f, 0x29, 0x2c, 0x75, 0x3d, 0x6b, 0x69, + 0x28, 0x75, 0x29, 0x2c, 0x6f, 0x26, 0x26, 0x75, 0x3b, 0x29, 0x63, + 0x3d, 0x6b, 0x69, 0x28, 0x63, 0x29, 0x2c, 0x69, 0x3d, 0x45, 0x69, + 0x28, 0x69, 0x29, 0x2c, 0x69, 0x2e, 0x61, 0x3d, 0x6e, 0x2c, 0x72, + 0x3d, 0x6f, 0x2e, 0x7a, 0x2b, 0x66, 0x2d, 0x75, 0x2e, 0x7a, 0x2d, + 0x6c, 0x2b, 0x61, 0x28, 0x6f, 0x2e, 0x5f, 0x2c, 0x75, 0x2e, 0x5f, + 0x29, 0x2c, 0x72, 0x3e, 0x30, 0x26, 0x26, 0x28, 0x41, 0x69, 0x28, + 0x43, 0x69, 0x28, 0x6f, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x2c, 0x6e, + 0x2c, 0x72, 0x29, 0x2c, 0x6c, 0x2b, 0x3d, 0x72, 0x2c, 0x73, 0x2b, + 0x3d, 0x72, 0x29, 0x2c, 0x66, 0x2b, 0x3d, 0x6f, 0x2e, 0x6d, 0x2c, + 0x6c, 0x2b, 0x3d, 0x75, 0x2e, 0x6d, 0x2c, 0x68, 0x2b, 0x3d, 0x63, + 0x2e, 0x6d, 0x2c, 0x73, 0x2b, 0x3d, 0x69, 0x2e, 0x6d, 0x3b, 0x6f, + 0x26, 0x26, 0x21, 0x45, 0x69, 0x28, 0x69, 0x29, 0x26, 0x26, 0x28, + 0x69, 0x2e, 0x74, 0x3d, 0x6f, 0x2c, 0x69, 0x2e, 0x6d, 0x2b, 0x3d, + 0x66, 0x2d, 0x73, 0x29, 0x2c, 0x75, 0x26, 0x26, 0x21, 0x6b, 0x69, + 0x28, 0x63, 0x29, 0x26, 0x26, 0x28, 0x63, 0x2e, 0x74, 0x3d, 0x75, + 0x2c, 0x63, 0x2e, 0x6d, 0x2b, 0x3d, 0x6c, 0x2d, 0x68, 0x2c, 0x65, + 0x3d, 0x6e, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x69, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x78, 0x2a, 0x3d, 0x63, + 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x2e, 0x79, 0x3d, 0x6e, 0x2e, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x2a, 0x63, 0x5b, 0x31, 0x5d, 0x7d, 0x76, + 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x79, + 0x6f, 0x75, 0x74, 0x2e, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, + 0x68, 0x79, 0x28, 0x29, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, 0x6e, + 0x75, 0x6c, 0x6c, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, + 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x61, 0x3d, 0x53, 0x69, 0x2c, + 0x63, 0x3d, 0x5b, 0x31, 0x2c, 0x31, 0x5d, 0x2c, 0x6c, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x2e, 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x61, 0x3d, 0x74, 0x2c, 0x6e, + 0x29, 0x3a, 0x61, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, 0x69, 0x7a, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6c, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, + 0x3d, 0x3d, 0x28, 0x63, 0x3d, 0x74, 0x29, 0x3f, 0x69, 0x3a, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x6e, 0x29, 0x3a, 0x6c, 0x3f, 0x6e, 0x75, + 0x6c, 0x6c, 0x3a, 0x63, 0x7d, 0x2c, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6c, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x28, 0x63, 0x3d, 0x74, + 0x29, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x69, 0x2c, 0x6e, 0x29, + 0x3a, 0x6c, 0x3f, 0x63, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, + 0x47, 0x75, 0x28, 0x6e, 0x2c, 0x6f, 0x29, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x2c, 0x69, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6f, 0x2c, 0x61, 0x3d, 0x74, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x69, + 0x29, 0x2c, 0x63, 0x3d, 0x61, 0x5b, 0x30, 0x5d, 0x2c, 0x6c, 0x3d, + 0x30, 0x3b, 0x51, 0x75, 0x28, 0x63, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, + 0x65, 0x6e, 0x3b, 0x74, 0x26, 0x26, 0x74, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6e, 0x2e, 0x78, 0x3d, 0x71, 0x69, + 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x2e, 0x79, 0x3d, 0x7a, 0x69, 0x28, + 0x74, 0x29, 0x29, 0x3a, 0x28, 0x6e, 0x2e, 0x78, 0x3d, 0x6f, 0x3f, + 0x6c, 0x2b, 0x3d, 0x65, 0x28, 0x6e, 0x2c, 0x6f, 0x29, 0x3a, 0x30, + 0x2c, 0x6e, 0x2e, 0x79, 0x3d, 0x30, 0x2c, 0x6f, 0x3d, 0x6e, 0x29, + 0x7d, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x4c, 0x69, + 0x28, 0x63, 0x29, 0x2c, 0x66, 0x3d, 0x54, 0x69, 0x28, 0x63, 0x29, + 0x2c, 0x68, 0x3d, 0x73, 0x2e, 0x78, 0x2d, 0x65, 0x28, 0x73, 0x2c, + 0x66, 0x29, 0x2f, 0x32, 0x2c, 0x67, 0x3d, 0x66, 0x2e, 0x78, 0x2b, + 0x65, 0x28, 0x66, 0x2c, 0x73, 0x29, 0x2f, 0x32, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x51, 0x75, 0x28, 0x63, 0x2c, 0x75, + 0x3f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x6e, 0x2e, 0x78, 0x3d, 0x28, 0x6e, 0x2e, 0x78, 0x2d, + 0x63, 0x2e, 0x78, 0x29, 0x2a, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x6e, + 0x2e, 0x79, 0x3d, 0x28, 0x63, 0x2e, 0x79, 0x2d, 0x6e, 0x2e, 0x79, + 0x29, 0x2a, 0x72, 0x5b, 0x31, 0x5d, 0x7d, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, + 0x78, 0x3d, 0x28, 0x6e, 0x2e, 0x78, 0x2d, 0x68, 0x29, 0x2f, 0x28, + 0x67, 0x2d, 0x68, 0x29, 0x2a, 0x72, 0x5b, 0x30, 0x5d, 0x2c, 0x6e, + 0x2e, 0x79, 0x3d, 0x28, 0x31, 0x2d, 0x28, 0x63, 0x2e, 0x79, 0x3f, + 0x6e, 0x2e, 0x79, 0x2f, 0x63, 0x2e, 0x79, 0x3a, 0x31, 0x29, 0x29, + 0x2a, 0x72, 0x5b, 0x31, 0x5d, 0x7d, 0x29, 0x2c, 0x61, 0x7d, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x79, + 0x6f, 0x75, 0x74, 0x2e, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, + 0x68, 0x79, 0x28, 0x29, 0x2e, 0x73, 0x6f, 0x72, 0x74, 0x28, 0x6e, + 0x75, 0x6c, 0x6c, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, + 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x65, 0x3d, 0x53, 0x69, 0x2c, + 0x72, 0x3d, 0x5b, 0x31, 0x2c, 0x31, 0x5d, 0x2c, 0x75, 0x3d, 0x21, + 0x31, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, + 0x73, 0x65, 0x70, 0x61, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, + 0x65, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x75, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, + 0x28, 0x72, 0x3d, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x75, 0x3f, + 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x75, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x28, 0x72, + 0x3d, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x75, 0x3f, 0x72, 0x3a, + 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x47, 0x75, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x79, 0x6f, + 0x75, 0x74, 0x2e, 0x74, 0x72, 0x65, 0x65, 0x6d, 0x61, 0x70, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, + 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3d, 0x2d, 0x31, 0x2c, + 0x69, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x2b, 0x2b, 0x75, 0x3c, 0x69, 0x3b, 0x29, 0x72, 0x3d, 0x28, 0x65, + 0x3d, 0x6e, 0x5b, 0x75, 0x5d, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x2a, 0x28, 0x30, 0x3e, 0x74, 0x3f, 0x30, 0x3a, 0x74, 0x29, + 0x2c, 0x65, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x69, 0x73, 0x4e, + 0x61, 0x4e, 0x28, 0x72, 0x29, 0x7c, 0x7c, 0x30, 0x3e, 0x3d, 0x72, + 0x3f, 0x30, 0x3a, 0x72, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x74, 0x28, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x3d, 0x65, 0x2e, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, + 0x65, 0x6e, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x26, 0x26, 0x69, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6f, 0x2c, 0x61, 0x2c, 0x63, 0x2c, 0x6c, 0x3d, 0x66, 0x28, + 0x65, 0x29, 0x2c, 0x73, 0x3d, 0x5b, 0x5d, 0x2c, 0x68, 0x3d, 0x69, + 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x29, 0x2c, 0x70, 0x3d, + 0x31, 0x2f, 0x30, 0x2c, 0x76, 0x3d, 0x22, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x22, 0x3d, 0x3d, 0x3d, 0x67, 0x3f, 0x6c, 0x2e, 0x64, 0x78, + 0x3a, 0x22, 0x64, 0x69, 0x63, 0x65, 0x22, 0x3d, 0x3d, 0x3d, 0x67, + 0x3f, 0x6c, 0x2e, 0x64, 0x79, 0x3a, 0x22, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x2d, 0x64, 0x69, 0x63, 0x65, 0x22, 0x3d, 0x3d, 0x3d, 0x67, + 0x3f, 0x31, 0x26, 0x65, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x3f, + 0x6c, 0x2e, 0x64, 0x79, 0x3a, 0x6c, 0x2e, 0x64, 0x78, 0x3a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6c, 0x2e, 0x64, + 0x78, 0x2c, 0x6c, 0x2e, 0x64, 0x79, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x6e, 0x28, 0x68, 0x2c, 0x6c, 0x2e, 0x64, 0x78, 0x2a, 0x6c, + 0x2e, 0x64, 0x79, 0x2f, 0x65, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x29, 0x2c, 0x73, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x30, 0x3b, + 0x28, 0x63, 0x3d, 0x68, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x29, 0x3e, 0x30, 0x3b, 0x29, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x6f, 0x3d, 0x68, 0x5b, 0x63, 0x2d, 0x31, 0x5d, 0x29, 0x2c, + 0x73, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x2b, 0x3d, 0x6f, 0x2e, 0x61, + 0x72, 0x65, 0x61, 0x2c, 0x22, 0x73, 0x71, 0x75, 0x61, 0x72, 0x69, + 0x66, 0x79, 0x22, 0x21, 0x3d, 0x3d, 0x67, 0x7c, 0x7c, 0x28, 0x61, + 0x3d, 0x72, 0x28, 0x73, 0x2c, 0x76, 0x29, 0x29, 0x3c, 0x3d, 0x70, + 0x3f, 0x28, 0x68, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2c, 0x70, + 0x3d, 0x61, 0x29, 0x3a, 0x28, 0x73, 0x2e, 0x61, 0x72, 0x65, 0x61, + 0x2d, 0x3d, 0x73, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2e, 0x61, + 0x72, 0x65, 0x61, 0x2c, 0x75, 0x28, 0x73, 0x2c, 0x76, 0x2c, 0x6c, + 0x2c, 0x21, 0x31, 0x29, 0x2c, 0x76, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x6c, 0x2e, 0x64, 0x78, 0x2c, 0x6c, + 0x2e, 0x64, 0x79, 0x29, 0x2c, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3d, 0x73, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x30, + 0x2c, 0x70, 0x3d, 0x31, 0x2f, 0x30, 0x29, 0x3b, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x26, 0x26, 0x28, 0x75, 0x28, 0x73, + 0x2c, 0x76, 0x2c, 0x6c, 0x2c, 0x21, 0x30, 0x29, 0x2c, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x73, 0x2e, 0x61, 0x72, + 0x65, 0x61, 0x3d, 0x30, 0x29, 0x2c, 0x69, 0x2e, 0x66, 0x6f, 0x72, + 0x45, 0x61, 0x63, 0x68, 0x28, 0x74, 0x29, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x74, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x68, + 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x3b, 0x69, 0x66, 0x28, 0x72, + 0x26, 0x26, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x2c, 0x6f, 0x3d, 0x66, 0x28, + 0x74, 0x29, 0x2c, 0x61, 0x3d, 0x72, 0x2e, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x28, 0x29, 0x2c, 0x63, 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x6e, 0x28, 0x61, 0x2c, 0x6f, 0x2e, 0x64, 0x78, 0x2a, + 0x6f, 0x2e, 0x64, 0x79, 0x2f, 0x74, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x29, 0x2c, 0x63, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x30, + 0x3b, 0x69, 0x3d, 0x61, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x3b, + 0x29, 0x63, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x69, 0x29, 0x2c, + 0x63, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x2b, 0x3d, 0x69, 0x2e, 0x61, + 0x72, 0x65, 0x61, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x69, + 0x2e, 0x7a, 0x26, 0x26, 0x28, 0x75, 0x28, 0x63, 0x2c, 0x69, 0x2e, + 0x7a, 0x3f, 0x6f, 0x2e, 0x64, 0x78, 0x3a, 0x6f, 0x2e, 0x64, 0x79, + 0x2c, 0x6f, 0x2c, 0x21, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x29, 0x2c, 0x63, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3d, 0x63, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x30, 0x29, 0x3b, + 0x72, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x65, + 0x29, 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x72, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, 0x3d, 0x6e, 0x2e, + 0x61, 0x72, 0x65, 0x61, 0x2c, 0x75, 0x3d, 0x30, 0x2c, 0x69, 0x3d, + 0x31, 0x2f, 0x30, 0x2c, 0x6f, 0x3d, 0x2d, 0x31, 0x2c, 0x61, 0x3d, + 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, + 0x6f, 0x3c, 0x61, 0x3b, 0x29, 0x28, 0x65, 0x3d, 0x6e, 0x5b, 0x6f, + 0x5d, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x29, 0x26, 0x26, 0x28, 0x69, + 0x3e, 0x65, 0x26, 0x26, 0x28, 0x69, 0x3d, 0x65, 0x29, 0x2c, 0x65, + 0x3e, 0x75, 0x26, 0x26, 0x28, 0x75, 0x3d, 0x65, 0x29, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x2a, 0x3d, 0x72, + 0x2c, 0x74, 0x2a, 0x3d, 0x74, 0x2c, 0x72, 0x3f, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x74, 0x2a, 0x75, 0x2a, 0x70, + 0x2f, 0x72, 0x2c, 0x72, 0x2f, 0x28, 0x74, 0x2a, 0x69, 0x2a, 0x70, + 0x29, 0x29, 0x3a, 0x31, 0x2f, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x2c, + 0x65, 0x2c, 0x72, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, + 0x69, 0x3d, 0x2d, 0x31, 0x2c, 0x6f, 0x3d, 0x6e, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x61, 0x3d, 0x65, 0x2e, 0x78, 0x2c, + 0x6c, 0x3d, 0x65, 0x2e, 0x79, 0x2c, 0x73, 0x3d, 0x74, 0x3f, 0x63, + 0x28, 0x6e, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x2f, 0x74, 0x29, 0x3a, + 0x30, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x3d, 0x3d, 0x65, 0x2e, 0x64, + 0x78, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x28, 0x72, 0x7c, 0x7c, + 0x73, 0x3e, 0x65, 0x2e, 0x64, 0x79, 0x29, 0x26, 0x26, 0x28, 0x73, + 0x3d, 0x65, 0x2e, 0x64, 0x79, 0x29, 0x3b, 0x2b, 0x2b, 0x69, 0x3c, + 0x6f, 0x3b, 0x29, 0x75, 0x3d, 0x6e, 0x5b, 0x69, 0x5d, 0x2c, 0x75, + 0x2e, 0x78, 0x3d, 0x61, 0x2c, 0x75, 0x2e, 0x79, 0x3d, 0x6c, 0x2c, + 0x75, 0x2e, 0x64, 0x79, 0x3d, 0x73, 0x2c, 0x61, 0x2b, 0x3d, 0x75, + 0x2e, 0x64, 0x78, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x65, 0x2e, 0x78, 0x2b, 0x65, 0x2e, 0x64, 0x78, 0x2d, + 0x61, 0x2c, 0x73, 0x3f, 0x63, 0x28, 0x75, 0x2e, 0x61, 0x72, 0x65, + 0x61, 0x2f, 0x73, 0x29, 0x3a, 0x30, 0x29, 0x3b, 0x75, 0x2e, 0x7a, + 0x3d, 0x21, 0x30, 0x2c, 0x75, 0x2e, 0x64, 0x78, 0x2b, 0x3d, 0x65, + 0x2e, 0x78, 0x2b, 0x65, 0x2e, 0x64, 0x78, 0x2d, 0x61, 0x2c, 0x65, + 0x2e, 0x79, 0x2b, 0x3d, 0x73, 0x2c, 0x65, 0x2e, 0x64, 0x79, 0x2d, + 0x3d, 0x73, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x66, 0x6f, 0x72, + 0x28, 0x28, 0x72, 0x7c, 0x7c, 0x73, 0x3e, 0x65, 0x2e, 0x64, 0x78, + 0x29, 0x26, 0x26, 0x28, 0x73, 0x3d, 0x65, 0x2e, 0x64, 0x78, 0x29, + 0x3b, 0x2b, 0x2b, 0x69, 0x3c, 0x6f, 0x3b, 0x29, 0x75, 0x3d, 0x6e, + 0x5b, 0x69, 0x5d, 0x2c, 0x75, 0x2e, 0x78, 0x3d, 0x61, 0x2c, 0x75, + 0x2e, 0x79, 0x3d, 0x6c, 0x2c, 0x75, 0x2e, 0x64, 0x78, 0x3d, 0x73, + 0x2c, 0x6c, 0x2b, 0x3d, 0x75, 0x2e, 0x64, 0x79, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x65, 0x2e, 0x79, 0x2b, + 0x65, 0x2e, 0x64, 0x79, 0x2d, 0x6c, 0x2c, 0x73, 0x3f, 0x63, 0x28, + 0x75, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x2f, 0x73, 0x29, 0x3a, 0x30, + 0x29, 0x3b, 0x75, 0x2e, 0x7a, 0x3d, 0x21, 0x31, 0x2c, 0x75, 0x2e, + 0x64, 0x79, 0x2b, 0x3d, 0x65, 0x2e, 0x79, 0x2b, 0x65, 0x2e, 0x64, + 0x79, 0x2d, 0x6c, 0x2c, 0x65, 0x2e, 0x78, 0x2b, 0x3d, 0x73, 0x2c, + 0x65, 0x2e, 0x64, 0x78, 0x2d, 0x3d, 0x73, 0x7d, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x72, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x6f, 0x7c, 0x7c, 0x61, + 0x28, 0x72, 0x29, 0x2c, 0x69, 0x3d, 0x75, 0x5b, 0x30, 0x5d, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x2e, 0x78, 0x3d, + 0x30, 0x2c, 0x69, 0x2e, 0x79, 0x3d, 0x30, 0x2c, 0x69, 0x2e, 0x64, + 0x78, 0x3d, 0x6c, 0x5b, 0x30, 0x5d, 0x2c, 0x69, 0x2e, 0x64, 0x79, + 0x3d, 0x6c, 0x5b, 0x31, 0x5d, 0x2c, 0x6f, 0x26, 0x26, 0x61, 0x2e, + 0x72, 0x65, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x28, 0x69, 0x29, 0x2c, + 0x6e, 0x28, 0x5b, 0x69, 0x5d, 0x2c, 0x69, 0x2e, 0x64, 0x78, 0x2a, + 0x69, 0x2e, 0x64, 0x79, 0x2f, 0x69, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x29, 0x2c, 0x28, 0x6f, 0x3f, 0x65, 0x3a, 0x74, 0x29, 0x28, + 0x69, 0x29, 0x2c, 0x68, 0x26, 0x26, 0x28, 0x6f, 0x3d, 0x75, 0x29, + 0x2c, 0x75, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x2c, 0x61, 0x3d, + 0x74, 0x61, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2e, 0x68, + 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x28, 0x29, 0x2c, + 0x63, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x2c, 0x6c, 0x3d, 0x5b, 0x31, 0x2c, 0x31, 0x5d, 0x2c, 0x73, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x66, 0x3d, 0x52, 0x69, 0x2c, + 0x68, 0x3d, 0x21, 0x31, 0x2c, 0x67, 0x3d, 0x22, 0x73, 0x71, 0x75, + 0x61, 0x72, 0x69, 0x66, 0x79, 0x22, 0x2c, 0x70, 0x3d, 0x2e, 0x35, + 0x2a, 0x28, 0x31, 0x2b, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x35, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x6c, 0x3d, 0x6e, 0x2c, 0x69, 0x29, 0x3a, 0x6c, + 0x7d, 0x2c, 0x69, 0x2e, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x6e, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x69, 0x2c, 0x74, 0x2c, + 0x74, 0x2e, 0x64, 0x65, 0x70, 0x74, 0x68, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, + 0x65, 0x3f, 0x52, 0x69, 0x28, 0x74, 0x29, 0x3a, 0x44, 0x69, 0x28, + 0x74, 0x2c, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3d, + 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x3f, 0x5b, + 0x65, 0x2c, 0x65, 0x2c, 0x65, 0x2c, 0x65, 0x5d, 0x3a, 0x65, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x44, 0x69, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7d, 0x69, 0x66, 0x28, + 0x21, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x73, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x3d, 0x3d, 0x28, 0x73, 0x3d, 0x6e, 0x29, 0x3f, 0x52, + 0x69, 0x3a, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3d, 0x3d, 0x28, 0x72, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, + 0x66, 0x20, 0x6e, 0x29, 0x3f, 0x74, 0x3a, 0x22, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x22, 0x3d, 0x3d, 0x3d, 0x72, 0x3f, 0x28, 0x6e, + 0x3d, 0x5b, 0x6e, 0x2c, 0x6e, 0x2c, 0x6e, 0x2c, 0x6e, 0x5d, 0x2c, + 0x65, 0x29, 0x3a, 0x65, 0x2c, 0x69, 0x7d, 0x2c, 0x69, 0x2e, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x63, 0x3d, + 0x6e, 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x6f, 0x75, 0x6e, + 0x64, 0x3a, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x2c, 0x69, 0x29, + 0x3a, 0x63, 0x21, 0x3d, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x7d, + 0x2c, 0x69, 0x2e, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x79, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x68, 0x3d, 0x6e, 0x2c, 0x6f, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x2c, 0x69, 0x29, 0x3a, 0x68, 0x7d, 0x2c, 0x69, 0x2e, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x70, + 0x3d, 0x6e, 0x2c, 0x69, 0x29, 0x3a, 0x70, 0x7d, 0x2c, 0x69, 0x2e, + 0x6d, 0x6f, 0x64, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x67, 0x3d, + 0x6e, 0x2b, 0x22, 0x22, 0x2c, 0x69, 0x29, 0x3a, 0x67, 0x7d, 0x2c, + 0x47, 0x75, 0x28, 0x69, 0x2c, 0x61, 0x29, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x3d, 0x7b, 0x6e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x65, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x32, 0x3e, 0x65, 0x26, 0x26, 0x28, + 0x74, 0x3d, 0x31, 0x29, 0x2c, 0x31, 0x3e, 0x65, 0x26, 0x26, 0x28, + 0x6e, 0x3d, 0x30, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, + 0x72, 0x2c, 0x75, 0x3b, 0x64, 0x6f, 0x20, 0x65, 0x3d, 0x32, 0x2a, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, + 0x28, 0x29, 0x2d, 0x31, 0x2c, 0x72, 0x3d, 0x32, 0x2a, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, + 0x2d, 0x31, 0x2c, 0x75, 0x3d, 0x65, 0x2a, 0x65, 0x2b, 0x72, 0x2a, + 0x72, 0x3b, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x28, 0x21, 0x75, 0x7c, + 0x7c, 0x75, 0x3e, 0x31, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2b, 0x74, 0x2a, 0x65, 0x2a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x2d, 0x32, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x75, 0x29, 0x2f, + 0x75, 0x29, 0x7d, 0x7d, 0x2c, 0x6c, 0x6f, 0x67, 0x4e, 0x6f, 0x72, + 0x6d, 0x61, 0x6c, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x74, + 0x61, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x2e, 0x6e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, + 0x74, 0x61, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x65, 0x78, 0x70, 0x28, 0x6e, 0x28, 0x29, 0x29, 0x7d, 0x7d, 0x2c, + 0x62, 0x61, 0x74, 0x65, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, + 0x2e, 0x69, 0x72, 0x77, 0x69, 0x6e, 0x48, 0x61, 0x6c, 0x6c, 0x28, + 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x28, 0x29, 0x2f, 0x6e, + 0x7d, 0x7d, 0x2c, 0x69, 0x72, 0x77, 0x69, 0x6e, 0x48, 0x61, 0x6c, + 0x6c, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x30, 0x2c, + 0x65, 0x3d, 0x30, 0x3b, 0x6e, 0x3e, 0x65, 0x3b, 0x65, 0x2b, 0x2b, + 0x29, 0x74, 0x2b, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x72, 0x61, + 0x6e, 0x64, 0x6f, 0x6d, 0x28, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x7d, 0x7d, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x3d, 0x7b, 0x7d, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x6d, 0x6c, 0x3d, 0x7b, 0x66, 0x6c, 0x6f, 0x6f, 0x72, + 0x3a, 0x79, 0x2c, 0x63, 0x65, 0x69, 0x6c, 0x3a, 0x79, 0x7d, 0x3b, + 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x61, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x49, 0x69, 0x28, 0x5b, 0x30, 0x2c, 0x31, 0x5d, 0x2c, 0x5b, + 0x30, 0x2c, 0x31, 0x5d, 0x2c, 0x6d, 0x75, 0x2c, 0x21, 0x31, 0x29, + 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x79, 0x6c, 0x3d, 0x7b, 0x73, + 0x3a, 0x31, 0x2c, 0x67, 0x3a, 0x31, 0x2c, 0x70, 0x3a, 0x31, 0x2c, + 0x72, 0x3a, 0x31, 0x2c, 0x65, 0x3a, 0x31, 0x7d, 0x3b, 0x74, 0x61, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4a, 0x69, 0x28, 0x74, + 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x61, 0x72, 0x28, 0x29, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, + 0x6e, 0x28, 0x5b, 0x30, 0x2c, 0x31, 0x5d, 0x29, 0x2c, 0x31, 0x30, + 0x2c, 0x21, 0x30, 0x2c, 0x5b, 0x31, 0x2c, 0x31, 0x30, 0x5d, 0x29, + 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x4d, 0x6c, 0x3d, 0x74, 0x61, + 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x28, 0x22, 0x2e, 0x30, + 0x65, 0x22, 0x29, 0x2c, 0x78, 0x6c, 0x3d, 0x7b, 0x66, 0x6c, 0x6f, + 0x6f, 0x72, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x2d, + 0x6e, 0x29, 0x7d, 0x2c, 0x63, 0x65, 0x69, 0x6c, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x2d, 0x6e, 0x29, 0x7d, 0x7d, + 0x3b, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x70, + 0x6f, 0x77, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, + 0x69, 0x28, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x28, 0x29, 0x2c, 0x31, 0x2c, + 0x5b, 0x30, 0x2c, 0x31, 0x5d, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x70, 0x6f, 0x77, 0x28, 0x29, 0x2e, + 0x65, 0x78, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x28, 0x2e, 0x35, + 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x51, 0x69, 0x28, 0x5b, 0x5d, 0x2c, + 0x7b, 0x74, 0x3a, 0x22, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x22, 0x2c, + 0x61, 0x3a, 0x5b, 0x5b, 0x5d, 0x5d, 0x7d, 0x29, 0x7d, 0x2c, 0x74, + 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x63, 0x61, 0x74, + 0x65, 0x67, 0x6f, 0x72, 0x79, 0x31, 0x30, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, + 0x65, 0x2e, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x28, 0x29, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x62, 0x6c, 0x29, 0x7d, + 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x63, + 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x32, 0x30, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, 0x2e, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2e, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, + 0x28, 0x29, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x5f, 0x6c, + 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, + 0x2e, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x32, 0x30, + 0x62, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, + 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6f, 0x72, 0x64, 0x69, + 0x6e, 0x61, 0x6c, 0x28, 0x29, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x28, 0x77, 0x6c, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2e, 0x63, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, + 0x79, 0x32, 0x30, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6f, + 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x28, 0x29, 0x2e, 0x72, 0x61, + 0x6e, 0x67, 0x65, 0x28, 0x53, 0x6c, 0x29, 0x7d, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x62, 0x6c, 0x3d, 0x5b, 0x32, 0x30, 0x36, 0x32, 0x32, + 0x36, 0x30, 0x2c, 0x31, 0x36, 0x37, 0x34, 0x34, 0x32, 0x30, 0x36, + 0x2c, 0x32, 0x39, 0x32, 0x34, 0x35, 0x38, 0x38, 0x2c, 0x31, 0x34, + 0x30, 0x33, 0x34, 0x37, 0x32, 0x38, 0x2c, 0x39, 0x37, 0x32, 0x35, + 0x38, 0x38, 0x35, 0x2c, 0x39, 0x31, 0x39, 0x37, 0x31, 0x33, 0x31, + 0x2c, 0x31, 0x34, 0x39, 0x30, 0x37, 0x33, 0x33, 0x30, 0x2c, 0x38, + 0x33, 0x35, 0x35, 0x37, 0x31, 0x31, 0x2c, 0x31, 0x32, 0x33, 0x36, + 0x39, 0x31, 0x38, 0x36, 0x2c, 0x31, 0x35, 0x35, 0x36, 0x31, 0x37, + 0x35, 0x5d, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x4d, 0x74, 0x29, 0x2c, + 0x5f, 0x6c, 0x3d, 0x5b, 0x32, 0x30, 0x36, 0x32, 0x32, 0x36, 0x30, + 0x2c, 0x31, 0x31, 0x34, 0x35, 0x34, 0x34, 0x34, 0x30, 0x2c, 0x31, + 0x36, 0x37, 0x34, 0x34, 0x32, 0x30, 0x36, 0x2c, 0x31, 0x36, 0x37, + 0x35, 0x39, 0x36, 0x37, 0x32, 0x2c, 0x32, 0x39, 0x32, 0x34, 0x35, + 0x38, 0x38, 0x2c, 0x31, 0x30, 0x30, 0x31, 0x38, 0x36, 0x39, 0x38, + 0x2c, 0x31, 0x34, 0x30, 0x33, 0x34, 0x37, 0x32, 0x38, 0x2c, 0x31, + 0x36, 0x37, 0x35, 0x30, 0x37, 0x34, 0x32, 0x2c, 0x39, 0x37, 0x32, + 0x35, 0x38, 0x38, 0x35, 0x2c, 0x31, 0x32, 0x39, 0x35, 0x35, 0x38, + 0x36, 0x31, 0x2c, 0x39, 0x31, 0x39, 0x37, 0x31, 0x33, 0x31, 0x2c, + 0x31, 0x32, 0x38, 0x38, 0x35, 0x31, 0x34, 0x30, 0x2c, 0x31, 0x34, + 0x39, 0x30, 0x37, 0x33, 0x33, 0x30, 0x2c, 0x31, 0x36, 0x32, 0x33, + 0x34, 0x31, 0x39, 0x34, 0x2c, 0x38, 0x33, 0x35, 0x35, 0x37, 0x31, + 0x31, 0x2c, 0x31, 0x33, 0x30, 0x39, 0x32, 0x38, 0x30, 0x37, 0x2c, + 0x31, 0x32, 0x33, 0x36, 0x39, 0x31, 0x38, 0x36, 0x2c, 0x31, 0x34, + 0x34, 0x30, 0x38, 0x35, 0x38, 0x39, 0x2c, 0x31, 0x35, 0x35, 0x36, + 0x31, 0x37, 0x35, 0x2c, 0x31, 0x30, 0x34, 0x31, 0x30, 0x37, 0x32, + 0x35, 0x5d, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x4d, 0x74, 0x29, 0x2c, + 0x77, 0x6c, 0x3d, 0x5b, 0x33, 0x37, 0x35, 0x30, 0x37, 0x37, 0x37, + 0x2c, 0x35, 0x33, 0x39, 0x35, 0x36, 0x31, 0x39, 0x2c, 0x37, 0x30, + 0x34, 0x30, 0x37, 0x31, 0x39, 0x2c, 0x31, 0x30, 0x32, 0x36, 0x34, + 0x32, 0x38, 0x36, 0x2c, 0x36, 0x35, 0x31, 0x39, 0x30, 0x39, 0x37, + 0x2c, 0x39, 0x32, 0x31, 0x36, 0x35, 0x39, 0x34, 0x2c, 0x31, 0x31, + 0x39, 0x31, 0x35, 0x31, 0x31, 0x35, 0x2c, 0x31, 0x33, 0x35, 0x35, + 0x36, 0x36, 0x33, 0x36, 0x2c, 0x39, 0x32, 0x30, 0x32, 0x39, 0x39, + 0x33, 0x2c, 0x31, 0x32, 0x34, 0x32, 0x36, 0x38, 0x30, 0x39, 0x2c, + 0x31, 0x35, 0x31, 0x38, 0x36, 0x35, 0x31, 0x34, 0x2c, 0x31, 0x35, + 0x31, 0x39, 0x30, 0x39, 0x33, 0x32, 0x2c, 0x38, 0x36, 0x36, 0x36, + 0x31, 0x36, 0x39, 0x2c, 0x31, 0x31, 0x33, 0x35, 0x36, 0x34, 0x39, + 0x30, 0x2c, 0x31, 0x34, 0x30, 0x34, 0x39, 0x36, 0x34, 0x33, 0x2c, + 0x31, 0x35, 0x31, 0x37, 0x37, 0x33, 0x37, 0x32, 0x2c, 0x38, 0x30, + 0x37, 0x37, 0x36, 0x38, 0x33, 0x2c, 0x31, 0x30, 0x38, 0x33, 0x34, + 0x33, 0x32, 0x34, 0x2c, 0x31, 0x33, 0x35, 0x32, 0x38, 0x35, 0x30, + 0x39, 0x2c, 0x31, 0x34, 0x35, 0x38, 0x39, 0x36, 0x35, 0x34, 0x5d, + 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x4d, 0x74, 0x29, 0x2c, 0x53, 0x6c, + 0x3d, 0x5b, 0x33, 0x32, 0x34, 0x34, 0x37, 0x33, 0x33, 0x2c, 0x37, + 0x30, 0x35, 0x37, 0x31, 0x31, 0x30, 0x2c, 0x31, 0x30, 0x34, 0x30, + 0x36, 0x36, 0x32, 0x35, 0x2c, 0x31, 0x33, 0x30, 0x33, 0x32, 0x34, + 0x33, 0x31, 0x2c, 0x31, 0x35, 0x30, 0x39, 0x35, 0x30, 0x35, 0x33, + 0x2c, 0x31, 0x36, 0x36, 0x31, 0x36, 0x37, 0x36, 0x34, 0x2c, 0x31, + 0x36, 0x36, 0x32, 0x35, 0x32, 0x35, 0x39, 0x2c, 0x31, 0x36, 0x36, + 0x33, 0x34, 0x30, 0x31, 0x38, 0x2c, 0x33, 0x32, 0x35, 0x33, 0x30, + 0x37, 0x36, 0x2c, 0x37, 0x36, 0x35, 0x32, 0x34, 0x37, 0x30, 0x2c, + 0x31, 0x30, 0x36, 0x30, 0x37, 0x30, 0x30, 0x33, 0x2c, 0x31, 0x33, + 0x31, 0x30, 0x31, 0x35, 0x30, 0x34, 0x2c, 0x37, 0x36, 0x39, 0x35, + 0x32, 0x38, 0x31, 0x2c, 0x31, 0x30, 0x33, 0x39, 0x34, 0x33, 0x31, + 0x32, 0x2c, 0x31, 0x32, 0x33, 0x36, 0x39, 0x33, 0x37, 0x32, 0x2c, + 0x31, 0x34, 0x33, 0x34, 0x32, 0x38, 0x39, 0x31, 0x2c, 0x36, 0x35, + 0x31, 0x33, 0x35, 0x30, 0x37, 0x2c, 0x39, 0x38, 0x36, 0x38, 0x39, + 0x35, 0x30, 0x2c, 0x31, 0x32, 0x34, 0x33, 0x34, 0x38, 0x37, 0x37, + 0x2c, 0x31, 0x34, 0x32, 0x37, 0x37, 0x30, 0x38, 0x31, 0x5d, 0x2e, + 0x6d, 0x61, 0x70, 0x28, 0x4d, 0x74, 0x29, 0x3b, 0x74, 0x61, 0x2e, + 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x71, 0x75, 0x61, 0x6e, 0x74, + 0x69, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x6f, 0x28, 0x5b, 0x5d, 0x2c, 0x5b, 0x5d, 0x29, 0x7d, 0x2c, + 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x71, 0x75, + 0x61, 0x6e, 0x74, 0x69, 0x7a, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x6f, 0x28, 0x30, 0x2c, 0x31, 0x2c, 0x5b, + 0x30, 0x2c, 0x31, 0x5d, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, + 0x6f, 0x6c, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x6f, 0x28, 0x5b, 0x2e, 0x35, 0x5d, 0x2c, 0x5b, 0x30, 0x2c, + 0x31, 0x5d, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x2e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x6f, 0x28, + 0x5b, 0x30, 0x2c, 0x31, 0x5d, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x73, 0x76, 0x67, 0x3d, 0x7b, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, + 0x76, 0x67, 0x2e, 0x61, 0x72, 0x63, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6e, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, + 0x78, 0x28, 0x30, 0x2c, 0x2b, 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x29, 0x2c, 0x6c, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x30, 0x2c, 0x2b, + 0x72, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x29, 0x2c, 0x73, 0x3d, 0x6f, 0x2e, 0x61, 0x70, 0x70, 0x6c, + 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x2d, 0x52, 0x61, 0x2c, 0x66, + 0x3d, 0x61, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x29, 0x2d, 0x52, 0x61, 0x2c, 0x68, 0x3d, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x61, 0x62, 0x73, 0x28, 0x66, 0x2d, 0x73, 0x29, 0x2c, + 0x67, 0x3d, 0x73, 0x3e, 0x66, 0x3f, 0x30, 0x3a, 0x31, 0x3b, 0x69, + 0x66, 0x28, 0x6e, 0x3e, 0x6c, 0x26, 0x26, 0x28, 0x70, 0x3d, 0x6c, + 0x2c, 0x6c, 0x3d, 0x6e, 0x2c, 0x6e, 0x3d, 0x70, 0x29, 0x2c, 0x68, + 0x3e, 0x3d, 0x54, 0x61, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x74, 0x28, 0x6c, 0x2c, 0x67, 0x29, 0x2b, 0x28, 0x6e, 0x3f, + 0x74, 0x28, 0x6e, 0x2c, 0x31, 0x2d, 0x67, 0x29, 0x3a, 0x22, 0x22, + 0x29, 0x2b, 0x22, 0x5a, 0x22, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x70, + 0x2c, 0x76, 0x2c, 0x64, 0x2c, 0x6d, 0x2c, 0x79, 0x2c, 0x4d, 0x2c, + 0x78, 0x2c, 0x62, 0x2c, 0x5f, 0x2c, 0x77, 0x2c, 0x53, 0x2c, 0x6b, + 0x2c, 0x45, 0x3d, 0x30, 0x2c, 0x41, 0x3d, 0x30, 0x2c, 0x4e, 0x3d, + 0x5b, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x28, 0x6d, 0x3d, 0x28, 0x2b, + 0x63, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x7c, 0x7c, 0x30, 0x29, 0x2f, 0x32, 0x29, 0x26, 0x26, 0x28, + 0x64, 0x3d, 0x69, 0x3d, 0x3d, 0x3d, 0x6b, 0x6c, 0x3f, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x6e, 0x2a, 0x6e, + 0x2b, 0x6c, 0x2a, 0x6c, 0x29, 0x3a, 0x2b, 0x69, 0x2e, 0x61, 0x70, + 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x2c, 0x67, 0x7c, + 0x7c, 0x28, 0x41, 0x2a, 0x3d, 0x2d, 0x31, 0x29, 0x2c, 0x6c, 0x26, + 0x26, 0x28, 0x41, 0x3d, 0x74, 0x74, 0x28, 0x64, 0x2f, 0x6c, 0x2a, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x6d, 0x29, + 0x29, 0x29, 0x2c, 0x6e, 0x26, 0x26, 0x28, 0x45, 0x3d, 0x74, 0x74, + 0x28, 0x64, 0x2f, 0x6e, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x69, 0x6e, 0x28, 0x6d, 0x29, 0x29, 0x29, 0x29, 0x2c, 0x6c, 0x29, + 0x7b, 0x79, 0x3d, 0x6c, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, + 0x6f, 0x73, 0x28, 0x73, 0x2b, 0x41, 0x29, 0x2c, 0x4d, 0x3d, 0x6c, + 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x73, + 0x2b, 0x41, 0x29, 0x2c, 0x78, 0x3d, 0x6c, 0x2a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x66, 0x2d, 0x41, 0x29, 0x2c, + 0x62, 0x3d, 0x6c, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, + 0x6e, 0x28, 0x66, 0x2d, 0x41, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x43, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, 0x62, 0x73, 0x28, + 0x66, 0x2d, 0x73, 0x2d, 0x32, 0x2a, 0x41, 0x29, 0x3c, 0x3d, 0x71, + 0x61, 0x3f, 0x30, 0x3a, 0x31, 0x3b, 0x69, 0x66, 0x28, 0x41, 0x26, + 0x26, 0x73, 0x6f, 0x28, 0x79, 0x2c, 0x4d, 0x2c, 0x78, 0x2c, 0x62, + 0x29, 0x3d, 0x3d, 0x3d, 0x67, 0x5e, 0x43, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x7a, 0x3d, 0x28, 0x73, 0x2b, 0x66, 0x29, 0x2f, 0x32, + 0x3b, 0x79, 0x3d, 0x6c, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, + 0x6f, 0x73, 0x28, 0x7a, 0x29, 0x2c, 0x4d, 0x3d, 0x6c, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x7a, 0x29, 0x2c, + 0x78, 0x3d, 0x62, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x7d, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x79, 0x3d, 0x4d, 0x3d, 0x30, 0x3b, 0x69, + 0x66, 0x28, 0x6e, 0x29, 0x7b, 0x5f, 0x3d, 0x6e, 0x2a, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x66, 0x2d, 0x45, 0x29, + 0x2c, 0x77, 0x3d, 0x6e, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x69, 0x6e, 0x28, 0x66, 0x2d, 0x45, 0x29, 0x2c, 0x53, 0x3d, 0x6e, + 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x73, + 0x2b, 0x45, 0x29, 0x2c, 0x6b, 0x3d, 0x6e, 0x2a, 0x4d, 0x61, 0x74, + 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x73, 0x2b, 0x45, 0x29, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x71, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x61, 0x62, 0x73, 0x28, 0x73, 0x2d, 0x66, 0x2b, 0x32, 0x2a, 0x45, + 0x29, 0x3c, 0x3d, 0x71, 0x61, 0x3f, 0x30, 0x3a, 0x31, 0x3b, 0x69, + 0x66, 0x28, 0x45, 0x26, 0x26, 0x73, 0x6f, 0x28, 0x5f, 0x2c, 0x77, + 0x2c, 0x53, 0x2c, 0x6b, 0x29, 0x3d, 0x3d, 0x3d, 0x31, 0x2d, 0x67, + 0x5e, 0x71, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x4c, 0x3d, 0x28, + 0x73, 0x2b, 0x66, 0x29, 0x2f, 0x32, 0x3b, 0x5f, 0x3d, 0x6e, 0x2a, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x4c, 0x29, + 0x2c, 0x77, 0x3d, 0x6e, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x69, 0x6e, 0x28, 0x4c, 0x29, 0x2c, 0x53, 0x3d, 0x6b, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x5f, + 0x3d, 0x77, 0x3d, 0x30, 0x3b, 0x69, 0x66, 0x28, 0x28, 0x70, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x61, 0x62, 0x73, 0x28, 0x6c, 0x2d, 0x6e, 0x29, + 0x2f, 0x32, 0x2c, 0x2b, 0x75, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x29, 0x29, 0x3e, 0x2e, 0x30, 0x30, + 0x31, 0x29, 0x7b, 0x76, 0x3d, 0x6c, 0x3e, 0x6e, 0x5e, 0x67, 0x3f, + 0x30, 0x3a, 0x31, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x54, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x53, 0x3f, 0x5b, 0x5f, 0x2c, 0x77, + 0x5d, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x78, 0x3f, 0x5b, + 0x79, 0x2c, 0x4d, 0x5d, 0x3a, 0x4c, 0x72, 0x28, 0x5b, 0x79, 0x2c, + 0x4d, 0x5d, 0x2c, 0x5b, 0x53, 0x2c, 0x6b, 0x5d, 0x2c, 0x5b, 0x78, + 0x2c, 0x62, 0x5d, 0x2c, 0x5b, 0x5f, 0x2c, 0x77, 0x5d, 0x29, 0x2c, + 0x52, 0x3d, 0x79, 0x2d, 0x54, 0x5b, 0x30, 0x5d, 0x2c, 0x44, 0x3d, + 0x4d, 0x2d, 0x54, 0x5b, 0x31, 0x5d, 0x2c, 0x50, 0x3d, 0x78, 0x2d, + 0x54, 0x5b, 0x30, 0x5d, 0x2c, 0x55, 0x3d, 0x62, 0x2d, 0x54, 0x5b, + 0x31, 0x5d, 0x2c, 0x6a, 0x3d, 0x31, 0x2f, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x73, 0x69, 0x6e, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x61, + 0x63, 0x6f, 0x73, 0x28, 0x28, 0x52, 0x2a, 0x50, 0x2b, 0x44, 0x2a, + 0x55, 0x29, 0x2f, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x52, 0x2a, 0x52, 0x2b, 0x44, 0x2a, 0x44, 0x29, + 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, + 0x50, 0x2a, 0x50, 0x2b, 0x55, 0x2a, 0x55, 0x29, 0x29, 0x29, 0x2f, + 0x32, 0x29, 0x2c, 0x46, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x71, 0x72, 0x74, 0x28, 0x54, 0x5b, 0x30, 0x5d, 0x2a, 0x54, 0x5b, + 0x30, 0x5d, 0x2b, 0x54, 0x5b, 0x31, 0x5d, 0x2a, 0x54, 0x5b, 0x31, + 0x5d, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x21, + 0x3d, 0x78, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x48, 0x3d, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e, 0x28, 0x70, 0x2c, 0x28, + 0x6c, 0x2d, 0x46, 0x29, 0x2f, 0x28, 0x6a, 0x2b, 0x31, 0x29, 0x29, + 0x2c, 0x4f, 0x3d, 0x66, 0x6f, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, + 0x3d, 0x53, 0x3f, 0x5b, 0x5f, 0x2c, 0x77, 0x5d, 0x3a, 0x5b, 0x53, + 0x2c, 0x6b, 0x5d, 0x2c, 0x5b, 0x79, 0x2c, 0x4d, 0x5d, 0x2c, 0x6c, + 0x2c, 0x48, 0x2c, 0x67, 0x29, 0x2c, 0x49, 0x3d, 0x66, 0x6f, 0x28, + 0x5b, 0x78, 0x2c, 0x62, 0x5d, 0x2c, 0x5b, 0x5f, 0x2c, 0x77, 0x5d, + 0x2c, 0x6c, 0x2c, 0x48, 0x2c, 0x67, 0x29, 0x3b, 0x70, 0x3d, 0x3d, + 0x3d, 0x48, 0x3f, 0x4e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, + 0x4d, 0x22, 0x2c, 0x4f, 0x5b, 0x30, 0x5d, 0x2c, 0x22, 0x41, 0x22, + 0x2c, 0x48, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x48, 0x2c, 0x22, 0x20, + 0x30, 0x20, 0x30, 0x2c, 0x22, 0x2c, 0x76, 0x2c, 0x22, 0x20, 0x22, + 0x2c, 0x4f, 0x5b, 0x31, 0x5d, 0x2c, 0x22, 0x41, 0x22, 0x2c, 0x6c, + 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x6c, 0x2c, 0x22, 0x20, 0x30, 0x20, + 0x22, 0x2c, 0x31, 0x2d, 0x67, 0x5e, 0x73, 0x6f, 0x28, 0x4f, 0x5b, + 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x4f, 0x5b, 0x31, 0x5d, 0x5b, + 0x31, 0x5d, 0x2c, 0x49, 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, + 0x49, 0x5b, 0x31, 0x5d, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x22, 0x2c, + 0x22, 0x2c, 0x67, 0x2c, 0x22, 0x20, 0x22, 0x2c, 0x49, 0x5b, 0x31, + 0x5d, 0x2c, 0x22, 0x41, 0x22, 0x2c, 0x48, 0x2c, 0x22, 0x2c, 0x22, + 0x2c, 0x48, 0x2c, 0x22, 0x20, 0x30, 0x20, 0x30, 0x2c, 0x22, 0x2c, + 0x76, 0x2c, 0x22, 0x20, 0x22, 0x2c, 0x49, 0x5b, 0x30, 0x5d, 0x29, + 0x3a, 0x4e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x4d, 0x22, + 0x2c, 0x4f, 0x5b, 0x30, 0x5d, 0x2c, 0x22, 0x41, 0x22, 0x2c, 0x48, + 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x48, 0x2c, 0x22, 0x20, 0x30, 0x20, + 0x31, 0x2c, 0x22, 0x2c, 0x76, 0x2c, 0x22, 0x20, 0x22, 0x2c, 0x49, + 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x4e, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x4d, 0x22, 0x2c, 0x79, + 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x4d, 0x29, 0x3b, 0x69, 0x66, 0x28, + 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, 0x53, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x59, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x70, 0x2c, 0x28, 0x6e, 0x2d, 0x46, 0x29, 0x2f, 0x28, + 0x6a, 0x2d, 0x31, 0x29, 0x29, 0x2c, 0x5a, 0x3d, 0x66, 0x6f, 0x28, + 0x5b, 0x79, 0x2c, 0x4d, 0x5d, 0x2c, 0x5b, 0x53, 0x2c, 0x6b, 0x5d, + 0x2c, 0x6e, 0x2c, 0x2d, 0x59, 0x2c, 0x67, 0x29, 0x2c, 0x56, 0x3d, + 0x66, 0x6f, 0x28, 0x5b, 0x5f, 0x2c, 0x77, 0x5d, 0x2c, 0x6e, 0x75, + 0x6c, 0x6c, 0x3d, 0x3d, 0x78, 0x3f, 0x5b, 0x79, 0x2c, 0x4d, 0x5d, + 0x3a, 0x5b, 0x78, 0x2c, 0x62, 0x5d, 0x2c, 0x6e, 0x2c, 0x2d, 0x59, + 0x2c, 0x67, 0x29, 0x3b, 0x70, 0x3d, 0x3d, 0x3d, 0x59, 0x3f, 0x4e, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x4c, 0x22, 0x2c, 0x56, + 0x5b, 0x30, 0x5d, 0x2c, 0x22, 0x41, 0x22, 0x2c, 0x59, 0x2c, 0x22, + 0x2c, 0x22, 0x2c, 0x59, 0x2c, 0x22, 0x20, 0x30, 0x20, 0x30, 0x2c, + 0x22, 0x2c, 0x76, 0x2c, 0x22, 0x20, 0x22, 0x2c, 0x56, 0x5b, 0x31, + 0x5d, 0x2c, 0x22, 0x41, 0x22, 0x2c, 0x6e, 0x2c, 0x22, 0x2c, 0x22, + 0x2c, 0x6e, 0x2c, 0x22, 0x20, 0x30, 0x20, 0x22, 0x2c, 0x67, 0x5e, + 0x73, 0x6f, 0x28, 0x56, 0x5b, 0x31, 0x5d, 0x5b, 0x30, 0x5d, 0x2c, + 0x56, 0x5b, 0x31, 0x5d, 0x5b, 0x31, 0x5d, 0x2c, 0x5a, 0x5b, 0x31, + 0x5d, 0x5b, 0x30, 0x5d, 0x2c, 0x5a, 0x5b, 0x31, 0x5d, 0x5b, 0x31, + 0x5d, 0x29, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x31, 0x2d, 0x67, 0x2c, + 0x22, 0x20, 0x22, 0x2c, 0x5a, 0x5b, 0x31, 0x5d, 0x2c, 0x22, 0x41, + 0x22, 0x2c, 0x59, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x59, 0x2c, 0x22, + 0x20, 0x30, 0x20, 0x30, 0x2c, 0x22, 0x2c, 0x76, 0x2c, 0x22, 0x20, + 0x22, 0x2c, 0x5a, 0x5b, 0x30, 0x5d, 0x29, 0x3a, 0x4e, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x22, 0x4c, 0x22, 0x2c, 0x56, 0x5b, 0x30, + 0x5d, 0x2c, 0x22, 0x41, 0x22, 0x2c, 0x59, 0x2c, 0x22, 0x2c, 0x22, + 0x2c, 0x59, 0x2c, 0x22, 0x20, 0x30, 0x20, 0x30, 0x2c, 0x22, 0x2c, + 0x76, 0x2c, 0x22, 0x20, 0x22, 0x2c, 0x5a, 0x5b, 0x30, 0x5d, 0x29, + 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x4e, 0x2e, 0x70, 0x75, 0x73, + 0x68, 0x28, 0x22, 0x4c, 0x22, 0x2c, 0x5f, 0x2c, 0x22, 0x2c, 0x22, + 0x2c, 0x77, 0x29, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x4e, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x4d, 0x22, 0x2c, 0x79, 0x2c, + 0x22, 0x2c, 0x22, 0x2c, 0x4d, 0x29, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, + 0x21, 0x3d, 0x78, 0x26, 0x26, 0x4e, 0x2e, 0x70, 0x75, 0x73, 0x68, + 0x28, 0x22, 0x41, 0x22, 0x2c, 0x6c, 0x2c, 0x22, 0x2c, 0x22, 0x2c, + 0x6c, 0x2c, 0x22, 0x20, 0x30, 0x20, 0x22, 0x2c, 0x43, 0x2c, 0x22, + 0x2c, 0x22, 0x2c, 0x67, 0x2c, 0x22, 0x20, 0x22, 0x2c, 0x78, 0x2c, + 0x22, 0x2c, 0x22, 0x2c, 0x62, 0x29, 0x2c, 0x4e, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x22, 0x4c, 0x22, 0x2c, 0x5f, 0x2c, 0x22, 0x2c, + 0x22, 0x2c, 0x77, 0x29, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x21, 0x3d, + 0x53, 0x26, 0x26, 0x4e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, + 0x41, 0x22, 0x2c, 0x6e, 0x2c, 0x22, 0x2c, 0x22, 0x2c, 0x6e, 0x2c, + 0x22, 0x20, 0x30, 0x20, 0x22, 0x2c, 0x71, 0x2c, 0x22, 0x2c, 0x22, + 0x2c, 0x31, 0x2d, 0x67, 0x2c, 0x22, 0x20, 0x22, 0x2c, 0x53, 0x2c, + 0x22, 0x2c, 0x22, 0x2c, 0x6b, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x4e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, + 0x5a, 0x22, 0x29, 0x2c, 0x4e, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, + 0x22, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x22, 0x4d, 0x30, 0x2c, 0x22, 0x2b, 0x6e, + 0x2b, 0x22, 0x41, 0x22, 0x2b, 0x6e, 0x2b, 0x22, 0x2c, 0x22, 0x2b, + 0x6e, 0x2b, 0x22, 0x20, 0x30, 0x20, 0x31, 0x2c, 0x22, 0x2b, 0x74, + 0x2b, 0x22, 0x20, 0x30, 0x2c, 0x22, 0x2b, 0x2d, 0x6e, 0x2b, 0x22, + 0x41, 0x22, 0x2b, 0x6e, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x6e, 0x2b, + 0x22, 0x20, 0x30, 0x20, 0x31, 0x2c, 0x22, 0x2b, 0x74, 0x2b, 0x22, + 0x20, 0x30, 0x2c, 0x22, 0x2b, 0x6e, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x69, 0x6f, 0x2c, 0x72, 0x3d, 0x6f, 0x6f, 0x2c, 0x75, + 0x3d, 0x75, 0x6f, 0x2c, 0x69, 0x3d, 0x6b, 0x6c, 0x2c, 0x6f, 0x3d, + 0x61, 0x6f, 0x2c, 0x61, 0x3d, 0x63, 0x6f, 0x2c, 0x63, 0x3d, 0x6c, + 0x6f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, + 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, 0x45, 0x74, 0x28, 0x74, + 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x6e, 0x2e, 0x6f, + 0x75, 0x74, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x72, 0x3d, 0x45, 0x74, 0x28, 0x74, 0x29, + 0x2c, 0x6e, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x2e, 0x63, 0x6f, + 0x72, 0x6e, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x75, 0x3d, 0x45, 0x74, 0x28, 0x74, 0x29, + 0x2c, 0x6e, 0x29, 0x3a, 0x75, 0x7d, 0x2c, 0x6e, 0x2e, 0x70, 0x61, + 0x64, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x69, 0x3d, 0x74, 0x3d, 0x3d, 0x6b, 0x6c, 0x3f, 0x6b, 0x6c, + 0x3a, 0x45, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x69, + 0x7d, 0x2c, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x41, 0x6e, + 0x67, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6f, 0x3d, 0x45, + 0x74, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x6f, 0x7d, 0x2c, + 0x6e, 0x2e, 0x65, 0x6e, 0x64, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x61, 0x3d, 0x45, 0x74, 0x28, 0x74, 0x29, + 0x2c, 0x6e, 0x29, 0x3a, 0x61, 0x7d, 0x2c, 0x6e, 0x2e, 0x70, 0x61, + 0x64, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x63, 0x3d, 0x45, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, + 0x63, 0x7d, 0x2c, 0x6e, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x6f, + 0x69, 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x28, 0x2b, + 0x65, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x2b, 0x20, 0x2b, 0x72, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x29, 0x29, 0x2f, 0x32, 0x2c, 0x74, 0x3d, + 0x28, 0x2b, 0x6f, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x29, 0x2b, 0x20, 0x2b, 0x61, 0x2e, 0x61, 0x70, 0x70, + 0x6c, 0x79, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x29, 0x2f, 0x32, 0x2d, + 0x52, 0x61, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, 0x74, 0x29, 0x2a, + 0x6e, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x69, 0x6e, 0x28, + 0x74, 0x29, 0x2a, 0x6e, 0x5d, 0x7d, 0x2c, 0x6e, 0x7d, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x6b, 0x6c, 0x3d, 0x22, 0x61, 0x75, 0x74, 0x6f, + 0x22, 0x3b, 0x74, 0x61, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x6c, 0x69, + 0x6e, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x68, + 0x6f, 0x28, 0x79, 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x45, + 0x6c, 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x7b, 0x6c, + 0x69, 0x6e, 0x65, 0x61, 0x72, 0x3a, 0x67, 0x6f, 0x2c, 0x22, 0x6c, + 0x69, 0x6e, 0x65, 0x61, 0x72, 0x2d, 0x63, 0x6c, 0x6f, 0x73, 0x65, + 0x64, 0x22, 0x3a, 0x70, 0x6f, 0x2c, 0x73, 0x74, 0x65, 0x70, 0x3a, + 0x76, 0x6f, 0x2c, 0x22, 0x73, 0x74, 0x65, 0x70, 0x2d, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x22, 0x3a, 0x6d, 0x6f, 0x2c, 0x22, 0x73, + 0x74, 0x65, 0x70, 0x2d, 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x3a, + 0x79, 0x6f, 0x2c, 0x62, 0x61, 0x73, 0x69, 0x73, 0x3a, 0x53, 0x6f, + 0x2c, 0x22, 0x62, 0x61, 0x73, 0x69, 0x73, 0x2d, 0x6f, 0x70, 0x65, + 0x6e, 0x22, 0x3a, 0x6b, 0x6f, 0x2c, 0x22, 0x62, 0x61, 0x73, 0x69, + 0x73, 0x2d, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x22, 0x3a, 0x45, + 0x6f, 0x2c, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x3a, 0x41, 0x6f, + 0x2c, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x3a, 0x62, + 0x6f, 0x2c, 0x22, 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, + 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x22, 0x3a, 0x4d, 0x6f, 0x2c, 0x22, + 0x63, 0x61, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0x2d, 0x63, 0x6c, + 0x6f, 0x73, 0x65, 0x64, 0x22, 0x3a, 0x78, 0x6f, 0x2c, 0x6d, 0x6f, + 0x6e, 0x6f, 0x74, 0x6f, 0x6e, 0x65, 0x3a, 0x54, 0x6f, 0x7d, 0x29, + 0x3b, 0x45, 0x6c, 0x2e, 0x66, 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x74, 0x29, 0x7b, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x3d, 0x6e, + 0x2c, 0x74, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x3d, 0x2f, + 0x2d, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x64, 0x24, 0x2f, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x28, 0x6e, 0x29, 0x7d, 0x29, 0x3b, 0x76, 0x61, + 0x72, 0x20, 0x41, 0x6c, 0x3d, 0x5b, 0x30, 0x2c, 0x32, 0x2f, 0x33, + 0x2c, 0x31, 0x2f, 0x33, 0x2c, 0x30, 0x5d, 0x2c, 0x4e, 0x6c, 0x3d, + 0x5b, 0x30, 0x2c, 0x31, 0x2f, 0x33, 0x2c, 0x32, 0x2f, 0x33, 0x2c, + 0x30, 0x5d, 0x2c, 0x43, 0x6c, 0x3d, 0x5b, 0x30, 0x2c, 0x31, 0x2f, + 0x36, 0x2c, 0x32, 0x2f, 0x33, 0x2c, 0x31, 0x2f, 0x36, 0x5d, 0x3b, + 0x74, 0x61, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x6c, 0x69, 0x6e, 0x65, + 0x2e, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6c, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6e, 0x3d, 0x68, 0x6f, 0x28, 0x52, 0x6f, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x72, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x3d, 0x6e, 0x2e, 0x78, 0x2c, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x20, 0x6e, 0x2e, 0x78, 0x2c, 0x6e, 0x2e, 0x61, + 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x6e, 0x2e, 0x79, 0x2c, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6e, 0x2e, 0x79, 0x2c, 0x6e, 0x7d, + 0x2c, 0x6d, 0x6f, 0x2e, 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, + 0x3d, 0x79, 0x6f, 0x2c, 0x79, 0x6f, 0x2e, 0x72, 0x65, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x3d, 0x6d, 0x6f, 0x2c, 0x74, 0x61, 0x2e, 0x73, + 0x76, 0x67, 0x2e, 0x61, 0x72, 0x65, 0x61, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x44, 0x6f, 0x28, 0x79, 0x29, 0x7d, 0x2c, + 0x74, 0x61, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, 0x72, 0x65, 0x61, + 0x2e, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6c, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x6e, 0x3d, 0x44, 0x6f, 0x28, 0x52, 0x6f, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x72, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x3d, 0x6e, 0x2e, 0x78, 0x2c, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x20, 0x6e, 0x2e, 0x78, 0x2c, 0x6e, 0x2e, 0x69, + 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3d, + 0x6e, 0x2e, 0x78, 0x30, 0x2c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x20, 0x6e, 0x2e, 0x78, 0x30, 0x2c, 0x6e, 0x2e, 0x6f, 0x75, 0x74, + 0x65, 0x72, 0x52, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3d, 0x6e, 0x2e, + 0x78, 0x31, 0x2c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6e, + 0x2e, 0x78, 0x31, 0x2c, 0x6e, 0x2e, 0x61, 0x6e, 0x67, 0x6c, 0x65, + 0x3d, 0x6e, 0x2e, 0x79, 0x2c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x20, 0x6e, 0x2e, 0x79, 0x2c, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x72, + 0x74, 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x6e, 0x2e, 0x79, 0x30, + 0x2c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x6e, 0x2e, 0x79, + 0x30, 0x2c, 0x6e, 0x2e, 0x65, 0x6e, 0x64, 0x41, 0x6e, 0x67, 0x6c, + 0x65, 0x3d, 0x6e, 0x2e, 0x79, 0x31, 0x2c, 0x64, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x20, 0x6e, 0x2e, 0x79, 0x31, 0x2c, 0x6e, 0x7d, 0x2c, + 0x74, 0x61, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x63, 0x68, 0x6f, 0x72, + 0x64, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6e, 0x28, 0x6e, 0x2c, 0x61, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x63, 0x3d, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x69, 0x2c, + 0x6e, 0x2c, 0x61, 0x29, 0x2c, 0x6c, 0x3d, 0x74, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x6f, 0x2c, 0x6e, 0x2c, 0x61, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x4d, 0x22, 0x2b, 0x63, 0x2e, + 0x70, 0x30, 0x2b, 0x72, 0x28, 0x63, 0x2e, 0x72, 0x2c, 0x63, 0x2e, + 0x70, 0x31, 0x2c, 0x63, 0x2e, 0x61, 0x31, 0x2d, 0x63, 0x2e, 0x61, + 0x30, 0x29, 0x2b, 0x28, 0x65, 0x28, 0x63, 0x2c, 0x6c, 0x29, 0x3f, + 0x75, 0x28, 0x63, 0x2e, 0x72, 0x2c, 0x63, 0x2e, 0x70, 0x31, 0x2c, + 0x63, 0x2e, 0x72, 0x2c, 0x63, 0x2e, 0x70, 0x30, 0x29, 0x3a, 0x75, + 0x28, 0x63, 0x2e, 0x72, 0x2c, 0x63, 0x2e, 0x70, 0x31, 0x2c, 0x6c, + 0x2e, 0x72, 0x2c, 0x6c, 0x2e, 0x70, 0x30, 0x29, 0x2b, 0x72, 0x28, + 0x6c, 0x2e, 0x72, 0x2c, 0x6c, 0x2e, 0x70, 0x31, 0x2c, 0x6c, 0x2e, + 0x61, 0x31, 0x2d, 0x6c, 0x2e, 0x61, 0x30, 0x29, 0x2b, 0x75, 0x28, + 0x6c, 0x2e, 0x72, 0x2c, 0x6c, 0x2e, 0x70, 0x31, 0x2c, 0x63, 0x2e, + 0x72, 0x2c, 0x63, 0x2e, 0x70, 0x30, 0x29, 0x29, 0x2b, 0x22, 0x5a, + 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x74, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x72, 0x29, 0x2c, 0x69, 0x3d, + 0x61, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x75, 0x2c, + 0x72, 0x29, 0x2c, 0x6f, 0x3d, 0x63, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x6e, 0x2c, 0x75, 0x2c, 0x72, 0x29, 0x2d, 0x52, 0x61, 0x2c, + 0x73, 0x3d, 0x6c, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, + 0x75, 0x2c, 0x72, 0x29, 0x2d, 0x52, 0x61, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x7b, 0x72, 0x3a, 0x69, 0x2c, 0x61, 0x30, 0x3a, + 0x6f, 0x2c, 0x61, 0x31, 0x3a, 0x73, 0x2c, 0x70, 0x30, 0x3a, 0x5b, + 0x69, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, + 0x6f, 0x29, 0x2c, 0x69, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x69, 0x6e, 0x28, 0x6f, 0x29, 0x5d, 0x2c, 0x70, 0x31, 0x3a, 0x5b, + 0x69, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x63, 0x6f, 0x73, 0x28, + 0x73, 0x29, 0x2c, 0x69, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x69, 0x6e, 0x28, 0x73, 0x29, 0x5d, 0x7d, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, + 0x61, 0x30, 0x3d, 0x3d, 0x74, 0x2e, 0x61, 0x30, 0x26, 0x26, 0x6e, + 0x2e, 0x61, 0x31, 0x3d, 0x3d, 0x74, 0x2e, 0x61, 0x31, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x6e, + 0x2c, 0x74, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x22, 0x41, 0x22, 0x2b, 0x6e, 0x2b, 0x22, 0x2c, 0x22, 0x2b, + 0x6e, 0x2b, 0x22, 0x20, 0x30, 0x20, 0x22, 0x2b, 0x20, 0x2b, 0x28, + 0x65, 0x3e, 0x71, 0x61, 0x29, 0x2b, 0x22, 0x2c, 0x31, 0x20, 0x22, + 0x2b, 0x74, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x75, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x51, 0x20, 0x30, + 0x2c, 0x30, 0x20, 0x22, 0x2b, 0x72, 0x7d, 0x76, 0x61, 0x72, 0x20, + 0x69, 0x3d, 0x6d, 0x72, 0x2c, 0x6f, 0x3d, 0x79, 0x72, 0x2c, 0x61, + 0x3d, 0x50, 0x6f, 0x2c, 0x63, 0x3d, 0x61, 0x6f, 0x2c, 0x6c, 0x3d, + 0x63, 0x6f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x61, 0x3d, 0x45, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, + 0x3a, 0x61, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x69, 0x3d, 0x45, 0x74, 0x28, + 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x69, 0x7d, 0x2c, 0x6e, 0x2e, + 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x6f, 0x3d, 0x45, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, + 0x6f, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x41, + 0x6e, 0x67, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x63, 0x3d, + 0x45, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x63, 0x7d, + 0x2c, 0x6e, 0x2e, 0x65, 0x6e, 0x64, 0x41, 0x6e, 0x67, 0x6c, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6c, 0x3d, 0x45, 0x74, 0x28, 0x74, + 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x6c, 0x7d, 0x2c, 0x6e, 0x7d, 0x2c, + 0x74, 0x61, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x64, 0x69, 0x61, 0x67, + 0x6f, 0x6e, 0x61, 0x6c, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x2c, 0x75, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x69, 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x75, 0x29, 0x2c, + 0x6f, 0x3d, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x75, 0x29, 0x2c, 0x61, 0x3d, 0x28, + 0x69, 0x2e, 0x79, 0x2b, 0x6f, 0x2e, 0x79, 0x29, 0x2f, 0x32, 0x2c, + 0x63, 0x3d, 0x5b, 0x69, 0x2c, 0x7b, 0x78, 0x3a, 0x69, 0x2e, 0x78, + 0x2c, 0x79, 0x3a, 0x61, 0x7d, 0x2c, 0x7b, 0x78, 0x3a, 0x6f, 0x2e, + 0x78, 0x2c, 0x79, 0x3a, 0x61, 0x7d, 0x2c, 0x6f, 0x5d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x3d, 0x63, 0x2e, 0x6d, + 0x61, 0x70, 0x28, 0x72, 0x29, 0x2c, 0x22, 0x4d, 0x22, 0x2b, 0x63, + 0x5b, 0x30, 0x5d, 0x2b, 0x22, 0x43, 0x22, 0x2b, 0x63, 0x5b, 0x31, + 0x5d, 0x2b, 0x22, 0x20, 0x22, 0x2b, 0x63, 0x5b, 0x32, 0x5d, 0x2b, + 0x22, 0x20, 0x22, 0x2b, 0x63, 0x5b, 0x33, 0x5d, 0x7d, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x6d, 0x72, 0x2c, 0x65, 0x3d, 0x79, 0x72, + 0x2c, 0x72, 0x3d, 0x55, 0x6f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x74, 0x3d, 0x45, 0x74, 0x28, 0x65, 0x29, + 0x2c, 0x6e, 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6e, 0x2e, 0x74, 0x61, + 0x72, 0x67, 0x65, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, + 0x45, 0x74, 0x28, 0x74, 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x65, 0x7d, + 0x2c, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x72, 0x3d, 0x74, 0x2c, + 0x6e, 0x29, 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x64, 0x69, 0x61, 0x67, 0x6f, 0x6e, + 0x61, 0x6c, 0x2e, 0x72, 0x61, 0x64, 0x69, 0x61, 0x6c, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x73, 0x76, 0x67, + 0x2e, 0x64, 0x69, 0x61, 0x67, 0x6f, 0x6e, 0x61, 0x6c, 0x28, 0x29, + 0x2c, 0x74, 0x3d, 0x55, 0x6f, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x65, 0x28, 0x6a, 0x6f, 0x28, 0x74, 0x3d, 0x6e, 0x29, 0x29, 0x3a, + 0x74, 0x7d, 0x2c, 0x6e, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x76, + 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x62, 0x6f, 0x6c, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x2c, + 0x72, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x28, 0x7a, + 0x6c, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x74, 0x2e, 0x63, 0x61, 0x6c, + 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x72, 0x29, + 0x29, 0x7c, 0x7c, 0x4f, 0x6f, 0x29, 0x28, 0x65, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x72, + 0x29, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x48, 0x6f, + 0x2c, 0x65, 0x3d, 0x46, 0x6f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x74, 0x3d, 0x45, 0x74, 0x28, 0x65, 0x29, 0x2c, 0x6e, + 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6e, 0x2e, 0x73, 0x69, 0x7a, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x65, 0x3d, 0x45, 0x74, 0x28, 0x74, + 0x29, 0x2c, 0x6e, 0x29, 0x3a, 0x65, 0x7d, 0x2c, 0x6e, 0x7d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x7a, 0x6c, 0x3d, 0x74, 0x61, 0x2e, 0x6d, + 0x61, 0x70, 0x28, 0x7b, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x3a, + 0x4f, 0x6f, 0x2c, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x3a, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, + 0x71, 0x72, 0x74, 0x28, 0x6e, 0x2f, 0x35, 0x29, 0x2f, 0x32, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x4d, 0x22, 0x2b, 0x2d, + 0x33, 0x2a, 0x74, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x2d, 0x74, 0x2b, + 0x22, 0x48, 0x22, 0x2b, 0x2d, 0x74, 0x2b, 0x22, 0x56, 0x22, 0x2b, + 0x2d, 0x33, 0x2a, 0x74, 0x2b, 0x22, 0x48, 0x22, 0x2b, 0x74, 0x2b, + 0x22, 0x56, 0x22, 0x2b, 0x2d, 0x74, 0x2b, 0x22, 0x48, 0x22, 0x2b, + 0x33, 0x2a, 0x74, 0x2b, 0x22, 0x56, 0x22, 0x2b, 0x74, 0x2b, 0x22, + 0x48, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x56, 0x22, 0x2b, 0x33, 0x2a, + 0x74, 0x2b, 0x22, 0x48, 0x22, 0x2b, 0x2d, 0x74, 0x2b, 0x22, 0x56, + 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x48, 0x22, 0x2b, 0x2d, 0x33, 0x2a, + 0x74, 0x2b, 0x22, 0x5a, 0x22, 0x7d, 0x2c, 0x64, 0x69, 0x61, 0x6d, + 0x6f, 0x6e, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x6e, + 0x2f, 0x28, 0x32, 0x2a, 0x4c, 0x6c, 0x29, 0x29, 0x2c, 0x65, 0x3d, + 0x74, 0x2a, 0x4c, 0x6c, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x22, 0x4d, 0x30, 0x2c, 0x22, 0x2b, 0x2d, 0x74, 0x2b, 0x22, 0x4c, + 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x2c, 0x30, 0x20, 0x30, 0x2c, 0x22, + 0x2b, 0x74, 0x2b, 0x22, 0x20, 0x22, 0x2b, 0x2d, 0x65, 0x2b, 0x22, + 0x2c, 0x30, 0x5a, 0x22, 0x7d, 0x2c, 0x73, 0x71, 0x75, 0x61, 0x72, + 0x65, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x6e, 0x29, 0x2f, + 0x32, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x4d, 0x22, + 0x2b, 0x2d, 0x74, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x2d, 0x74, 0x2b, + 0x22, 0x4c, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x2d, + 0x74, 0x2b, 0x22, 0x20, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x2c, 0x22, + 0x2b, 0x74, 0x2b, 0x22, 0x20, 0x22, 0x2b, 0x2d, 0x74, 0x2b, 0x22, + 0x2c, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x5a, 0x22, 0x7d, 0x2c, 0x22, + 0x74, 0x72, 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2d, 0x64, 0x6f, + 0x77, 0x6e, 0x22, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, 0x28, 0x6e, + 0x2f, 0x71, 0x6c, 0x29, 0x2c, 0x65, 0x3d, 0x74, 0x2a, 0x71, 0x6c, + 0x2f, 0x32, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x4d, + 0x30, 0x2c, 0x22, 0x2b, 0x65, 0x2b, 0x22, 0x4c, 0x22, 0x2b, 0x74, + 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x2d, 0x65, 0x2b, 0x22, 0x20, 0x22, + 0x2b, 0x2d, 0x74, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x2d, 0x65, 0x2b, + 0x22, 0x5a, 0x22, 0x7d, 0x2c, 0x22, 0x74, 0x72, 0x69, 0x61, 0x6e, + 0x67, 0x6c, 0x65, 0x2d, 0x75, 0x70, 0x22, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, + 0x72, 0x74, 0x28, 0x6e, 0x2f, 0x71, 0x6c, 0x29, 0x2c, 0x65, 0x3d, + 0x74, 0x2a, 0x71, 0x6c, 0x2f, 0x32, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x4d, 0x30, 0x2c, 0x22, 0x2b, 0x2d, 0x65, 0x2b, + 0x22, 0x4c, 0x22, 0x2b, 0x74, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x65, + 0x2b, 0x22, 0x20, 0x22, 0x2b, 0x2d, 0x74, 0x2b, 0x22, 0x2c, 0x22, + 0x2b, 0x65, 0x2b, 0x22, 0x5a, 0x22, 0x7d, 0x7d, 0x29, 0x3b, 0x74, + 0x61, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x73, 0x79, 0x6d, 0x62, 0x6f, + 0x6c, 0x54, 0x79, 0x70, 0x65, 0x73, 0x3d, 0x7a, 0x6c, 0x2e, 0x6b, + 0x65, 0x79, 0x73, 0x28, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x71, + 0x6c, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x73, 0x71, 0x72, 0x74, + 0x28, 0x33, 0x29, 0x2c, 0x4c, 0x6c, 0x3d, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x74, 0x61, 0x6e, 0x28, 0x33, 0x30, 0x2a, 0x44, 0x61, 0x29, + 0x3b, 0x5f, 0x61, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x3d, 0x54, 0x6c, 0x7c, + 0x7c, 0x2b, 0x2b, 0x55, 0x6c, 0x2c, 0x75, 0x3d, 0x58, 0x6f, 0x28, + 0x6e, 0x29, 0x2c, 0x69, 0x3d, 0x5b, 0x5d, 0x2c, 0x6f, 0x3d, 0x52, + 0x6c, 0x7c, 0x7c, 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x44, 0x61, + 0x74, 0x65, 0x2e, 0x6e, 0x6f, 0x77, 0x28, 0x29, 0x2c, 0x65, 0x61, + 0x73, 0x65, 0x3a, 0x53, 0x75, 0x2c, 0x64, 0x65, 0x6c, 0x61, 0x79, + 0x3a, 0x30, 0x2c, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x32, 0x35, 0x30, 0x7d, 0x2c, 0x61, 0x3d, 0x2d, 0x31, 0x2c, + 0x63, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x61, 0x3c, 0x63, 0x3b, 0x29, 0x7b, + 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x3d, 0x5b, 0x5d, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6c, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x61, 0x5d, 0x2c, 0x73, 0x3d, + 0x2d, 0x31, 0x2c, 0x66, 0x3d, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x73, 0x3c, 0x66, 0x3b, 0x29, 0x28, + 0x65, 0x3d, 0x6c, 0x5b, 0x73, 0x5d, 0x29, 0x26, 0x26, 0x24, 0x6f, + 0x28, 0x65, 0x2c, 0x73, 0x2c, 0x75, 0x2c, 0x72, 0x2c, 0x6f, 0x29, + 0x2c, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x29, 0x7d, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x59, 0x6f, 0x28, 0x69, + 0x2c, 0x75, 0x2c, 0x72, 0x29, 0x7d, 0x2c, 0x5f, 0x61, 0x2e, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x65, 0x61, 0x63, 0x68, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, + 0x6e, 0x3f, 0x44, 0x6c, 0x3a, 0x49, 0x6f, 0x28, 0x58, 0x6f, 0x28, + 0x6e, 0x29, 0x29, 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x54, + 0x6c, 0x2c, 0x52, 0x6c, 0x2c, 0x44, 0x6c, 0x3d, 0x49, 0x6f, 0x28, + 0x58, 0x6f, 0x28, 0x29, 0x29, 0x2c, 0x50, 0x6c, 0x3d, 0x5b, 0x5d, + 0x2c, 0x55, 0x6c, 0x3d, 0x30, 0x3b, 0x50, 0x6c, 0x2e, 0x63, 0x61, + 0x6c, 0x6c, 0x3d, 0x5f, 0x61, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x2c, + 0x50, 0x6c, 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3d, 0x5f, 0x61, + 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2c, 0x50, 0x6c, 0x2e, 0x6e, + 0x6f, 0x64, 0x65, 0x3d, 0x5f, 0x61, 0x2e, 0x6e, 0x6f, 0x64, 0x65, + 0x2c, 0x50, 0x6c, 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x3d, 0x5f, 0x61, + 0x2e, 0x73, 0x69, 0x7a, 0x65, 0x2c, 0x74, 0x61, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x26, 0x26, + 0x6e, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x3f, 0x54, 0x6c, 0x3f, 0x6e, 0x2e, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x3a, 0x6e, + 0x3a, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7d, 0x2c, 0x74, 0x61, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x50, 0x6c, 0x2c, 0x50, 0x6c, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, + 0x72, 0x2c, 0x75, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, + 0x2c, 0x69, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x6f, 0x3d, 0x5b, 0x5d, + 0x3b, 0x6e, 0x3d, 0x4e, 0x28, 0x6e, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x2d, 0x31, 0x2c, 0x63, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x2b, 0x2b, 0x61, 0x3c, 0x63, 0x3b, 0x29, 0x7b, 0x6f, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x3d, 0x5b, 0x5d, 0x29, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x5b, 0x61, 0x5d, 0x2c, 0x73, 0x3d, 0x2d, + 0x31, 0x2c, 0x66, 0x3d, 0x6c, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x2b, 0x2b, 0x73, 0x3c, 0x66, 0x3b, 0x29, 0x28, 0x72, + 0x3d, 0x6c, 0x5b, 0x73, 0x5d, 0x29, 0x26, 0x26, 0x28, 0x65, 0x3d, + 0x6e, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x72, 0x2e, + 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x73, 0x2c, + 0x61, 0x29, 0x29, 0x3f, 0x28, 0x22, 0x5f, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x5f, 0x5f, 0x22, 0x69, 0x6e, 0x20, 0x72, 0x26, 0x26, 0x28, + 0x65, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x3d, + 0x72, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x29, + 0x2c, 0x24, 0x6f, 0x28, 0x65, 0x2c, 0x73, 0x2c, 0x69, 0x2c, 0x75, + 0x2c, 0x72, 0x5b, 0x69, 0x5d, 0x5b, 0x75, 0x5d, 0x29, 0x2c, 0x74, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x65, 0x29, 0x29, 0x3a, 0x74, + 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x59, 0x6f, 0x28, + 0x6f, 0x2c, 0x69, 0x2c, 0x75, 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, + 0x2c, 0x69, 0x2c, 0x6f, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x64, 0x2c, 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x63, 0x3d, 0x5b, + 0x5d, 0x3b, 0x6e, 0x3d, 0x43, 0x28, 0x6e, 0x29, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x2d, 0x31, 0x2c, + 0x73, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x6c, 0x3c, 0x73, 0x3b, 0x29, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x66, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x5b, 0x6c, 0x5d, 0x2c, 0x68, 0x3d, 0x2d, 0x31, 0x2c, + 0x67, 0x3d, 0x66, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x2b, 0x2b, 0x68, 0x3c, 0x67, 0x3b, 0x29, 0x69, 0x66, 0x28, 0x72, + 0x3d, 0x66, 0x5b, 0x68, 0x5d, 0x29, 0x7b, 0x69, 0x3d, 0x72, 0x5b, + 0x61, 0x5d, 0x5b, 0x6f, 0x5d, 0x2c, 0x65, 0x3d, 0x6e, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x72, 0x2e, 0x5f, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x68, 0x2c, 0x6c, 0x29, 0x2c, + 0x63, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x3d, 0x5b, 0x5d, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x70, + 0x3d, 0x2d, 0x31, 0x2c, 0x76, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3b, 0x2b, 0x2b, 0x70, 0x3c, 0x76, 0x3b, 0x29, + 0x28, 0x75, 0x3d, 0x65, 0x5b, 0x70, 0x5d, 0x29, 0x26, 0x26, 0x24, + 0x6f, 0x28, 0x75, 0x2c, 0x70, 0x2c, 0x61, 0x2c, 0x6f, 0x2c, 0x69, + 0x29, 0x2c, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x75, 0x29, + 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x59, 0x6f, 0x28, + 0x63, 0x2c, 0x61, 0x2c, 0x6f, 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, + 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x75, 0x3d, 0x5b, 0x5d, + 0x3b, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x21, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x26, + 0x26, 0x28, 0x6e, 0x3d, 0x4f, 0x28, 0x6e, 0x29, 0x29, 0x3b, 0x66, + 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x30, 0x2c, + 0x6f, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x6f, 0x3e, 0x69, 0x3b, 0x69, 0x2b, 0x2b, 0x29, + 0x7b, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x74, 0x3d, 0x5b, + 0x5d, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x69, 0x5d, 0x2c, 0x61, + 0x3d, 0x30, 0x2c, 0x63, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3b, 0x63, 0x3e, 0x61, 0x3b, 0x61, 0x2b, 0x2b, 0x29, + 0x28, 0x72, 0x3d, 0x65, 0x5b, 0x61, 0x5d, 0x29, 0x26, 0x26, 0x6e, + 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x72, 0x2e, 0x5f, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x61, 0x2c, 0x69, + 0x29, 0x26, 0x26, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x72, + 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x59, 0x6f, + 0x28, 0x75, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x69, 0x64, 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, 0x74, 0x77, + 0x65, 0x65, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x2c, 0x72, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, 0x3f, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x5b, 0x72, + 0x5d, 0x5b, 0x65, 0x5d, 0x2e, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x2e, + 0x67, 0x65, 0x74, 0x28, 0x6e, 0x29, 0x3a, 0x59, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, 0x3f, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, + 0x7b, 0x74, 0x5b, 0x72, 0x5d, 0x5b, 0x65, 0x5d, 0x2e, 0x74, 0x77, + 0x65, 0x65, 0x6e, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, + 0x6e, 0x29, 0x7d, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x75, 0x29, 0x7b, 0x75, 0x5b, 0x72, 0x5d, 0x5b, 0x65, + 0x5d, 0x2e, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x2e, 0x73, 0x65, 0x74, + 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7d, 0x29, 0x7d, 0x2c, 0x50, 0x6c, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x29, 0x7b, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x61, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x72, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x4e, 0x53, 0x28, 0x61, 0x2e, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x2c, 0x61, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x3f, 0x65, 0x3a, 0x28, 0x6e, + 0x2b, 0x3d, 0x22, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, + 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, 0x61, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x21, 0x3d, + 0x3d, 0x6e, 0x26, 0x26, 0x28, 0x74, 0x3d, 0x6f, 0x28, 0x65, 0x2c, + 0x6e, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, + 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x28, + 0x61, 0x2c, 0x74, 0x28, 0x6e, 0x29, 0x29, 0x7d, 0x29, 0x7d, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x6e, 0x3f, 0x72, 0x3a, 0x28, + 0x6e, 0x2b, 0x3d, 0x22, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x2c, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x67, 0x65, 0x74, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x53, + 0x28, 0x61, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x61, 0x2e, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x65, 0x21, 0x3d, 0x3d, 0x6e, 0x26, 0x26, 0x28, + 0x74, 0x3d, 0x6f, 0x28, 0x65, 0x2c, 0x6e, 0x29, 0x2c, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x53, 0x28, 0x61, 0x2e, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x2c, 0x61, 0x2e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x2c, 0x74, 0x28, 0x6e, 0x29, 0x29, 0x7d, 0x29, 0x7d, 0x29, + 0x7d, 0x69, 0x66, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, + 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x74, 0x20, 0x69, 0x6e, 0x20, + 0x6e, 0x29, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x74, 0x2c, 0x6e, 0x5b, 0x74, 0x5d, 0x29, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x7d, 0x76, + 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x22, 0x3d, 0x3d, 0x6e, 0x3f, 0x48, 0x75, + 0x3a, 0x6d, 0x75, 0x2c, 0x61, 0x3d, 0x74, 0x61, 0x2e, 0x6e, 0x73, + 0x2e, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x79, 0x28, 0x6e, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5a, 0x6f, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x22, 0x61, 0x74, 0x74, 0x72, 0x2e, + 0x22, 0x2b, 0x6e, 0x2c, 0x74, 0x2c, 0x61, 0x2e, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x3f, 0x69, 0x3a, 0x75, 0x29, 0x7d, 0x2c, 0x50, 0x6c, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x54, 0x77, 0x65, 0x65, 0x6e, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x65, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x28, 0x75, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x72, 0x26, 0x26, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x28, 0x75, 0x2c, 0x72, 0x28, 0x6e, 0x29, 0x29, + 0x7d, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x72, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x4e, 0x53, 0x28, 0x75, 0x2e, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x2c, 0x75, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x29, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x26, 0x26, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4e, 0x53, 0x28, 0x75, + 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2c, 0x75, 0x2e, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x2c, 0x72, 0x28, 0x6e, 0x29, 0x29, 0x7d, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x74, 0x61, 0x2e, 0x6e, 0x73, + 0x2e, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x66, 0x79, 0x28, 0x6e, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x28, 0x22, 0x61, 0x74, + 0x74, 0x72, 0x2e, 0x22, 0x2b, 0x6e, 0x2c, 0x75, 0x2e, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x3f, 0x72, 0x3a, 0x65, 0x29, 0x7d, 0x2c, 0x50, + 0x6c, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x72, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x75, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6e, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, + 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x65, 0x3f, 0x75, 0x3a, 0x28, 0x65, + 0x2b, 0x3d, 0x22, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, + 0x69, 0x3d, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x2e, 0x67, + 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x53, + 0x74, 0x79, 0x6c, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x6e, + 0x75, 0x6c, 0x6c, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x79, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x28, + 0x6e, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, + 0x21, 0x3d, 0x3d, 0x65, 0x26, 0x26, 0x28, 0x75, 0x3d, 0x6d, 0x75, + 0x28, 0x69, 0x2c, 0x65, 0x29, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x74, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6e, 0x2c, 0x75, + 0x28, 0x74, 0x29, 0x2c, 0x72, 0x29, 0x7d, 0x29, 0x7d, 0x29, 0x7d, + 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x69, 0x66, 0x28, 0x33, 0x3e, 0x6f, 0x29, 0x7b, 0x69, 0x66, + 0x28, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x21, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x29, 0x7b, 0x32, + 0x3e, 0x6f, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x22, 0x22, 0x29, 0x3b, + 0x66, 0x6f, 0x72, 0x28, 0x72, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, + 0x72, 0x2c, 0x6e, 0x5b, 0x72, 0x5d, 0x2c, 0x65, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x7d, + 0x72, 0x3d, 0x22, 0x22, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x5a, 0x6f, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x22, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x22, 0x2b, 0x6e, 0x2c, 0x65, 0x2c, + 0x69, 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x54, 0x77, 0x65, 0x65, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x72, 0x29, + 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, + 0x28, 0x75, 0x2c, 0x69, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, + 0x3d, 0x65, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x74, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x75, + 0x74, 0x65, 0x64, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2e, 0x67, 0x65, + 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x28, 0x6e, 0x29, 0x29, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x26, 0x26, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x73, 0x65, 0x74, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x28, 0x6e, 0x2c, + 0x6f, 0x28, 0x74, 0x29, 0x2c, 0x72, 0x29, 0x7d, 0x7d, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, + 0x33, 0x26, 0x26, 0x28, 0x72, 0x3d, 0x22, 0x22, 0x29, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x74, 0x77, 0x65, 0x65, 0x6e, 0x28, 0x22, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2e, 0x22, 0x2b, 0x6e, 0x2c, 0x75, + 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x5a, 0x6f, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x2c, 0x6e, 0x2c, 0x56, 0x6f, 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x65, 0x61, 0x63, 0x68, + 0x28, 0x22, 0x65, 0x6e, 0x64, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x74, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x6e, 0x5d, 0x2e, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x3c, 0x32, 0x26, 0x26, 0x28, 0x74, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x4e, 0x6f, 0x64, 0x65, 0x29, 0x26, 0x26, 0x74, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x7d, 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, + 0x65, 0x61, 0x73, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x2c, 0x65, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x31, 0x3f, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x5b, 0x65, 0x5d, + 0x5b, 0x74, 0x5d, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x3a, 0x28, 0x22, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x21, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, 0x26, 0x26, 0x28, + 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x2e, 0x61, + 0x70, 0x70, 0x6c, 0x79, 0x28, 0x74, 0x61, 0x2c, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x29, 0x29, 0x2c, 0x59, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x72, 0x29, 0x7b, 0x72, 0x5b, 0x65, 0x5d, 0x5b, + 0x74, 0x5d, 0x2e, 0x65, 0x61, 0x73, 0x65, 0x3d, 0x6e, 0x7d, 0x29, + 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, 0x64, 0x65, 0x6c, 0x61, 0x79, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x69, 0x64, 0x2c, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3c, 0x31, 0x3f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x28, 0x29, 0x5b, 0x65, 0x5d, 0x5b, 0x74, 0x5d, 0x2e, + 0x64, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x59, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, + 0x3f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, + 0x2c, 0x75, 0x2c, 0x69, 0x29, 0x7b, 0x72, 0x5b, 0x65, 0x5d, 0x5b, + 0x74, 0x5d, 0x2e, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x3d, 0x2b, 0x6e, + 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x72, 0x2e, 0x5f, + 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x75, 0x2c, 0x69, + 0x29, 0x7d, 0x3a, 0x28, 0x6e, 0x3d, 0x2b, 0x6e, 0x2c, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, 0x29, 0x7b, 0x72, + 0x5b, 0x65, 0x5d, 0x5b, 0x74, 0x5d, 0x2e, 0x64, 0x65, 0x6c, 0x61, + 0x79, 0x3d, 0x6e, 0x7d, 0x29, 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, + 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x64, 0x2c, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x3b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x31, + 0x3f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x28, + 0x29, 0x5b, 0x65, 0x5d, 0x5b, 0x74, 0x5d, 0x2e, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x59, 0x28, 0x74, 0x68, 0x69, + 0x73, 0x2c, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6e, + 0x3f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, + 0x2c, 0x75, 0x2c, 0x69, 0x29, 0x7b, 0x72, 0x5b, 0x65, 0x5d, 0x5b, + 0x74, 0x5d, 0x2e, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x31, + 0x2c, 0x6e, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x2c, 0x72, + 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x5f, 0x2c, 0x75, + 0x2c, 0x69, 0x29, 0x29, 0x7d, 0x3a, 0x28, 0x6e, 0x3d, 0x4d, 0x61, + 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x31, 0x2c, 0x6e, 0x29, + 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x72, + 0x29, 0x7b, 0x72, 0x5b, 0x65, 0x5d, 0x5b, 0x74, 0x5d, 0x2e, 0x64, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x6e, 0x7d, 0x29, + 0x29, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x69, 0x64, 0x2c, 0x72, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x3b, 0x69, 0x66, 0x28, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3c, 0x32, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, 0x52, 0x6c, 0x2c, + 0x69, 0x3d, 0x54, 0x6c, 0x3b, 0x74, 0x72, 0x79, 0x7b, 0x54, 0x6c, + 0x3d, 0x65, 0x2c, 0x59, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x75, + 0x2c, 0x69, 0x29, 0x7b, 0x52, 0x6c, 0x3d, 0x74, 0x5b, 0x72, 0x5d, + 0x5b, 0x65, 0x5d, 0x2c, 0x6e, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x74, 0x2c, 0x74, 0x2e, 0x5f, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, + 0x5f, 0x2c, 0x75, 0x2c, 0x69, 0x29, 0x7d, 0x29, 0x7d, 0x66, 0x69, + 0x6e, 0x61, 0x6c, 0x6c, 0x79, 0x7b, 0x52, 0x6c, 0x3d, 0x75, 0x2c, + 0x54, 0x6c, 0x3d, 0x69, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x59, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x3d, 0x75, 0x5b, 0x72, 0x5d, 0x5b, 0x65, 0x5d, 0x3b, + 0x28, 0x69, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x7c, 0x7c, 0x28, + 0x69, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x74, 0x61, 0x2e, + 0x64, 0x69, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x28, 0x22, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x22, 0x2c, 0x22, 0x65, 0x6e, 0x64, 0x22, + 0x2c, 0x22, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, + 0x22, 0x29, 0x29, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, + 0x29, 0x7d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x7d, 0x2c, 0x50, 0x6c, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x6f, + 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x2c, 0x72, 0x2c, 0x75, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x64, 0x2c, 0x69, 0x3d, 0x2b, 0x2b, 0x55, 0x6c, 0x2c, 0x6f, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x2c, 0x61, 0x3d, 0x5b, 0x5d, 0x2c, 0x63, 0x3d, + 0x30, 0x2c, 0x6c, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x6c, 0x3e, 0x63, 0x3b, 0x63, 0x2b, + 0x2b, 0x29, 0x7b, 0x61, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x6e, + 0x3d, 0x5b, 0x5d, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x63, 0x5d, + 0x2c, 0x73, 0x3d, 0x30, 0x2c, 0x66, 0x3d, 0x74, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x66, 0x3e, 0x73, 0x3b, 0x73, 0x2b, + 0x2b, 0x29, 0x28, 0x65, 0x3d, 0x74, 0x5b, 0x73, 0x5d, 0x29, 0x26, + 0x26, 0x28, 0x72, 0x3d, 0x65, 0x5b, 0x6f, 0x5d, 0x5b, 0x75, 0x5d, + 0x2c, 0x24, 0x6f, 0x28, 0x65, 0x2c, 0x73, 0x2c, 0x6f, 0x2c, 0x69, + 0x2c, 0x7b, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x72, 0x2e, 0x74, 0x69, + 0x6d, 0x65, 0x2c, 0x65, 0x61, 0x73, 0x65, 0x3a, 0x72, 0x2e, 0x65, + 0x61, 0x73, 0x65, 0x2c, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x3a, 0x72, + 0x2e, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x2b, 0x72, 0x2e, 0x64, 0x75, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x64, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x72, 0x2e, 0x64, 0x75, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x7d, 0x29, 0x29, 0x2c, 0x6e, 0x2e, 0x70, + 0x75, 0x73, 0x68, 0x28, 0x65, 0x29, 0x7d, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x59, 0x6f, 0x28, 0x61, 0x2c, 0x6f, 0x2c, 0x69, + 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x61, + 0x78, 0x69, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x20, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x65, 0x61, + 0x63, 0x68, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x2c, 0x6c, 0x3d, + 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x2c, 0x73, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x5f, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x74, 0x5f, 0x5f, 0x7c, + 0x7c, 0x65, 0x2c, 0x66, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x5f, 0x63, 0x68, 0x61, 0x72, 0x74, 0x5f, 0x5f, 0x3d, 0x65, 0x2e, + 0x63, 0x6f, 0x70, 0x79, 0x28, 0x29, 0x2c, 0x68, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x3d, 0x3d, 0x63, 0x3f, 0x66, 0x2e, 0x74, 0x69, 0x63, + 0x6b, 0x73, 0x3f, 0x66, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x73, 0x2e, + 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, 0x66, 0x2c, 0x61, 0x29, 0x3a, + 0x66, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x3a, + 0x63, 0x2c, 0x67, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0x3d, 0x74, + 0x3f, 0x66, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x3f, 0x66, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x46, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x28, + 0x66, 0x2c, 0x61, 0x29, 0x3a, 0x79, 0x3a, 0x74, 0x2c, 0x70, 0x3d, + 0x6c, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, + 0x28, 0x22, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x22, 0x29, 0x2e, 0x64, + 0x61, 0x74, 0x61, 0x28, 0x68, 0x2c, 0x66, 0x29, 0x2c, 0x76, 0x3d, + 0x70, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x69, + 0x6e, 0x73, 0x65, 0x72, 0x74, 0x28, 0x22, 0x67, 0x22, 0x2c, 0x22, + 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, + 0x2c, 0x22, 0x74, 0x69, 0x63, 0x6b, 0x22, 0x29, 0x2e, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x28, 0x22, 0x6f, 0x70, 0x61, 0x63, 0x69, 0x74, + 0x79, 0x22, 0x2c, 0x43, 0x61, 0x29, 0x2c, 0x64, 0x3d, 0x74, 0x61, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x70, 0x2e, 0x65, 0x78, 0x69, 0x74, 0x28, 0x29, 0x29, 0x2e, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x6f, 0x70, 0x61, 0x63, + 0x69, 0x74, 0x79, 0x22, 0x2c, 0x43, 0x61, 0x29, 0x2e, 0x72, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x2c, 0x6d, 0x3d, 0x74, 0x61, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x70, 0x2e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x28, 0x29, 0x29, + 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x6f, 0x70, 0x61, + 0x63, 0x69, 0x74, 0x79, 0x22, 0x2c, 0x31, 0x29, 0x2c, 0x4d, 0x3d, + 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, 0x78, 0x28, 0x75, 0x2c, + 0x30, 0x29, 0x2b, 0x6f, 0x2c, 0x78, 0x3d, 0x55, 0x69, 0x28, 0x66, + 0x29, 0x2c, 0x62, 0x3d, 0x6c, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x2e, 0x64, 0x6f, 0x6d, 0x61, + 0x69, 0x6e, 0x22, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, + 0x30, 0x5d, 0x29, 0x2c, 0x5f, 0x3d, 0x28, 0x62, 0x2e, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, + 0x64, 0x28, 0x22, 0x70, 0x61, 0x74, 0x68, 0x22, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, + 0x2c, 0x22, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x22, 0x29, 0x2c, + 0x74, 0x61, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x62, 0x29, 0x29, 0x3b, 0x76, 0x2e, 0x61, 0x70, + 0x70, 0x65, 0x6e, 0x64, 0x28, 0x22, 0x6c, 0x69, 0x6e, 0x65, 0x22, + 0x29, 0x2c, 0x76, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, + 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x29, 0x3b, 0x76, 0x61, 0x72, + 0x20, 0x77, 0x2c, 0x53, 0x2c, 0x6b, 0x2c, 0x45, 0x2c, 0x41, 0x3d, + 0x76, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x22, 0x6c, + 0x69, 0x6e, 0x65, 0x22, 0x29, 0x2c, 0x4e, 0x3d, 0x6d, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x22, 0x6c, 0x69, 0x6e, 0x65, + 0x22, 0x29, 0x2c, 0x43, 0x3d, 0x70, 0x2e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x28, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x29, 0x2e, + 0x74, 0x65, 0x78, 0x74, 0x28, 0x67, 0x29, 0x2c, 0x7a, 0x3d, 0x76, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x22, 0x74, 0x65, + 0x78, 0x74, 0x22, 0x29, 0x2c, 0x71, 0x3d, 0x6d, 0x2e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x28, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, + 0x29, 0x2c, 0x4c, 0x3d, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x3d, 0x3d, + 0x3d, 0x72, 0x7c, 0x7c, 0x22, 0x6c, 0x65, 0x66, 0x74, 0x22, 0x3d, + 0x3d, 0x3d, 0x72, 0x3f, 0x2d, 0x31, 0x3a, 0x31, 0x3b, 0x69, 0x66, + 0x28, 0x22, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x22, 0x3d, 0x3d, + 0x3d, 0x72, 0x7c, 0x7c, 0x22, 0x74, 0x6f, 0x70, 0x22, 0x3d, 0x3d, + 0x3d, 0x72, 0x3f, 0x28, 0x6e, 0x3d, 0x42, 0x6f, 0x2c, 0x77, 0x3d, + 0x22, 0x78, 0x22, 0x2c, 0x6b, 0x3d, 0x22, 0x79, 0x22, 0x2c, 0x53, + 0x3d, 0x22, 0x78, 0x32, 0x22, 0x2c, 0x45, 0x3d, 0x22, 0x79, 0x32, + 0x22, 0x2c, 0x43, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x64, + 0x79, 0x22, 0x2c, 0x30, 0x3e, 0x4c, 0x3f, 0x22, 0x30, 0x65, 0x6d, + 0x22, 0x3a, 0x22, 0x2e, 0x37, 0x31, 0x65, 0x6d, 0x22, 0x29, 0x2e, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x22, 0x2c, 0x22, 0x6d, + 0x69, 0x64, 0x64, 0x6c, 0x65, 0x22, 0x29, 0x2c, 0x5f, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x22, 0x64, 0x22, 0x2c, 0x22, 0x4d, 0x22, + 0x2b, 0x78, 0x5b, 0x30, 0x5d, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x4c, + 0x2a, 0x69, 0x2b, 0x22, 0x56, 0x30, 0x48, 0x22, 0x2b, 0x78, 0x5b, + 0x31, 0x5d, 0x2b, 0x22, 0x56, 0x22, 0x2b, 0x4c, 0x2a, 0x69, 0x29, + 0x29, 0x3a, 0x28, 0x6e, 0x3d, 0x57, 0x6f, 0x2c, 0x77, 0x3d, 0x22, + 0x79, 0x22, 0x2c, 0x6b, 0x3d, 0x22, 0x78, 0x22, 0x2c, 0x53, 0x3d, + 0x22, 0x79, 0x32, 0x22, 0x2c, 0x45, 0x3d, 0x22, 0x78, 0x32, 0x22, + 0x2c, 0x43, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x64, 0x79, + 0x22, 0x2c, 0x22, 0x2e, 0x33, 0x32, 0x65, 0x6d, 0x22, 0x29, 0x2e, + 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x2d, 0x61, 0x6e, 0x63, 0x68, 0x6f, 0x72, 0x22, 0x2c, 0x30, 0x3e, + 0x4c, 0x3f, 0x22, 0x65, 0x6e, 0x64, 0x22, 0x3a, 0x22, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x22, 0x29, 0x2c, 0x5f, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x22, 0x64, 0x22, 0x2c, 0x22, 0x4d, 0x22, 0x2b, 0x4c, + 0x2a, 0x69, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x78, 0x5b, 0x30, 0x5d, + 0x2b, 0x22, 0x48, 0x30, 0x56, 0x22, 0x2b, 0x78, 0x5b, 0x31, 0x5d, + 0x2b, 0x22, 0x48, 0x22, 0x2b, 0x4c, 0x2a, 0x69, 0x29, 0x29, 0x2c, + 0x41, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x45, 0x2c, 0x4c, 0x2a, + 0x75, 0x29, 0x2c, 0x7a, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x6b, + 0x2c, 0x4c, 0x2a, 0x4d, 0x29, 0x2c, 0x4e, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x53, 0x2c, 0x30, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x28, 0x45, 0x2c, 0x4c, 0x2a, 0x75, 0x29, 0x2c, 0x71, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x77, 0x2c, 0x30, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x6b, 0x2c, 0x4c, 0x2a, 0x4d, 0x29, 0x2c, 0x66, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x54, 0x3d, 0x66, 0x2c, 0x52, 0x3d, + 0x54, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, + 0x28, 0x29, 0x2f, 0x32, 0x3b, 0x73, 0x3d, 0x66, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x54, 0x28, 0x6e, 0x29, 0x2b, + 0x52, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x73, 0x2e, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x42, 0x61, 0x6e, 0x64, 0x3f, 0x73, 0x3d, + 0x66, 0x3a, 0x64, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, + 0x66, 0x2c, 0x73, 0x29, 0x3b, 0x76, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x6e, 0x2c, 0x73, 0x2c, 0x66, 0x29, 0x2c, 0x6d, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x6e, 0x2c, 0x66, 0x2c, 0x66, 0x29, 0x7d, + 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x74, 0x2c, 0x65, 0x3d, 0x74, + 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6c, 0x69, 0x6e, + 0x65, 0x61, 0x72, 0x28, 0x29, 0x2c, 0x72, 0x3d, 0x6a, 0x6c, 0x2c, + 0x75, 0x3d, 0x36, 0x2c, 0x69, 0x3d, 0x36, 0x2c, 0x6f, 0x3d, 0x33, + 0x2c, 0x61, 0x3d, 0x5b, 0x31, 0x30, 0x5d, 0x2c, 0x63, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, + 0x28, 0x65, 0x3d, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x65, 0x7d, 0x2c, + 0x6e, 0x2e, 0x6f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x3d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3f, 0x28, 0x72, 0x3d, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x46, 0x6c, + 0x3f, 0x74, 0x2b, 0x22, 0x22, 0x3a, 0x6a, 0x6c, 0x2c, 0x6e, 0x29, + 0x3a, 0x72, 0x7d, 0x2c, 0x6e, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x73, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x3f, 0x28, 0x61, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2c, 0x6e, 0x29, 0x3a, 0x61, 0x7d, 0x2c, + 0x6e, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x63, 0x3d, 0x74, 0x2c, 0x6e, + 0x29, 0x3a, 0x63, 0x7d, 0x2c, 0x6e, 0x2e, 0x74, 0x69, 0x63, 0x6b, + 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, + 0x74, 0x3d, 0x65, 0x2c, 0x6e, 0x29, 0x3a, 0x74, 0x7d, 0x2c, 0x6e, + 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, 0x61, 0x72, 0x67, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x3f, 0x28, + 0x75, 0x3d, 0x2b, 0x74, 0x2c, 0x69, 0x3d, 0x2b, 0x61, 0x72, 0x67, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x5b, 0x65, 0x2d, 0x31, 0x5d, + 0x2c, 0x6e, 0x29, 0x3a, 0x75, 0x7d, 0x2c, 0x6e, 0x2e, 0x69, 0x6e, + 0x6e, 0x65, 0x72, 0x54, 0x69, 0x63, 0x6b, 0x53, 0x69, 0x7a, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3f, 0x28, 0x75, 0x3d, 0x2b, 0x74, 0x2c, 0x6e, + 0x29, 0x3a, 0x75, 0x7d, 0x2c, 0x6e, 0x2e, 0x6f, 0x75, 0x74, 0x65, + 0x72, 0x54, 0x69, 0x63, 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x3d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3f, 0x28, 0x69, 0x3d, 0x2b, 0x74, 0x2c, 0x6e, 0x29, 0x3a, + 0x69, 0x7d, 0x2c, 0x6e, 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x50, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6f, + 0x3d, 0x2b, 0x74, 0x2c, 0x6e, 0x29, 0x3a, 0x6f, 0x7d, 0x2c, 0x6e, + 0x2e, 0x74, 0x69, 0x63, 0x6b, 0x53, 0x75, 0x62, 0x64, 0x69, 0x76, + 0x69, 0x64, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x26, 0x26, 0x6e, 0x7d, 0x2c, 0x6e, + 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x6a, 0x6c, 0x3d, 0x22, 0x62, + 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x22, 0x2c, 0x46, 0x6c, 0x3d, 0x7b, + 0x74, 0x6f, 0x70, 0x3a, 0x31, 0x2c, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x31, 0x2c, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x31, + 0x2c, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x31, 0x7d, 0x3b, 0x74, 0x61, + 0x2e, 0x73, 0x76, 0x67, 0x2e, 0x62, 0x72, 0x75, 0x73, 0x68, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x74, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x2e, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x2d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x2c, + 0x22, 0x61, 0x6c, 0x6c, 0x22, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, + 0x65, 0x28, 0x22, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, + 0x74, 0x61, 0x70, 0x2d, 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, + 0x68, 0x74, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x2c, 0x22, + 0x72, 0x67, 0x62, 0x61, 0x28, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, + 0x30, 0x29, 0x22, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x6d, 0x6f, + 0x75, 0x73, 0x65, 0x64, 0x6f, 0x77, 0x6e, 0x2e, 0x62, 0x72, 0x75, + 0x73, 0x68, 0x22, 0x2c, 0x69, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, + 0x74, 0x6f, 0x75, 0x63, 0x68, 0x73, 0x74, 0x61, 0x72, 0x74, 0x2e, + 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, 0x2c, 0x69, 0x29, 0x2c, 0x6f, + 0x3d, 0x74, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, + 0x6c, 0x28, 0x22, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x22, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, + 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x6f, 0x2e, 0x65, 0x6e, 0x74, 0x65, + 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, + 0x22, 0x72, 0x65, 0x63, 0x74, 0x22, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x2c, 0x22, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x22, + 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x2c, 0x22, + 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x22, 0x29, 0x2e, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x28, 0x22, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, + 0x22, 0x2c, 0x22, 0x63, 0x72, 0x6f, 0x73, 0x73, 0x68, 0x61, 0x69, + 0x72, 0x22, 0x29, 0x2c, 0x74, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x2e, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x22, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x5b, + 0x30, 0x5d, 0x29, 0x2e, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, + 0x2e, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x28, 0x22, 0x72, 0x65, + 0x63, 0x74, 0x22, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x2c, 0x22, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x22, 0x29, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x28, 0x22, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0x2c, 0x22, + 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, + 0x61, 0x3d, 0x74, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, + 0x6c, 0x6c, 0x28, 0x22, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, + 0x22, 0x29, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x28, 0x76, 0x2c, 0x79, + 0x29, 0x3b, 0x61, 0x2e, 0x65, 0x78, 0x69, 0x74, 0x28, 0x29, 0x2e, + 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x28, 0x29, 0x2c, 0x61, 0x2e, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x22, 0x67, 0x22, 0x29, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x28, 0x22, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x22, 0x2c, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x65, 0x20, 0x22, 0x2b, 0x6e, 0x7d, 0x29, 0x2e, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x63, 0x75, 0x72, 0x73, 0x6f, + 0x72, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x48, 0x6c, 0x5b, 0x6e, 0x5d, 0x7d, 0x29, 0x2e, 0x61, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x28, 0x22, 0x72, 0x65, 0x63, 0x74, 0x22, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x78, 0x22, 0x2c, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2f, 0x5b, 0x65, 0x77, 0x5d, + 0x24, 0x2f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x6e, 0x29, 0x3f, + 0x2d, 0x33, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x22, 0x79, 0x22, 0x2c, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x2f, 0x5e, 0x5b, 0x6e, 0x73, 0x5d, 0x2f, + 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x6e, 0x29, 0x3f, 0x2d, 0x33, + 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x7d, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x22, 0x2c, 0x36, + 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x68, 0x65, 0x69, + 0x67, 0x68, 0x74, 0x22, 0x2c, 0x36, 0x29, 0x2e, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x28, 0x22, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x22, 0x2c, 0x22, 0x68, 0x69, 0x64, 0x64, 0x65, + 0x6e, 0x22, 0x29, 0x2c, 0x61, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, + 0x28, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x22, 0x2c, + 0x6e, 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x29, 0x3f, 0x22, + 0x6e, 0x6f, 0x6e, 0x65, 0x22, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x63, 0x2c, 0x66, 0x3d, 0x74, 0x61, + 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x2c, 0x68, 0x3d, 0x74, 0x61, 0x2e, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6f, 0x29, + 0x3b, 0x6c, 0x26, 0x26, 0x28, 0x63, 0x3d, 0x55, 0x69, 0x28, 0x6c, + 0x29, 0x2c, 0x68, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x78, + 0x22, 0x2c, 0x63, 0x5b, 0x30, 0x5d, 0x29, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x22, 0x2c, 0x63, + 0x5b, 0x31, 0x5d, 0x2d, 0x63, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x72, + 0x28, 0x66, 0x29, 0x29, 0x2c, 0x73, 0x26, 0x26, 0x28, 0x63, 0x3d, + 0x55, 0x69, 0x28, 0x73, 0x29, 0x2c, 0x68, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x28, 0x22, 0x79, 0x22, 0x2c, 0x63, 0x5b, 0x30, 0x5d, 0x29, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x22, 0x2c, 0x63, 0x5b, 0x31, 0x5d, 0x2d, 0x63, 0x5b, + 0x30, 0x5d, 0x29, 0x2c, 0x75, 0x28, 0x66, 0x29, 0x29, 0x2c, 0x65, + 0x28, 0x66, 0x29, 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x22, + 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x29, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x28, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x22, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x65, + 0x28, 0x22, 0x2b, 0x66, 0x5b, 0x2b, 0x2f, 0x65, 0x24, 0x2f, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x28, 0x6e, 0x29, 0x5d, 0x2b, 0x22, 0x2c, + 0x22, 0x2b, 0x68, 0x5b, 0x2b, 0x2f, 0x5e, 0x73, 0x2f, 0x2e, 0x74, + 0x65, 0x73, 0x74, 0x28, 0x6e, 0x29, 0x5d, 0x2b, 0x22, 0x29, 0x22, + 0x7d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x72, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x28, 0x22, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, + 0x74, 0x22, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x78, + 0x22, 0x2c, 0x66, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x6e, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x2e, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x2c, 0x2e, 0x6e, 0x3e, 0x72, + 0x65, 0x63, 0x74, 0x2c, 0x2e, 0x73, 0x3e, 0x72, 0x65, 0x63, 0x74, + 0x22, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, 0x77, 0x69, + 0x64, 0x74, 0x68, 0x22, 0x2c, 0x66, 0x5b, 0x31, 0x5d, 0x2d, 0x66, + 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x22, 0x2e, 0x65, 0x78, 0x74, + 0x65, 0x6e, 0x74, 0x22, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, + 0x22, 0x79, 0x22, 0x2c, 0x68, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x6e, + 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, + 0x22, 0x2e, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x2c, 0x2e, 0x65, + 0x3e, 0x72, 0x65, 0x63, 0x74, 0x2c, 0x2e, 0x77, 0x3e, 0x72, 0x65, + 0x63, 0x74, 0x22, 0x29, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x28, 0x22, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x2c, 0x68, 0x5b, 0x31, + 0x5d, 0x2d, 0x68, 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x29, 0x7b, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x29, + 0x7b, 0x33, 0x32, 0x3d, 0x3d, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x43, 0x6f, 0x64, 0x65, 0x26, + 0x26, 0x28, 0x43, 0x7c, 0x7c, 0x28, 0x4d, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x2c, 0x71, 0x5b, 0x30, 0x5d, 0x2d, 0x3d, 0x66, 0x5b, 0x31, + 0x5d, 0x2c, 0x71, 0x5b, 0x31, 0x5d, 0x2d, 0x3d, 0x68, 0x5b, 0x31, + 0x5d, 0x2c, 0x43, 0x3d, 0x32, 0x29, 0x2c, 0x53, 0x28, 0x29, 0x29, + 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x28, 0x29, 0x7b, 0x33, 0x32, 0x3d, 0x3d, 0x74, 0x61, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x43, 0x6f, 0x64, + 0x65, 0x26, 0x26, 0x32, 0x3d, 0x3d, 0x43, 0x26, 0x26, 0x28, 0x71, + 0x5b, 0x30, 0x5d, 0x2b, 0x3d, 0x66, 0x5b, 0x31, 0x5d, 0x2c, 0x71, + 0x5b, 0x31, 0x5d, 0x2b, 0x3d, 0x68, 0x5b, 0x31, 0x5d, 0x2c, 0x43, + 0x3d, 0x30, 0x2c, 0x53, 0x28, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x28, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x74, 0x61, 0x2e, 0x6d, 0x6f, 0x75, + 0x73, 0x65, 0x28, 0x62, 0x29, 0x2c, 0x74, 0x3d, 0x21, 0x31, 0x3b, + 0x78, 0x26, 0x26, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x2b, 0x3d, 0x78, + 0x5b, 0x30, 0x5d, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x2b, 0x3d, 0x78, + 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x43, 0x7c, 0x7c, 0x28, 0x74, 0x61, + 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x6c, 0x74, 0x4b, + 0x65, 0x79, 0x3f, 0x28, 0x4d, 0x7c, 0x7c, 0x28, 0x4d, 0x3d, 0x5b, + 0x28, 0x66, 0x5b, 0x30, 0x5d, 0x2b, 0x66, 0x5b, 0x31, 0x5d, 0x29, + 0x2f, 0x32, 0x2c, 0x28, 0x68, 0x5b, 0x30, 0x5d, 0x2b, 0x68, 0x5b, + 0x31, 0x5d, 0x29, 0x2f, 0x32, 0x5d, 0x29, 0x2c, 0x71, 0x5b, 0x30, + 0x5d, 0x3d, 0x66, 0x5b, 0x2b, 0x28, 0x6e, 0x5b, 0x30, 0x5d, 0x3c, + 0x4d, 0x5b, 0x30, 0x5d, 0x29, 0x5d, 0x2c, 0x71, 0x5b, 0x31, 0x5d, + 0x3d, 0x68, 0x5b, 0x2b, 0x28, 0x6e, 0x5b, 0x31, 0x5d, 0x3c, 0x4d, + 0x5b, 0x31, 0x5d, 0x29, 0x5d, 0x29, 0x3a, 0x4d, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x29, 0x2c, 0x41, 0x26, 0x26, 0x6d, 0x28, 0x6e, 0x2c, + 0x6c, 0x2c, 0x30, 0x29, 0x26, 0x26, 0x28, 0x72, 0x28, 0x6b, 0x29, + 0x2c, 0x74, 0x3d, 0x21, 0x30, 0x29, 0x2c, 0x4e, 0x26, 0x26, 0x6d, + 0x28, 0x6e, 0x2c, 0x73, 0x2c, 0x31, 0x29, 0x26, 0x26, 0x28, 0x75, + 0x28, 0x6b, 0x29, 0x2c, 0x74, 0x3d, 0x21, 0x30, 0x29, 0x2c, 0x74, + 0x26, 0x26, 0x28, 0x65, 0x28, 0x6b, 0x29, 0x2c, 0x77, 0x28, 0x7b, + 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, + 0x22, 0x2c, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x43, 0x3f, 0x22, 0x6d, + 0x6f, 0x76, 0x65, 0x22, 0x3a, 0x22, 0x72, 0x65, 0x73, 0x69, 0x7a, + 0x65, 0x22, 0x7d, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x2c, 0x75, 0x2c, 0x69, + 0x3d, 0x55, 0x69, 0x28, 0x74, 0x29, 0x2c, 0x63, 0x3d, 0x69, 0x5b, + 0x30, 0x5d, 0x2c, 0x6c, 0x3d, 0x69, 0x5b, 0x31, 0x5d, 0x2c, 0x73, + 0x3d, 0x71, 0x5b, 0x65, 0x5d, 0x2c, 0x76, 0x3d, 0x65, 0x3f, 0x68, + 0x3a, 0x66, 0x2c, 0x64, 0x3d, 0x76, 0x5b, 0x31, 0x5d, 0x2d, 0x76, + 0x5b, 0x30, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x43, 0x26, 0x26, 0x28, 0x63, 0x2d, 0x3d, 0x73, 0x2c, 0x6c, 0x2d, + 0x3d, 0x64, 0x2b, 0x73, 0x29, 0x2c, 0x72, 0x3d, 0x28, 0x65, 0x3f, + 0x70, 0x3a, 0x67, 0x29, 0x3f, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, + 0x61, 0x78, 0x28, 0x63, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, + 0x69, 0x6e, 0x28, 0x6c, 0x2c, 0x6e, 0x5b, 0x65, 0x5d, 0x29, 0x29, + 0x3a, 0x6e, 0x5b, 0x65, 0x5d, 0x2c, 0x43, 0x3f, 0x75, 0x3d, 0x28, + 0x72, 0x2b, 0x3d, 0x73, 0x29, 0x2b, 0x64, 0x3a, 0x28, 0x4d, 0x26, + 0x26, 0x28, 0x73, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x61, + 0x78, 0x28, 0x63, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, + 0x6e, 0x28, 0x6c, 0x2c, 0x32, 0x2a, 0x4d, 0x5b, 0x65, 0x5d, 0x2d, + 0x72, 0x29, 0x29, 0x29, 0x2c, 0x72, 0x3e, 0x73, 0x3f, 0x28, 0x75, + 0x3d, 0x72, 0x2c, 0x72, 0x3d, 0x73, 0x29, 0x3a, 0x75, 0x3d, 0x73, + 0x29, 0x2c, 0x76, 0x5b, 0x30, 0x5d, 0x21, 0x3d, 0x72, 0x7c, 0x7c, + 0x76, 0x5b, 0x31, 0x5d, 0x21, 0x3d, 0x75, 0x3f, 0x28, 0x65, 0x3f, + 0x61, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x6f, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x2c, 0x76, 0x5b, 0x30, 0x5d, 0x3d, 0x72, 0x2c, 0x76, + 0x5b, 0x31, 0x5d, 0x3d, 0x75, 0x2c, 0x21, 0x30, 0x29, 0x3a, 0x76, + 0x6f, 0x69, 0x64, 0x20, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x79, 0x28, 0x29, 0x7b, 0x64, 0x28, 0x29, + 0x2c, 0x6b, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x22, 0x2c, 0x22, 0x61, 0x6c, 0x6c, 0x22, 0x29, 0x2e, + 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x22, + 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x29, 0x2e, 0x73, + 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x64, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x22, 0x2c, 0x6e, 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, + 0x28, 0x29, 0x3f, 0x22, 0x6e, 0x6f, 0x6e, 0x65, 0x22, 0x3a, 0x6e, + 0x75, 0x6c, 0x6c, 0x29, 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x28, 0x22, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x29, + 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x63, 0x75, 0x72, + 0x73, 0x6f, 0x72, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2c, + 0x4c, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x2e, 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, + 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, + 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x75, 0x70, 0x2e, 0x62, 0x72, 0x75, + 0x73, 0x68, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2e, 0x6f, + 0x6e, 0x28, 0x22, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x6d, 0x6f, 0x76, + 0x65, 0x2e, 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, 0x2c, 0x6e, 0x75, + 0x6c, 0x6c, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x74, 0x6f, 0x75, + 0x63, 0x68, 0x65, 0x6e, 0x64, 0x2e, 0x62, 0x72, 0x75, 0x73, 0x68, + 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2e, 0x6f, 0x6e, 0x28, + 0x22, 0x6b, 0x65, 0x79, 0x64, 0x6f, 0x77, 0x6e, 0x2e, 0x62, 0x72, + 0x75, 0x73, 0x68, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, 0x2e, + 0x6f, 0x6e, 0x28, 0x22, 0x6b, 0x65, 0x79, 0x75, 0x70, 0x2e, 0x62, + 0x72, 0x75, 0x73, 0x68, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x2c, 0x7a, 0x28, 0x29, 0x2c, 0x77, 0x28, 0x7b, 0x74, 0x79, 0x70, + 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, + 0x22, 0x7d, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x4d, 0x2c, 0x78, + 0x2c, 0x62, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x5f, 0x3d, 0x74, + 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, 0x61, + 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67, + 0x65, 0x74, 0x29, 0x2c, 0x77, 0x3d, 0x63, 0x2e, 0x6f, 0x66, 0x28, + 0x62, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x29, 0x2c, 0x6b, 0x3d, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x28, 0x62, 0x29, 0x2c, 0x45, 0x3d, 0x5f, 0x2e, 0x64, + 0x61, 0x74, 0x75, 0x6d, 0x28, 0x29, 0x2c, 0x41, 0x3d, 0x21, 0x2f, + 0x5e, 0x28, 0x6e, 0x7c, 0x73, 0x29, 0x24, 0x2f, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x28, 0x45, 0x29, 0x26, 0x26, 0x6c, 0x2c, 0x4e, 0x3d, + 0x21, 0x2f, 0x5e, 0x28, 0x65, 0x7c, 0x77, 0x29, 0x24, 0x2f, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x28, 0x45, 0x29, 0x26, 0x26, 0x73, 0x2c, + 0x43, 0x3d, 0x5f, 0x2e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x64, + 0x28, 0x22, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x74, 0x22, 0x29, 0x2c, + 0x7a, 0x3d, 0x57, 0x28, 0x62, 0x29, 0x2c, 0x71, 0x3d, 0x74, 0x61, + 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x28, 0x62, 0x29, 0x2c, 0x4c, + 0x3d, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x74, 0x28, 0x62, 0x29, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x6b, + 0x65, 0x79, 0x64, 0x6f, 0x77, 0x6e, 0x2e, 0x62, 0x72, 0x75, 0x73, + 0x68, 0x22, 0x2c, 0x69, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x6b, + 0x65, 0x79, 0x75, 0x70, 0x2e, 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, + 0x2c, 0x76, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x61, 0x2e, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x64, 0x54, 0x6f, 0x75, 0x63, 0x68, 0x65, 0x73, 0x3f, 0x4c, 0x2e, + 0x6f, 0x6e, 0x28, 0x22, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x6d, 0x6f, + 0x76, 0x65, 0x2e, 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, 0x2c, 0x64, + 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x74, 0x6f, 0x75, 0x63, 0x68, + 0x65, 0x6e, 0x64, 0x2e, 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, 0x2c, + 0x79, 0x29, 0x3a, 0x4c, 0x2e, 0x6f, 0x6e, 0x28, 0x22, 0x6d, 0x6f, + 0x75, 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x2e, 0x62, 0x72, 0x75, + 0x73, 0x68, 0x22, 0x2c, 0x64, 0x29, 0x2e, 0x6f, 0x6e, 0x28, 0x22, + 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x75, 0x70, 0x2e, 0x62, 0x72, 0x75, + 0x73, 0x68, 0x22, 0x2c, 0x79, 0x29, 0x2c, 0x6b, 0x2e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, 0x74, 0x28, 0x29, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, 0x28, 0x22, 0x2a, + 0x22, 0x29, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x72, 0x75, 0x70, + 0x74, 0x28, 0x29, 0x2c, 0x43, 0x29, 0x71, 0x5b, 0x30, 0x5d, 0x3d, + 0x66, 0x5b, 0x30, 0x5d, 0x2d, 0x71, 0x5b, 0x30, 0x5d, 0x2c, 0x71, + 0x5b, 0x31, 0x5d, 0x3d, 0x68, 0x5b, 0x30, 0x5d, 0x2d, 0x71, 0x5b, + 0x31, 0x5d, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x69, 0x66, 0x28, + 0x45, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x54, 0x3d, 0x2b, 0x2f, + 0x77, 0x24, 0x2f, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x28, 0x45, 0x29, + 0x2c, 0x52, 0x3d, 0x2b, 0x2f, 0x5e, 0x6e, 0x2f, 0x2e, 0x74, 0x65, + 0x73, 0x74, 0x28, 0x45, 0x29, 0x3b, 0x78, 0x3d, 0x5b, 0x66, 0x5b, + 0x31, 0x2d, 0x54, 0x5d, 0x2d, 0x71, 0x5b, 0x30, 0x5d, 0x2c, 0x68, + 0x5b, 0x31, 0x2d, 0x52, 0x5d, 0x2d, 0x71, 0x5b, 0x31, 0x5d, 0x5d, + 0x2c, 0x71, 0x5b, 0x30, 0x5d, 0x3d, 0x66, 0x5b, 0x54, 0x5d, 0x2c, + 0x71, 0x5b, 0x31, 0x5d, 0x3d, 0x68, 0x5b, 0x52, 0x5d, 0x7d, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x74, 0x61, 0x2e, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x2e, 0x61, 0x6c, 0x74, 0x4b, 0x65, 0x79, 0x26, 0x26, 0x28, + 0x4d, 0x3d, 0x71, 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x29, + 0x29, 0x3b, 0x6b, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x2d, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x22, 0x2c, 0x22, 0x6e, 0x6f, 0x6e, 0x65, 0x22, + 0x29, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x41, 0x6c, 0x6c, + 0x28, 0x22, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x29, + 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x64, 0x69, 0x73, + 0x70, 0x6c, 0x61, 0x79, 0x22, 0x2c, 0x6e, 0x75, 0x6c, 0x6c, 0x29, + 0x2c, 0x74, 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, + 0x22, 0x62, 0x6f, 0x64, 0x79, 0x22, 0x29, 0x2e, 0x73, 0x74, 0x79, + 0x6c, 0x65, 0x28, 0x22, 0x63, 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, + 0x2c, 0x5f, 0x2e, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x28, 0x22, 0x63, + 0x75, 0x72, 0x73, 0x6f, 0x72, 0x22, 0x29, 0x29, 0x2c, 0x77, 0x28, + 0x7b, 0x74, 0x79, 0x70, 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, + 0x68, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x7d, 0x29, 0x2c, 0x64, + 0x28, 0x29, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x2c, 0x61, 0x2c, + 0x63, 0x3d, 0x45, 0x28, 0x6e, 0x2c, 0x22, 0x62, 0x72, 0x75, 0x73, + 0x68, 0x73, 0x74, 0x61, 0x72, 0x74, 0x22, 0x2c, 0x22, 0x62, 0x72, + 0x75, 0x73, 0x68, 0x22, 0x2c, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, + 0x65, 0x6e, 0x64, 0x22, 0x29, 0x2c, 0x6c, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x2c, 0x73, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x66, 0x3d, + 0x5b, 0x30, 0x2c, 0x30, 0x5d, 0x2c, 0x68, 0x3d, 0x5b, 0x30, 0x2c, + 0x30, 0x5d, 0x2c, 0x67, 0x3d, 0x21, 0x30, 0x2c, 0x70, 0x3d, 0x21, + 0x30, 0x2c, 0x76, 0x3d, 0x4f, 0x6c, 0x5b, 0x30, 0x5d, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x63, 0x2e, 0x6f, 0x66, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2c, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x29, 0x2c, 0x74, 0x3d, 0x7b, 0x78, 0x3a, 0x66, + 0x2c, 0x79, 0x3a, 0x68, 0x2c, 0x69, 0x3a, 0x6f, 0x2c, 0x6a, 0x3a, + 0x61, 0x7d, 0x2c, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, + 0x5f, 0x63, 0x68, 0x61, 0x72, 0x74, 0x5f, 0x5f, 0x7c, 0x7c, 0x74, + 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x5f, 0x5f, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x5f, 0x5f, 0x3d, 0x74, 0x2c, 0x54, 0x6c, 0x3f, 0x74, + 0x61, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x29, 0x2e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x2e, 0x65, 0x61, 0x63, 0x68, 0x28, + 0x22, 0x73, 0x74, 0x61, 0x72, 0x74, 0x2e, 0x62, 0x72, 0x75, 0x73, + 0x68, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x6f, 0x3d, 0x65, 0x2e, 0x69, 0x2c, 0x61, 0x3d, + 0x65, 0x2e, 0x6a, 0x2c, 0x66, 0x3d, 0x65, 0x2e, 0x78, 0x2c, 0x68, + 0x3d, 0x65, 0x2e, 0x79, 0x2c, 0x6e, 0x28, 0x7b, 0x74, 0x79, 0x70, + 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x73, 0x74, 0x61, + 0x72, 0x74, 0x22, 0x7d, 0x29, 0x7d, 0x29, 0x2e, 0x74, 0x77, 0x65, + 0x65, 0x6e, 0x28, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x3a, 0x62, + 0x72, 0x75, 0x73, 0x68, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, + 0x3d, 0x79, 0x75, 0x28, 0x66, 0x2c, 0x74, 0x2e, 0x78, 0x29, 0x2c, + 0x72, 0x3d, 0x79, 0x75, 0x28, 0x68, 0x2c, 0x74, 0x2e, 0x79, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x3d, 0x61, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x29, 0x7b, 0x66, 0x3d, 0x74, 0x2e, + 0x78, 0x3d, 0x65, 0x28, 0x75, 0x29, 0x2c, 0x68, 0x3d, 0x74, 0x2e, + 0x79, 0x3d, 0x72, 0x28, 0x75, 0x29, 0x2c, 0x6e, 0x28, 0x7b, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, + 0x2c, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x22, 0x72, 0x65, 0x73, 0x69, + 0x7a, 0x65, 0x22, 0x7d, 0x29, 0x7d, 0x7d, 0x29, 0x2e, 0x65, 0x61, + 0x63, 0x68, 0x28, 0x22, 0x65, 0x6e, 0x64, 0x2e, 0x62, 0x72, 0x75, + 0x73, 0x68, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x6f, 0x3d, 0x74, 0x2e, 0x69, 0x2c, 0x61, + 0x3d, 0x74, 0x2e, 0x6a, 0x2c, 0x6e, 0x28, 0x7b, 0x74, 0x79, 0x70, + 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, 0x2c, 0x6d, + 0x6f, 0x64, 0x65, 0x3a, 0x22, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, + 0x22, 0x7d, 0x29, 0x2c, 0x6e, 0x28, 0x7b, 0x74, 0x79, 0x70, 0x65, + 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x65, 0x6e, 0x64, 0x22, + 0x7d, 0x29, 0x7d, 0x29, 0x3a, 0x28, 0x6e, 0x28, 0x7b, 0x74, 0x79, + 0x70, 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x22, 0x7d, 0x29, 0x2c, 0x6e, 0x28, 0x7b, 0x74, + 0x79, 0x70, 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x22, + 0x2c, 0x6d, 0x6f, 0x64, 0x65, 0x3a, 0x22, 0x72, 0x65, 0x73, 0x69, + 0x7a, 0x65, 0x22, 0x7d, 0x29, 0x2c, 0x6e, 0x28, 0x7b, 0x74, 0x79, + 0x70, 0x65, 0x3a, 0x22, 0x62, 0x72, 0x75, 0x73, 0x68, 0x65, 0x6e, + 0x64, 0x22, 0x7d, 0x29, 0x29, 0x7d, 0x29, 0x7d, 0x2c, 0x6e, 0x2e, + 0x78, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6c, 0x3d, 0x74, 0x2c, 0x76, + 0x3d, 0x4f, 0x6c, 0x5b, 0x21, 0x6c, 0x3c, 0x3c, 0x31, 0x7c, 0x21, + 0x73, 0x5d, 0x2c, 0x6e, 0x29, 0x3a, 0x6c, 0x7d, 0x2c, 0x6e, 0x2e, + 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x73, 0x3d, 0x74, 0x2c, 0x76, + 0x3d, 0x4f, 0x6c, 0x5b, 0x21, 0x6c, 0x3c, 0x3c, 0x31, 0x7c, 0x21, + 0x73, 0x5d, 0x2c, 0x6e, 0x29, 0x3a, 0x73, 0x7d, 0x2c, 0x6e, 0x2e, + 0x63, 0x6c, 0x61, 0x6d, 0x70, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6c, + 0x26, 0x26, 0x73, 0x3f, 0x28, 0x67, 0x3d, 0x21, 0x21, 0x74, 0x5b, + 0x30, 0x5d, 0x2c, 0x70, 0x3d, 0x21, 0x21, 0x74, 0x5b, 0x31, 0x5d, + 0x29, 0x3a, 0x6c, 0x3f, 0x67, 0x3d, 0x21, 0x21, 0x74, 0x3a, 0x73, + 0x26, 0x26, 0x28, 0x70, 0x3d, 0x21, 0x21, 0x74, 0x29, 0x2c, 0x6e, + 0x29, 0x3a, 0x6c, 0x26, 0x26, 0x73, 0x3f, 0x5b, 0x67, 0x2c, 0x70, + 0x5d, 0x3a, 0x6c, 0x3f, 0x67, 0x3a, 0x73, 0x3f, 0x70, 0x3a, 0x6e, + 0x75, 0x6c, 0x6c, 0x7d, 0x2c, 0x6e, 0x2e, 0x65, 0x78, 0x74, 0x65, + 0x6e, 0x74, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x72, + 0x2c, 0x75, 0x2c, 0x69, 0x2c, 0x63, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x28, 0x6c, + 0x26, 0x26, 0x28, 0x65, 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x72, + 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x73, 0x26, 0x26, 0x28, 0x65, + 0x3d, 0x65, 0x5b, 0x30, 0x5d, 0x2c, 0x72, 0x3d, 0x72, 0x5b, 0x30, + 0x5d, 0x29, 0x2c, 0x6f, 0x3d, 0x5b, 0x65, 0x2c, 0x72, 0x5d, 0x2c, + 0x6c, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x26, 0x26, 0x28, + 0x65, 0x3d, 0x6c, 0x28, 0x65, 0x29, 0x2c, 0x72, 0x3d, 0x6c, 0x28, + 0x72, 0x29, 0x29, 0x2c, 0x65, 0x3e, 0x72, 0x26, 0x26, 0x28, 0x63, + 0x3d, 0x65, 0x2c, 0x65, 0x3d, 0x72, 0x2c, 0x72, 0x3d, 0x63, 0x29, + 0x2c, 0x28, 0x65, 0x21, 0x3d, 0x66, 0x5b, 0x30, 0x5d, 0x7c, 0x7c, + 0x72, 0x21, 0x3d, 0x66, 0x5b, 0x31, 0x5d, 0x29, 0x26, 0x26, 0x28, + 0x66, 0x3d, 0x5b, 0x65, 0x2c, 0x72, 0x5d, 0x29, 0x29, 0x2c, 0x73, + 0x26, 0x26, 0x28, 0x75, 0x3d, 0x74, 0x5b, 0x30, 0x5d, 0x2c, 0x69, + 0x3d, 0x74, 0x5b, 0x31, 0x5d, 0x2c, 0x6c, 0x26, 0x26, 0x28, 0x75, + 0x3d, 0x75, 0x5b, 0x31, 0x5d, 0x2c, 0x69, 0x3d, 0x69, 0x5b, 0x31, + 0x5d, 0x29, 0x2c, 0x61, 0x3d, 0x5b, 0x75, 0x2c, 0x69, 0x5d, 0x2c, + 0x73, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x26, 0x26, 0x28, + 0x75, 0x3d, 0x73, 0x28, 0x75, 0x29, 0x2c, 0x69, 0x3d, 0x73, 0x28, + 0x69, 0x29, 0x29, 0x2c, 0x75, 0x3e, 0x69, 0x26, 0x26, 0x28, 0x63, + 0x3d, 0x75, 0x2c, 0x75, 0x3d, 0x69, 0x2c, 0x69, 0x3d, 0x63, 0x29, + 0x2c, 0x28, 0x75, 0x21, 0x3d, 0x68, 0x5b, 0x30, 0x5d, 0x7c, 0x7c, + 0x69, 0x21, 0x3d, 0x68, 0x5b, 0x31, 0x5d, 0x29, 0x26, 0x26, 0x28, + 0x68, 0x3d, 0x5b, 0x75, 0x2c, 0x69, 0x5d, 0x29, 0x29, 0x2c, 0x6e, + 0x29, 0x3a, 0x28, 0x6c, 0x26, 0x26, 0x28, 0x6f, 0x3f, 0x28, 0x65, + 0x3d, 0x6f, 0x5b, 0x30, 0x5d, 0x2c, 0x72, 0x3d, 0x6f, 0x5b, 0x31, + 0x5d, 0x29, 0x3a, 0x28, 0x65, 0x3d, 0x66, 0x5b, 0x30, 0x5d, 0x2c, + 0x72, 0x3d, 0x66, 0x5b, 0x31, 0x5d, 0x2c, 0x6c, 0x2e, 0x69, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x26, 0x26, 0x28, 0x65, 0x3d, 0x6c, 0x2e, + 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x65, 0x29, 0x2c, 0x72, + 0x3d, 0x6c, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x72, + 0x29, 0x29, 0x2c, 0x65, 0x3e, 0x72, 0x26, 0x26, 0x28, 0x63, 0x3d, + 0x65, 0x2c, 0x65, 0x3d, 0x72, 0x2c, 0x72, 0x3d, 0x63, 0x29, 0x29, + 0x29, 0x2c, 0x73, 0x26, 0x26, 0x28, 0x61, 0x3f, 0x28, 0x75, 0x3d, + 0x61, 0x5b, 0x30, 0x5d, 0x2c, 0x69, 0x3d, 0x61, 0x5b, 0x31, 0x5d, + 0x29, 0x3a, 0x28, 0x75, 0x3d, 0x68, 0x5b, 0x30, 0x5d, 0x2c, 0x69, + 0x3d, 0x68, 0x5b, 0x31, 0x5d, 0x2c, 0x73, 0x2e, 0x69, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x26, 0x26, 0x28, 0x75, 0x3d, 0x73, 0x2e, 0x69, + 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x75, 0x29, 0x2c, 0x69, 0x3d, + 0x73, 0x2e, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x28, 0x69, 0x29, + 0x29, 0x2c, 0x75, 0x3e, 0x69, 0x26, 0x26, 0x28, 0x63, 0x3d, 0x75, + 0x2c, 0x75, 0x3d, 0x69, 0x2c, 0x69, 0x3d, 0x63, 0x29, 0x29, 0x29, + 0x2c, 0x6c, 0x26, 0x26, 0x73, 0x3f, 0x5b, 0x5b, 0x65, 0x2c, 0x75, + 0x5d, 0x2c, 0x5b, 0x72, 0x2c, 0x69, 0x5d, 0x5d, 0x3a, 0x6c, 0x3f, + 0x5b, 0x65, 0x2c, 0x72, 0x5d, 0x3a, 0x73, 0x26, 0x26, 0x5b, 0x75, + 0x2c, 0x69, 0x5d, 0x29, 0x7d, 0x2c, 0x6e, 0x2e, 0x63, 0x6c, 0x65, + 0x61, 0x72, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x29, 0x7c, 0x7c, 0x28, + 0x66, 0x3d, 0x5b, 0x30, 0x2c, 0x30, 0x5d, 0x2c, 0x68, 0x3d, 0x5b, + 0x30, 0x2c, 0x30, 0x5d, 0x2c, 0x6f, 0x3d, 0x61, 0x3d, 0x6e, 0x75, + 0x6c, 0x6c, 0x29, 0x2c, 0x6e, 0x7d, 0x2c, 0x6e, 0x2e, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, + 0x21, 0x6c, 0x26, 0x26, 0x66, 0x5b, 0x30, 0x5d, 0x3d, 0x3d, 0x66, + 0x5b, 0x31, 0x5d, 0x7c, 0x7c, 0x21, 0x21, 0x73, 0x26, 0x26, 0x68, + 0x5b, 0x30, 0x5d, 0x3d, 0x3d, 0x68, 0x5b, 0x31, 0x5d, 0x7d, 0x2c, + 0x74, 0x61, 0x2e, 0x72, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x6e, + 0x2c, 0x63, 0x2c, 0x22, 0x6f, 0x6e, 0x22, 0x29, 0x7d, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x48, 0x6c, 0x3d, 0x7b, 0x6e, 0x3a, 0x22, 0x6e, + 0x73, 0x2d, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x2c, 0x65, + 0x3a, 0x22, 0x65, 0x77, 0x2d, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, + 0x22, 0x2c, 0x73, 0x3a, 0x22, 0x6e, 0x73, 0x2d, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x65, 0x22, 0x2c, 0x77, 0x3a, 0x22, 0x65, 0x77, 0x2d, + 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x2c, 0x6e, 0x77, 0x3a, + 0x22, 0x6e, 0x77, 0x73, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x69, 0x7a, + 0x65, 0x22, 0x2c, 0x6e, 0x65, 0x3a, 0x22, 0x6e, 0x65, 0x73, 0x77, + 0x2d, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x2c, 0x73, 0x65, + 0x3a, 0x22, 0x6e, 0x77, 0x73, 0x65, 0x2d, 0x72, 0x65, 0x73, 0x69, + 0x7a, 0x65, 0x22, 0x2c, 0x73, 0x77, 0x3a, 0x22, 0x6e, 0x65, 0x73, + 0x77, 0x2d, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x7d, 0x2c, + 0x4f, 0x6c, 0x3d, 0x5b, 0x5b, 0x22, 0x6e, 0x22, 0x2c, 0x22, 0x65, + 0x22, 0x2c, 0x22, 0x73, 0x22, 0x2c, 0x22, 0x77, 0x22, 0x2c, 0x22, + 0x6e, 0x77, 0x22, 0x2c, 0x22, 0x6e, 0x65, 0x22, 0x2c, 0x22, 0x73, + 0x65, 0x22, 0x2c, 0x22, 0x73, 0x77, 0x22, 0x5d, 0x2c, 0x5b, 0x22, + 0x65, 0x22, 0x2c, 0x22, 0x77, 0x22, 0x5d, 0x2c, 0x5b, 0x22, 0x6e, + 0x22, 0x2c, 0x22, 0x73, 0x22, 0x5d, 0x2c, 0x5b, 0x5d, 0x5d, 0x2c, + 0x49, 0x6c, 0x3d, 0x61, 0x63, 0x2e, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x3d, 0x67, 0x63, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x2c, 0x59, 0x6c, 0x3d, 0x49, 0x6c, 0x2e, + 0x75, 0x74, 0x63, 0x2c, 0x5a, 0x6c, 0x3d, 0x59, 0x6c, 0x28, 0x22, + 0x25, 0x59, 0x2d, 0x25, 0x6d, 0x2d, 0x25, 0x64, 0x54, 0x25, 0x48, + 0x3a, 0x25, 0x4d, 0x3a, 0x25, 0x53, 0x2e, 0x25, 0x4c, 0x5a, 0x22, + 0x29, 0x3b, 0x49, 0x6c, 0x2e, 0x69, 0x73, 0x6f, 0x3d, 0x44, 0x61, + 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, + 0x65, 0x2e, 0x74, 0x6f, 0x49, 0x53, 0x4f, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x26, 0x26, 0x2b, 0x6e, 0x65, 0x77, 0x20, 0x44, 0x61, + 0x74, 0x65, 0x28, 0x22, 0x32, 0x30, 0x30, 0x30, 0x2d, 0x30, 0x31, + 0x2d, 0x30, 0x31, 0x54, 0x30, 0x30, 0x3a, 0x30, 0x30, 0x3a, 0x30, + 0x30, 0x2e, 0x30, 0x30, 0x30, 0x5a, 0x22, 0x29, 0x3f, 0x4a, 0x6f, + 0x3a, 0x5a, 0x6c, 0x2c, 0x4a, 0x6f, 0x2e, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x65, + 0x77, 0x20, 0x44, 0x61, 0x74, 0x65, 0x28, 0x6e, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x73, 0x4e, 0x61, 0x4e, + 0x28, 0x74, 0x29, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x74, 0x7d, + 0x2c, 0x4a, 0x6f, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x3d, 0x5a, 0x6c, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2c, 0x61, 0x63, 0x2e, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x3d, 0x46, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x63, 0x63, 0x28, 0x31, 0x65, + 0x33, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, + 0x72, 0x28, 0x6e, 0x2f, 0x31, 0x65, 0x33, 0x29, 0x29, 0x7d, 0x2c, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x6e, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x28, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x28, 0x29, 0x2b, 0x31, 0x65, 0x33, 0x2a, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x74, 0x29, 0x29, 0x7d, + 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, + 0x67, 0x65, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x28, + 0x29, 0x7d, 0x29, 0x2c, 0x61, 0x63, 0x2e, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x73, 0x3d, 0x61, 0x63, 0x2e, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, 0x63, + 0x2e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x2e, 0x75, 0x74, + 0x63, 0x3d, 0x61, 0x63, 0x2e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x2e, 0x75, 0x74, 0x63, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, + 0x61, 0x63, 0x2e, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x3d, 0x46, + 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x65, 0x77, 0x20, 0x63, 0x63, 0x28, 0x36, 0x65, 0x34, 0x2a, 0x4d, + 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x6e, + 0x2f, 0x36, 0x65, 0x34, 0x29, 0x29, 0x7d, 0x2c, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, + 0x6e, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x2b, + 0x36, 0x65, 0x34, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, 0x6c, + 0x6f, 0x6f, 0x72, 0x28, 0x74, 0x29, 0x29, 0x7d, 0x2c, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, + 0x4d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, 0x28, 0x29, 0x7d, 0x29, + 0x2c, 0x61, 0x63, 0x2e, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, + 0x3d, 0x61, 0x63, 0x2e, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, 0x63, 0x2e, 0x6d, 0x69, + 0x6e, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x75, 0x74, 0x63, 0x3d, 0x61, + 0x63, 0x2e, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x2e, 0x75, 0x74, + 0x63, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, 0x63, 0x2e, + 0x68, 0x6f, 0x75, 0x72, 0x3d, 0x46, 0x74, 0x28, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x74, 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, + 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x4f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x28, 0x29, 0x2f, 0x36, 0x30, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x63, 0x63, 0x28, 0x33, + 0x36, 0x65, 0x35, 0x2a, 0x28, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x66, + 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x6e, 0x2f, 0x33, 0x36, 0x65, 0x35, + 0x2d, 0x74, 0x29, 0x2b, 0x74, 0x29, 0x29, 0x7d, 0x2c, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, + 0x7b, 0x6e, 0x2e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, + 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, + 0x2b, 0x33, 0x36, 0x65, 0x35, 0x2a, 0x4d, 0x61, 0x74, 0x68, 0x2e, + 0x66, 0x6c, 0x6f, 0x6f, 0x72, 0x28, 0x74, 0x29, 0x29, 0x7d, 0x2c, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, + 0x65, 0x74, 0x48, 0x6f, 0x75, 0x72, 0x73, 0x28, 0x29, 0x7d, 0x29, + 0x2c, 0x61, 0x63, 0x2e, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x3d, 0x61, + 0x63, 0x2e, 0x68, 0x6f, 0x75, 0x72, 0x2e, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x2c, 0x61, 0x63, 0x2e, 0x68, 0x6f, 0x75, 0x72, 0x73, 0x2e, + 0x75, 0x74, 0x63, 0x3d, 0x61, 0x63, 0x2e, 0x68, 0x6f, 0x75, 0x72, + 0x2e, 0x75, 0x74, 0x63, 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, + 0x61, 0x63, 0x2e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x3d, 0x46, 0x74, + 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x3d, + 0x61, 0x63, 0x2e, 0x64, 0x61, 0x79, 0x28, 0x6e, 0x29, 0x2c, 0x6e, + 0x2e, 0x73, 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x31, 0x29, + 0x2c, 0x6e, 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x6e, 0x2e, 0x73, 0x65, + 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x28, 0x6e, 0x2e, 0x67, 0x65, + 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x28, 0x29, 0x2b, 0x74, 0x29, + 0x7d, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x28, 0x29, + 0x7d, 0x29, 0x2c, 0x61, 0x63, 0x2e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, + 0x73, 0x3d, 0x61, 0x63, 0x2e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x2c, 0x61, 0x63, 0x2e, 0x6d, 0x6f, + 0x6e, 0x74, 0x68, 0x73, 0x2e, 0x75, 0x74, 0x63, 0x3d, 0x61, 0x63, + 0x2e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x2e, 0x75, 0x74, 0x63, 0x2e, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x56, + 0x6c, 0x3d, 0x5b, 0x31, 0x65, 0x33, 0x2c, 0x35, 0x65, 0x33, 0x2c, + 0x31, 0x35, 0x65, 0x33, 0x2c, 0x33, 0x65, 0x34, 0x2c, 0x36, 0x65, + 0x34, 0x2c, 0x33, 0x65, 0x35, 0x2c, 0x39, 0x65, 0x35, 0x2c, 0x31, + 0x38, 0x65, 0x35, 0x2c, 0x33, 0x36, 0x65, 0x35, 0x2c, 0x31, 0x30, + 0x38, 0x65, 0x35, 0x2c, 0x32, 0x31, 0x36, 0x65, 0x35, 0x2c, 0x34, + 0x33, 0x32, 0x65, 0x35, 0x2c, 0x38, 0x36, 0x34, 0x65, 0x35, 0x2c, + 0x31, 0x37, 0x32, 0x38, 0x65, 0x35, 0x2c, 0x36, 0x30, 0x34, 0x38, + 0x65, 0x35, 0x2c, 0x32, 0x35, 0x39, 0x32, 0x65, 0x36, 0x2c, 0x37, + 0x37, 0x37, 0x36, 0x65, 0x36, 0x2c, 0x33, 0x31, 0x35, 0x33, 0x36, + 0x65, 0x36, 0x5d, 0x2c, 0x58, 0x6c, 0x3d, 0x5b, 0x5b, 0x61, 0x63, + 0x2e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x2c, 0x31, 0x5d, 0x2c, + 0x5b, 0x61, 0x63, 0x2e, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x2c, + 0x35, 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, 0x73, 0x65, 0x63, 0x6f, + 0x6e, 0x64, 0x2c, 0x31, 0x35, 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x2c, 0x33, 0x30, 0x5d, 0x2c, + 0x5b, 0x61, 0x63, 0x2e, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x2c, + 0x31, 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, 0x6d, 0x69, 0x6e, 0x75, + 0x74, 0x65, 0x2c, 0x35, 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, 0x6d, + 0x69, 0x6e, 0x75, 0x74, 0x65, 0x2c, 0x31, 0x35, 0x5d, 0x2c, 0x5b, + 0x61, 0x63, 0x2e, 0x6d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x2c, 0x33, + 0x30, 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, 0x68, 0x6f, 0x75, 0x72, + 0x2c, 0x31, 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, 0x68, 0x6f, 0x75, + 0x72, 0x2c, 0x33, 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, 0x68, 0x6f, + 0x75, 0x72, 0x2c, 0x36, 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, 0x68, + 0x6f, 0x75, 0x72, 0x2c, 0x31, 0x32, 0x5d, 0x2c, 0x5b, 0x61, 0x63, + 0x2e, 0x64, 0x61, 0x79, 0x2c, 0x31, 0x5d, 0x2c, 0x5b, 0x61, 0x63, + 0x2e, 0x64, 0x61, 0x79, 0x2c, 0x32, 0x5d, 0x2c, 0x5b, 0x61, 0x63, + 0x2e, 0x77, 0x65, 0x65, 0x6b, 0x2c, 0x31, 0x5d, 0x2c, 0x5b, 0x61, + 0x63, 0x2e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x2c, 0x31, 0x5d, 0x2c, + 0x5b, 0x61, 0x63, 0x2e, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x2c, 0x33, + 0x5d, 0x2c, 0x5b, 0x61, 0x63, 0x2e, 0x79, 0x65, 0x61, 0x72, 0x2c, + 0x31, 0x5d, 0x5d, 0x2c, 0x24, 0x6c, 0x3d, 0x49, 0x6c, 0x2e, 0x6d, + 0x75, 0x6c, 0x74, 0x69, 0x28, 0x5b, 0x5b, 0x22, 0x2e, 0x25, 0x4c, + 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, + 0x22, 0x3a, 0x25, 0x53, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x53, 0x65, 0x63, + 0x6f, 0x6e, 0x64, 0x73, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, 0x22, + 0x25, 0x49, 0x3a, 0x25, 0x4d, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x69, + 0x6e, 0x75, 0x74, 0x65, 0x73, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, + 0x22, 0x25, 0x49, 0x20, 0x25, 0x70, 0x22, 0x2c, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x48, + 0x6f, 0x75, 0x72, 0x73, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, 0x22, + 0x25, 0x61, 0x20, 0x25, 0x64, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x44, 0x61, + 0x79, 0x28, 0x29, 0x26, 0x26, 0x31, 0x21, 0x3d, 0x6e, 0x2e, 0x67, + 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x7d, 0x5d, 0x2c, + 0x5b, 0x22, 0x25, 0x62, 0x20, 0x25, 0x64, 0x22, 0x2c, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x21, 0x3d, 0x6e, 0x2e, + 0x67, 0x65, 0x74, 0x44, 0x61, 0x74, 0x65, 0x28, 0x29, 0x7d, 0x5d, + 0x2c, 0x5b, 0x22, 0x25, 0x42, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x4d, 0x6f, + 0x6e, 0x74, 0x68, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, 0x22, 0x25, + 0x59, 0x22, 0x2c, 0x4e, 0x65, 0x5d, 0x5d, 0x29, 0x2c, 0x42, 0x6c, + 0x3d, 0x7b, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x2c, 0x65, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x61, + 0x2e, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x28, 0x4d, 0x61, 0x74, 0x68, + 0x2e, 0x63, 0x65, 0x69, 0x6c, 0x28, 0x6e, 0x2f, 0x65, 0x29, 0x2a, + 0x65, 0x2c, 0x2b, 0x74, 0x2c, 0x65, 0x29, 0x2e, 0x6d, 0x61, 0x70, + 0x28, 0x4b, 0x6f, 0x29, 0x7d, 0x2c, 0x66, 0x6c, 0x6f, 0x6f, 0x72, + 0x3a, 0x79, 0x2c, 0x63, 0x65, 0x69, 0x6c, 0x3a, 0x79, 0x7d, 0x3b, + 0x58, 0x6c, 0x2e, 0x79, 0x65, 0x61, 0x72, 0x3d, 0x61, 0x63, 0x2e, + 0x79, 0x65, 0x61, 0x72, 0x2c, 0x61, 0x63, 0x2e, 0x73, 0x63, 0x61, + 0x6c, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x47, + 0x6f, 0x28, 0x74, 0x61, 0x2e, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x2e, + 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x28, 0x29, 0x2c, 0x58, 0x6c, + 0x2c, 0x24, 0x6c, 0x29, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x57, + 0x6c, 0x3d, 0x58, 0x6c, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x6e, 0x5b, 0x30, 0x5d, 0x2e, + 0x75, 0x74, 0x63, 0x2c, 0x6e, 0x5b, 0x31, 0x5d, 0x5d, 0x7d, 0x29, + 0x2c, 0x4a, 0x6c, 0x3d, 0x59, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, + 0x69, 0x28, 0x5b, 0x5b, 0x22, 0x2e, 0x25, 0x4c, 0x22, 0x2c, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, + 0x74, 0x55, 0x54, 0x43, 0x4d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, + 0x22, 0x3a, 0x25, 0x53, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, + 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x28, 0x29, 0x7d, 0x5d, + 0x2c, 0x5b, 0x22, 0x25, 0x49, 0x3a, 0x25, 0x4d, 0x22, 0x2c, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, + 0x74, 0x55, 0x54, 0x43, 0x4d, 0x69, 0x6e, 0x75, 0x74, 0x65, 0x73, + 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, 0x22, 0x25, 0x49, 0x20, 0x25, + 0x70, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x48, 0x6f, 0x75, + 0x72, 0x73, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, 0x22, 0x25, 0x61, + 0x20, 0x25, 0x64, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x44, + 0x61, 0x79, 0x28, 0x29, 0x26, 0x26, 0x31, 0x21, 0x3d, 0x6e, 0x2e, + 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x44, 0x61, 0x74, 0x65, 0x28, + 0x29, 0x7d, 0x5d, 0x2c, 0x5b, 0x22, 0x25, 0x62, 0x20, 0x25, 0x64, + 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, + 0x21, 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x44, + 0x61, 0x74, 0x65, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, 0x22, 0x25, + 0x42, 0x22, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x55, 0x54, 0x43, 0x4d, 0x6f, 0x6e, + 0x74, 0x68, 0x28, 0x29, 0x7d, 0x5d, 0x2c, 0x5b, 0x22, 0x25, 0x59, + 0x22, 0x2c, 0x4e, 0x65, 0x5d, 0x5d, 0x29, 0x3b, 0x57, 0x6c, 0x2e, + 0x79, 0x65, 0x61, 0x72, 0x3d, 0x61, 0x63, 0x2e, 0x79, 0x65, 0x61, + 0x72, 0x2e, 0x75, 0x74, 0x63, 0x2c, 0x61, 0x63, 0x2e, 0x73, 0x63, + 0x61, 0x6c, 0x65, 0x2e, 0x75, 0x74, 0x63, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x47, 0x6f, 0x28, 0x74, 0x61, 0x2e, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x2e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, + 0x28, 0x29, 0x2c, 0x57, 0x6c, 0x2c, 0x4a, 0x6c, 0x29, 0x7d, 0x2c, + 0x74, 0x61, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x3d, 0x41, 0x74, 0x28, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x54, 0x65, 0x78, 0x74, + 0x7d, 0x29, 0x2c, 0x74, 0x61, 0x2e, 0x6a, 0x73, 0x6f, 0x6e, 0x3d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x4e, + 0x74, 0x28, 0x6e, 0x2c, 0x22, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x22, + 0x2c, 0x51, 0x6f, 0x2c, 0x74, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, + 0x68, 0x74, 0x6d, 0x6c, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x4e, 0x74, 0x28, 0x6e, 0x2c, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x2c, 0x6e, + 0x61, 0x2c, 0x74, 0x29, 0x7d, 0x2c, 0x74, 0x61, 0x2e, 0x78, 0x6d, + 0x6c, 0x3d, 0x41, 0x74, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x6e, 0x2e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x58, 0x4d, 0x4c, 0x7d, 0x29, 0x2c, 0x22, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x26, + 0x26, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x2e, 0x61, 0x6d, 0x64, + 0x3f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x28, 0x74, 0x61, 0x29, + 0x3a, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3d, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x26, 0x26, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, + 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x26, 0x26, 0x28, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x3d, 0x74, 0x61, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x64, 0x33, 0x3d, 0x74, 0x61, 0x7d, 0x28, 0x29, 0x3b, 0x00 +}; + +const int d3_js_length = 151140; diff --git a/goaccess++/src/error.c b/goaccess++/src/error.c new file mode 100644 index 0000000..7738eed --- /dev/null +++ b/goaccess++/src/error.c @@ -0,0 +1,237 @@ +/** + * error.c -- error handling + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#if defined(__GLIBC__) +#include <execinfo.h> +#endif +#include <sys/types.h> +#include <unistd.h> + +#include "error.h" +#include "labels.h" +#include "parser.h" + +static FILE *access_log; +static FILE *log_file; +static FILE *log_invalid; +static GLog *log_data; + +/* Open a debug file whose name is specified in the given path. */ +void +dbg_log_open (const char *path) +{ + if (path != NULL) { + log_file = fopen (path, "w"); + if (log_file == NULL) + return; + } +} + +/* Close the debug file. */ +void +dbg_log_close (void) +{ + if (log_file != NULL) + fclose (log_file); +} + +/* Open the invalid requests log file whose name is specified in the + * given path. */ +void +invalid_log_open (const char *path) +{ + if (path != NULL) { + log_invalid = fopen (path, "w"); + if (log_invalid == NULL) + return; + } +} + +/* Close the invalid requests log file. */ +void +invalid_log_close (void) +{ + if (log_invalid != NULL) + fclose (log_invalid); +} + +/* Set current overall parsed log data. */ +void +set_signal_data (void *p) +{ + log_data = p; +} + +/* Open the WebSocket access log file whose name is specified in the + * given path. */ +int +access_log_open (const char *path) +{ + if (path == NULL) + return 0; + + if (access (path, F_OK) != -1) + access_log = fopen (path, "a"); + else + access_log = fopen (path, "w"); + if (access_log == NULL) + return 1; + + return 0; +} + +/* Close the WebSocket access log file. */ +void +access_log_close (void) +{ + if (access_log != NULL) + fclose (access_log); +} + +/* Dump to the standard output the values of the overall parsed log + * data. */ +static void +dump_struct (FILE * fp) +{ + int pid = getpid (); + if (!log_data) + return; + + fprintf (fp, "==%d== VALUES AT CRASH POINT\n", pid); + fprintf (fp, "==%d==\n", pid); + fprintf (fp, "==%d== Line number: %u\n", pid, log_data->processed); + fprintf (fp, "==%d== Offset: %u\n", pid, log_data->offset); + fprintf (fp, "==%d== Invalid data: %u\n", pid, log_data->invalid); + fprintf (fp, "==%d== Piping: %d\n", pid, log_data->piping); + fprintf (fp, "==%d== Response size: %llu bytes\n", pid, log_data->resp_size); + fprintf (fp, "==%d==\n", pid); +} + +/* Custom SIGSEGV handler. */ +void +sigsegv_handler (int sig) +{ + FILE *fp = stderr; + int pid = getpid (); + +#if defined(__GLIBC__) + char **messages; + size_t size, i; + void *trace_stack[TRACE_SIZE]; +#endif + + (void) endwin (); + fprintf (fp, "\n"); + fprintf (fp, "==%d== GoAccess %s crashed by Sig %d\n", pid, GO_VERSION, sig); + fprintf (fp, "==%d==\n", pid); + + dump_struct (fp); + +#if defined(__GLIBC__) + size = backtrace (trace_stack, TRACE_SIZE); + messages = backtrace_symbols (trace_stack, size); + + fprintf (fp, "==%d== STACK TRACE:\n", pid); + fprintf (fp, "==%d==\n", pid); + + for (i = 0; i < size; i++) + fprintf (fp, "==%d== %zu %s\n", pid, i, messages[i]); +#endif + + fprintf (fp, "==%d==\n", pid); + fprintf (fp, "==%d== %s:\n", pid, ERR_PLEASE_REPORT); + fprintf (fp, "==%d== https://github.com/allinurl/goaccess/issues\n\n", pid); + exit (EXIT_FAILURE); +} + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +/* Write formatted debug log data to the logfile. */ +void +dbg_fprintf (const char *fmt, ...) +{ + va_list args; + + if (!log_file) + return; + + va_start (args, fmt); + vfprintf (log_file, fmt, args); + fflush (log_file); + va_end (args); +} + +/* Write formatted invalid requests log data to the logfile. */ +void +invalid_fprintf (const char *fmt, ...) +{ + va_list args; + + if (!log_invalid) + return; + + va_start (args, fmt); + vfprintf (log_invalid, fmt, args); + fflush (log_invalid); + va_end (args); +} + +/* Debug otuput */ +void +dbg_printf (const char *fmt, ...) +{ + va_list args; + va_start (args, fmt); + vfprintf (stderr, fmt, args); + va_end (args); +} + +/* Write formatted access log data to the logfile. */ +void +access_fprintf (const char *fmt, ...) +{ + va_list args; + + if (!access_log) + return; + + va_start (args, fmt); + vfprintf (access_log, fmt, args); + fflush (access_log); + va_end (args); +} + +#pragma GCC diagnostic warning "-Wformat-nonliteral" diff --git a/goaccess++/src/error.h b/goaccess++/src/error.h new file mode 100644 index 0000000..08b754e --- /dev/null +++ b/goaccess++/src/error.h @@ -0,0 +1,94 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef ERROR_H_INCLUDED +#define ERROR_H_INCLUDED + +#ifndef COMMONS +#include "commons.h" +#endif + +#ifdef HAVE_NCURSESW_NCURSES_H +#include <ncursesw/ncurses.h> +#elif HAVE_NCURSES_NCURSES_H +#include <ncurses/ncurses.h> +#elif HAVE_NCURSES_H +#include <ncurses.h> +#elif HAVE_CURSES_H +#include <curses.h> +#endif + +#include "settings.h" + +#define TRACE_SIZE 128 + +#define FATAL(fmt, ...) do { \ + (void) endwin (); \ + fprintf (stderr, "\nGoAccess - version %s - %s %s\n", GO_VERSION, __DATE__, \ + __TIME__); \ + fprintf (stderr, "Config file: %s\n", conf.iconfigfile ?: NO_CONFIG_FILE); \ + fprintf (stderr, "\nFatal error has occurred"); \ + fprintf (stderr, "\nError occurred at: %s - %s - %d\n", __FILE__, \ + __FUNCTION__, __LINE__); \ + fprintf (stderr, fmt, ##__VA_ARGS__); \ + fprintf (stderr, "\n\n"); \ + LOG_DEBUG ((fmt, ##__VA_ARGS__)); \ + exit(EXIT_FAILURE); \ +} while (0) + +#ifdef DEBUG +#define DEBUG_TEST 1 +#else +#define DEBUG_TEST 0 +#endif + +/* access requests log */ +#define ACCESS_LOG(x, ...) do { access_fprintf x; } while (0) +/* debug log */ +#define LOG_DEBUG(x, ...) do { dbg_fprintf x; } while (0) +/* invalid requests log */ +#define LOG_INVALID(x, ...) do { invalid_fprintf x; } while (0) +/* log debug wrapper */ +#define LOG(x) do { if (DEBUG_TEST) dbg_printf x; } while (0) + +int access_log_open (const char *path); +void access_fprintf (const char *fmt, ...); +void access_log_close (void); +void dbg_printf (const char *fmt, ...); + +void dbg_fprintf (const char *fmt, ...); +void dbg_log_close (void); +void dbg_log_open (const char *file); +void invalid_fprintf (const char *fmt, ...); +void invalid_log_close (void); +void invalid_log_open (const char *path); +void set_signal_data (void *p); +void sigsegv_handler (int sig); + +#endif diff --git a/goaccess++/src/error.o b/goaccess++/src/error.o new file mode 100644 index 0000000..67efa2a Binary files /dev/null and b/goaccess++/src/error.o differ diff --git a/goaccess++/src/facss.h b/goaccess++/src/facss.h new file mode 100644 index 0000000..af7a141 --- /dev/null +++ b/goaccess++/src/facss.h @@ -0,0 +1,1683 @@ +const char fa_css[18459] = { + 0x40, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x63, 0x65, 0x20, + 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, 0x6d, 0x69, 0x6c, + 0x79, 0x3a, 0x20, 0x27, 0x66, 0x61, 0x27, 0x3b, 0x73, 0x72, 0x63, + 0x3a, 0x20, 0x75, 0x72, 0x6c, 0x28, 0x64, 0x61, 0x74, 0x61, 0x3a, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2f, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x6f, 0x66, 0x66, 0x3b, + 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x3d, 0x75, 0x74, 0x66, + 0x2d, 0x38, 0x3b, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x2c, 0x64, + 0x30, 0x39, 0x47, 0x52, 0x67, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x43, 0x32, 0x73, 0x41, 0x41, 0x73, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x4c, 0x57, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x42, 0x50, 0x55, 0x79, 0x38, 0x79, 0x41, 0x41, 0x41, + 0x42, 0x43, 0x41, 0x41, 0x41, 0x41, 0x47, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x67, 0x44, 0x78, 0x49, 0x50, 0x48, 0x47, 0x4e, 0x74, 0x59, + 0x58, 0x41, 0x41, 0x41, 0x41, 0x46, 0x6f, 0x41, 0x41, 0x41, 0x42, + 0x62, 0x41, 0x41, 0x41, 0x41, 0x57, 0x7a, 0x7a, 0x59, 0x50, 0x4e, + 0x38, 0x5a, 0x32, 0x46, 0x7a, 0x63, 0x41, 0x41, 0x41, 0x41, 0x74, + 0x51, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, 0x43, + 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x6e, 0x62, 0x48, 0x6c, 0x6d, + 0x41, 0x41, 0x41, 0x43, 0x33, 0x41, 0x41, 0x41, 0x4a, 0x37, 0x51, + 0x41, 0x41, 0x43, 0x65, 0x30, 0x50, 0x71, 0x52, 0x50, 0x66, 0x32, + 0x68, 0x6c, 0x59, 0x57, 0x51, 0x41, 0x41, 0x43, 0x71, 0x51, 0x41, + 0x41, 0x41, 0x41, 0x4e, 0x67, 0x41, 0x41, 0x41, 0x44, 0x59, 0x53, + 0x42, 0x68, 0x72, 0x48, 0x61, 0x47, 0x68, 0x6c, 0x59, 0x51, 0x41, + 0x41, 0x4b, 0x73, 0x67, 0x41, 0x41, 0x41, 0x41, 0x6b, 0x41, 0x41, + 0x41, 0x41, 0x4a, 0x41, 0x68, 0x55, 0x42, 0x49, 0x5a, 0x6f, 0x62, + 0x58, 0x52, 0x34, 0x41, 0x41, 0x41, 0x71, 0x37, 0x41, 0x41, 0x41, + 0x41, 0x4d, 0x77, 0x41, 0x41, 0x41, 0x44, 0x4d, 0x70, 0x43, 0x6f, + 0x43, 0x43, 0x32, 0x78, 0x76, 0x59, 0x32, 0x45, 0x41, 0x41, 0x43, + 0x75, 0x34, 0x41, 0x41, 0x41, 0x41, 0x61, 0x41, 0x41, 0x41, 0x41, + 0x47, 0x6a, 0x79, 0x72, 0x76, 0x75, 0x65, 0x62, 0x57, 0x46, 0x34, + 0x63, 0x41, 0x41, 0x41, 0x4c, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x67, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x2b, 0x41, 0x56, + 0x64, 0x75, 0x59, 0x57, 0x31, 0x6c, 0x41, 0x41, 0x41, 0x73, 0x51, + 0x41, 0x41, 0x41, 0x41, 0x55, 0x6f, 0x41, 0x41, 0x41, 0x46, 0x4b, + 0x49, 0x68, 0x57, 0x54, 0x73, 0x6e, 0x42, 0x76, 0x63, 0x33, 0x51, + 0x41, 0x41, 0x43, 0x32, 0x4d, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, + 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x77, 0x41, 0x41, 0x41, + 0x41, 0x4d, 0x44, 0x56, 0x67, 0x47, 0x51, 0x41, 0x41, 0x55, 0x41, + 0x41, 0x41, 0x4b, 0x5a, 0x41, 0x73, 0x77, 0x41, 0x41, 0x41, 0x43, + 0x50, 0x41, 0x70, 0x6b, 0x43, 0x7a, 0x41, 0x41, 0x41, 0x41, 0x65, + 0x73, 0x41, 0x4d, 0x77, 0x45, 0x4a, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x52, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x38, + 0x70, 0x77, 0x44, 0x77, 0x50, 0x2f, 0x41, 0x41, 0x45, 0x41, 0x44, + 0x77, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x77, 0x41, 0x41, 0x41, 0x41, 0x4d, 0x41, 0x41, 0x41, 0x41, 0x63, + 0x41, 0x41, 0x45, 0x41, 0x41, 0x77, 0x41, 0x41, 0x41, 0x42, 0x77, + 0x41, 0x41, 0x77, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, 0x48, 0x41, + 0x41, 0x45, 0x41, 0x56, 0x41, 0x41, 0x41, 0x41, 0x42, 0x51, 0x41, + 0x45, 0x41, 0x41, 0x42, 0x51, 0x41, 0x51, 0x41, 0x41, 0x45, 0x41, + 0x49, 0x50, 0x41, 0x48, 0x38, 0x41, 0x6e, 0x77, 0x44, 0x66, 0x41, + 0x54, 0x38, 0x42, 0x66, 0x77, 0x49, 0x76, 0x41, 0x36, 0x38, 0x45, + 0x48, 0x77, 0x52, 0x76, 0x42, 0x55, 0x38, 0x48, 0x48, 0x77, 0x67, + 0x50, 0x43, 0x46, 0x38, 0x49, 0x37, 0x77, 0x6c, 0x76, 0x43, 0x69, + 0x38, 0x4d, 0x44, 0x77, 0x79, 0x66, 0x44, 0x4f, 0x38, 0x4e, 0x72, + 0x77, 0x33, 0x50, 0x44, 0x6b, 0x38, 0x51, 0x48, 0x78, 0x42, 0x66, + 0x45, 0x49, 0x38, 0x51, 0x7a, 0x78, 0x45, 0x66, 0x45, 0x68, 0x38, + 0x56, 0x7a, 0x78, 0x6f, 0x50, 0x48, 0x4f, 0x38, 0x66, 0x66, 0x78, + 0x2f, 0x76, 0x4a, 0x6f, 0x38, 0x70, 0x4c, 0x79, 0x6e, 0x50, 0x2f, + 0x39, 0x2f, 0x2f, 0x38, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, + 0x44, 0x77, 0x42, 0x2f, 0x41, 0x4a, 0x38, 0x41, 0x76, 0x77, 0x45, + 0x2f, 0x41, 0x57, 0x38, 0x43, 0x48, 0x77, 0x4f, 0x76, 0x42, 0x42, + 0x38, 0x45, 0x62, 0x77, 0x55, 0x2f, 0x42, 0x78, 0x38, 0x49, 0x44, + 0x77, 0x68, 0x66, 0x43, 0x4f, 0x38, 0x4a, 0x62, 0x77, 0x6f, 0x76, + 0x44, 0x41, 0x38, 0x4d, 0x6e, 0x77, 0x7a, 0x76, 0x44, 0x58, 0x38, + 0x4e, 0x7a, 0x77, 0x35, 0x50, 0x45, 0x41, 0x38, 0x51, 0x54, 0x78, + 0x43, 0x50, 0x45, 0x4d, 0x38, 0x52, 0x48, 0x78, 0x49, 0x66, 0x46, + 0x62, 0x38, 0x61, 0x44, 0x78, 0x7a, 0x76, 0x48, 0x33, 0x38, 0x66, + 0x37, 0x79, 0x61, 0x50, 0x4b, 0x53, 0x38, 0x70, 0x7a, 0x2f, 0x2f, + 0x66, 0x2f, 0x2f, 0x41, 0x41, 0x48, 0x2f, 0x34, 0x77, 0x2f, 0x39, + 0x44, 0x2f, 0x77, 0x50, 0x2b, 0x77, 0x2f, 0x32, 0x44, 0x2f, 0x51, + 0x50, 0x36, 0x77, 0x2f, 0x55, 0x44, 0x38, 0x34, 0x50, 0x79, 0x67, + 0x2b, 0x2b, 0x44, 0x36, 0x49, 0x50, 0x6c, 0x41, 0x2b, 0x51, 0x44, + 0x34, 0x67, 0x50, 0x67, 0x51, 0x39, 0x32, 0x44, 0x31, 0x6b, 0x50, + 0x55, 0x51, 0x39, 0x4e, 0x44, 0x30, 0x55, 0x50, 0x52, 0x41, 0x38, + 0x39, 0x44, 0x79, 0x49, 0x50, 0x49, 0x41, 0x38, 0x65, 0x44, 0x78, + 0x73, 0x50, 0x46, 0x77, 0x38, 0x49, 0x44, 0x73, 0x38, 0x4f, 0x6a, + 0x41, 0x35, 0x66, 0x44, 0x6a, 0x63, 0x4f, 0x4d, 0x51, 0x33, 0x49, + 0x44, 0x5a, 0x38, 0x4e, 0x6c, 0x67, 0x41, 0x44, 0x41, 0x41, 0x45, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, + 0x41, 0x48, 0x2f, 0x2f, 0x77, 0x41, 0x50, 0x41, 0x41, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x43, 0x41, 0x41, 0x41, 0x33, 0x4f, 0x51, 0x45, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x44, 0x63, 0x35, + 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x67, + 0x41, 0x41, 0x4e, 0x7a, 0x6b, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x74, 0x73, 0x44, + 0x62, 0x67, 0x41, 0x62, 0x41, 0x44, 0x63, 0x41, 0x41, 0x43, 0x55, + 0x55, 0x42, 0x69, 0x4d, 0x68, 0x49, 0x69, 0x59, 0x31, 0x4e, 0x44, + 0x63, 0x2b, 0x41, 0x54, 0x63, 0x32, 0x4d, 0x78, 0x34, 0x42, 0x4d, + 0x7a, 0x49, 0x32, 0x4e, 0x7a, 0x49, 0x58, 0x48, 0x67, 0x45, 0x58, + 0x46, 0x68, 0x55, 0x44, 0x46, 0x41, 0x63, 0x4f, 0x41, 0x51, 0x63, + 0x47, 0x49, 0x79, 0x49, 0x6e, 0x4c, 0x67, 0x45, 0x6e, 0x4a, 0x6a, + 0x55, 0x30, 0x4e, 0x7a, 0x34, 0x42, 0x4e, 0x7a, 0x59, 0x7a, 0x4d, + 0x68, 0x63, 0x65, 0x41, 0x52, 0x63, 0x57, 0x41, 0x74, 0x74, 0x48, + 0x4d, 0x76, 0x34, 0x59, 0x4d, 0x6b, 0x67, 0x49, 0x43, 0x43, 0x6f, + 0x6c, 0x4a, 0x44, 0x67, 0x6a, 0x57, 0x7a, 0x55, 0x30, 0x58, 0x43, + 0x4d, 0x34, 0x4a, 0x43, 0x51, 0x71, 0x43, 0x41, 0x69, 0x53, 0x45, + 0x52, 0x45, 0x38, 0x4b, 0x43, 0x67, 0x74, 0x4c, 0x69, 0x67, 0x6f, + 0x4f, 0x78, 0x45, 0x53, 0x45, 0x68, 0x45, 0x37, 0x4b, 0x43, 0x67, + 0x75, 0x4c, 0x53, 0x67, 0x6f, 0x50, 0x42, 0x45, 0x52, 0x6c, 0x7a, + 0x35, 0x5a, 0x57, 0x54, 0x34, 0x35, 0x4f, 0x54, 0x70, 0x64, 0x48, + 0x68, 0x30, 0x68, 0x4b, 0x43, 0x67, 0x68, 0x48, 0x52, 0x35, 0x64, + 0x4f, 0x6a, 0x6b, 0x35, 0x41, 0x66, 0x73, 0x74, 0x4b, 0x43, 0x67, + 0x38, 0x45, 0x52, 0x45, 0x52, 0x45, 0x54, 0x77, 0x6f, 0x4b, 0x43, + 0x30, 0x75, 0x4b, 0x43, 0x67, 0x37, 0x45, 0x52, 0x49, 0x53, 0x45, + 0x54, 0x73, 0x6f, 0x4b, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, + 0x41, 0x41, 0x41, 0x41, 0x53, 0x51, 0x4f, 0x33, 0x41, 0x32, 0x34, + 0x41, 0x45, 0x41, 0x41, 0x68, 0x41, 0x44, 0x45, 0x41, 0x51, 0x51, + 0x41, 0x41, 0x41, 0x52, 0x55, 0x55, 0x42, 0x69, 0x4d, 0x68, 0x49, + 0x69, 0x59, 0x39, 0x41, 0x54, 0x51, 0x32, 0x4d, 0x79, 0x45, 0x79, + 0x46, 0x68, 0x55, 0x52, 0x46, 0x52, 0x51, 0x47, 0x49, 0x79, 0x45, + 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, 0x7a, 0x49, 0x54, + 0x49, 0x57, 0x46, 0x51, 0x45, 0x56, 0x46, 0x41, 0x59, 0x6a, 0x49, + 0x53, 0x49, 0x6d, 0x50, 0x51, 0x45, 0x30, 0x4e, 0x6a, 0x4d, 0x68, + 0x4d, 0x68, 0x59, 0x52, 0x46, 0x52, 0x51, 0x47, 0x49, 0x79, 0x45, + 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, 0x7a, 0x49, 0x54, + 0x49, 0x57, 0x41, 0x62, 0x63, 0x72, 0x48, 0x76, 0x37, 0x62, 0x48, + 0x69, 0x73, 0x72, 0x48, 0x67, 0x45, 0x6c, 0x48, 0x69, 0x73, 0x72, + 0x48, 0x76, 0x37, 0x62, 0x48, 0x69, 0x73, 0x72, 0x48, 0x67, 0x45, + 0x6c, 0x48, 0x69, 0x73, 0x43, 0x41, 0x43, 0x73, 0x65, 0x2f, 0x74, + 0x73, 0x65, 0x4b, 0x79, 0x73, 0x65, 0x41, 0x53, 0x55, 0x65, 0x4b, + 0x79, 0x73, 0x65, 0x2f, 0x74, 0x73, 0x65, 0x4b, 0x79, 0x73, 0x65, + 0x41, 0x53, 0x55, 0x65, 0x4b, 0x77, 0x46, 0x75, 0x33, 0x42, 0x34, + 0x72, 0x4b, 0x78, 0x37, 0x63, 0x48, 0x69, 0x73, 0x72, 0x48, 0x67, + 0x47, 0x33, 0x33, 0x42, 0x34, 0x72, 0x4b, 0x78, 0x37, 0x63, 0x48, + 0x69, 0x73, 0x72, 0x48, 0x76, 0x35, 0x4a, 0x33, 0x42, 0x34, 0x72, + 0x4b, 0x78, 0x37, 0x63, 0x48, 0x69, 0x73, 0x72, 0x41, 0x5a, 0x6e, + 0x63, 0x48, 0x69, 0x73, 0x72, 0x48, 0x74, 0x77, 0x65, 0x4b, 0x79, + 0x73, 0x41, 0x42, 0x67, 0x41, 0x41, 0x41, 0x45, 0x6b, 0x45, 0x41, + 0x41, 0x4e, 0x75, 0x41, 0x41, 0x38, 0x41, 0x48, 0x77, 0x41, 0x76, + 0x41, 0x44, 0x38, 0x41, 0x54, 0x77, 0x42, 0x66, 0x41, 0x41, 0x41, + 0x6c, 0x46, 0x52, 0x51, 0x47, 0x4b, 0x77, 0x45, 0x69, 0x4a, 0x6a, + 0x30, 0x42, 0x4e, 0x44, 0x59, 0x37, 0x41, 0x54, 0x49, 0x57, 0x45, + 0x52, 0x55, 0x55, 0x42, 0x69, 0x73, 0x42, 0x49, 0x69, 0x59, 0x39, + 0x41, 0x54, 0x51, 0x32, 0x4f, 0x77, 0x45, 0x79, 0x46, 0x67, 0x45, + 0x56, 0x46, 0x41, 0x59, 0x6a, 0x49, 0x53, 0x49, 0x6d, 0x50, 0x51, + 0x45, 0x30, 0x4e, 0x6a, 0x4d, 0x68, 0x4d, 0x68, 0x59, 0x42, 0x46, + 0x52, 0x51, 0x47, 0x4b, 0x77, 0x45, 0x69, 0x4a, 0x6a, 0x30, 0x42, + 0x4e, 0x44, 0x59, 0x37, 0x41, 0x54, 0x49, 0x57, 0x41, 0x52, 0x55, + 0x55, 0x42, 0x69, 0x4d, 0x68, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, + 0x51, 0x32, 0x4d, 0x79, 0x45, 0x79, 0x46, 0x68, 0x45, 0x56, 0x46, + 0x41, 0x59, 0x6a, 0x49, 0x53, 0x49, 0x6d, 0x50, 0x51, 0x45, 0x30, + 0x4e, 0x6a, 0x4d, 0x68, 0x4d, 0x68, 0x59, 0x42, 0x4a, 0x53, 0x45, + 0x57, 0x74, 0x78, 0x63, 0x67, 0x49, 0x42, 0x65, 0x33, 0x46, 0x69, + 0x45, 0x68, 0x46, 0x72, 0x63, 0x58, 0x49, 0x43, 0x41, 0x58, 0x74, + 0x78, 0x59, 0x68, 0x41, 0x74, 0x73, 0x67, 0x46, 0x2f, 0x33, 0x63, + 0x46, 0x79, 0x41, 0x67, 0x46, 0x77, 0x49, 0x6b, 0x46, 0x79, 0x44, + 0x39, 0x4a, 0x53, 0x45, 0x57, 0x74, 0x78, 0x63, 0x67, 0x49, 0x42, + 0x65, 0x33, 0x46, 0x69, 0x45, 0x43, 0x32, 0x79, 0x41, 0x58, 0x2f, + 0x64, 0x77, 0x58, 0x49, 0x43, 0x41, 0x58, 0x41, 0x69, 0x51, 0x58, + 0x49, 0x43, 0x41, 0x58, 0x2f, 0x64, 0x77, 0x58, 0x49, 0x43, 0x41, + 0x58, 0x41, 0x69, 0x51, 0x58, 0x49, 0x4f, 0x35, 0x75, 0x46, 0x79, + 0x41, 0x67, 0x46, 0x32, 0x34, 0x57, 0x49, 0x53, 0x45, 0x42, 0x44, + 0x6d, 0x30, 0x58, 0x49, 0x43, 0x41, 0x58, 0x62, 0x52, 0x63, 0x67, + 0x49, 0x50, 0x37, 0x46, 0x62, 0x68, 0x63, 0x67, 0x49, 0x42, 0x64, + 0x75, 0x46, 0x69, 0x45, 0x68, 0x41, 0x6a, 0x4e, 0x75, 0x46, 0x79, + 0x41, 0x67, 0x46, 0x32, 0x34, 0x58, 0x49, 0x43, 0x44, 0x2b, 0x78, + 0x47, 0x30, 0x58, 0x49, 0x43, 0x41, 0x58, 0x62, 0x52, 0x63, 0x67, + 0x49, 0x41, 0x45, 0x4f, 0x62, 0x68, 0x63, 0x67, 0x49, 0x42, 0x64, + 0x75, 0x46, 0x79, 0x41, 0x67, 0x41, 0x41, 0x41, 0x42, 0x41, 0x45, + 0x55, 0x41, 0x55, 0x51, 0x4f, 0x37, 0x41, 0x76, 0x67, 0x41, 0x4a, + 0x41, 0x41, 0x41, 0x41, 0x52, 0x51, 0x47, 0x42, 0x77, 0x45, 0x4f, + 0x41, 0x53, 0x4d, 0x69, 0x4a, 0x69, 0x63, 0x42, 0x4c, 0x67, 0x45, + 0x31, 0x4e, 0x44, 0x59, 0x2f, 0x41, 0x54, 0x34, 0x42, 0x4d, 0x7a, + 0x49, 0x57, 0x48, 0x77, 0x45, 0x42, 0x50, 0x67, 0x45, 0x7a, 0x4d, + 0x68, 0x59, 0x66, 0x41, 0x52, 0x34, 0x42, 0x46, 0x51, 0x4f, 0x37, + 0x43, 0x41, 0x6a, 0x2b, 0x46, 0x41, 0x63, 0x56, 0x43, 0x67, 0x73, + 0x56, 0x42, 0x2f, 0x37, 0x6a, 0x43, 0x41, 0x67, 0x49, 0x43, 0x45, + 0x34, 0x49, 0x46, 0x41, 0x73, 0x4b, 0x46, 0x51, 0x69, 0x6f, 0x41, + 0x58, 0x59, 0x49, 0x46, 0x51, 0x6f, 0x4c, 0x46, 0x41, 0x68, 0x4f, + 0x43, 0x41, 0x67, 0x43, 0x63, 0x77, 0x6f, 0x56, 0x42, 0x2f, 0x34, + 0x55, 0x43, 0x41, 0x67, 0x49, 0x43, 0x41, 0x45, 0x64, 0x42, 0x78, + 0x55, 0x4c, 0x43, 0x68, 0x55, 0x48, 0x54, 0x67, 0x67, 0x49, 0x43, + 0x41, 0x69, 0x6f, 0x41, 0x58, 0x63, 0x49, 0x43, 0x41, 0x67, 0x49, + 0x54, 0x67, 0x63, 0x56, 0x43, 0x77, 0x41, 0x41, 0x41, 0x51, 0x41, + 0x2f, 0x41, 0x44, 0x38, 0x43, 0x35, 0x67, 0x4c, 0x6d, 0x41, 0x44, + 0x77, 0x41, 0x41, 0x43, 0x55, 0x55, 0x42, 0x67, 0x38, 0x42, 0x44, + 0x67, 0x45, 0x6a, 0x49, 0x69, 0x59, 0x76, 0x41, 0x51, 0x63, 0x4f, + 0x41, 0x53, 0x4d, 0x69, 0x4a, 0x69, 0x38, 0x42, 0x4c, 0x67, 0x45, + 0x31, 0x4e, 0x44, 0x59, 0x2f, 0x41, 0x53, 0x63, 0x75, 0x41, 0x54, + 0x55, 0x30, 0x4e, 0x6a, 0x38, 0x42, 0x50, 0x67, 0x45, 0x7a, 0x4d, + 0x68, 0x59, 0x66, 0x41, 0x54, 0x63, 0x2b, 0x41, 0x54, 0x4d, 0x79, + 0x46, 0x68, 0x38, 0x42, 0x48, 0x67, 0x45, 0x56, 0x46, 0x41, 0x59, + 0x50, 0x41, 0x52, 0x63, 0x65, 0x41, 0x52, 0x55, 0x43, 0x35, 0x67, + 0x6b, 0x48, 0x54, 0x67, 0x67, 0x55, 0x43, 0x77, 0x73, 0x55, 0x43, + 0x4b, 0x69, 0x6f, 0x42, 0x78, 0x55, 0x4c, 0x43, 0x68, 0x55, 0x48, + 0x54, 0x67, 0x67, 0x49, 0x43, 0x41, 0x69, 0x6f, 0x71, 0x41, 0x67, + 0x49, 0x43, 0x41, 0x68, 0x4f, 0x42, 0x78, 0x55, 0x4b, 0x43, 0x78, + 0x55, 0x48, 0x71, 0x4b, 0x67, 0x49, 0x46, 0x41, 0x73, 0x4c, 0x46, + 0x41, 0x68, 0x4f, 0x42, 0x77, 0x6b, 0x4a, 0x42, 0x36, 0x69, 0x6f, + 0x42, 0x77, 0x6e, 0x44, 0x43, 0x68, 0x55, 0x48, 0x54, 0x67, 0x67, + 0x49, 0x43, 0x41, 0x69, 0x6f, 0x71, 0x41, 0x67, 0x49, 0x43, 0x41, + 0x68, 0x4f, 0x42, 0x78, 0x55, 0x4b, 0x43, 0x78, 0x55, 0x48, 0x71, + 0x4b, 0x67, 0x49, 0x46, 0x41, 0x73, 0x4c, 0x46, 0x41, 0x68, 0x4f, + 0x42, 0x77, 0x6b, 0x4a, 0x42, 0x36, 0x69, 0x6f, 0x42, 0x77, 0x6b, + 0x4a, 0x42, 0x30, 0x34, 0x49, 0x46, 0x41, 0x73, 0x4c, 0x46, 0x41, + 0x69, 0x6f, 0x71, 0x41, 0x63, 0x56, 0x43, 0x77, 0x41, 0x41, 0x41, + 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x32, 0x34, 0x44, + 0x62, 0x67, 0x41, 0x4c, 0x41, 0x4a, 0x49, 0x41, 0x41, 0x41, 0x45, + 0x30, 0x4a, 0x69, 0x4d, 0x69, 0x42, 0x68, 0x55, 0x55, 0x46, 0x6a, + 0x4d, 0x79, 0x4e, 0x69, 0x55, 0x56, 0x46, 0x41, 0x59, 0x50, 0x41, + 0x51, 0x34, 0x42, 0x42, 0x78, 0x34, 0x42, 0x46, 0x78, 0x34, 0x42, + 0x46, 0x52, 0x51, 0x47, 0x42, 0x77, 0x34, 0x42, 0x49, 0x79, 0x49, + 0x6d, 0x4c, 0x77, 0x45, 0x4f, 0x41, 0x51, 0x63, 0x4f, 0x41, 0x51, + 0x63, 0x4f, 0x41, 0x53, 0x73, 0x42, 0x49, 0x69, 0x59, 0x76, 0x41, + 0x53, 0x34, 0x42, 0x4a, 0x77, 0x63, 0x4f, 0x41, 0x53, 0x4d, 0x69, + 0x4a, 0x69, 0x63, 0x75, 0x41, 0x53, 0x63, 0x75, 0x41, 0x54, 0x55, + 0x30, 0x4e, 0x6a, 0x63, 0x2b, 0x41, 0x54, 0x63, 0x75, 0x41, 0x53, + 0x38, 0x42, 0x4c, 0x67, 0x45, 0x39, 0x41, 0x54, 0x51, 0x32, 0x50, + 0x77, 0x45, 0x2b, 0x41, 0x54, 0x63, 0x75, 0x41, 0x53, 0x63, 0x75, + 0x41, 0x54, 0x55, 0x30, 0x4e, 0x6a, 0x63, 0x2b, 0x41, 0x54, 0x4d, + 0x79, 0x46, 0x68, 0x38, 0x42, 0x50, 0x67, 0x45, 0x33, 0x50, 0x67, + 0x45, 0x33, 0x50, 0x67, 0x45, 0x37, 0x41, 0x54, 0x49, 0x57, 0x48, + 0x77, 0x45, 0x65, 0x41, 0x52, 0x63, 0x33, 0x50, 0x67, 0x45, 0x7a, + 0x4d, 0x68, 0x59, 0x58, 0x48, 0x67, 0x45, 0x58, 0x48, 0x67, 0x45, + 0x56, 0x46, 0x41, 0x59, 0x48, 0x44, 0x67, 0x45, 0x48, 0x48, 0x67, + 0x45, 0x66, 0x41, 0x52, 0x34, 0x42, 0x46, 0x51, 0x4a, 0x4a, 0x56, + 0x6a, 0x77, 0x39, 0x56, 0x56, 0x55, 0x39, 0x50, 0x46, 0x59, 0x42, + 0x4a, 0x51, 0x6b, 0x48, 0x61, 0x67, 0x55, 0x4b, 0x42, 0x77, 0x34, + 0x66, 0x45, 0x41, 0x49, 0x45, 0x41, 0x77, 0x4d, 0x4b, 0x56, 0x51, + 0x38, 0x45, 0x42, 0x77, 0x52, 0x50, 0x44, 0x42, 0x6f, 0x4f, 0x41, + 0x77, 0x59, 0x48, 0x41, 0x67, 0x73, 0x49, 0x66, 0x77, 0x63, 0x4d, + 0x41, 0x52, 0x41, 0x4e, 0x47, 0x67, 0x31, 0x51, 0x41, 0x77, 0x67, + 0x44, 0x42, 0x41, 0x67, 0x44, 0x46, 0x6a, 0x59, 0x53, 0x41, 0x67, + 0x49, 0x43, 0x41, 0x77, 0x34, 0x66, 0x44, 0x77, 0x67, 0x4d, 0x42, + 0x47, 0x67, 0x49, 0x43, 0x51, 0x6b, 0x47, 0x61, 0x77, 0x51, 0x4c, + 0x42, 0x77, 0x38, 0x65, 0x45, 0x41, 0x4d, 0x44, 0x41, 0x77, 0x49, + 0x4c, 0x56, 0x51, 0x38, 0x44, 0x43, 0x41, 0x4e, 0x50, 0x44, 0x52, + 0x6f, 0x4e, 0x41, 0x77, 0x63, 0x48, 0x41, 0x67, 0x73, 0x48, 0x66, + 0x77, 0x67, 0x4d, 0x41, 0x52, 0x41, 0x4e, 0x47, 0x67, 0x78, 0x52, + 0x41, 0x77, 0x63, 0x45, 0x42, 0x41, 0x63, 0x44, 0x46, 0x7a, 0x59, + 0x53, 0x41, 0x67, 0x49, 0x44, 0x41, 0x67, 0x34, 0x66, 0x44, 0x77, + 0x63, 0x4d, 0x42, 0x57, 0x67, 0x48, 0x43, 0x67, 0x47, 0x33, 0x50, + 0x46, 0x5a, 0x57, 0x50, 0x44, 0x31, 0x56, 0x56, 0x58, 0x74, 0x2f, + 0x42, 0x67, 0x30, 0x42, 0x45, 0x41, 0x34, 0x61, 0x44, 0x42, 0x55, + 0x6e, 0x45, 0x77, 0x4d, 0x49, 0x41, 0x77, 0x51, 0x48, 0x41, 0x77, + 0x31, 0x5a, 0x41, 0x77, 0x49, 0x2b, 0x42, 0x67, 0x73, 0x46, 0x47, + 0x6a, 0x59, 0x61, 0x42, 0x77, 0x6b, 0x4b, 0x42, 0x32, 0x6b, 0x46, + 0x43, 0x67, 0x59, 0x39, 0x41, 0x67, 0x4d, 0x44, 0x41, 0x78, 0x55, + 0x7a, 0x47, 0x41, 0x4d, 0x48, 0x42, 0x41, 0x4d, 0x48, 0x41, 0x78, + 0x4d, 0x6e, 0x46, 0x41, 0x34, 0x63, 0x44, 0x77, 0x38, 0x42, 0x44, + 0x41, 0x68, 0x2b, 0x42, 0x77, 0x30, 0x42, 0x45, 0x41, 0x34, 0x61, + 0x44, 0x52, 0x51, 0x6e, 0x45, 0x77, 0x4d, 0x48, 0x42, 0x41, 0x51, + 0x47, 0x41, 0x77, 0x35, 0x5a, 0x42, 0x41, 0x49, 0x39, 0x42, 0x67, + 0x73, 0x45, 0x47, 0x7a, 0x59, 0x61, 0x42, 0x77, 0x6b, 0x4b, 0x42, + 0x32, 0x6f, 0x45, 0x43, 0x67, 0x63, 0x39, 0x41, 0x77, 0x4d, 0x45, + 0x41, 0x68, 0x55, 0x7a, 0x47, 0x51, 0x4d, 0x47, 0x42, 0x41, 0x51, + 0x47, 0x41, 0x78, 0x51, 0x6d, 0x46, 0x41, 0x34, 0x63, 0x44, 0x68, + 0x41, 0x43, 0x44, 0x41, 0x63, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x77, 0x41, 0x41, 0x2f, 0x37, 0x63, 0x44, 0x62, 0x67, 0x4f, 0x33, + 0x41, 0x42, 0x4d, 0x41, 0x48, 0x41, 0x41, 0x6d, 0x41, 0x41, 0x41, + 0x42, 0x48, 0x67, 0x45, 0x56, 0x45, 0x52, 0x51, 0x47, 0x49, 0x79, + 0x45, 0x69, 0x4a, 0x6a, 0x55, 0x52, 0x4e, 0x44, 0x59, 0x7a, 0x49, + 0x54, 0x49, 0x57, 0x46, 0x77, 0x63, 0x56, 0x4d, 0x79, 0x34, 0x42, + 0x4c, 0x77, 0x45, 0x75, 0x41, 0x52, 0x4d, 0x52, 0x49, 0x79, 0x49, + 0x6d, 0x50, 0x51, 0x45, 0x68, 0x45, 0x53, 0x45, 0x44, 0x52, 0x78, + 0x41, 0x58, 0x49, 0x42, 0x66, 0x39, 0x41, 0x42, 0x63, 0x67, 0x49, + 0x42, 0x63, 0x43, 0x41, 0x42, 0x63, 0x33, 0x45, 0x45, 0x7a, 0x58, + 0x41, 0x77, 0x63, 0x44, 0x73, 0x67, 0x4d, 0x4f, 0x31, 0x65, 0x34, + 0x58, 0x49, 0x50, 0x35, 0x4a, 0x41, 0x74, 0x77, 0x43, 0x33, 0x68, + 0x41, 0x33, 0x46, 0x2f, 0x31, 0x75, 0x46, 0x79, 0x41, 0x67, 0x46, + 0x77, 0x4f, 0x53, 0x46, 0x79, 0x41, 0x58, 0x45, 0x43, 0x66, 0x58, + 0x43, 0x41, 0x30, 0x44, 0x73, 0x77, 0x4d, 0x48, 0x2f, 0x4a, 0x6b, + 0x43, 0x53, 0x53, 0x41, 0x58, 0x37, 0x76, 0x79, 0x53, 0x41, 0x41, + 0x4d, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x32, 0x34, 0x44, 0x62, + 0x67, 0x41, 0x56, 0x41, 0x44, 0x45, 0x41, 0x54, 0x51, 0x41, 0x41, + 0x41, 0x52, 0x45, 0x55, 0x42, 0x69, 0x73, 0x42, 0x49, 0x69, 0x59, + 0x39, 0x41, 0x54, 0x51, 0x32, 0x4f, 0x77, 0x45, 0x31, 0x4e, 0x44, + 0x59, 0x37, 0x41, 0x54, 0x49, 0x57, 0x46, 0x52, 0x63, 0x30, 0x4a, + 0x79, 0x34, 0x42, 0x4a, 0x79, 0x59, 0x6a, 0x49, 0x67, 0x63, 0x4f, + 0x41, 0x51, 0x63, 0x47, 0x46, 0x52, 0x51, 0x58, 0x48, 0x67, 0x45, + 0x58, 0x46, 0x6a, 0x4d, 0x79, 0x4e, 0x7a, 0x34, 0x42, 0x4e, 0x7a, + 0x59, 0x33, 0x46, 0x41, 0x63, 0x4f, 0x41, 0x51, 0x63, 0x47, 0x49, + 0x79, 0x49, 0x6e, 0x4c, 0x67, 0x45, 0x6e, 0x4a, 0x6a, 0x55, 0x30, + 0x4e, 0x7a, 0x34, 0x42, 0x4e, 0x7a, 0x59, 0x7a, 0x4d, 0x68, 0x63, + 0x65, 0x41, 0x52, 0x63, 0x57, 0x41, 0x67, 0x41, 0x4c, 0x42, 0x37, + 0x63, 0x49, 0x43, 0x67, 0x6f, 0x49, 0x67, 0x41, 0x6f, 0x49, 0x4a, + 0x51, 0x63, 0x4c, 0x37, 0x68, 0x6b, 0x59, 0x56, 0x54, 0x67, 0x35, + 0x51, 0x45, 0x41, 0x35, 0x4f, 0x56, 0x51, 0x5a, 0x47, 0x42, 0x67, + 0x5a, 0x56, 0x44, 0x6b, 0x35, 0x51, 0x45, 0x41, 0x35, 0x4f, 0x46, + 0x55, 0x59, 0x47, 0x59, 0x41, 0x6a, 0x49, 0x6e, 0x64, 0x51, 0x55, + 0x46, 0x74, 0x62, 0x55, 0x46, 0x42, 0x33, 0x49, 0x79, 0x49, 0x69, + 0x49, 0x33, 0x64, 0x51, 0x55, 0x46, 0x74, 0x62, 0x55, 0x46, 0x42, + 0x33, 0x49, 0x69, 0x4d, 0x43, 0x67, 0x50, 0x38, 0x41, 0x43, 0x41, + 0x6f, 0x4b, 0x43, 0x43, 0x55, 0x48, 0x43, 0x38, 0x6b, 0x49, 0x43, + 0x67, 0x6f, 0x49, 0x79, 0x55, 0x41, 0x35, 0x4f, 0x46, 0x55, 0x59, + 0x47, 0x52, 0x6b, 0x59, 0x56, 0x54, 0x67, 0x35, 0x51, 0x45, 0x41, + 0x35, 0x4f, 0x56, 0x51, 0x5a, 0x47, 0x42, 0x67, 0x5a, 0x56, 0x44, + 0x6b, 0x35, 0x51, 0x46, 0x74, 0x51, 0x55, 0x48, 0x63, 0x69, 0x49, + 0x79, 0x4d, 0x69, 0x64, 0x31, 0x42, 0x51, 0x57, 0x31, 0x74, 0x51, + 0x55, 0x48, 0x63, 0x69, 0x49, 0x79, 0x4d, 0x69, 0x64, 0x31, 0x42, + 0x51, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x32, 0x34, 0x44, 0x62, 0x67, 0x41, 0x30, 0x41, + 0x47, 0x63, 0x41, 0x41, 0x41, 0x45, 0x77, 0x46, 0x42, 0x55, 0x47, + 0x42, 0x77, 0x34, 0x42, 0x42, 0x77, 0x59, 0x6a, 0x49, 0x69, 0x63, + 0x75, 0x41, 0x53, 0x63, 0x6d, 0x4a, 0x77, 0x63, 0x4f, 0x41, 0x53, + 0x4d, 0x69, 0x4a, 0x6a, 0x55, 0x52, 0x4e, 0x44, 0x59, 0x7a, 0x49, + 0x54, 0x49, 0x57, 0x46, 0x52, 0x51, 0x47, 0x44, 0x77, 0x45, 0x65, + 0x41, 0x54, 0x4d, 0x79, 0x4e, 0x6a, 0x63, 0x2b, 0x41, 0x54, 0x63, + 0x2b, 0x41, 0x54, 0x73, 0x42, 0x4d, 0x68, 0x59, 0x56, 0x45, 0x78, + 0x45, 0x55, 0x42, 0x69, 0x4d, 0x68, 0x49, 0x69, 0x59, 0x31, 0x4e, + 0x44, 0x59, 0x2f, 0x41, 0x53, 0x34, 0x42, 0x49, 0x79, 0x49, 0x47, + 0x42, 0x77, 0x34, 0x42, 0x42, 0x77, 0x34, 0x42, 0x4b, 0x77, 0x45, + 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x6a, 0x63, 0x2b, 0x41, 0x54, + 0x63, 0x32, 0x4d, 0x7a, 0x49, 0x58, 0x48, 0x67, 0x45, 0x58, 0x46, + 0x68, 0x63, 0x33, 0x50, 0x67, 0x45, 0x7a, 0x4d, 0x68, 0x59, 0x56, + 0x41, 0x31, 0x38, 0x53, 0x4b, 0x43, 0x64, 0x76, 0x52, 0x6b, 0x56, + 0x50, 0x4b, 0x69, 0x6b, 0x70, 0x54, 0x43, 0x4d, 0x6b, 0x48, 0x6b, + 0x6f, 0x46, 0x44, 0x51, 0x63, 0x50, 0x46, 0x68, 0x59, 0x50, 0x41, + 0x51, 0x41, 0x50, 0x46, 0x51, 0x59, 0x46, 0x54, 0x69, 0x68, 0x6f, + 0x4e, 0x30, 0x79, 0x46, 0x4b, 0x41, 0x6f, 0x4e, 0x42, 0x77, 0x49, + 0x4a, 0x42, 0x6d, 0x34, 0x49, 0x43, 0x67, 0x38, 0x57, 0x44, 0x2f, + 0x38, 0x41, 0x44, 0x78, 0x55, 0x46, 0x42, 0x55, 0x38, 0x6f, 0x61, + 0x44, 0x64, 0x4d, 0x68, 0x53, 0x67, 0x4c, 0x44, 0x41, 0x67, 0x43, + 0x43, 0x41, 0x64, 0x78, 0x43, 0x41, 0x73, 0x54, 0x4a, 0x79, 0x68, + 0x77, 0x52, 0x6b, 0x5a, 0x50, 0x4b, 0x69, 0x6b, 0x70, 0x54, 0x53, + 0x4d, 0x6b, 0x48, 0x6b, 0x6f, 0x47, 0x44, 0x51, 0x63, 0x50, 0x46, + 0x67, 0x46, 0x62, 0x41, 0x77, 0x46, 0x4c, 0x51, 0x44, 0x39, 0x62, + 0x47, 0x52, 0x6b, 0x49, 0x43, 0x42, 0x38, 0x58, 0x46, 0x68, 0x31, + 0x4b, 0x42, 0x51, 0x55, 0x56, 0x44, 0x77, 0x45, 0x41, 0x44, 0x78, + 0x59, 0x57, 0x44, 0x77, 0x63, 0x4e, 0x42, 0x6b, 0x34, 0x6d, 0x4b, + 0x55, 0x74, 0x42, 0x45, 0x43, 0x45, 0x53, 0x42, 0x67, 0x63, 0x4c, + 0x43, 0x41, 0x48, 0x4b, 0x2f, 0x77, 0x41, 0x50, 0x46, 0x68, 0x59, + 0x50, 0x42, 0x77, 0x30, 0x46, 0x54, 0x79, 0x59, 0x6f, 0x53, 0x6b, + 0x45, 0x52, 0x49, 0x52, 0x45, 0x47, 0x42, 0x77, 0x73, 0x48, 0x42, + 0x45, 0x78, 0x41, 0x50, 0x31, 0x6f, 0x61, 0x47, 0x51, 0x67, 0x4a, + 0x48, 0x78, 0x59, 0x58, 0x48, 0x45, 0x6b, 0x46, 0x42, 0x68, 0x55, + 0x50, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x45, + 0x6b, 0x45, 0x41, 0x41, 0x4e, 0x75, 0x41, 0x42, 0x41, 0x41, 0x49, + 0x41, 0x41, 0x77, 0x41, 0x45, 0x45, 0x41, 0x55, 0x67, 0x42, 0x6a, + 0x41, 0x48, 0x51, 0x41, 0x68, 0x41, 0x41, 0x41, 0x45, 0x78, 0x55, + 0x55, 0x42, 0x69, 0x73, 0x42, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, + 0x51, 0x32, 0x4f, 0x77, 0x45, 0x79, 0x46, 0x68, 0x55, 0x31, 0x46, + 0x52, 0x51, 0x47, 0x4b, 0x77, 0x45, 0x69, 0x4a, 0x6a, 0x30, 0x42, + 0x4e, 0x44, 0x59, 0x37, 0x41, 0x54, 0x49, 0x57, 0x4e, 0x52, 0x55, + 0x55, 0x42, 0x69, 0x73, 0x42, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, + 0x51, 0x32, 0x4f, 0x77, 0x45, 0x79, 0x46, 0x67, 0x45, 0x56, 0x46, + 0x41, 0x59, 0x6a, 0x49, 0x53, 0x49, 0x6d, 0x50, 0x51, 0x45, 0x30, + 0x4e, 0x6a, 0x4d, 0x68, 0x4d, 0x68, 0x59, 0x56, 0x4e, 0x52, 0x55, + 0x55, 0x42, 0x69, 0x4d, 0x68, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, + 0x51, 0x32, 0x4d, 0x79, 0x45, 0x79, 0x46, 0x68, 0x55, 0x31, 0x46, + 0x52, 0x51, 0x47, 0x49, 0x79, 0x45, 0x69, 0x4a, 0x6a, 0x30, 0x42, + 0x4e, 0x44, 0x59, 0x7a, 0x49, 0x54, 0x49, 0x57, 0x46, 0x52, 0x4d, + 0x52, 0x4e, 0x43, 0x59, 0x6a, 0x49, 0x53, 0x49, 0x47, 0x46, 0x52, + 0x45, 0x55, 0x46, 0x6a, 0x4d, 0x68, 0x4d, 0x6a, 0x59, 0x31, 0x45, + 0x78, 0x45, 0x55, 0x42, 0x69, 0x4d, 0x68, 0x49, 0x69, 0x59, 0x31, + 0x45, 0x54, 0x51, 0x32, 0x4d, 0x79, 0x45, 0x79, 0x46, 0x74, 0x73, + 0x4c, 0x42, 0x79, 0x51, 0x49, 0x43, 0x77, 0x73, 0x49, 0x4a, 0x41, + 0x63, 0x4c, 0x43, 0x77, 0x63, 0x6b, 0x43, 0x41, 0x73, 0x4c, 0x43, + 0x43, 0x51, 0x48, 0x43, 0x77, 0x73, 0x48, 0x4a, 0x41, 0x67, 0x4c, + 0x43, 0x77, 0x67, 0x6b, 0x42, 0x77, 0x73, 0x43, 0x6b, 0x77, 0x73, + 0x49, 0x2f, 0x64, 0x77, 0x48, 0x43, 0x77, 0x73, 0x48, 0x41, 0x69, + 0x51, 0x49, 0x43, 0x77, 0x73, 0x49, 0x2f, 0x64, 0x77, 0x48, 0x43, + 0x77, 0x73, 0x48, 0x41, 0x69, 0x51, 0x49, 0x43, 0x77, 0x73, 0x49, + 0x2f, 0x64, 0x77, 0x48, 0x43, 0x77, 0x73, 0x48, 0x41, 0x69, 0x51, + 0x49, 0x43, 0x30, 0x6b, 0x4c, 0x42, 0x2f, 0x79, 0x32, 0x42, 0x77, + 0x73, 0x4c, 0x42, 0x77, 0x4e, 0x4b, 0x42, 0x77, 0x74, 0x4a, 0x4e, + 0x69, 0x58, 0x38, 0x74, 0x69, 0x55, 0x32, 0x4e, 0x69, 0x55, 0x44, + 0x53, 0x69, 0x55, 0x32, 0x41, 0x52, 0x49, 0x6b, 0x43, 0x41, 0x73, + 0x4c, 0x43, 0x43, 0x51, 0x49, 0x43, 0x77, 0x73, 0x49, 0x6b, 0x79, + 0x55, 0x48, 0x43, 0x77, 0x73, 0x48, 0x4a, 0x51, 0x63, 0x4c, 0x43, + 0x34, 0x73, 0x6c, 0x42, 0x77, 0x73, 0x4c, 0x42, 0x79, 0x55, 0x48, + 0x43, 0x77, 0x76, 0x2b, 0x31, 0x43, 0x51, 0x49, 0x43, 0x77, 0x73, + 0x49, 0x4a, 0x41, 0x67, 0x4c, 0x43, 0x77, 0x69, 0x54, 0x4a, 0x51, + 0x63, 0x4c, 0x43, 0x77, 0x63, 0x6c, 0x42, 0x77, 0x73, 0x4c, 0x42, + 0x35, 0x49, 0x6c, 0x42, 0x77, 0x73, 0x4c, 0x42, 0x79, 0x55, 0x48, + 0x43, 0x77, 0x73, 0x48, 0x2f, 0x6d, 0x34, 0x42, 0x32, 0x77, 0x63, + 0x4c, 0x43, 0x77, 0x66, 0x2b, 0x4a, 0x51, 0x67, 0x4c, 0x43, 0x77, + 0x67, 0x43, 0x62, 0x66, 0x32, 0x54, 0x4a, 0x6a, 0x59, 0x32, 0x4a, + 0x67, 0x4a, 0x74, 0x4a, 0x6a, 0x59, 0x32, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x67, 0x41, 0x41, 0x41, 0x42, 0x4a, 0x42, 0x41, 0x41, + 0x44, 0x62, 0x67, 0x41, 0x51, 0x41, 0x43, 0x45, 0x41, 0x4d, 0x51, + 0x42, 0x43, 0x41, 0x46, 0x49, 0x41, 0x59, 0x77, 0x42, 0x7a, 0x41, + 0x49, 0x4d, 0x41, 0x41, 0x44, 0x63, 0x56, 0x46, 0x41, 0x59, 0x72, + 0x41, 0x53, 0x49, 0x6d, 0x50, 0x51, 0x45, 0x30, 0x4e, 0x6a, 0x73, + 0x42, 0x4d, 0x68, 0x59, 0x56, 0x4e, 0x52, 0x55, 0x55, 0x42, 0x69, + 0x73, 0x42, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, 0x51, 0x32, 0x4f, + 0x77, 0x45, 0x79, 0x46, 0x68, 0x55, 0x31, 0x46, 0x52, 0x51, 0x47, + 0x4b, 0x77, 0x45, 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, + 0x37, 0x41, 0x54, 0x49, 0x57, 0x41, 0x52, 0x55, 0x55, 0x42, 0x69, + 0x4d, 0x68, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, 0x51, 0x32, 0x4d, + 0x79, 0x45, 0x79, 0x46, 0x68, 0x55, 0x42, 0x46, 0x52, 0x51, 0x47, + 0x4b, 0x77, 0x45, 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, + 0x37, 0x41, 0x54, 0x49, 0x57, 0x41, 0x52, 0x55, 0x55, 0x42, 0x69, + 0x4d, 0x68, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, 0x51, 0x32, 0x4d, + 0x79, 0x45, 0x79, 0x46, 0x68, 0x55, 0x31, 0x46, 0x52, 0x51, 0x47, + 0x49, 0x79, 0x45, 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, + 0x7a, 0x49, 0x54, 0x49, 0x57, 0x4e, 0x52, 0x55, 0x55, 0x42, 0x69, + 0x4d, 0x68, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, 0x51, 0x32, 0x4d, + 0x79, 0x45, 0x79, 0x46, 0x70, 0x49, 0x4c, 0x42, 0x32, 0x34, 0x48, + 0x43, 0x77, 0x73, 0x48, 0x62, 0x67, 0x63, 0x4c, 0x43, 0x77, 0x64, + 0x75, 0x42, 0x77, 0x73, 0x4c, 0x42, 0x32, 0x34, 0x48, 0x43, 0x77, + 0x73, 0x48, 0x62, 0x67, 0x63, 0x4c, 0x43, 0x77, 0x64, 0x75, 0x42, + 0x77, 0x73, 0x44, 0x62, 0x67, 0x73, 0x48, 0x2f, 0x51, 0x41, 0x49, + 0x43, 0x77, 0x73, 0x49, 0x41, 0x77, 0x41, 0x48, 0x43, 0x2f, 0x79, + 0x53, 0x43, 0x77, 0x64, 0x75, 0x42, 0x77, 0x73, 0x4c, 0x42, 0x32, + 0x34, 0x48, 0x43, 0x77, 0x4e, 0x75, 0x43, 0x77, 0x66, 0x39, 0x41, + 0x41, 0x67, 0x4c, 0x43, 0x77, 0x67, 0x44, 0x41, 0x41, 0x63, 0x4c, + 0x43, 0x77, 0x66, 0x39, 0x41, 0x41, 0x67, 0x4c, 0x43, 0x77, 0x67, + 0x44, 0x41, 0x41, 0x63, 0x4c, 0x43, 0x77, 0x66, 0x39, 0x41, 0x41, + 0x67, 0x4c, 0x43, 0x77, 0x67, 0x44, 0x41, 0x41, 0x63, 0x4c, 0x79, + 0x57, 0x34, 0x48, 0x43, 0x77, 0x73, 0x48, 0x62, 0x67, 0x63, 0x4c, + 0x43, 0x77, 0x66, 0x63, 0x62, 0x67, 0x63, 0x4c, 0x43, 0x77, 0x64, + 0x75, 0x42, 0x77, 0x73, 0x4c, 0x42, 0x39, 0x74, 0x75, 0x42, 0x77, + 0x73, 0x4c, 0x42, 0x32, 0x34, 0x48, 0x43, 0x77, 0x76, 0x2b, 0x51, + 0x6d, 0x34, 0x48, 0x43, 0x77, 0x73, 0x48, 0x62, 0x67, 0x63, 0x4c, + 0x43, 0x77, 0x63, 0x43, 0x6b, 0x6d, 0x30, 0x49, 0x43, 0x77, 0x73, + 0x49, 0x62, 0x51, 0x67, 0x4c, 0x43, 0x2f, 0x35, 0x43, 0x62, 0x67, + 0x63, 0x4c, 0x43, 0x77, 0x64, 0x75, 0x42, 0x77, 0x73, 0x4c, 0x42, + 0x39, 0x74, 0x75, 0x42, 0x77, 0x73, 0x4c, 0x42, 0x32, 0x34, 0x48, + 0x43, 0x77, 0x76, 0x55, 0x62, 0x51, 0x67, 0x4c, 0x43, 0x77, 0x68, + 0x74, 0x43, 0x41, 0x73, 0x4c, 0x41, 0x41, 0x41, 0x41, 0x41, 0x67, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x53, 0x51, 0x4e, 0x75, 0x41, + 0x41, 0x73, 0x41, 0x4b, 0x41, 0x41, 0x41, 0x41, 0x54, 0x51, 0x6d, + 0x49, 0x79, 0x49, 0x47, 0x46, 0x52, 0x51, 0x57, 0x4d, 0x7a, 0x49, + 0x32, 0x4e, 0x78, 0x51, 0x47, 0x42, 0x77, 0x4d, 0x4f, 0x41, 0x53, + 0x4d, 0x69, 0x4a, 0x69, 0x63, 0x44, 0x4c, 0x67, 0x45, 0x31, 0x4e, + 0x44, 0x63, 0x2b, 0x41, 0x54, 0x63, 0x32, 0x4d, 0x7a, 0x49, 0x58, + 0x48, 0x67, 0x45, 0x58, 0x46, 0x68, 0x55, 0x42, 0x74, 0x31, 0x59, + 0x38, 0x50, 0x56, 0x5a, 0x57, 0x50, 0x54, 0x78, 0x57, 0x6b, 0x67, + 0x67, 0x4c, 0x30, 0x41, 0x6b, 0x6b, 0x46, 0x42, 0x55, 0x6b, 0x43, + 0x64, 0x41, 0x4c, 0x43, 0x42, 0x63, 0x58, 0x54, 0x7a, 0x59, 0x31, + 0x50, 0x54, 0x77, 0x32, 0x4e, 0x55, 0x38, 0x58, 0x46, 0x77, 0x4a, + 0x4a, 0x50, 0x56, 0x56, 0x56, 0x50, 0x54, 0x78, 0x57, 0x56, 0x6a, + 0x77, 0x61, 0x4e, 0x52, 0x66, 0x2b, 0x52, 0x68, 0x4d, 0x57, 0x46, + 0x68, 0x4d, 0x42, 0x75, 0x68, 0x63, 0x31, 0x47, 0x6a, 0x30, 0x31, + 0x4e, 0x56, 0x41, 0x58, 0x46, 0x78, 0x63, 0x58, 0x55, 0x44, 0x55, + 0x31, 0x50, 0x51, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x53, 0x51, + 0x4f, 0x70, 0x41, 0x32, 0x34, 0x41, 0x4f, 0x67, 0x42, 0x51, 0x41, + 0x41, 0x41, 0x42, 0x46, 0x52, 0x51, 0x47, 0x49, 0x79, 0x45, 0x69, + 0x4a, 0x6a, 0x55, 0x52, 0x4e, 0x44, 0x59, 0x7a, 0x49, 0x54, 0x49, + 0x57, 0x46, 0x78, 0x34, 0x42, 0x46, 0x78, 0x59, 0x47, 0x44, 0x77, + 0x45, 0x4f, 0x41, 0x53, 0x4d, 0x69, 0x4a, 0x69, 0x4d, 0x75, 0x41, + 0x53, 0x4d, 0x68, 0x49, 0x67, 0x59, 0x56, 0x45, 0x52, 0x51, 0x57, + 0x4d, 0x79, 0x45, 0x79, 0x4e, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, + 0x2f, 0x41, 0x54, 0x34, 0x42, 0x4d, 0x7a, 0x49, 0x57, 0x46, 0x78, + 0x34, 0x42, 0x46, 0x52, 0x4d, 0x42, 0x42, 0x69, 0x49, 0x76, 0x41, + 0x53, 0x59, 0x30, 0x50, 0x77, 0x45, 0x32, 0x4d, 0x68, 0x38, 0x42, + 0x41, 0x54, 0x59, 0x79, 0x48, 0x77, 0x45, 0x57, 0x46, 0x41, 0x63, + 0x44, 0x4a, 0x57, 0x46, 0x45, 0x2f, 0x69, 0x56, 0x46, 0x59, 0x47, + 0x42, 0x46, 0x41, 0x64, 0x73, 0x52, 0x49, 0x68, 0x41, 0x45, 0x42, + 0x51, 0x45, 0x42, 0x41, 0x77, 0x4d, 0x63, 0x41, 0x77, 0x63, 0x44, + 0x41, 0x51, 0x4d, 0x42, 0x42, 0x77, 0x30, 0x47, 0x2f, 0x69, 0x55, + 0x6d, 0x4e, 0x6a, 0x59, 0x6d, 0x41, 0x64, 0x73, 0x6d, 0x4e, 0x51, + 0x4d, 0x44, 0x4a, 0x41, 0x4d, 0x48, 0x41, 0x77, 0x49, 0x44, 0x41, + 0x67, 0x55, 0x48, 0x68, 0x50, 0x34, 0x75, 0x44, 0x53, 0x59, 0x4f, + 0x39, 0x51, 0x34, 0x4f, 0x50, 0x67, 0x34, 0x6d, 0x44, 0x70, 0x59, + 0x42, 0x63, 0x67, 0x30, 0x6d, 0x44, 0x6a, 0x38, 0x4e, 0x44, 0x51, + 0x47, 0x6a, 0x74, 0x55, 0x52, 0x68, 0x59, 0x55, 0x51, 0x42, 0x32, + 0x30, 0x52, 0x68, 0x42, 0x77, 0x67, 0x42, 0x42, 0x77, 0x55, 0x45, + 0x43, 0x51, 0x4d, 0x63, 0x41, 0x77, 0x4d, 0x42, 0x41, 0x67, 0x49, + 0x32, 0x4a, 0x76, 0x34, 0x6c, 0x4a, 0x6a, 0x59, 0x32, 0x4a, 0x70, + 0x45, 0x44, 0x42, 0x77, 0x49, 0x6c, 0x41, 0x77, 0x4d, 0x42, 0x41, + 0x51, 0x49, 0x4a, 0x42, 0x67, 0x45, 0x59, 0x2f, 0x69, 0x38, 0x4f, + 0x44, 0x76, 0x55, 0x4f, 0x4a, 0x67, 0x34, 0x2b, 0x44, 0x67, 0x36, + 0x57, 0x41, 0x58, 0x49, 0x4f, 0x44, 0x6a, 0x38, 0x4f, 0x4a, 0x51, + 0x34, 0x41, 0x41, 0x41, 0x41, 0x42, 0x41, 0x47, 0x4d, 0x41, 0x47, + 0x67, 0x4b, 0x64, 0x41, 0x35, 0x30, 0x41, 0x46, 0x51, 0x41, 0x41, + 0x43, 0x51, 0x49, 0x57, 0x46, 0x41, 0x38, 0x42, 0x42, 0x69, 0x49, + 0x6e, 0x41, 0x53, 0x59, 0x30, 0x4e, 0x77, 0x45, 0x32, 0x4d, 0x68, + 0x38, 0x42, 0x46, 0x68, 0x51, 0x48, 0x41, 0x70, 0x33, 0x2b, 0x30, + 0x51, 0x45, 0x76, 0x43, 0x77, 0x74, 0x66, 0x43, 0x68, 0x34, 0x4c, + 0x2f, 0x6c, 0x67, 0x4c, 0x43, 0x77, 0x47, 0x6f, 0x43, 0x78, 0x34, + 0x4b, 0x58, 0x77, 0x73, 0x4c, 0x41, 0x77, 0x76, 0x2b, 0x30, 0x50, + 0x37, 0x52, 0x43, 0x78, 0x34, 0x4b, 0x58, 0x77, 0x73, 0x4c, 0x41, + 0x61, 0x67, 0x4b, 0x48, 0x67, 0x73, 0x42, 0x71, 0x41, 0x73, 0x4c, + 0x58, 0x77, 0x6f, 0x65, 0x43, 0x77, 0x41, 0x42, 0x41, 0x44, 0x34, + 0x41, 0x47, 0x67, 0x4a, 0x35, 0x41, 0x35, 0x30, 0x41, 0x46, 0x51, + 0x41, 0x41, 0x43, 0x51, 0x45, 0x47, 0x49, 0x69, 0x38, 0x42, 0x4a, + 0x6a, 0x51, 0x33, 0x43, 0x51, 0x45, 0x6d, 0x4e, 0x44, 0x38, 0x42, + 0x4e, 0x6a, 0x49, 0x58, 0x41, 0x52, 0x59, 0x55, 0x42, 0x77, 0x4a, + 0x35, 0x2f, 0x6c, 0x67, 0x4c, 0x48, 0x67, 0x74, 0x66, 0x43, 0x67, + 0x6f, 0x42, 0x4d, 0x50, 0x37, 0x51, 0x43, 0x67, 0x70, 0x66, 0x43, + 0x78, 0x34, 0x4c, 0x41, 0x61, 0x67, 0x4b, 0x43, 0x67, 0x48, 0x43, + 0x2f, 0x6c, 0x67, 0x4c, 0x43, 0x31, 0x38, 0x4b, 0x48, 0x67, 0x73, + 0x42, 0x4c, 0x77, 0x45, 0x77, 0x43, 0x78, 0x34, 0x4b, 0x58, 0x77, + 0x73, 0x4c, 0x2f, 0x6c, 0x67, 0x4c, 0x48, 0x67, 0x6f, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x77, 0x41, 0x4a, 0x41, 0x41, 0x41, 0x44, + 0x39, 0x77, 0x4f, 0x33, 0x41, 0x41, 0x38, 0x41, 0x4a, 0x67, 0x41, + 0x38, 0x41, 0x41, 0x41, 0x6c, 0x4e, 0x54, 0x51, 0x6d, 0x4b, 0x77, + 0x45, 0x69, 0x42, 0x68, 0x30, 0x42, 0x46, 0x42, 0x59, 0x37, 0x41, + 0x54, 0x49, 0x32, 0x4a, 0x78, 0x4d, 0x30, 0x4a, 0x69, 0x63, 0x75, + 0x41, 0x53, 0x73, 0x42, 0x49, 0x67, 0x59, 0x48, 0x44, 0x67, 0x45, + 0x56, 0x45, 0x78, 0x51, 0x57, 0x4f, 0x77, 0x45, 0x79, 0x4e, 0x6a, + 0x55, 0x44, 0x41, 0x52, 0x59, 0x55, 0x42, 0x77, 0x34, 0x42, 0x49, + 0x79, 0x45, 0x69, 0x4a, 0x69, 0x63, 0x6d, 0x4e, 0x44, 0x63, 0x42, + 0x50, 0x67, 0x45, 0x7a, 0x4d, 0x68, 0x59, 0x58, 0x41, 0x6b, 0x6b, + 0x4b, 0x43, 0x47, 0x34, 0x49, 0x43, 0x67, 0x6f, 0x49, 0x62, 0x67, + 0x67, 0x4b, 0x41, 0x51, 0x6f, 0x43, 0x41, 0x77, 0x4d, 0x48, 0x42, + 0x48, 0x34, 0x45, 0x42, 0x77, 0x4d, 0x44, 0x41, 0x67, 0x6b, 0x4d, + 0x43, 0x47, 0x6f, 0x48, 0x44, 0x41, 0x67, 0x42, 0x74, 0x77, 0x6b, + 0x4b, 0x43, 0x69, 0x49, 0x54, 0x2f, 0x4a, 0x49, 0x54, 0x49, 0x67, + 0x6f, 0x4b, 0x43, 0x51, 0x47, 0x33, 0x43, 0x53, 0x4d, 0x55, 0x46, + 0x43, 0x4d, 0x4a, 0x70, 0x57, 0x30, 0x48, 0x44, 0x41, 0x77, 0x48, + 0x62, 0x51, 0x67, 0x4c, 0x43, 0x39, 0x34, 0x42, 0x42, 0x67, 0x4d, + 0x47, 0x41, 0x67, 0x49, 0x45, 0x42, 0x41, 0x49, 0x43, 0x42, 0x77, + 0x50, 0x2b, 0x2b, 0x77, 0x59, 0x48, 0x42, 0x77, 0x59, 0x43, 0x46, + 0x76, 0x7a, 0x62, 0x45, 0x53, 0x59, 0x52, 0x45, 0x52, 0x4d, 0x54, + 0x45, 0x52, 0x45, 0x6d, 0x45, 0x51, 0x4d, 0x6c, 0x45, 0x52, 0x55, + 0x56, 0x45, 0x51, 0x41, 0x41, 0x41, 0x41, 0x55, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x42, 0x4a, 0x49, 0x44, 0x62, 0x67, 0x41, 0x44, 0x41, + 0x41, 0x67, 0x41, 0x44, 0x67, 0x41, 0x54, 0x41, 0x42, 0x67, 0x41, + 0x41, 0x41, 0x45, 0x52, 0x49, 0x78, 0x45, 0x42, 0x45, 0x53, 0x4d, + 0x52, 0x4d, 0x77, 0x45, 0x56, 0x49, 0x52, 0x45, 0x7a, 0x45, 0x51, + 0x45, 0x52, 0x49, 0x78, 0x45, 0x7a, 0x4e, 0x78, 0x45, 0x6a, 0x45, + 0x54, 0x4d, 0x42, 0x62, 0x70, 0x4d, 0x42, 0x62, 0x70, 0x4b, 0x53, + 0x41, 0x6b, 0x6e, 0x37, 0x62, 0x6b, 0x6b, 0x43, 0x33, 0x4a, 0x4f, + 0x54, 0x32, 0x35, 0x4b, 0x53, 0x41, 0x62, 0x66, 0x2b, 0x32, 0x77, + 0x45, 0x6c, 0x41, 0x53, 0x54, 0x39, 0x74, 0x77, 0x4a, 0x4a, 0x2f, + 0x57, 0x35, 0x4a, 0x41, 0x32, 0x37, 0x38, 0x32, 0x77, 0x49, 0x41, + 0x2f, 0x6b, 0x6b, 0x42, 0x74, 0x39, 0x7a, 0x39, 0x62, 0x51, 0x4b, + 0x54, 0x41, 0x41, 0x59, 0x41, 0x41, 0x50, 0x2b, 0x2f, 0x42, 0x45, + 0x6b, 0x44, 0x72, 0x67, 0x41, 0x4c, 0x41, 0x42, 0x63, 0x41, 0x49, + 0x77, 0x43, 0x6b, 0x41, 0x50, 0x77, 0x42, 0x56, 0x41, 0x41, 0x41, + 0x41, 0x54, 0x51, 0x6d, 0x49, 0x79, 0x49, 0x47, 0x46, 0x52, 0x51, + 0x57, 0x4d, 0x7a, 0x49, 0x32, 0x42, 0x54, 0x51, 0x6d, 0x49, 0x79, + 0x49, 0x47, 0x46, 0x52, 0x51, 0x57, 0x4d, 0x7a, 0x49, 0x32, 0x45, + 0x54, 0x51, 0x6d, 0x49, 0x79, 0x49, 0x47, 0x46, 0x52, 0x51, 0x57, + 0x4d, 0x7a, 0x49, 0x32, 0x42, 0x78, 0x55, 0x55, 0x42, 0x67, 0x38, + 0x42, 0x44, 0x67, 0x45, 0x48, 0x48, 0x67, 0x45, 0x58, 0x48, 0x67, + 0x45, 0x56, 0x46, 0x41, 0x59, 0x48, 0x44, 0x67, 0x45, 0x6a, 0x49, + 0x69, 0x59, 0x76, 0x41, 0x51, 0x34, 0x42, 0x42, 0x77, 0x34, 0x42, + 0x42, 0x77, 0x34, 0x42, 0x4b, 0x77, 0x45, 0x69, 0x4a, 0x69, 0x38, + 0x42, 0x4c, 0x67, 0x45, 0x6e, 0x42, 0x77, 0x34, 0x42, 0x49, 0x79, + 0x49, 0x6d, 0x4a, 0x79, 0x34, 0x42, 0x4e, 0x54, 0x51, 0x32, 0x4e, + 0x7a, 0x34, 0x42, 0x4e, 0x79, 0x34, 0x42, 0x4c, 0x77, 0x45, 0x75, + 0x41, 0x54, 0x30, 0x42, 0x4e, 0x44, 0x59, 0x2f, 0x41, 0x54, 0x34, + 0x42, 0x4e, 0x79, 0x34, 0x42, 0x4a, 0x79, 0x34, 0x42, 0x4e, 0x54, + 0x51, 0x32, 0x4e, 0x7a, 0x34, 0x42, 0x4d, 0x7a, 0x49, 0x57, 0x48, + 0x77, 0x45, 0x2b, 0x41, 0x54, 0x63, 0x2b, 0x41, 0x54, 0x63, 0x2b, + 0x41, 0x54, 0x73, 0x42, 0x4d, 0x68, 0x59, 0x66, 0x41, 0x52, 0x34, + 0x42, 0x46, 0x7a, 0x63, 0x2b, 0x41, 0x54, 0x4d, 0x79, 0x46, 0x68, + 0x63, 0x65, 0x41, 0x52, 0x55, 0x55, 0x42, 0x67, 0x63, 0x4f, 0x41, + 0x51, 0x63, 0x65, 0x41, 0x52, 0x38, 0x42, 0x48, 0x67, 0x45, 0x56, + 0x41, 0x52, 0x55, 0x55, 0x42, 0x69, 0x4d, 0x4f, 0x41, 0x51, 0x63, + 0x65, 0x41, 0x52, 0x55, 0x55, 0x42, 0x67, 0x63, 0x4f, 0x41, 0x53, + 0x4d, 0x69, 0x4a, 0x69, 0x63, 0x69, 0x42, 0x69, 0x4d, 0x69, 0x4a, + 0x69, 0x4d, 0x4f, 0x41, 0x53, 0x4d, 0x69, 0x4a, 0x69, 0x63, 0x75, + 0x41, 0x54, 0x55, 0x30, 0x4e, 0x6a, 0x63, 0x75, 0x41, 0x53, 0x63, + 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, 0x33, 0x50, 0x67, + 0x45, 0x33, 0x4c, 0x67, 0x45, 0x31, 0x4d, 0x44, 0x59, 0x33, 0x50, + 0x67, 0x45, 0x7a, 0x4d, 0x68, 0x59, 0x58, 0x50, 0x67, 0x45, 0x7a, + 0x4d, 0x68, 0x59, 0x58, 0x50, 0x67, 0x45, 0x2f, 0x41, 0x54, 0x49, + 0x57, 0x46, 0x78, 0x34, 0x42, 0x4d, 0x52, 0x51, 0x47, 0x42, 0x78, + 0x34, 0x42, 0x46, 0x78, 0x34, 0x42, 0x46, 0x52, 0x45, 0x56, 0x46, + 0x41, 0x59, 0x48, 0x44, 0x67, 0x45, 0x48, 0x48, 0x67, 0x45, 0x56, + 0x46, 0x41, 0x59, 0x48, 0x44, 0x67, 0x45, 0x6a, 0x49, 0x69, 0x59, + 0x6e, 0x49, 0x67, 0x59, 0x6a, 0x49, 0x69, 0x59, 0x6a, 0x44, 0x67, + 0x45, 0x6a, 0x49, 0x69, 0x59, 0x6e, 0x4c, 0x67, 0x45, 0x31, 0x4e, + 0x44, 0x59, 0x33, 0x4c, 0x67, 0x45, 0x6e, 0x4c, 0x67, 0x45, 0x39, + 0x41, 0x54, 0x51, 0x32, 0x4e, 0x7a, 0x34, 0x42, 0x4e, 0x79, 0x34, + 0x42, 0x4e, 0x54, 0x51, 0x32, 0x4e, 0x7a, 0x34, 0x42, 0x4d, 0x7a, + 0x49, 0x57, 0x46, 0x7a, 0x49, 0x32, 0x4d, 0x7a, 0x49, 0x57, 0x4d, + 0x7a, 0x34, 0x42, 0x50, 0x77, 0x45, 0x79, 0x46, 0x68, 0x63, 0x65, + 0x41, 0x52, 0x55, 0x55, 0x42, 0x67, 0x63, 0x65, 0x41, 0x52, 0x63, + 0x65, 0x41, 0x52, 0x55, 0x43, 0x41, 0x46, 0x59, 0x38, 0x50, 0x56, + 0x5a, 0x57, 0x50, 0x54, 0x78, 0x57, 0x41, 0x62, 0x63, 0x72, 0x48, + 0x68, 0x34, 0x72, 0x4b, 0x78, 0x34, 0x65, 0x4b, 0x79, 0x73, 0x65, + 0x48, 0x69, 0x73, 0x72, 0x48, 0x68, 0x34, 0x72, 0x33, 0x41, 0x63, + 0x47, 0x57, 0x41, 0x51, 0x4a, 0x42, 0x67, 0x77, 0x61, 0x44, 0x67, + 0x49, 0x43, 0x41, 0x67, 0x49, 0x4a, 0x52, 0x77, 0x77, 0x45, 0x42, + 0x67, 0x4a, 0x43, 0x43, 0x78, 0x55, 0x4d, 0x41, 0x67, 0x55, 0x47, + 0x41, 0x67, 0x6b, 0x47, 0x61, 0x67, 0x59, 0x4c, 0x41, 0x51, 0x30, + 0x4c, 0x46, 0x51, 0x74, 0x44, 0x41, 0x67, 0x59, 0x44, 0x42, 0x41, + 0x59, 0x43, 0x44, 0x45, 0x63, 0x44, 0x41, 0x51, 0x30, 0x5a, 0x44, + 0x51, 0x59, 0x4c, 0x41, 0x31, 0x63, 0x47, 0x43, 0x41, 0x67, 0x46, + 0x57, 0x51, 0x4d, 0x4a, 0x42, 0x67, 0x77, 0x61, 0x44, 0x51, 0x49, + 0x43, 0x41, 0x51, 0x4d, 0x49, 0x52, 0x77, 0x30, 0x44, 0x42, 0x67, + 0x4e, 0x42, 0x43, 0x78, 0x59, 0x4c, 0x41, 0x67, 0x59, 0x46, 0x41, + 0x67, 0x6f, 0x47, 0x61, 0x67, 0x59, 0x4b, 0x41, 0x51, 0x30, 0x4c, + 0x46, 0x67, 0x70, 0x44, 0x41, 0x77, 0x59, 0x44, 0x41, 0x77, 0x59, + 0x44, 0x43, 0x30, 0x63, 0x43, 0x41, 0x67, 0x77, 0x61, 0x44, 0x41, + 0x59, 0x4b, 0x42, 0x46, 0x63, 0x47, 0x42, 0x77, 0x46, 0x75, 0x54, + 0x41, 0x6b, 0x44, 0x43, 0x51, 0x55, 0x45, 0x47, 0x51, 0x45, 0x42, + 0x42, 0x55, 0x41, 0x43, 0x42, 0x69, 0x34, 0x45, 0x42, 0x41, 0x6b, + 0x45, 0x42, 0x51, 0x67, 0x45, 0x42, 0x53, 0x34, 0x46, 0x41, 0x7a, + 0x38, 0x46, 0x41, 0x67, 0x45, 0x61, 0x42, 0x41, 0x59, 0x49, 0x42, + 0x41, 0x68, 0x4e, 0x54, 0x51, 0x67, 0x45, 0x43, 0x41, 0x59, 0x45, + 0x47, 0x67, 0x45, 0x43, 0x42, 0x54, 0x38, 0x44, 0x42, 0x53, 0x34, + 0x46, 0x42, 0x41, 0x67, 0x46, 0x42, 0x41, 0x6b, 0x45, 0x44, 0x42, + 0x6f, 0x4f, 0x42, 0x41, 0x4a, 0x41, 0x42, 0x51, 0x45, 0x42, 0x47, + 0x51, 0x51, 0x46, 0x43, 0x51, 0x4d, 0x4a, 0x54, 0x45, 0x77, 0x4a, + 0x41, 0x77, 0x6b, 0x46, 0x42, 0x42, 0x6b, 0x42, 0x41, 0x51, 0x56, + 0x41, 0x41, 0x67, 0x59, 0x75, 0x42, 0x41, 0x51, 0x4a, 0x42, 0x41, + 0x55, 0x49, 0x42, 0x41, 0x55, 0x75, 0x42, 0x51, 0x4d, 0x2f, 0x42, + 0x51, 0x49, 0x42, 0x47, 0x67, 0x51, 0x47, 0x43, 0x41, 0x51, 0x49, + 0x54, 0x55, 0x30, 0x49, 0x42, 0x41, 0x67, 0x47, 0x42, 0x42, 0x6f, + 0x42, 0x41, 0x67, 0x55, 0x2f, 0x41, 0x77, 0x55, 0x75, 0x42, 0x51, + 0x51, 0x49, 0x42, 0x51, 0x51, 0x4a, 0x42, 0x41, 0x77, 0x61, 0x44, + 0x67, 0x51, 0x43, 0x51, 0x41, 0x55, 0x42, 0x41, 0x52, 0x6b, 0x45, + 0x42, 0x51, 0x6b, 0x44, 0x43, 0x55, 0x77, 0x42, 0x74, 0x7a, 0x78, + 0x57, 0x56, 0x6a, 0x77, 0x39, 0x56, 0x56, 0x58, 0x6f, 0x48, 0x69, + 0x73, 0x72, 0x48, 0x68, 0x34, 0x72, 0x4b, 0x77, 0x4a, 0x6e, 0x48, + 0x69, 0x77, 0x73, 0x48, 0x68, 0x34, 0x72, 0x4b, 0x39, 0x4a, 0x71, + 0x42, 0x51, 0x73, 0x42, 0x44, 0x67, 0x73, 0x56, 0x43, 0x78, 0x45, + 0x68, 0x45, 0x41, 0x49, 0x47, 0x41, 0x77, 0x4d, 0x47, 0x41, 0x67, + 0x78, 0x4a, 0x41, 0x67, 0x49, 0x7a, 0x42, 0x51, 0x6b, 0x45, 0x46, + 0x53, 0x34, 0x56, 0x42, 0x67, 0x67, 0x49, 0x42, 0x6c, 0x67, 0x44, + 0x43, 0x51, 0x59, 0x7a, 0x41, 0x67, 0x49, 0x43, 0x41, 0x67, 0x74, + 0x45, 0x44, 0x51, 0x4d, 0x46, 0x41, 0x78, 0x41, 0x67, 0x45, 0x51, + 0x73, 0x59, 0x44, 0x41, 0x30, 0x42, 0x43, 0x67, 0x5a, 0x71, 0x42, + 0x51, 0x73, 0x42, 0x44, 0x51, 0x77, 0x56, 0x43, 0x78, 0x45, 0x67, + 0x45, 0x51, 0x49, 0x47, 0x41, 0x77, 0x4d, 0x47, 0x41, 0x67, 0x78, + 0x4a, 0x41, 0x67, 0x49, 0x7a, 0x42, 0x51, 0x6b, 0x45, 0x46, 0x53, + 0x34, 0x56, 0x42, 0x67, 0x67, 0x4a, 0x42, 0x6c, 0x63, 0x45, 0x43, + 0x51, 0x55, 0x7a, 0x41, 0x67, 0x49, 0x43, 0x41, 0x77, 0x70, 0x46, + 0x44, 0x41, 0x4d, 0x46, 0x41, 0x78, 0x45, 0x66, 0x45, 0x51, 0x77, + 0x58, 0x44, 0x41, 0x30, 0x42, 0x43, 0x67, 0x62, 0x2b, 0x7a, 0x31, + 0x41, 0x47, 0x43, 0x77, 0x6b, 0x4f, 0x42, 0x77, 0x6b, 0x2b, 0x43, + 0x41, 0x45, 0x43, 0x41, 0x51, 0x4d, 0x6d, 0x50, 0x41, 0x59, 0x42, + 0x41, 0x51, 0x59, 0x38, 0x4a, 0x67, 0x4d, 0x42, 0x41, 0x67, 0x45, + 0x48, 0x50, 0x77, 0x6b, 0x48, 0x44, 0x67, 0x6b, 0x4c, 0x42, 0x6c, + 0x41, 0x48, 0x43, 0x67, 0x45, 0x49, 0x44, 0x77, 0x63, 0x49, 0x50, + 0x77, 0x67, 0x44, 0x41, 0x51, 0x49, 0x6d, 0x4f, 0x77, 0x63, 0x42, + 0x41, 0x51, 0x45, 0x42, 0x45, 0x53, 0x45, 0x4f, 0x41, 0x69, 0x55, + 0x44, 0x41, 0x51, 0x4d, 0x49, 0x50, 0x77, 0x67, 0x48, 0x44, 0x77, + 0x67, 0x42, 0x43, 0x67, 0x63, 0x43, 0x53, 0x56, 0x41, 0x47, 0x43, + 0x67, 0x45, 0x49, 0x44, 0x77, 0x63, 0x4a, 0x50, 0x67, 0x67, 0x42, + 0x41, 0x67, 0x45, 0x44, 0x4a, 0x54, 0x73, 0x47, 0x41, 0x51, 0x45, + 0x47, 0x4f, 0x79, 0x55, 0x44, 0x41, 0x51, 0x49, 0x42, 0x42, 0x7a, + 0x38, 0x4a, 0x42, 0x77, 0x38, 0x49, 0x41, 0x51, 0x6f, 0x47, 0x55, + 0x41, 0x63, 0x4b, 0x41, 0x51, 0x67, 0x50, 0x42, 0x77, 0x67, 0x2f, + 0x43, 0x41, 0x45, 0x43, 0x41, 0x51, 0x49, 0x6d, 0x4f, 0x77, 0x59, + 0x42, 0x41, 0x52, 0x41, 0x68, 0x44, 0x77, 0x45, 0x6c, 0x41, 0x77, + 0x45, 0x43, 0x41, 0x51, 0x67, 0x2f, 0x43, 0x41, 0x63, 0x50, 0x43, + 0x41, 0x45, 0x4b, 0x42, 0x77, 0x41, 0x41, 0x41, 0x67, 0x41, 0x41, + 0x41, 0x45, 0x6b, 0x45, 0x41, 0x41, 0x4f, 0x33, 0x41, 0x43, 0x67, + 0x41, 0x53, 0x77, 0x41, 0x41, 0x41, 0x52, 0x55, 0x55, 0x42, 0x69, + 0x4d, 0x68, 0x49, 0x69, 0x59, 0x31, 0x45, 0x54, 0x51, 0x32, 0x4d, + 0x79, 0x45, 0x79, 0x46, 0x68, 0x30, 0x42, 0x46, 0x41, 0x59, 0x6a, + 0x49, 0x53, 0x49, 0x47, 0x46, 0x52, 0x45, 0x55, 0x46, 0x6a, 0x4d, + 0x68, 0x4d, 0x6a, 0x59, 0x39, 0x41, 0x54, 0x51, 0x32, 0x4f, 0x77, + 0x45, 0x79, 0x46, 0x68, 0x55, 0x54, 0x45, 0x52, 0x51, 0x47, 0x49, + 0x79, 0x49, 0x6d, 0x4c, 0x77, 0x45, 0x42, 0x44, 0x67, 0x45, 0x6a, + 0x49, 0x69, 0x59, 0x76, 0x41, 0x53, 0x34, 0x42, 0x4e, 0x54, 0x51, + 0x32, 0x4e, 0x77, 0x45, 0x6e, 0x4c, 0x67, 0x45, 0x31, 0x4e, 0x44, + 0x59, 0x7a, 0x49, 0x54, 0x49, 0x57, 0x46, 0x51, 0x4d, 0x6c, 0x59, + 0x55, 0x54, 0x2b, 0x4a, 0x55, 0x56, 0x67, 0x59, 0x45, 0x55, 0x42, + 0x6b, 0x67, 0x67, 0x4b, 0x43, 0x67, 0x6a, 0x2b, 0x62, 0x69, 0x59, + 0x32, 0x4e, 0x69, 0x59, 0x42, 0x32, 0x79, 0x59, 0x31, 0x43, 0x77, + 0x67, 0x6b, 0x43, 0x41, 0x76, 0x62, 0x46, 0x67, 0x38, 0x48, 0x44, + 0x51, 0x56, 0x6c, 0x2f, 0x6f, 0x77, 0x44, 0x42, 0x77, 0x51, 0x44, + 0x42, 0x77, 0x4e, 0x42, 0x41, 0x67, 0x51, 0x45, 0x41, 0x67, 0x46, + 0x31, 0x5a, 0x51, 0x55, 0x47, 0x46, 0x67, 0x38, 0x42, 0x4a, 0x41, + 0x38, 0x57, 0x41, 0x61, 0x57, 0x33, 0x52, 0x47, 0x46, 0x68, 0x52, + 0x41, 0x48, 0x62, 0x52, 0x47, 0x45, 0x4c, 0x43, 0x43, 0x51, 0x49, + 0x43, 0x6a, 0x59, 0x6d, 0x2f, 0x69, 0x55, 0x6d, 0x4e, 0x6a, 0x59, + 0x6d, 0x74, 0x77, 0x63, 0x4c, 0x43, 0x77, 0x63, 0x42, 0x37, 0x66, + 0x37, 0x63, 0x44, 0x78, 0x59, 0x47, 0x42, 0x57, 0x58, 0x2b, 0x69, + 0x77, 0x4d, 0x44, 0x41, 0x77, 0x4e, 0x42, 0x41, 0x77, 0x63, 0x44, + 0x42, 0x41, 0x63, 0x43, 0x41, 0x58, 0x56, 0x6c, 0x42, 0x51, 0x30, + 0x48, 0x44, 0x78, 0x59, 0x57, 0x44, 0x77, 0x41, 0x41, 0x41, 0x67, + 0x41, 0x41, 0x41, 0x45, 0x6b, 0x44, 0x4a, 0x51, 0x4e, 0x75, 0x41, + 0x41, 0x38, 0x41, 0x48, 0x77, 0x41, 0x41, 0x41, 0x53, 0x45, 0x69, + 0x42, 0x68, 0x55, 0x52, 0x46, 0x42, 0x59, 0x7a, 0x49, 0x54, 0x49, + 0x32, 0x4e, 0x52, 0x45, 0x30, 0x4a, 0x68, 0x63, 0x52, 0x46, 0x41, + 0x59, 0x6a, 0x49, 0x53, 0x49, 0x6d, 0x4e, 0x52, 0x45, 0x30, 0x4e, + 0x6a, 0x4d, 0x68, 0x4d, 0x68, 0x59, 0x43, 0x67, 0x50, 0x34, 0x6c, + 0x4a, 0x6a, 0x59, 0x32, 0x4a, 0x67, 0x48, 0x62, 0x4a, 0x6a, 0x55, + 0x31, 0x66, 0x32, 0x46, 0x45, 0x2f, 0x69, 0x56, 0x46, 0x59, 0x47, + 0x42, 0x46, 0x41, 0x64, 0x74, 0x45, 0x59, 0x51, 0x4d, 0x6c, 0x4e, + 0x69, 0x62, 0x2b, 0x4a, 0x53, 0x59, 0x32, 0x4e, 0x69, 0x59, 0x42, + 0x32, 0x79, 0x59, 0x32, 0x58, 0x50, 0x34, 0x6c, 0x52, 0x47, 0x46, + 0x68, 0x52, 0x41, 0x48, 0x62, 0x52, 0x47, 0x46, 0x68, 0x41, 0x41, + 0x4d, 0x41, 0x4a, 0x66, 0x2b, 0x33, 0x41, 0x39, 0x73, 0x44, 0x74, + 0x77, 0x41, 0x53, 0x41, 0x44, 0x41, 0x41, 0x5a, 0x77, 0x41, 0x41, + 0x42, 0x54, 0x51, 0x6d, 0x49, 0x79, 0x49, 0x6d, 0x4e, 0x54, 0x51, + 0x6d, 0x49, 0x79, 0x49, 0x47, 0x46, 0x52, 0x51, 0x57, 0x4d, 0x7a, + 0x49, 0x32, 0x4e, 0x53, 0x55, 0x68, 0x4a, 0x69, 0x63, 0x75, 0x41, + 0x53, 0x63, 0x6d, 0x4e, 0x54, 0x51, 0x6e, 0x4c, 0x67, 0x45, 0x6e, + 0x4a, 0x69, 0x4d, 0x69, 0x42, 0x77, 0x34, 0x42, 0x42, 0x77, 0x59, + 0x56, 0x46, 0x41, 0x63, 0x4f, 0x41, 0x51, 0x63, 0x47, 0x42, 0x79, + 0x45, 0x55, 0x42, 0x69, 0x4d, 0x68, 0x46, 0x41, 0x59, 0x6a, 0x49, + 0x69, 0x59, 0x31, 0x49, 0x53, 0x49, 0x6d, 0x4e, 0x54, 0x59, 0x33, + 0x50, 0x67, 0x45, 0x33, 0x4e, 0x6a, 0x55, 0x30, 0x4e, 0x7a, 0x34, + 0x42, 0x4e, 0x7a, 0x59, 0x33, 0x4c, 0x67, 0x45, 0x31, 0x4e, 0x44, + 0x59, 0x7a, 0x4d, 0x68, 0x59, 0x56, 0x46, 0x41, 0x59, 0x48, 0x46, + 0x68, 0x63, 0x65, 0x41, 0x52, 0x63, 0x57, 0x46, 0x52, 0x51, 0x58, + 0x48, 0x67, 0x45, 0x58, 0x46, 0x68, 0x63, 0x43, 0x43, 0x51, 0x55, + 0x45, 0x49, 0x6a, 0x41, 0x47, 0x41, 0x77, 0x51, 0x47, 0x4f, 0x79, + 0x6f, 0x45, 0x42, 0x66, 0x36, 0x45, 0x41, 0x75, 0x59, 0x6d, 0x48, + 0x42, 0x30, 0x6d, 0x43, 0x51, 0x6f, 0x4e, 0x44, 0x54, 0x59, 0x71, + 0x4b, 0x54, 0x67, 0x34, 0x4b, 0x53, 0x6f, 0x32, 0x44, 0x51, 0x30, + 0x4b, 0x43, 0x53, 0x59, 0x64, 0x48, 0x43, 0x59, 0x44, 0x54, 0x69, + 0x73, 0x65, 0x2f, 0x77, 0x42, 0x57, 0x50, 0x44, 0x78, 0x57, 0x2f, + 0x77, 0x41, 0x65, 0x4b, 0x78, 0x38, 0x68, 0x49, 0x44, 0x55, 0x52, + 0x45, 0x42, 0x45, 0x52, 0x50, 0x69, 0x30, 0x74, 0x4f, 0x51, 0x49, + 0x44, 0x49, 0x42, 0x63, 0x58, 0x49, 0x41, 0x4d, 0x43, 0x4f, 0x53, + 0x30, 0x74, 0x50, 0x68, 0x45, 0x52, 0x45, 0x42, 0x45, 0x31, 0x49, + 0x43, 0x45, 0x66, 0x45, 0x67, 0x51, 0x46, 0x4d, 0x43, 0x49, 0x45, + 0x42, 0x51, 0x55, 0x45, 0x4b, 0x54, 0x73, 0x46, 0x42, 0x4b, 0x51, + 0x73, 0x4d, 0x7a, 0x4e, 0x32, 0x52, 0x45, 0x4e, 0x4e, 0x47, 0x79, + 0x41, 0x67, 0x4e, 0x78, 0x49, 0x54, 0x45, 0x78, 0x49, 0x33, 0x49, + 0x43, 0x41, 0x62, 0x54, 0x55, 0x4e, 0x45, 0x64, 0x6a, 0x4d, 0x7a, + 0x4c, 0x42, 0x34, 0x72, 0x50, 0x46, 0x5a, 0x57, 0x50, 0x43, 0x73, + 0x65, 0x47, 0x79, 0x63, 0x6e, 0x63, 0x55, 0x31, 0x4e, 0x61, 0x43, + 0x6b, 0x70, 0x4b, 0x6b, 0x55, 0x5a, 0x47, 0x51, 0x6b, 0x46, 0x43, + 0x77, 0x59, 0x58, 0x49, 0x43, 0x41, 0x58, 0x42, 0x67, 0x73, 0x46, + 0x43, 0x52, 0x6b, 0x5a, 0x52, 0x53, 0x6f, 0x70, 0x4b, 0x57, 0x68, + 0x4e, 0x54, 0x58, 0x45, 0x6e, 0x4a, 0x78, 0x73, 0x41, 0x42, 0x67, + 0x41, 0x41, 0x2f, 0x37, 0x63, 0x45, 0x53, 0x51, 0x4f, 0x33, 0x41, + 0x42, 0x6f, 0x41, 0x4e, 0x67, 0x42, 0x43, 0x41, 0x46, 0x34, 0x41, + 0x65, 0x41, 0x43, 0x45, 0x41, 0x41, 0x41, 0x42, 0x44, 0x67, 0x45, + 0x48, 0x49, 0x79, 0x49, 0x6d, 0x4e, 0x54, 0x51, 0x33, 0x50, 0x67, + 0x45, 0x33, 0x4e, 0x6a, 0x4d, 0x79, 0x46, 0x6a, 0x4d, 0x79, 0x4e, + 0x6a, 0x63, 0x4f, 0x41, 0x52, 0x55, 0x55, 0x46, 0x68, 0x63, 0x42, + 0x46, 0x41, 0x59, 0x6a, 0x49, 0x53, 0x49, 0x6d, 0x4e, 0x54, 0x51, + 0x33, 0x50, 0x67, 0x45, 0x33, 0x4e, 0x6a, 0x4d, 0x79, 0x46, 0x6a, + 0x4d, 0x79, 0x4e, 0x6a, 0x4d, 0x79, 0x46, 0x78, 0x34, 0x42, 0x46, + 0x78, 0x59, 0x56, 0x41, 0x52, 0x51, 0x47, 0x49, 0x79, 0x49, 0x6d, + 0x4e, 0x54, 0x51, 0x32, 0x4d, 0x7a, 0x49, 0x57, 0x41, 0x52, 0x51, + 0x48, 0x44, 0x67, 0x45, 0x48, 0x42, 0x69, 0x4d, 0x69, 0x4a, 0x79, + 0x34, 0x42, 0x4a, 0x79, 0x59, 0x31, 0x4e, 0x44, 0x63, 0x2b, 0x41, + 0x54, 0x63, 0x32, 0x4d, 0x7a, 0x49, 0x58, 0x48, 0x67, 0x45, 0x58, + 0x46, 0x67, 0x55, 0x55, 0x42, 0x69, 0x73, 0x42, 0x4c, 0x67, 0x45, + 0x6e, 0x50, 0x67, 0x45, 0x31, 0x4e, 0x43, 0x59, 0x6e, 0x48, 0x67, + 0x45, 0x7a, 0x4d, 0x6a, 0x59, 0x7a, 0x4d, 0x68, 0x63, 0x65, 0x41, + 0x52, 0x63, 0x57, 0x41, 0x78, 0x51, 0x47, 0x49, 0x79, 0x49, 0x6d, + 0x4e, 0x54, 0x51, 0x32, 0x4d, 0x7a, 0x49, 0x57, 0x41, 0x56, 0x4d, + 0x74, 0x54, 0x68, 0x31, 0x4d, 0x4b, 0x30, 0x51, 0x42, 0x41, 0x51, + 0x30, 0x4f, 0x44, 0x78, 0x73, 0x4a, 0x55, 0x6a, 0x6b, 0x55, 0x4a, + 0x68, 0x49, 0x42, 0x41, 0x52, 0x67, 0x57, 0x41, 0x6d, 0x52, 0x55, + 0x52, 0x66, 0x34, 0x4e, 0x52, 0x56, 0x51, 0x49, 0x42, 0x79, 0x73, + 0x6d, 0x4a, 0x7a, 0x38, 0x50, 0x61, 0x46, 0x5a, 0x56, 0x61, 0x51, + 0x34, 0x2f, 0x4a, 0x79, 0x59, 0x72, 0x43, 0x41, 0x66, 0x39, 0x74, + 0x31, 0x59, 0x39, 0x50, 0x46, 0x5a, 0x57, 0x50, 0x44, 0x31, 0x57, + 0x41, 0x5a, 0x49, 0x52, 0x45, 0x6a, 0x73, 0x6f, 0x4b, 0x43, 0x30, + 0x75, 0x4b, 0x43, 0x67, 0x37, 0x45, 0x68, 0x45, 0x52, 0x45, 0x6a, + 0x73, 0x6f, 0x4b, 0x43, 0x34, 0x74, 0x4b, 0x43, 0x67, 0x37, 0x45, + 0x68, 0x45, 0x42, 0x53, 0x55, 0x51, 0x72, 0x54, 0x42, 0x31, 0x4f, + 0x4c, 0x52, 0x63, 0x59, 0x41, 0x67, 0x45, 0x53, 0x4a, 0x68, 0x51, + 0x36, 0x55, 0x51, 0x6b, 0x63, 0x44, 0x67, 0x34, 0x4e, 0x41, 0x51, + 0x46, 0x4a, 0x56, 0x6a, 0x77, 0x39, 0x56, 0x6c, 0x59, 0x39, 0x50, + 0x46, 0x59, 0x42, 0x74, 0x77, 0x45, 0x6d, 0x49, 0x69, 0x73, 0x77, + 0x45, 0x53, 0x49, 0x68, 0x51, 0x78, 0x6b, 0x5a, 0x4d, 0x41, 0x59, + 0x48, 0x43, 0x68, 0x49, 0x4b, 0x4a, 0x30, 0x73, 0x67, 0x2f, 0x70, + 0x52, 0x47, 0x54, 0x6b, 0x35, 0x47, 0x4d, 0x44, 0x6f, 0x35, 0x59, + 0x69, 0x45, 0x68, 0x54, 0x30, 0x38, 0x68, 0x49, 0x57, 0x49, 0x35, + 0x4f, 0x6a, 0x41, 0x43, 0x32, 0x6a, 0x31, 0x57, 0x56, 0x6a, 0x30, + 0x38, 0x56, 0x6c, 0x62, 0x2b, 0x36, 0x43, 0x30, 0x6f, 0x4b, 0x44, + 0x77, 0x52, 0x45, 0x52, 0x45, 0x52, 0x50, 0x43, 0x67, 0x6f, 0x4c, + 0x53, 0x34, 0x6f, 0x4b, 0x44, 0x73, 0x52, 0x45, 0x68, 0x49, 0x52, + 0x4f, 0x79, 0x67, 0x6f, 0x72, 0x6a, 0x41, 0x72, 0x49, 0x69, 0x59, + 0x42, 0x49, 0x45, 0x73, 0x6e, 0x43, 0x68, 0x49, 0x4b, 0x42, 0x77, + 0x59, 0x77, 0x47, 0x52, 0x6c, 0x44, 0x49, 0x53, 0x49, 0x42, 0x53, + 0x7a, 0x31, 0x57, 0x56, 0x6a, 0x30, 0x38, 0x56, 0x6c, 0x59, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x77, 0x41, 0x41, 0x41, 0x45, 0x6b, + 0x44, 0x62, 0x67, 0x4d, 0x6c, 0x41, 0x41, 0x38, 0x41, 0x48, 0x77, + 0x41, 0x76, 0x41, 0x41, 0x41, 0x6c, 0x46, 0x52, 0x51, 0x47, 0x49, + 0x79, 0x45, 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, 0x7a, + 0x49, 0x54, 0x49, 0x57, 0x45, 0x52, 0x55, 0x55, 0x42, 0x69, 0x4d, + 0x68, 0x49, 0x69, 0x59, 0x39, 0x41, 0x54, 0x51, 0x32, 0x4d, 0x79, + 0x45, 0x79, 0x46, 0x68, 0x45, 0x56, 0x46, 0x41, 0x59, 0x6a, 0x49, + 0x53, 0x49, 0x6d, 0x50, 0x51, 0x45, 0x30, 0x4e, 0x6a, 0x4d, 0x68, + 0x4d, 0x68, 0x59, 0x44, 0x62, 0x68, 0x59, 0x50, 0x2f, 0x4e, 0x77, + 0x50, 0x46, 0x68, 0x59, 0x50, 0x41, 0x79, 0x51, 0x50, 0x46, 0x68, + 0x59, 0x50, 0x2f, 0x4e, 0x77, 0x50, 0x46, 0x68, 0x59, 0x50, 0x41, + 0x79, 0x51, 0x50, 0x46, 0x68, 0x59, 0x50, 0x2f, 0x4e, 0x77, 0x50, + 0x46, 0x68, 0x59, 0x50, 0x41, 0x79, 0x51, 0x50, 0x46, 0x72, 0x64, + 0x4a, 0x44, 0x78, 0x59, 0x57, 0x44, 0x30, 0x6b, 0x50, 0x46, 0x52, + 0x55, 0x42, 0x46, 0x55, 0x6b, 0x50, 0x46, 0x52, 0x55, 0x50, 0x53, + 0x51, 0x38, 0x57, 0x46, 0x67, 0x45, 0x57, 0x53, 0x51, 0x38, 0x57, + 0x46, 0x67, 0x39, 0x4a, 0x44, 0x78, 0x59, 0x57, 0x41, 0x41, 0x6f, + 0x41, 0x41, 0x41, 0x42, 0x4a, 0x41, 0x37, 0x63, 0x44, 0x62, 0x67, + 0x41, 0x51, 0x41, 0x43, 0x41, 0x41, 0x4d, 0x51, 0x42, 0x42, 0x41, + 0x46, 0x45, 0x41, 0x59, 0x67, 0x42, 0x79, 0x41, 0x49, 0x4d, 0x41, + 0x6c, 0x41, 0x43, 0x6b, 0x41, 0x41, 0x41, 0x6c, 0x4e, 0x54, 0x51, + 0x6d, 0x4b, 0x77, 0x45, 0x69, 0x42, 0x68, 0x30, 0x42, 0x46, 0x42, + 0x59, 0x37, 0x41, 0x54, 0x49, 0x32, 0x4e, 0x54, 0x30, 0x42, 0x4e, + 0x43, 0x59, 0x72, 0x41, 0x53, 0x49, 0x47, 0x48, 0x51, 0x45, 0x55, + 0x46, 0x6a, 0x73, 0x42, 0x4d, 0x6a, 0x59, 0x46, 0x4e, 0x54, 0x51, + 0x6d, 0x4b, 0x77, 0x45, 0x69, 0x42, 0x68, 0x30, 0x42, 0x46, 0x42, + 0x59, 0x37, 0x41, 0x54, 0x49, 0x32, 0x4e, 0x51, 0x45, 0x31, 0x4e, + 0x43, 0x59, 0x72, 0x41, 0x53, 0x49, 0x47, 0x48, 0x51, 0x45, 0x55, + 0x46, 0x6a, 0x73, 0x42, 0x4d, 0x6a, 0x59, 0x46, 0x4e, 0x54, 0x51, + 0x6d, 0x4b, 0x77, 0x45, 0x69, 0x42, 0x68, 0x30, 0x42, 0x46, 0x42, + 0x59, 0x37, 0x41, 0x54, 0x49, 0x32, 0x42, 0x54, 0x55, 0x30, 0x4a, + 0x69, 0x73, 0x42, 0x49, 0x67, 0x59, 0x64, 0x41, 0x52, 0x51, 0x57, + 0x4f, 0x77, 0x45, 0x79, 0x4e, 0x6a, 0x55, 0x42, 0x4e, 0x54, 0x51, + 0x6d, 0x4b, 0x77, 0x45, 0x69, 0x42, 0x68, 0x30, 0x42, 0x46, 0x42, + 0x59, 0x37, 0x41, 0x54, 0x49, 0x32, 0x42, 0x54, 0x55, 0x30, 0x4a, + 0x69, 0x73, 0x42, 0x49, 0x67, 0x59, 0x64, 0x41, 0x52, 0x51, 0x57, + 0x4f, 0x77, 0x45, 0x79, 0x4e, 0x6a, 0x55, 0x39, 0x41, 0x54, 0x51, + 0x6d, 0x4b, 0x77, 0x45, 0x69, 0x42, 0x68, 0x30, 0x42, 0x46, 0x42, + 0x59, 0x37, 0x41, 0x54, 0x49, 0x32, 0x4e, 0x54, 0x63, 0x52, 0x46, + 0x41, 0x59, 0x6a, 0x49, 0x53, 0x49, 0x6d, 0x4e, 0x52, 0x45, 0x30, + 0x4e, 0x6a, 0x4d, 0x68, 0x4d, 0x68, 0x59, 0x42, 0x4a, 0x51, 0x73, + 0x49, 0x74, 0x77, 0x63, 0x4c, 0x43, 0x77, 0x65, 0x33, 0x43, 0x41, + 0x73, 0x4c, 0x43, 0x4c, 0x63, 0x48, 0x43, 0x77, 0x73, 0x48, 0x74, + 0x77, 0x67, 0x4c, 0x41, 0x53, 0x51, 0x4b, 0x43, 0x4c, 0x63, 0x49, + 0x43, 0x67, 0x6f, 0x49, 0x74, 0x77, 0x67, 0x4b, 0x2f, 0x74, 0x77, + 0x4c, 0x43, 0x4c, 0x63, 0x48, 0x43, 0x77, 0x73, 0x48, 0x74, 0x77, + 0x67, 0x4c, 0x41, 0x53, 0x51, 0x4b, 0x43, 0x4c, 0x63, 0x49, 0x43, + 0x67, 0x6f, 0x49, 0x74, 0x77, 0x67, 0x4b, 0x41, 0x53, 0x55, 0x4c, + 0x43, 0x4c, 0x59, 0x49, 0x43, 0x77, 0x73, 0x49, 0x74, 0x67, 0x67, + 0x4c, 0x2f, 0x74, 0x73, 0x4b, 0x43, 0x4c, 0x63, 0x49, 0x43, 0x67, + 0x6f, 0x49, 0x74, 0x77, 0x67, 0x4b, 0x41, 0x53, 0x55, 0x4c, 0x43, + 0x4c, 0x59, 0x49, 0x43, 0x77, 0x73, 0x49, 0x74, 0x67, 0x67, 0x4c, + 0x43, 0x77, 0x69, 0x32, 0x43, 0x41, 0x73, 0x4c, 0x43, 0x4c, 0x59, + 0x49, 0x43, 0x30, 0x6b, 0x32, 0x4a, 0x76, 0x30, 0x41, 0x4a, 0x54, + 0x59, 0x32, 0x4a, 0x51, 0x4d, 0x41, 0x4a, 0x6a, 0x61, 0x6c, 0x62, + 0x51, 0x67, 0x4c, 0x43, 0x77, 0x68, 0x74, 0x43, 0x41, 0x73, 0x4c, + 0x43, 0x4e, 0x74, 0x75, 0x42, 0x77, 0x73, 0x4c, 0x42, 0x32, 0x34, + 0x49, 0x43, 0x67, 0x72, 0x54, 0x62, 0x51, 0x67, 0x4c, 0x43, 0x77, + 0x68, 0x74, 0x43, 0x41, 0x73, 0x4c, 0x43, 0x41, 0x47, 0x32, 0x62, + 0x67, 0x67, 0x4b, 0x43, 0x67, 0x68, 0x75, 0x42, 0x77, 0x73, 0x4c, + 0x31, 0x47, 0x34, 0x48, 0x43, 0x77, 0x73, 0x48, 0x62, 0x67, 0x67, + 0x4b, 0x43, 0x74, 0x4e, 0x74, 0x43, 0x41, 0x73, 0x4c, 0x43, 0x47, + 0x30, 0x49, 0x43, 0x77, 0x73, 0x49, 0x41, 0x62, 0x5a, 0x75, 0x43, + 0x41, 0x6f, 0x4b, 0x43, 0x47, 0x34, 0x48, 0x43, 0x77, 0x76, 0x55, + 0x62, 0x67, 0x63, 0x4c, 0x43, 0x77, 0x64, 0x75, 0x43, 0x41, 0x6f, + 0x4b, 0x43, 0x4e, 0x74, 0x75, 0x43, 0x41, 0x6f, 0x4b, 0x43, 0x47, + 0x34, 0x48, 0x43, 0x77, 0x73, 0x48, 0x74, 0x2f, 0x32, 0x54, 0x4a, + 0x6a, 0x59, 0x32, 0x4a, 0x67, 0x4a, 0x74, 0x4a, 0x6a, 0x59, 0x32, + 0x41, 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, 0x42, 0x41, 0x41, 0x4a, + 0x4a, 0x41, 0x6b, 0x6b, 0x41, 0x46, 0x51, 0x41, 0x41, 0x41, 0x52, + 0x51, 0x47, 0x42, 0x77, 0x45, 0x4f, 0x41, 0x53, 0x4d, 0x69, 0x4a, + 0x69, 0x63, 0x42, 0x4c, 0x67, 0x45, 0x31, 0x4e, 0x44, 0x59, 0x7a, + 0x49, 0x54, 0x49, 0x57, 0x46, 0x51, 0x4a, 0x4a, 0x42, 0x67, 0x58, + 0x2f, 0x41, 0x41, 0x55, 0x4e, 0x42, 0x77, 0x67, 0x4e, 0x42, 0x66, + 0x38, 0x41, 0x42, 0x51, 0x59, 0x57, 0x44, 0x77, 0x49, 0x41, 0x44, + 0x78, 0x55, 0x43, 0x4a, 0x51, 0x67, 0x4e, 0x42, 0x66, 0x38, 0x41, + 0x42, 0x51, 0x59, 0x47, 0x42, 0x51, 0x45, 0x41, 0x42, 0x51, 0x30, + 0x49, 0x44, 0x78, 0x55, 0x56, 0x44, 0x77, 0x41, 0x41, 0x41, 0x41, + 0x45, 0x41, 0x41, 0x41, 0x44, 0x62, 0x41, 0x6b, 0x6b, 0x43, 0x4a, + 0x51, 0x41, 0x55, 0x41, 0x41, 0x41, 0x42, 0x46, 0x41, 0x59, 0x6a, + 0x49, 0x53, 0x49, 0x6d, 0x4e, 0x54, 0x51, 0x32, 0x4e, 0x77, 0x45, + 0x2b, 0x41, 0x54, 0x4d, 0x79, 0x46, 0x68, 0x63, 0x42, 0x48, 0x67, + 0x45, 0x43, 0x53, 0x52, 0x55, 0x50, 0x2f, 0x67, 0x41, 0x50, 0x46, + 0x67, 0x59, 0x46, 0x41, 0x51, 0x41, 0x46, 0x44, 0x51, 0x67, 0x48, + 0x44, 0x51, 0x55, 0x42, 0x41, 0x41, 0x55, 0x47, 0x41, 0x51, 0x41, + 0x50, 0x46, 0x68, 0x59, 0x50, 0x42, 0x77, 0x34, 0x46, 0x41, 0x51, + 0x41, 0x46, 0x42, 0x67, 0x59, 0x46, 0x2f, 0x77, 0x41, 0x46, 0x44, + 0x67, 0x41, 0x42, 0x41, 0x43, 0x55, 0x41, 0x6b, 0x67, 0x46, 0x75, + 0x41, 0x74, 0x73, 0x41, 0x46, 0x51, 0x41, 0x41, 0x41, 0x52, 0x45, + 0x55, 0x42, 0x69, 0x4d, 0x69, 0x4a, 0x69, 0x63, 0x42, 0x4c, 0x67, + 0x45, 0x31, 0x4e, 0x44, 0x59, 0x33, 0x41, 0x54, 0x34, 0x42, 0x4d, + 0x7a, 0x49, 0x57, 0x46, 0x51, 0x46, 0x75, 0x46, 0x67, 0x38, 0x48, + 0x44, 0x51, 0x62, 0x2f, 0x41, 0x41, 0x55, 0x46, 0x42, 0x51, 0x55, + 0x42, 0x41, 0x41, 0x59, 0x4e, 0x42, 0x77, 0x38, 0x57, 0x41, 0x72, + 0x66, 0x2b, 0x41, 0x41, 0x38, 0x57, 0x42, 0x67, 0x55, 0x42, 0x41, + 0x41, 0x55, 0x4f, 0x42, 0x77, 0x63, 0x4e, 0x42, 0x67, 0x45, 0x41, + 0x42, 0x51, 0x55, 0x56, 0x44, 0x77, 0x41, 0x41, 0x41, 0x41, 0x45, + 0x41, 0x41, 0x41, 0x43, 0x53, 0x41, 0x55, 0x6b, 0x43, 0x32, 0x77, + 0x41, 0x56, 0x41, 0x41, 0x41, 0x42, 0x46, 0x41, 0x59, 0x48, 0x41, + 0x51, 0x34, 0x42, 0x49, 0x79, 0x49, 0x6d, 0x4e, 0x52, 0x45, 0x30, + 0x4e, 0x6a, 0x4d, 0x79, 0x46, 0x68, 0x63, 0x42, 0x48, 0x67, 0x45, + 0x56, 0x41, 0x55, 0x6b, 0x47, 0x42, 0x66, 0x38, 0x41, 0x42, 0x51, + 0x30, 0x48, 0x44, 0x78, 0x59, 0x57, 0x44, 0x77, 0x63, 0x4e, 0x42, + 0x51, 0x45, 0x41, 0x42, 0x51, 0x59, 0x42, 0x74, 0x77, 0x63, 0x4f, + 0x42, 0x66, 0x38, 0x41, 0x42, 0x51, 0x59, 0x57, 0x44, 0x77, 0x49, + 0x41, 0x44, 0x78, 0x55, 0x46, 0x42, 0x66, 0x38, 0x41, 0x42, 0x67, + 0x30, 0x48, 0x41, 0x41, 0x41, 0x41, 0x41, 0x67, 0x41, 0x41, 0x41, + 0x43, 0x55, 0x43, 0x53, 0x51, 0x4e, 0x4a, 0x41, 0x42, 0x55, 0x41, + 0x4b, 0x77, 0x41, 0x41, 0x41, 0x52, 0x51, 0x47, 0x42, 0x77, 0x45, + 0x4f, 0x41, 0x53, 0x4d, 0x69, 0x4a, 0x69, 0x63, 0x42, 0x4c, 0x67, + 0x45, 0x31, 0x4e, 0x44, 0x59, 0x7a, 0x49, 0x54, 0x49, 0x57, 0x46, + 0x54, 0x55, 0x55, 0x42, 0x69, 0x4d, 0x68, 0x49, 0x69, 0x59, 0x31, + 0x4e, 0x44, 0x59, 0x33, 0x41, 0x54, 0x34, 0x42, 0x4d, 0x7a, 0x49, + 0x57, 0x46, 0x77, 0x45, 0x65, 0x41, 0x52, 0x55, 0x43, 0x53, 0x51, + 0x59, 0x46, 0x2f, 0x77, 0x41, 0x46, 0x44, 0x51, 0x63, 0x49, 0x44, + 0x51, 0x58, 0x2f, 0x41, 0x41, 0x55, 0x47, 0x46, 0x67, 0x38, 0x43, + 0x41, 0x41, 0x38, 0x56, 0x46, 0x51, 0x2f, 0x2b, 0x41, 0x41, 0x38, + 0x57, 0x42, 0x67, 0x55, 0x42, 0x41, 0x41, 0x55, 0x4e, 0x43, 0x41, + 0x63, 0x4e, 0x42, 0x51, 0x45, 0x41, 0x42, 0x51, 0x59, 0x42, 0x53, + 0x51, 0x63, 0x4e, 0x42, 0x76, 0x38, 0x41, 0x42, 0x51, 0x55, 0x46, + 0x42, 0x51, 0x45, 0x41, 0x42, 0x67, 0x30, 0x48, 0x44, 0x78, 0x59, + 0x57, 0x44, 0x39, 0x77, 0x50, 0x46, 0x68, 0x59, 0x50, 0x42, 0x77, + 0x30, 0x46, 0x41, 0x51, 0x41, 0x46, 0x42, 0x67, 0x59, 0x46, 0x2f, + 0x77, 0x41, 0x46, 0x44, 0x51, 0x63, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x42, 0x77, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x4d, + 0x6c, 0x41, 0x41, 0x73, 0x41, 0x46, 0x77, 0x41, 0x74, 0x41, 0x44, + 0x6b, 0x41, 0x52, 0x51, 0x42, 0x52, 0x41, 0x47, 0x30, 0x41, 0x41, + 0x42, 0x4d, 0x30, 0x4a, 0x69, 0x4d, 0x69, 0x42, 0x68, 0x55, 0x55, + 0x46, 0x6a, 0x4d, 0x79, 0x4e, 0x68, 0x4d, 0x30, 0x4a, 0x69, 0x4d, + 0x69, 0x42, 0x68, 0x55, 0x55, 0x46, 0x6a, 0x4d, 0x79, 0x4e, 0x68, + 0x63, 0x33, 0x4e, 0x69, 0x59, 0x6e, 0x4d, 0x53, 0x59, 0x47, 0x44, + 0x77, 0x45, 0x4f, 0x41, 0x51, 0x63, 0x47, 0x46, 0x68, 0x63, 0x57, + 0x4e, 0x6a, 0x63, 0x32, 0x4a, 0x69, 0x63, 0x6c, 0x4e, 0x43, 0x59, + 0x6a, 0x49, 0x67, 0x59, 0x56, 0x46, 0x42, 0x59, 0x7a, 0x4d, 0x6a, + 0x59, 0x42, 0x4e, 0x43, 0x59, 0x6a, 0x49, 0x67, 0x59, 0x56, 0x46, + 0x42, 0x59, 0x7a, 0x4d, 0x6a, 0x59, 0x46, 0x4e, 0x43, 0x59, 0x6a, + 0x49, 0x67, 0x59, 0x56, 0x46, 0x42, 0x59, 0x7a, 0x4d, 0x6a, 0x59, + 0x58, 0x46, 0x41, 0x59, 0x48, 0x44, 0x67, 0x45, 0x6a, 0x49, 0x53, + 0x49, 0x6d, 0x4a, 0x79, 0x34, 0x42, 0x4e, 0x54, 0x51, 0x33, 0x50, + 0x67, 0x45, 0x33, 0x4e, 0x6a, 0x4d, 0x79, 0x46, 0x78, 0x34, 0x42, + 0x46, 0x78, 0x59, 0x56, 0x32, 0x79, 0x6f, 0x66, 0x48, 0x69, 0x73, + 0x72, 0x48, 0x68, 0x38, 0x71, 0x62, 0x69, 0x73, 0x65, 0x48, 0x69, + 0x73, 0x72, 0x48, 0x68, 0x34, 0x72, 0x39, 0x54, 0x6b, 0x45, 0x44, + 0x77, 0x38, 0x4f, 0x47, 0x77, 0x4d, 0x36, 0x49, 0x6a, 0x59, 0x4a, + 0x44, 0x43, 0x34, 0x73, 0x4c, 0x45, 0x38, 0x4c, 0x43, 0x52, 0x6b, + 0x63, 0x41, 0x58, 0x6b, 0x72, 0x48, 0x68, 0x38, 0x71, 0x4b, 0x68, + 0x38, 0x65, 0x4b, 0x2f, 0x36, 0x53, 0x4b, 0x78, 0x34, 0x65, 0x4b, + 0x79, 0x73, 0x65, 0x48, 0x69, 0x73, 0x42, 0x41, 0x43, 0x73, 0x65, + 0x48, 0x69, 0x73, 0x72, 0x48, 0x68, 0x34, 0x72, 0x74, 0x79, 0x6b, + 0x6f, 0x42, 0x52, 0x41, 0x4a, 0x2f, 0x4e, 0x34, 0x4a, 0x45, 0x41, + 0x55, 0x6f, 0x4b, 0x53, 0x67, 0x70, 0x69, 0x31, 0x31, 0x64, 0x61, + 0x6d, 0x70, 0x64, 0x58, 0x59, 0x73, 0x70, 0x4b, 0x41, 0x45, 0x6c, + 0x48, 0x69, 0x73, 0x72, 0x48, 0x68, 0x38, 0x72, 0x4b, 0x77, 0x45, + 0x66, 0x48, 0x69, 0x73, 0x72, 0x48, 0x68, 0x38, 0x72, 0x4b, 0x2f, + 0x54, 0x61, 0x44, 0x78, 0x6f, 0x45, 0x41, 0x77, 0x38, 0x50, 0x32, + 0x67, 0x4d, 0x72, 0x49, 0x79, 0x78, 0x50, 0x43, 0x77, 0x77, 0x75, + 0x4c, 0x43, 0x4e, 0x41, 0x46, 0x42, 0x4d, 0x65, 0x4b, 0x79, 0x73, + 0x65, 0x48, 0x79, 0x73, 0x72, 0x41, 0x59, 0x77, 0x66, 0x4b, 0x69, + 0x6f, 0x66, 0x48, 0x69, 0x73, 0x72, 0x54, 0x78, 0x34, 0x72, 0x4b, + 0x78, 0x34, 0x66, 0x4b, 0x79, 0x76, 0x68, 0x53, 0x6f, 0x77, 0x2b, + 0x43, 0x41, 0x6b, 0x4a, 0x43, 0x44, 0x32, 0x4e, 0x53, 0x6d, 0x6c, + 0x65, 0x58, 0x59, 0x73, 0x6f, 0x4b, 0x53, 0x6b, 0x6f, 0x69, 0x31, + 0x31, 0x65, 0x61, 0x51, 0x41, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, + 0x42, 0x6f, 0x41, 0x64, 0x51, 0x4a, 0x43, 0x41, 0x71, 0x38, 0x41, + 0x4a, 0x41, 0x42, 0x4a, 0x41, 0x41, 0x41, 0x6c, 0x46, 0x41, 0x59, + 0x50, 0x41, 0x51, 0x34, 0x42, 0x49, 0x79, 0x49, 0x6d, 0x4a, 0x77, + 0x45, 0x75, 0x41, 0x54, 0x55, 0x30, 0x4e, 0x6a, 0x63, 0x42, 0x50, + 0x67, 0x45, 0x7a, 0x4d, 0x68, 0x59, 0x66, 0x41, 0x52, 0x34, 0x42, + 0x46, 0x52, 0x51, 0x47, 0x44, 0x77, 0x45, 0x58, 0x48, 0x67, 0x45, + 0x56, 0x4d, 0x78, 0x51, 0x47, 0x44, 0x77, 0x45, 0x4f, 0x41, 0x53, + 0x4d, 0x69, 0x4a, 0x69, 0x63, 0x42, 0x4c, 0x67, 0x45, 0x31, 0x4e, + 0x44, 0x59, 0x33, 0x41, 0x54, 0x34, 0x42, 0x4d, 0x7a, 0x49, 0x57, + 0x48, 0x77, 0x45, 0x65, 0x41, 0x52, 0x55, 0x55, 0x42, 0x67, 0x38, + 0x42, 0x46, 0x78, 0x34, 0x42, 0x46, 0x51, 0x46, 0x6d, 0x41, 0x77, + 0x49, 0x64, 0x41, 0x77, 0x63, 0x44, 0x42, 0x41, 0x63, 0x43, 0x2f, + 0x76, 0x55, 0x43, 0x41, 0x77, 0x4d, 0x43, 0x41, 0x51, 0x73, 0x43, + 0x42, 0x77, 0x51, 0x44, 0x42, 0x77, 0x4d, 0x64, 0x41, 0x67, 0x4d, + 0x44, 0x41, 0x75, 0x48, 0x68, 0x41, 0x67, 0x50, 0x63, 0x41, 0x77, + 0x4d, 0x64, 0x41, 0x67, 0x63, 0x45, 0x41, 0x77, 0x63, 0x44, 0x2f, + 0x76, 0x59, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x51, 0x6f, 0x44, + 0x42, 0x77, 0x4d, 0x45, 0x42, 0x77, 0x49, 0x64, 0x41, 0x77, 0x4d, + 0x44, 0x41, 0x2b, 0x48, 0x68, 0x41, 0x77, 0x4f, 0x6c, 0x42, 0x41, + 0x63, 0x44, 0x48, 0x41, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x42, 0x43, + 0x67, 0x4d, 0x48, 0x41, 0x77, 0x51, 0x48, 0x41, 0x67, 0x45, 0x4c, + 0x41, 0x67, 0x4d, 0x44, 0x41, 0x68, 0x30, 0x43, 0x43, 0x41, 0x4d, + 0x44, 0x43, 0x41, 0x4c, 0x68, 0x34, 0x41, 0x4d, 0x48, 0x41, 0x77, + 0x51, 0x48, 0x41, 0x78, 0x77, 0x44, 0x41, 0x77, 0x4d, 0x44, 0x41, + 0x51, 0x6f, 0x44, 0x42, 0x77, 0x4d, 0x45, 0x42, 0x77, 0x49, 0x42, + 0x43, 0x77, 0x49, 0x44, 0x41, 0x77, 0x49, 0x64, 0x41, 0x67, 0x67, + 0x44, 0x41, 0x77, 0x67, 0x43, 0x34, 0x65, 0x41, 0x44, 0x42, 0x77, + 0x4d, 0x41, 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x63, 0x41, 0x64, + 0x51, 0x49, 0x76, 0x41, 0x71, 0x38, 0x41, 0x4a, 0x41, 0x42, 0x4a, + 0x41, 0x41, 0x41, 0x42, 0x46, 0x41, 0x59, 0x48, 0x41, 0x51, 0x34, + 0x42, 0x49, 0x79, 0x49, 0x6d, 0x4c, 0x77, 0x45, 0x75, 0x41, 0x54, + 0x55, 0x30, 0x4e, 0x6a, 0x38, 0x42, 0x4a, 0x79, 0x34, 0x42, 0x4e, + 0x54, 0x51, 0x32, 0x50, 0x77, 0x45, 0x2b, 0x41, 0x54, 0x4d, 0x79, + 0x46, 0x68, 0x63, 0x42, 0x48, 0x67, 0x45, 0x56, 0x4d, 0x78, 0x51, + 0x47, 0x42, 0x77, 0x45, 0x4f, 0x41, 0x53, 0x4d, 0x69, 0x4a, 0x69, + 0x38, 0x42, 0x4c, 0x67, 0x45, 0x31, 0x4e, 0x44, 0x59, 0x2f, 0x41, + 0x53, 0x63, 0x75, 0x41, 0x54, 0x55, 0x30, 0x4e, 0x6a, 0x38, 0x42, + 0x50, 0x67, 0x45, 0x7a, 0x4d, 0x68, 0x59, 0x58, 0x41, 0x52, 0x34, + 0x42, 0x46, 0x51, 0x46, 0x55, 0x41, 0x77, 0x50, 0x2b, 0x39, 0x67, + 0x4d, 0x48, 0x41, 0x77, 0x51, 0x48, 0x41, 0x68, 0x30, 0x43, 0x42, + 0x41, 0x51, 0x43, 0x34, 0x65, 0x45, 0x43, 0x42, 0x41, 0x51, 0x43, + 0x48, 0x51, 0x49, 0x48, 0x42, 0x41, 0x4d, 0x48, 0x41, 0x77, 0x45, + 0x4b, 0x41, 0x77, 0x50, 0x62, 0x41, 0x77, 0x4c, 0x2b, 0x39, 0x51, + 0x49, 0x48, 0x42, 0x41, 0x4d, 0x48, 0x41, 0x78, 0x77, 0x44, 0x41, + 0x77, 0x4d, 0x44, 0x34, 0x4f, 0x41, 0x44, 0x41, 0x77, 0x4d, 0x44, + 0x48, 0x41, 0x4d, 0x48, 0x41, 0x77, 0x51, 0x48, 0x41, 0x67, 0x45, + 0x4c, 0x41, 0x67, 0x4d, 0x42, 0x6b, 0x67, 0x4d, 0x48, 0x41, 0x2f, + 0x37, 0x32, 0x41, 0x77, 0x4d, 0x44, 0x41, 0x78, 0x77, 0x44, 0x42, + 0x77, 0x51, 0x44, 0x42, 0x77, 0x50, 0x67, 0x34, 0x51, 0x49, 0x49, + 0x41, 0x77, 0x4d, 0x49, 0x41, 0x68, 0x30, 0x43, 0x41, 0x77, 0x4d, + 0x43, 0x2f, 0x76, 0x55, 0x43, 0x42, 0x77, 0x51, 0x44, 0x42, 0x77, + 0x50, 0x2b, 0x39, 0x67, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x63, 0x41, + 0x77, 0x63, 0x45, 0x41, 0x77, 0x63, 0x44, 0x34, 0x4f, 0x45, 0x43, + 0x43, 0x41, 0x4d, 0x44, 0x43, 0x41, 0x49, 0x64, 0x41, 0x67, 0x4d, + 0x44, 0x41, 0x76, 0x37, 0x31, 0x41, 0x67, 0x63, 0x45, 0x41, 0x41, + 0x41, 0x42, 0x41, 0x42, 0x6f, 0x41, 0x64, 0x51, 0x46, 0x6d, 0x41, + 0x71, 0x38, 0x41, 0x4a, 0x41, 0x41, 0x41, 0x41, 0x52, 0x51, 0x47, + 0x44, 0x77, 0x45, 0x58, 0x48, 0x67, 0x45, 0x56, 0x46, 0x41, 0x59, + 0x50, 0x41, 0x51, 0x34, 0x42, 0x49, 0x79, 0x49, 0x6d, 0x4a, 0x77, + 0x45, 0x75, 0x41, 0x54, 0x55, 0x30, 0x4e, 0x6a, 0x63, 0x42, 0x50, + 0x67, 0x45, 0x7a, 0x4d, 0x68, 0x59, 0x66, 0x41, 0x52, 0x34, 0x42, + 0x46, 0x51, 0x46, 0x6d, 0x41, 0x77, 0x4c, 0x68, 0x34, 0x51, 0x49, + 0x44, 0x41, 0x77, 0x49, 0x64, 0x41, 0x77, 0x63, 0x44, 0x42, 0x41, + 0x63, 0x43, 0x2f, 0x76, 0x55, 0x43, 0x41, 0x77, 0x4d, 0x43, 0x41, + 0x51, 0x73, 0x43, 0x42, 0x77, 0x51, 0x44, 0x42, 0x77, 0x4d, 0x64, + 0x41, 0x67, 0x4d, 0x43, 0x67, 0x41, 0x4d, 0x49, 0x41, 0x75, 0x48, + 0x67, 0x41, 0x77, 0x63, 0x44, 0x42, 0x41, 0x63, 0x44, 0x48, 0x41, + 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x42, 0x43, 0x67, 0x4d, 0x48, 0x41, + 0x77, 0x51, 0x48, 0x41, 0x67, 0x45, 0x4c, 0x41, 0x67, 0x4d, 0x44, + 0x41, 0x68, 0x30, 0x43, 0x42, 0x77, 0x51, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x51, 0x41, 0x48, 0x41, 0x48, 0x55, 0x42, 0x56, 0x41, + 0x4b, 0x76, 0x41, 0x43, 0x51, 0x41, 0x41, 0x41, 0x45, 0x55, 0x42, + 0x67, 0x63, 0x42, 0x44, 0x67, 0x45, 0x6a, 0x49, 0x69, 0x59, 0x76, + 0x41, 0x53, 0x34, 0x42, 0x4e, 0x54, 0x51, 0x32, 0x50, 0x77, 0x45, + 0x6e, 0x4c, 0x67, 0x45, 0x31, 0x4e, 0x44, 0x59, 0x2f, 0x41, 0x54, + 0x34, 0x42, 0x4d, 0x7a, 0x49, 0x57, 0x46, 0x77, 0x45, 0x65, 0x41, + 0x52, 0x55, 0x42, 0x56, 0x41, 0x4d, 0x44, 0x2f, 0x76, 0x59, 0x44, + 0x42, 0x77, 0x4d, 0x45, 0x42, 0x77, 0x49, 0x64, 0x41, 0x67, 0x51, + 0x45, 0x41, 0x75, 0x48, 0x68, 0x41, 0x67, 0x51, 0x45, 0x41, 0x68, + 0x30, 0x43, 0x42, 0x77, 0x51, 0x44, 0x42, 0x77, 0x4d, 0x42, 0x43, + 0x67, 0x4d, 0x44, 0x41, 0x5a, 0x49, 0x44, 0x42, 0x77, 0x50, 0x2b, + 0x39, 0x67, 0x4d, 0x44, 0x41, 0x77, 0x4d, 0x63, 0x41, 0x77, 0x63, + 0x45, 0x41, 0x77, 0x63, 0x44, 0x34, 0x4f, 0x45, 0x43, 0x43, 0x41, + 0x4d, 0x44, 0x43, 0x41, 0x49, 0x64, 0x41, 0x67, 0x4d, 0x44, 0x41, + 0x76, 0x37, 0x31, 0x41, 0x67, 0x63, 0x45, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x45, 0x6b, + 0x44, 0x74, 0x77, 0x41, 0x50, 0x41, 0x43, 0x34, 0x41, 0x41, 0x41, + 0x45, 0x52, 0x4e, 0x43, 0x59, 0x6a, 0x49, 0x53, 0x49, 0x47, 0x46, + 0x52, 0x45, 0x55, 0x46, 0x6a, 0x4d, 0x68, 0x4d, 0x6a, 0x59, 0x54, + 0x45, 0x52, 0x51, 0x47, 0x49, 0x79, 0x45, 0x55, 0x46, 0x68, 0x55, + 0x55, 0x42, 0x69, 0x4d, 0x68, 0x49, 0x69, 0x59, 0x31, 0x4e, 0x44, + 0x59, 0x31, 0x49, 0x53, 0x49, 0x6d, 0x4e, 0x52, 0x45, 0x30, 0x4e, + 0x6a, 0x4d, 0x68, 0x4d, 0x68, 0x59, 0x56, 0x42, 0x41, 0x41, 0x4c, + 0x42, 0x2f, 0x78, 0x74, 0x42, 0x77, 0x73, 0x4c, 0x42, 0x77, 0x4f, + 0x54, 0x42, 0x77, 0x74, 0x4a, 0x4e, 0x69, 0x58, 0x2b, 0x79, 0x53, + 0x51, 0x56, 0x44, 0x2f, 0x37, 0x62, 0x44, 0x78, 0x55, 0x6b, 0x2f, + 0x73, 0x6b, 0x6c, 0x4e, 0x6a, 0x59, 0x6c, 0x41, 0x35, 0x4d, 0x6c, + 0x4e, 0x67, 0x47, 0x41, 0x41, 0x64, 0x73, 0x49, 0x43, 0x77, 0x73, + 0x49, 0x2f, 0x69, 0x55, 0x48, 0x43, 0x77, 0x73, 0x42, 0x34, 0x76, + 0x32, 0x54, 0x4a, 0x6a, 0x59, 0x6b, 0x4f, 0x67, 0x38, 0x50, 0x46, + 0x68, 0x59, 0x50, 0x44, 0x7a, 0x6b, 0x6c, 0x4e, 0x69, 0x59, 0x43, + 0x62, 0x53, 0x59, 0x32, 0x4e, 0x69, 0x59, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x67, 0x41, 0x41, 0x41, 0x41, 0x41, 0x44, 0x62, 0x67, + 0x4e, 0x75, 0x41, 0x42, 0x77, 0x41, 0x4f, 0x51, 0x41, 0x41, 0x41, + 0x53, 0x49, 0x48, 0x44, 0x67, 0x45, 0x48, 0x42, 0x68, 0x55, 0x55, + 0x46, 0x78, 0x34, 0x42, 0x46, 0x78, 0x59, 0x7a, 0x4d, 0x6a, 0x63, + 0x2b, 0x41, 0x54, 0x63, 0x32, 0x4e, 0x54, 0x51, 0x6e, 0x4c, 0x67, + 0x45, 0x6e, 0x4a, 0x69, 0x4d, 0x42, 0x46, 0x41, 0x63, 0x4f, 0x41, + 0x51, 0x63, 0x47, 0x49, 0x79, 0x49, 0x6e, 0x4c, 0x67, 0x45, 0x6e, + 0x4a, 0x6a, 0x55, 0x30, 0x4e, 0x7a, 0x34, 0x42, 0x4e, 0x7a, 0x59, + 0x7a, 0x4d, 0x54, 0x49, 0x58, 0x48, 0x67, 0x45, 0x58, 0x46, 0x67, + 0x47, 0x33, 0x51, 0x44, 0x6b, 0x35, 0x56, 0x42, 0x6b, 0x59, 0x47, + 0x42, 0x6c, 0x55, 0x4f, 0x54, 0x6c, 0x41, 0x51, 0x44, 0x6b, 0x34, + 0x56, 0x52, 0x67, 0x5a, 0x47, 0x52, 0x68, 0x56, 0x4f, 0x44, 0x6c, + 0x41, 0x41, 0x62, 0x63, 0x6a, 0x49, 0x6e, 0x64, 0x51, 0x55, 0x46, + 0x74, 0x62, 0x55, 0x46, 0x42, 0x33, 0x49, 0x79, 0x49, 0x69, 0x49, + 0x33, 0x64, 0x51, 0x55, 0x46, 0x74, 0x62, 0x55, 0x46, 0x42, 0x33, + 0x49, 0x69, 0x4d, 0x43, 0x37, 0x68, 0x6b, 0x59, 0x56, 0x54, 0x67, + 0x35, 0x51, 0x45, 0x41, 0x35, 0x4f, 0x56, 0x51, 0x5a, 0x47, 0x42, + 0x67, 0x5a, 0x56, 0x44, 0x6b, 0x35, 0x51, 0x45, 0x41, 0x35, 0x4f, + 0x46, 0x55, 0x59, 0x47, 0x66, 0x37, 0x4a, 0x57, 0x31, 0x42, 0x51, + 0x64, 0x79, 0x49, 0x6a, 0x49, 0x79, 0x4a, 0x33, 0x55, 0x46, 0x42, + 0x62, 0x57, 0x31, 0x42, 0x51, 0x64, 0x79, 0x49, 0x6a, 0x49, 0x79, + 0x4a, 0x33, 0x55, 0x46, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x51, 0x41, 0x41, 0x41, 0x41, 0x41, 0x44, 0x62, 0x67, 0x4e, 0x75, + 0x41, 0x42, 0x73, 0x41, 0x41, 0x41, 0x45, 0x55, 0x42, 0x77, 0x34, + 0x42, 0x42, 0x77, 0x59, 0x6a, 0x49, 0x69, 0x63, 0x75, 0x41, 0x53, + 0x63, 0x6d, 0x4e, 0x54, 0x51, 0x33, 0x50, 0x67, 0x45, 0x33, 0x4e, + 0x6a, 0x4d, 0x79, 0x46, 0x78, 0x34, 0x42, 0x46, 0x78, 0x59, 0x44, + 0x62, 0x69, 0x4d, 0x69, 0x64, 0x31, 0x42, 0x51, 0x57, 0x31, 0x74, + 0x51, 0x55, 0x48, 0x63, 0x6a, 0x49, 0x69, 0x49, 0x6a, 0x64, 0x31, + 0x42, 0x51, 0x57, 0x31, 0x74, 0x51, 0x55, 0x48, 0x63, 0x69, 0x49, + 0x77, 0x47, 0x33, 0x57, 0x31, 0x42, 0x51, 0x64, 0x79, 0x49, 0x6a, + 0x49, 0x79, 0x4a, 0x33, 0x55, 0x46, 0x42, 0x62, 0x57, 0x31, 0x42, + 0x51, 0x64, 0x79, 0x49, 0x6a, 0x49, 0x79, 0x4a, 0x33, 0x55, 0x46, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x77, 0x41, 0x66, 0x41, + 0x41, 0x73, 0x45, 0x4b, 0x67, 0x4d, 0x61, 0x41, 0x42, 0x55, 0x41, + 0x4a, 0x67, 0x41, 0x38, 0x41, 0x41, 0x41, 0x6c, 0x42, 0x77, 0x59, + 0x69, 0x4a, 0x77, 0x45, 0x6d, 0x4e, 0x44, 0x63, 0x42, 0x4e, 0x6a, + 0x49, 0x66, 0x41, 0x52, 0x59, 0x55, 0x44, 0x77, 0x45, 0x58, 0x46, + 0x68, 0x51, 0x48, 0x41, 0x51, 0x4d, 0x4f, 0x41, 0x53, 0x38, 0x42, + 0x4c, 0x67, 0x45, 0x33, 0x45, 0x7a, 0x34, 0x42, 0x48, 0x77, 0x45, + 0x65, 0x41, 0x51, 0x63, 0x4a, 0x41, 0x51, 0x59, 0x69, 0x4c, 0x77, + 0x45, 0x6d, 0x4e, 0x44, 0x38, 0x42, 0x4a, 0x79, 0x59, 0x30, 0x50, + 0x77, 0x45, 0x32, 0x4d, 0x68, 0x63, 0x42, 0x46, 0x68, 0x51, 0x48, + 0x41, 0x57, 0x45, 0x64, 0x42, 0x67, 0x38, 0x46, 0x2f, 0x76, 0x55, + 0x46, 0x42, 0x51, 0x45, 0x4c, 0x42, 0x51, 0x38, 0x47, 0x48, 0x51, + 0x55, 0x46, 0x34, 0x65, 0x45, 0x46, 0x42, 0x51, 0x46, 0x52, 0x31, + 0x51, 0x49, 0x4e, 0x42, 0x79, 0x51, 0x48, 0x42, 0x77, 0x4c, 0x56, + 0x41, 0x67, 0x30, 0x48, 0x4a, 0x41, 0x63, 0x48, 0x41, 0x67, 0x46, + 0x34, 0x2f, 0x76, 0x55, 0x46, 0x44, 0x77, 0x59, 0x63, 0x42, 0x67, + 0x62, 0x67, 0x34, 0x41, 0x59, 0x47, 0x48, 0x41, 0x59, 0x50, 0x42, + 0x51, 0x45, 0x4c, 0x42, 0x51, 0x57, 0x58, 0x48, 0x41, 0x59, 0x47, + 0x41, 0x51, 0x6f, 0x47, 0x44, 0x77, 0x55, 0x42, 0x43, 0x77, 0x55, + 0x46, 0x48, 0x51, 0x55, 0x51, 0x42, 0x65, 0x48, 0x67, 0x42, 0x67, + 0x38, 0x47, 0x41, 0x6d, 0x4c, 0x39, 0x48, 0x67, 0x63, 0x48, 0x41, + 0x67, 0x6f, 0x43, 0x44, 0x51, 0x63, 0x43, 0x34, 0x67, 0x63, 0x49, + 0x41, 0x67, 0x6f, 0x43, 0x44, 0x67, 0x66, 0x2b, 0x6a, 0x50, 0x37, + 0x32, 0x42, 0x67, 0x59, 0x63, 0x42, 0x67, 0x38, 0x47, 0x34, 0x4f, + 0x45, 0x46, 0x45, 0x41, 0x55, 0x64, 0x42, 0x51, 0x58, 0x2b, 0x39, + 0x51, 0x55, 0x50, 0x42, 0x67, 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, + 0x41, 0x50, 0x2b, 0x33, 0x41, 0x32, 0x34, 0x44, 0x74, 0x77, 0x41, + 0x49, 0x41, 0x42, 0x73, 0x41, 0x41, 0x41, 0x45, 0x52, 0x48, 0x67, + 0x45, 0x66, 0x41, 0x52, 0x34, 0x42, 0x46, 0x77, 0x55, 0x55, 0x46, + 0x6a, 0x4d, 0x68, 0x45, 0x52, 0x51, 0x47, 0x49, 0x79, 0x45, 0x69, + 0x4a, 0x6a, 0x55, 0x52, 0x4e, 0x44, 0x59, 0x7a, 0x49, 0x52, 0x45, + 0x43, 0x53, 0x51, 0x59, 0x4b, 0x42, 0x65, 0x6b, 0x45, 0x43, 0x41, + 0x54, 0x2b, 0x71, 0x53, 0x41, 0x58, 0x41, 0x54, 0x63, 0x67, 0x46, + 0x2f, 0x30, 0x41, 0x46, 0x79, 0x41, 0x67, 0x46, 0x77, 0x48, 0x4a, + 0x41, 0x70, 0x49, 0x42, 0x44, 0x67, 0x51, 0x49, 0x42, 0x4f, 0x6b, + 0x45, 0x43, 0x77, 0x59, 0x53, 0x46, 0x79, 0x44, 0x39, 0x70, 0x52, + 0x63, 0x67, 0x49, 0x42, 0x63, 0x44, 0x6b, 0x68, 0x63, 0x67, 0x2f, + 0x73, 0x6b, 0x41, 0x41, 0x41, 0x55, 0x41, 0x41, 0x50, 0x2b, 0x33, + 0x41, 0x32, 0x34, 0x44, 0x74, 0x77, 0x41, 0x49, 0x41, 0x42, 0x6f, + 0x41, 0x4b, 0x77, 0x41, 0x38, 0x41, 0x45, 0x30, 0x41, 0x41, 0x41, + 0x45, 0x65, 0x41, 0x52, 0x63, 0x68, 0x45, 0x52, 0x34, 0x42, 0x46, + 0x77, 0x4d, 0x68, 0x45, 0x52, 0x51, 0x47, 0x49, 0x79, 0x45, 0x69, + 0x4a, 0x6a, 0x55, 0x52, 0x4e, 0x44, 0x59, 0x7a, 0x49, 0x52, 0x45, + 0x55, 0x46, 0x68, 0x4d, 0x31, 0x4e, 0x43, 0x59, 0x6a, 0x49, 0x53, + 0x49, 0x47, 0x48, 0x51, 0x45, 0x55, 0x46, 0x6a, 0x4d, 0x68, 0x4d, + 0x6a, 0x59, 0x31, 0x50, 0x51, 0x45, 0x30, 0x4a, 0x69, 0x4d, 0x68, + 0x49, 0x67, 0x59, 0x64, 0x41, 0x52, 0x51, 0x57, 0x4d, 0x79, 0x45, + 0x79, 0x4e, 0x6a, 0x55, 0x39, 0x41, 0x54, 0x51, 0x6d, 0x49, 0x79, + 0x45, 0x69, 0x42, 0x68, 0x30, 0x42, 0x46, 0x42, 0x59, 0x7a, 0x49, + 0x54, 0x49, 0x32, 0x4e, 0x51, 0x4e, 0x48, 0x42, 0x41, 0x67, 0x45, + 0x2f, 0x76, 0x49, 0x47, 0x43, 0x67, 0x55, 0x6e, 0x41, 0x54, 0x63, + 0x67, 0x46, 0x2f, 0x30, 0x41, 0x46, 0x79, 0x41, 0x67, 0x46, 0x77, + 0x48, 0x4a, 0x49, 0x48, 0x49, 0x4b, 0x43, 0x50, 0x35, 0x75, 0x43, + 0x41, 0x73, 0x4c, 0x43, 0x41, 0x47, 0x53, 0x43, 0x41, 0x6f, 0x4b, + 0x43, 0x50, 0x35, 0x75, 0x43, 0x41, 0x73, 0x4c, 0x43, 0x41, 0x47, + 0x53, 0x43, 0x41, 0x6f, 0x4b, 0x43, 0x50, 0x35, 0x75, 0x43, 0x41, + 0x73, 0x4c, 0x43, 0x41, 0x47, 0x53, 0x43, 0x41, 0x6f, 0x43, 0x70, + 0x77, 0x51, 0x4c, 0x42, 0x67, 0x45, 0x4f, 0x42, 0x41, 0x67, 0x45, + 0x2f, 0x72, 0x6e, 0x39, 0x70, 0x52, 0x63, 0x67, 0x49, 0x42, 0x63, + 0x44, 0x6b, 0x68, 0x63, 0x67, 0x2f, 0x73, 0x6b, 0x58, 0x49, 0x50, + 0x35, 0x63, 0x4a, 0x41, 0x67, 0x4b, 0x43, 0x67, 0x67, 0x6b, 0x43, + 0x41, 0x73, 0x4c, 0x43, 0x4a, 0x49, 0x6b, 0x43, 0x41, 0x73, 0x4c, + 0x43, 0x43, 0x51, 0x49, 0x43, 0x67, 0x6f, 0x49, 0x6b, 0x69, 0x55, + 0x48, 0x43, 0x77, 0x73, 0x48, 0x4a, 0x51, 0x67, 0x4b, 0x43, 0x67, + 0x67, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x44, 0x58, 0x41, 0x4e, 0x75, 0x41, 0x44, 0x73, 0x41, + 0x41, 0x41, 0x45, 0x68, 0x48, 0x67, 0x45, 0x56, 0x46, 0x41, 0x63, + 0x4f, 0x41, 0x51, 0x63, 0x47, 0x49, 0x79, 0x49, 0x6e, 0x4c, 0x67, + 0x45, 0x6e, 0x4a, 0x6a, 0x55, 0x30, 0x4e, 0x7a, 0x34, 0x42, 0x4e, + 0x7a, 0x59, 0x7a, 0x4d, 0x68, 0x63, 0x65, 0x41, 0x52, 0x63, 0x57, + 0x46, 0x77, 0x63, 0x75, 0x41, 0x53, 0x4d, 0x69, 0x42, 0x77, 0x34, + 0x42, 0x42, 0x77, 0x59, 0x56, 0x46, 0x42, 0x63, 0x65, 0x41, 0x52, + 0x63, 0x57, 0x4d, 0x7a, 0x49, 0x33, 0x50, 0x67, 0x45, 0x33, 0x4e, + 0x6a, 0x63, 0x6a, 0x4e, 0x51, 0x47, 0x33, 0x41, 0x5a, 0x34, 0x44, + 0x42, 0x42, 0x34, 0x65, 0x62, 0x30, 0x35, 0x4e, 0x58, 0x31, 0x74, + 0x51, 0x55, 0x48, 0x63, 0x6a, 0x49, 0x69, 0x49, 0x6a, 0x64, 0x31, + 0x42, 0x51, 0x57, 0x79, 0x77, 0x70, 0x4b, 0x55, 0x6f, 0x67, 0x49, + 0x52, 0x31, 0x33, 0x47, 0x56, 0x5a, 0x41, 0x4f, 0x44, 0x49, 0x78, + 0x53, 0x68, 0x59, 0x56, 0x46, 0x52, 0x5a, 0x4b, 0x4d, 0x54, 0x49, + 0x34, 0x51, 0x53, 0x34, 0x74, 0x4f, 0x77, 0x38, 0x50, 0x42, 0x50, + 0x6b, 0x42, 0x39, 0x68, 0x45, 0x6a, 0x46, 0x56, 0x35, 0x50, 0x54, + 0x33, 0x45, 0x67, 0x49, 0x43, 0x49, 0x6a, 0x64, 0x31, 0x42, 0x51, + 0x57, 0x31, 0x74, 0x51, 0x55, 0x48, 0x63, 0x69, 0x49, 0x77, 0x67, + 0x49, 0x48, 0x68, 0x55, 0x56, 0x47, 0x33, 0x4d, 0x59, 0x4c, 0x42, + 0x59, 0x57, 0x53, 0x7a, 0x49, 0x7a, 0x4f, 0x54, 0x6f, 0x79, 0x4d, + 0x30, 0x73, 0x57, 0x46, 0x52, 0x51, 0x56, 0x4f, 0x69, 0x45, 0x68, + 0x47, 0x4a, 0x63, 0x41, 0x41, 0x51, 0x41, 0x53, 0x2f, 0x38, 0x6b, + 0x44, 0x37, 0x67, 0x4f, 0x66, 0x41, 0x44, 0x6f, 0x41, 0x41, 0x41, + 0x45, 0x55, 0x42, 0x77, 0x34, 0x42, 0x42, 0x77, 0x59, 0x6a, 0x49, + 0x69, 0x63, 0x75, 0x41, 0x53, 0x63, 0x6d, 0x4e, 0x54, 0x51, 0x33, + 0x50, 0x67, 0x45, 0x33, 0x4e, 0x6a, 0x63, 0x56, 0x42, 0x67, 0x63, + 0x4f, 0x41, 0x51, 0x63, 0x47, 0x46, 0x52, 0x51, 0x58, 0x48, 0x67, + 0x45, 0x58, 0x46, 0x6a, 0x4d, 0x79, 0x4e, 0x7a, 0x34, 0x42, 0x4e, + 0x7a, 0x59, 0x31, 0x4e, 0x43, 0x63, 0x75, 0x41, 0x53, 0x63, 0x6d, + 0x4a, 0x7a, 0x55, 0x57, 0x46, 0x78, 0x34, 0x42, 0x46, 0x78, 0x59, + 0x56, 0x41, 0x2b, 0x34, 0x6e, 0x4a, 0x34, 0x5a, 0x61, 0x57, 0x6d, + 0x5a, 0x6d, 0x57, 0x6c, 0x71, 0x47, 0x4a, 0x79, 0x63, 0x68, 0x49, + 0x48, 0x46, 0x4e, 0x54, 0x56, 0x6b, 0x2f, 0x4e, 0x54, 0x5a, 0x4f, + 0x46, 0x68, 0x63, 0x64, 0x48, 0x57, 0x4e, 0x44, 0x51, 0x6b, 0x78, + 0x4d, 0x51, 0x6b, 0x4e, 0x6a, 0x48, 0x52, 0x30, 0x58, 0x46, 0x6b, + 0x34, 0x32, 0x4e, 0x54, 0x39, 0x5a, 0x54, 0x55, 0x31, 0x78, 0x49, + 0x43, 0x45, 0x42, 0x74, 0x32, 0x5a, 0x61, 0x57, 0x6f, 0x59, 0x6e, + 0x4a, 0x79, 0x63, 0x6e, 0x68, 0x6c, 0x70, 0x61, 0x5a, 0x6c, 0x31, + 0x54, 0x55, 0x34, 0x49, 0x72, 0x4b, 0x77, 0x32, 0x43, 0x44, 0x53, + 0x41, 0x68, 0x58, 0x7a, 0x73, 0x38, 0x51, 0x6b, 0x78, 0x43, 0x51, + 0x32, 0x4d, 0x64, 0x48, 0x52, 0x30, 0x64, 0x59, 0x30, 0x4e, 0x43, + 0x54, 0x45, 0x49, 0x38, 0x4f, 0x31, 0x38, 0x68, 0x49, 0x41, 0x32, + 0x43, 0x44, 0x53, 0x73, 0x72, 0x67, 0x6c, 0x4e, 0x54, 0x58, 0x51, + 0x41, 0x41, 0x42, 0x41, 0x41, 0x4e, 0x2f, 0x37, 0x63, 0x45, 0x68, + 0x67, 0x4f, 0x33, 0x41, 0x42, 0x49, 0x41, 0x4a, 0x51, 0x41, 0x39, + 0x41, 0x47, 0x38, 0x41, 0x41, 0x41, 0x55, 0x30, 0x4a, 0x69, 0x4d, + 0x69, 0x4a, 0x6a, 0x55, 0x30, 0x4a, 0x69, 0x4d, 0x69, 0x42, 0x68, + 0x55, 0x55, 0x46, 0x6a, 0x4d, 0x79, 0x4e, 0x6a, 0x55, 0x4a, 0x41, + 0x53, 0x34, 0x42, 0x49, 0x79, 0x49, 0x48, 0x44, 0x67, 0x45, 0x48, + 0x42, 0x68, 0x55, 0x55, 0x42, 0x77, 0x34, 0x42, 0x42, 0x77, 0x59, + 0x48, 0x42, 0x52, 0x51, 0x47, 0x49, 0x79, 0x45, 0x55, 0x42, 0x69, + 0x4d, 0x69, 0x4a, 0x6a, 0x55, 0x33, 0x49, 0x53, 0x34, 0x42, 0x4a, + 0x7a, 0x63, 0x57, 0x46, 0x78, 0x34, 0x42, 0x46, 0x78, 0x59, 0x58, + 0x45, 0x78, 0x63, 0x57, 0x46, 0x41, 0x63, 0x42, 0x42, 0x69, 0x59, + 0x76, 0x41, 0x53, 0x59, 0x32, 0x50, 0x77, 0x45, 0x75, 0x41, 0x54, + 0x55, 0x32, 0x4e, 0x7a, 0x34, 0x42, 0x4e, 0x7a, 0x59, 0x31, 0x4e, + 0x44, 0x63, 0x2b, 0x41, 0x54, 0x63, 0x32, 0x4e, 0x79, 0x34, 0x42, + 0x4e, 0x54, 0x51, 0x32, 0x4d, 0x7a, 0x49, 0x57, 0x46, 0x52, 0x51, + 0x47, 0x42, 0x78, 0x34, 0x42, 0x46, 0x7a, 0x63, 0x32, 0x46, 0x68, + 0x63, 0x43, 0x55, 0x67, 0x55, 0x45, 0x49, 0x6a, 0x41, 0x46, 0x42, + 0x41, 0x51, 0x46, 0x4f, 0x79, 0x6b, 0x45, 0x42, 0x66, 0x37, 0x4e, + 0x41, 0x66, 0x59, 0x57, 0x5a, 0x46, 0x49, 0x34, 0x4b, 0x53, 0x6f, + 0x32, 0x44, 0x51, 0x30, 0x46, 0x42, 0x52, 0x4d, 0x50, 0x44, 0x78, + 0x51, 0x44, 0x42, 0x69, 0x77, 0x65, 0x2f, 0x77, 0x42, 0x56, 0x50, + 0x54, 0x78, 0x57, 0x56, 0x51, 0x47, 0x78, 0x4d, 0x45, 0x45, 0x52, + 0x50, 0x77, 0x73, 0x54, 0x45, 0x79, 0x30, 0x61, 0x47, 0x68, 0x6b, + 0x78, 0x4d, 0x41, 0x51, 0x47, 0x2b, 0x39, 0x49, 0x46, 0x45, 0x41, + 0x51, 0x77, 0x42, 0x51, 0x45, 0x46, 0x61, 0x77, 0x59, 0x46, 0x48, + 0x79, 0x45, 0x68, 0x4e, 0x42, 0x45, 0x52, 0x45, 0x42, 0x45, 0x2b, + 0x4c, 0x53, 0x30, 0x35, 0x41, 0x67, 0x4d, 0x67, 0x46, 0x78, 0x63, + 0x67, 0x41, 0x67, 0x4e, 0x4b, 0x61, 0x78, 0x33, 0x76, 0x42, 0x67, + 0x38, 0x46, 0x45, 0x67, 0x51, 0x46, 0x4d, 0x43, 0x49, 0x45, 0x42, + 0x51, 0x55, 0x45, 0x4b, 0x54, 0x73, 0x46, 0x42, 0x41, 0x45, 0x50, + 0x41, 0x62, 0x49, 0x74, 0x53, 0x52, 0x4d, 0x53, 0x4e, 0x79, 0x41, + 0x67, 0x47, 0x7a, 0x63, 0x7a, 0x4d, 0x6c, 0x77, 0x71, 0x4b, 0x53, + 0x5a, 0x72, 0x48, 0x69, 0x73, 0x38, 0x56, 0x6c, 0x55, 0x39, 0x53, + 0x54, 0x61, 0x44, 0x54, 0x6a, 0x64, 0x41, 0x4d, 0x6a, 0x46, 0x4e, + 0x48, 0x42, 0x30, 0x56, 0x41, 0x78, 0x77, 0x33, 0x42, 0x67, 0x38, + 0x46, 0x2f, 0x47, 0x45, 0x46, 0x41, 0x51, 0x59, 0x33, 0x42, 0x67, + 0x38, 0x46, 0x58, 0x41, 0x67, 0x54, 0x43, 0x68, 0x73, 0x6e, 0x4a, + 0x33, 0x46, 0x4e, 0x54, 0x57, 0x67, 0x70, 0x4b, 0x53, 0x70, 0x46, + 0x47, 0x52, 0x6b, 0x4a, 0x42, 0x51, 0x73, 0x47, 0x46, 0x79, 0x41, + 0x67, 0x46, 0x77, 0x59, 0x4c, 0x42, 0x51, 0x74, 0x4d, 0x4d, 0x73, + 0x38, 0x46, 0x41, 0x51, 0x59, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x67, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, 0x6b, 0x67, 0x4e, 0x75, + 0x41, 0x41, 0x55, 0x41, 0x43, 0x77, 0x41, 0x41, 0x4a, 0x52, 0x55, + 0x68, 0x45, 0x54, 0x4d, 0x52, 0x41, 0x52, 0x4d, 0x68, 0x45, 0x51, + 0x6b, 0x42, 0x42, 0x4a, 0x4c, 0x37, 0x62, 0x6b, 0x6b, 0x44, 0x62, + 0x70, 0x4c, 0x38, 0x53, 0x51, 0x45, 0x41, 0x41, 0x55, 0x6c, 0x4a, + 0x53, 0x51, 0x4e, 0x75, 0x2f, 0x4e, 0x73, 0x43, 0x53, 0x66, 0x34, + 0x41, 0x41, 0x55, 0x6b, 0x42, 0x53, 0x76, 0x36, 0x32, 0x41, 0x41, + 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, 0x2f, 0x37, 0x63, 0x45, 0x41, + 0x41, 0x4f, 0x33, 0x41, 0x42, 0x59, 0x41, 0x4b, 0x67, 0x41, 0x39, + 0x41, 0x45, 0x6b, 0x41, 0x41, 0x41, 0x45, 0x79, 0x46, 0x68, 0x63, + 0x65, 0x41, 0x52, 0x63, 0x6c, 0x4a, 0x67, 0x63, 0x4f, 0x41, 0x51, + 0x63, 0x47, 0x42, 0x79, 0x63, 0x32, 0x4e, 0x7a, 0x34, 0x42, 0x4e, + 0x7a, 0x59, 0x7a, 0x42, 0x52, 0x4d, 0x57, 0x46, 0x78, 0x34, 0x42, + 0x46, 0x78, 0x59, 0x33, 0x41, 0x79, 0x59, 0x6e, 0x4c, 0x67, 0x45, + 0x6e, 0x4a, 0x6a, 0x55, 0x30, 0x4e, 0x6a, 0x63, 0x46, 0x46, 0x68, + 0x63, 0x57, 0x42, 0x67, 0x63, 0x47, 0x42, 0x77, 0x34, 0x42, 0x4a, + 0x78, 0x4d, 0x32, 0x4e, 0x7a, 0x59, 0x6d, 0x4a, 0x79, 0x59, 0x6e, + 0x4a, 0x7a, 0x49, 0x57, 0x46, 0x52, 0x51, 0x47, 0x49, 0x79, 0x49, + 0x6d, 0x4e, 0x54, 0x51, 0x32, 0x41, 0x66, 0x35, 0x43, 0x67, 0x7a, + 0x31, 0x44, 0x5a, 0x69, 0x44, 0x2b, 0x57, 0x43, 0x30, 0x72, 0x4b, + 0x30, 0x67, 0x63, 0x48, 0x41, 0x2b, 0x64, 0x4a, 0x53, 0x30, 0x74, + 0x5a, 0x6a, 0x67, 0x33, 0x4f, 0x50, 0x35, 0x56, 0x77, 0x52, 0x51, + 0x66, 0x48, 0x30, 0x77, 0x71, 0x4b, 0x79, 0x32, 0x44, 0x58, 0x45, + 0x39, 0x51, 0x64, 0x43, 0x45, 0x68, 0x4c, 0x43, 0x63, 0x44, 0x69, + 0x79, 0x45, 0x42, 0x41, 0x54, 0x73, 0x35, 0x4f, 0x6c, 0x4e, 0x44, + 0x6b, 0x6b, 0x6a, 0x6f, 0x47, 0x51, 0x73, 0x4d, 0x41, 0x67, 0x38, + 0x50, 0x48, 0x72, 0x31, 0x49, 0x5a, 0x57, 0x56, 0x49, 0x53, 0x47, + 0x56, 0x6c, 0x41, 0x37, 0x63, 0x69, 0x49, 0x79, 0x64, 0x74, 0x51, + 0x42, 0x59, 0x44, 0x43, 0x77, 0x73, 0x74, 0x49, 0x69, 0x45, 0x72, + 0x38, 0x79, 0x30, 0x6b, 0x49, 0x7a, 0x45, 0x4d, 0x44, 0x65, 0x6a, + 0x2b, 0x68, 0x69, 0x6b, 0x66, 0x49, 0x43, 0x67, 0x48, 0x43, 0x41, + 0x6e, 0x2b, 0x2f, 0x67, 0x34, 0x74, 0x4c, 0x59, 0x5a, 0x57, 0x56, + 0x6d, 0x42, 0x4e, 0x6a, 0x7a, 0x78, 0x67, 0x56, 0x31, 0x74, 0x61, + 0x71, 0x45, 0x68, 0x49, 0x4d, 0x43, 0x63, 0x67, 0x41, 0x77, 0x46, + 0x6b, 0x4a, 0x69, 0x73, 0x72, 0x56, 0x53, 0x6b, 0x70, 0x49, 0x67, + 0x4e, 0x6c, 0x52, 0x30, 0x68, 0x6c, 0x5a, 0x55, 0x68, 0x48, 0x5a, + 0x51, 0x41, 0x41, 0x41, 0x67, 0x41, 0x54, 0x41, 0x41, 0x41, 0x44, + 0x37, 0x51, 0x4e, 0x75, 0x41, 0x41, 0x4d, 0x41, 0x61, 0x41, 0x41, + 0x41, 0x41, 0x54, 0x63, 0x6a, 0x42, 0x77, 0x45, 0x48, 0x44, 0x67, + 0x45, 0x72, 0x41, 0x51, 0x63, 0x7a, 0x4d, 0x68, 0x59, 0x58, 0x48, + 0x67, 0x45, 0x50, 0x41, 0x51, 0x34, 0x42, 0x4b, 0x77, 0x45, 0x48, + 0x44, 0x67, 0x45, 0x72, 0x41, 0x53, 0x49, 0x6d, 0x4a, 0x79, 0x34, + 0x42, 0x50, 0x77, 0x45, 0x6a, 0x42, 0x77, 0x34, 0x42, 0x4b, 0x77, + 0x45, 0x69, 0x4a, 0x69, 0x63, 0x75, 0x41, 0x54, 0x38, 0x42, 0x49, + 0x79, 0x49, 0x6d, 0x4a, 0x79, 0x34, 0x42, 0x50, 0x77, 0x45, 0x2b, + 0x41, 0x54, 0x73, 0x42, 0x4e, 0x79, 0x4d, 0x69, 0x4a, 0x69, 0x63, + 0x75, 0x41, 0x54, 0x38, 0x42, 0x50, 0x67, 0x45, 0x37, 0x41, 0x54, + 0x63, 0x2b, 0x41, 0x54, 0x73, 0x42, 0x4d, 0x68, 0x59, 0x58, 0x48, + 0x67, 0x45, 0x50, 0x41, 0x54, 0x4d, 0x33, 0x50, 0x67, 0x45, 0x37, + 0x41, 0x54, 0x49, 0x57, 0x46, 0x78, 0x34, 0x42, 0x44, 0x77, 0x45, + 0x7a, 0x4d, 0x68, 0x59, 0x58, 0x48, 0x67, 0x45, 0x48, 0x41, 0x6a, + 0x59, 0x6c, 0x6b, 0x53, 0x55, 0x43, 0x53, 0x43, 0x41, 0x43, 0x43, + 0x51, 0x65, 0x36, 0x4a, 0x62, 0x49, 0x45, 0x42, 0x77, 0x4d, 0x44, + 0x41, 0x67, 0x49, 0x67, 0x41, 0x51, 0x6f, 0x47, 0x75, 0x79, 0x34, + 0x43, 0x43, 0x67, 0x61, 0x41, 0x42, 0x41, 0x67, 0x44, 0x41, 0x77, + 0x45, 0x42, 0x4c, 0x4a, 0x45, 0x75, 0x41, 0x67, 0x6f, 0x47, 0x67, + 0x51, 0x4d, 0x49, 0x41, 0x77, 0x49, 0x43, 0x41, 0x53, 0x79, 0x78, + 0x42, 0x51, 0x63, 0x44, 0x41, 0x67, 0x49, 0x42, 0x49, 0x41, 0x49, + 0x4a, 0x42, 0x37, 0x6f, 0x6c, 0x73, 0x67, 0x51, 0x48, 0x41, 0x77, + 0x4d, 0x43, 0x41, 0x69, 0x41, 0x42, 0x43, 0x67, 0x61, 0x37, 0x4c, + 0x67, 0x49, 0x4b, 0x42, 0x34, 0x41, 0x45, 0x42, 0x77, 0x4d, 0x44, + 0x41, 0x51, 0x45, 0x73, 0x6b, 0x53, 0x34, 0x43, 0x43, 0x67, 0x65, + 0x41, 0x41, 0x77, 0x67, 0x44, 0x41, 0x67, 0x49, 0x42, 0x4c, 0x4c, + 0x45, 0x46, 0x42, 0x77, 0x4d, 0x43, 0x41, 0x67, 0x45, 0x42, 0x62, + 0x70, 0x4b, 0x53, 0x41, 0x53, 0x43, 0x41, 0x42, 0x67, 0x69, 0x53, + 0x42, 0x41, 0x4d, 0x45, 0x43, 0x41, 0x53, 0x41, 0x42, 0x67, 0x69, + 0x37, 0x42, 0x67, 0x67, 0x45, 0x41, 0x77, 0x4d, 0x4a, 0x42, 0x4c, + 0x4b, 0x37, 0x42, 0x67, 0x67, 0x45, 0x41, 0x77, 0x4d, 0x4a, 0x42, + 0x4c, 0x49, 0x45, 0x41, 0x77, 0x4d, 0x4a, 0x42, 0x49, 0x41, 0x47, + 0x43, 0x4a, 0x49, 0x45, 0x41, 0x77, 0x4d, 0x4a, 0x42, 0x49, 0x41, + 0x47, 0x43, 0x4c, 0x73, 0x47, 0x43, 0x41, 0x51, 0x44, 0x42, 0x41, + 0x67, 0x45, 0x73, 0x72, 0x73, 0x47, 0x43, 0x41, 0x51, 0x44, 0x42, + 0x41, 0x67, 0x45, 0x73, 0x67, 0x51, 0x44, 0x42, 0x41, 0x67, 0x45, + 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x32, 0x34, + 0x44, 0x62, 0x67, 0x41, 0x51, 0x41, 0x45, 0x51, 0x41, 0x59, 0x51, + 0x42, 0x2b, 0x41, 0x41, 0x41, 0x42, 0x46, 0x52, 0x51, 0x47, 0x4b, + 0x77, 0x45, 0x69, 0x4a, 0x6a, 0x30, 0x42, 0x4e, 0x44, 0x59, 0x37, + 0x41, 0x54, 0x49, 0x57, 0x46, 0x52, 0x4d, 0x55, 0x42, 0x67, 0x63, + 0x4f, 0x41, 0x52, 0x30, 0x42, 0x46, 0x41, 0x59, 0x72, 0x41, 0x53, + 0x49, 0x6d, 0x50, 0x51, 0x45, 0x30, 0x4e, 0x6a, 0x63, 0x2b, 0x41, + 0x54, 0x55, 0x30, 0x4a, 0x69, 0x4d, 0x69, 0x42, 0x67, 0x63, 0x4f, + 0x41, 0x51, 0x63, 0x4f, 0x41, 0x53, 0x4d, 0x69, 0x4a, 0x69, 0x38, + 0x42, 0x4c, 0x67, 0x45, 0x33, 0x50, 0x67, 0x45, 0x7a, 0x4d, 0x54, + 0x49, 0x58, 0x48, 0x67, 0x45, 0x58, 0x46, 0x68, 0x55, 0x44, 0x49, + 0x67, 0x63, 0x4f, 0x41, 0x51, 0x63, 0x47, 0x46, 0x52, 0x51, 0x58, + 0x48, 0x67, 0x45, 0x58, 0x46, 0x6a, 0x4d, 0x79, 0x4e, 0x7a, 0x34, + 0x42, 0x4e, 0x7a, 0x59, 0x31, 0x4e, 0x43, 0x63, 0x75, 0x41, 0x53, + 0x63, 0x6d, 0x49, 0x77, 0x45, 0x55, 0x42, 0x77, 0x34, 0x42, 0x42, + 0x77, 0x59, 0x6a, 0x49, 0x69, 0x63, 0x75, 0x41, 0x53, 0x63, 0x6d, + 0x4e, 0x54, 0x51, 0x33, 0x50, 0x67, 0x45, 0x33, 0x4e, 0x6a, 0x4d, + 0x78, 0x4d, 0x68, 0x63, 0x65, 0x41, 0x52, 0x63, 0x57, 0x41, 0x66, + 0x63, 0x4c, 0x42, 0x31, 0x77, 0x49, 0x43, 0x67, 0x6f, 0x49, 0x58, + 0x41, 0x63, 0x4c, 0x6b, 0x6b, 0x4d, 0x66, 0x46, 0x68, 0x6f, 0x4c, + 0x42, 0x31, 0x77, 0x49, 0x43, 0x6a, 0x77, 0x66, 0x47, 0x52, 0x34, + 0x7a, 0x48, 0x41, 0x38, 0x65, 0x43, 0x67, 0x6b, 0x55, 0x45, 0x41, + 0x4d, 0x48, 0x42, 0x51, 0x4d, 0x46, 0x41, 0x6a, 0x34, 0x47, 0x41, + 0x67, 0x51, 0x6a, 0x59, 0x30, 0x45, 0x6a, 0x4a, 0x43, 0x4d, 0x35, + 0x45, 0x68, 0x4c, 0x53, 0x54, 0x45, 0x4a, 0x44, 0x59, 0x78, 0x30, + 0x64, 0x48, 0x52, 0x31, 0x6a, 0x51, 0x30, 0x4a, 0x4d, 0x53, 0x30, + 0x4e, 0x44, 0x59, 0x78, 0x30, 0x64, 0x48, 0x52, 0x31, 0x6a, 0x51, + 0x30, 0x4e, 0x4c, 0x41, 0x62, 0x63, 0x6a, 0x49, 0x6e, 0x64, 0x51, + 0x55, 0x46, 0x74, 0x62, 0x55, 0x46, 0x42, 0x33, 0x49, 0x79, 0x49, + 0x69, 0x49, 0x33, 0x64, 0x51, 0x55, 0x46, 0x74, 0x62, 0x55, 0x46, + 0x42, 0x33, 0x49, 0x69, 0x4d, 0x42, 0x43, 0x56, 0x73, 0x49, 0x43, + 0x77, 0x73, 0x49, 0x57, 0x77, 0x67, 0x4b, 0x43, 0x67, 0x67, 0x42, + 0x48, 0x44, 0x30, 0x36, 0x45, 0x67, 0x30, 0x55, 0x44, 0x52, 0x4d, + 0x48, 0x43, 0x77, 0x73, 0x48, 0x4a, 0x7a, 0x55, 0x73, 0x44, 0x67, + 0x77, 0x56, 0x46, 0x42, 0x6b, 0x67, 0x43, 0x41, 0x63, 0x47, 0x46, + 0x68, 0x4d, 0x45, 0x41, 0x77, 0x45, 0x43, 0x4c, 0x77, 0x51, 0x50, + 0x42, 0x6a, 0x63, 0x32, 0x44, 0x51, 0x30, 0x76, 0x48, 0x79, 0x41, + 0x6c, 0x41, 0x51, 0x41, 0x64, 0x48, 0x57, 0x4e, 0x44, 0x51, 0x30, + 0x74, 0x4d, 0x51, 0x6b, 0x4e, 0x6a, 0x48, 0x52, 0x30, 0x64, 0x48, + 0x57, 0x4e, 0x44, 0x51, 0x6b, 0x78, 0x4c, 0x51, 0x30, 0x4e, 0x6a, + 0x48, 0x52, 0x33, 0x2b, 0x6b, 0x6c, 0x74, 0x51, 0x55, 0x48, 0x63, + 0x69, 0x49, 0x79, 0x4d, 0x69, 0x64, 0x31, 0x42, 0x51, 0x57, 0x31, + 0x74, 0x51, 0x55, 0x48, 0x63, 0x69, 0x49, 0x79, 0x4d, 0x69, 0x64, + 0x31, 0x42, 0x51, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, 0x55, 0x38, 0x73, 0x33, + 0x37, 0x58, 0x77, 0x38, 0x38, 0x39, 0x51, 0x41, 0x4c, 0x42, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x31, 0x79, 0x70, 0x72, 0x4c, + 0x67, 0x41, 0x41, 0x41, 0x41, 0x44, 0x58, 0x4b, 0x6d, 0x73, 0x75, + 0x41, 0x41, 0x44, 0x2f, 0x74, 0x77, 0x53, 0x53, 0x41, 0x37, 0x63, + 0x41, 0x41, 0x41, 0x41, 0x49, 0x41, 0x41, 0x49, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, + 0x38, 0x44, 0x2f, 0x77, 0x41, 0x41, 0x41, 0x42, 0x4a, 0x49, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x42, 0x4a, 0x49, 0x41, 0x41, 0x51, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x44, 0x4d, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x43, 0x41, 0x41, 0x41, 0x41, 0x41, 0x74, 0x73, + 0x41, 0x41, 0x41, 0x4f, 0x33, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, + 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, 0x52, 0x51, 0x4d, 0x6c, 0x41, + 0x44, 0x38, 0x44, 0x62, 0x67, 0x41, 0x41, 0x41, 0x32, 0x34, 0x41, + 0x41, 0x41, 0x4e, 0x75, 0x41, 0x41, 0x41, 0x44, 0x62, 0x67, 0x41, + 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, 0x51, 0x41, 0x41, 0x41, + 0x41, 0x43, 0x53, 0x51, 0x41, 0x41, 0x41, 0x37, 0x73, 0x41, 0x41, + 0x41, 0x4d, 0x41, 0x41, 0x47, 0x4d, 0x43, 0x74, 0x77, 0x41, 0x2b, + 0x42, 0x41, 0x41, 0x41, 0x43, 0x51, 0x53, 0x53, 0x41, 0x41, 0x41, + 0x45, 0x53, 0x51, 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x4d, 0x6c, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x6c, 0x42, + 0x45, 0x6b, 0x41, 0x41, 0x41, 0x4e, 0x75, 0x41, 0x41, 0x41, 0x44, + 0x74, 0x77, 0x41, 0x41, 0x41, 0x6b, 0x6b, 0x41, 0x41, 0x41, 0x4a, + 0x4a, 0x41, 0x41, 0x41, 0x42, 0x6b, 0x67, 0x41, 0x6c, 0x41, 0x55, + 0x6b, 0x41, 0x41, 0x41, 0x4a, 0x4a, 0x41, 0x41, 0x41, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x6c, 0x73, 0x41, 0x47, 0x67, 0x49, 0x33, + 0x41, 0x41, 0x63, 0x42, 0x67, 0x41, 0x41, 0x61, 0x41, 0x56, 0x73, + 0x41, 0x42, 0x77, 0x52, 0x4a, 0x41, 0x41, 0x41, 0x44, 0x62, 0x67, + 0x41, 0x41, 0x41, 0x32, 0x34, 0x41, 0x41, 0x41, 0x52, 0x4a, 0x41, + 0x42, 0x38, 0x44, 0x62, 0x67, 0x41, 0x41, 0x41, 0x32, 0x34, 0x41, + 0x41, 0x41, 0x4e, 0x63, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, + 0x53, 0x42, 0x4a, 0x49, 0x41, 0x44, 0x51, 0x53, 0x53, 0x41, 0x41, + 0x41, 0x45, 0x4e, 0x77, 0x41, 0x41, 0x42, 0x41, 0x41, 0x41, 0x45, + 0x77, 0x4e, 0x75, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x6f, 0x41, 0x46, 0x41, 0x41, 0x65, 0x41, 0x48, 0x51, + 0x41, 0x30, 0x41, 0x46, 0x53, 0x41, 0x5a, 0x41, 0x42, 0x37, 0x41, + 0x4c, 0x43, 0x41, 0x77, 0x41, 0x44, 0x63, 0x67, 0x51, 0x47, 0x42, + 0x4c, 0x59, 0x46, 0x59, 0x67, 0x57, 0x69, 0x42, 0x68, 0x6f, 0x47, + 0x52, 0x41, 0x5a, 0x77, 0x42, 0x73, 0x77, 0x47, 0x2f, 0x41, 0x6a, + 0x55, 0x43, 0x55, 0x41, 0x4a, 0x63, 0x67, 0x6f, 0x47, 0x43, 0x73, + 0x59, 0x4c, 0x43, 0x67, 0x76, 0x65, 0x44, 0x41, 0x59, 0x4d, 0x4c, + 0x41, 0x78, 0x55, 0x44, 0x48, 0x77, 0x4d, 0x78, 0x41, 0x31, 0x6b, + 0x44, 0x64, 0x59, 0x4f, 0x53, 0x41, 0x36, 0x47, 0x44, 0x73, 0x51, + 0x50, 0x43, 0x67, 0x39, 0x6b, 0x44, 0x35, 0x51, 0x50, 0x2f, 0x42, + 0x41, 0x73, 0x45, 0x4a, 0x77, 0x51, 0x39, 0x68, 0x46, 0x51, 0x45, + 0x66, 0x67, 0x53, 0x46, 0x68, 0x4b, 0x4f, 0x45, 0x79, 0x59, 0x54, + 0x32, 0x67, 0x41, 0x42, 0x41, 0x41, 0x41, 0x41, 0x4d, 0x77, 0x46, + 0x56, 0x41, 0x41, 0x6f, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x49, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x44, 0x67, 0x43, 0x75, 0x41, 0x41, 0x45, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x67, + 0x41, 0x41, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x49, 0x41, 0x42, 0x77, 0x41, 0x7a, 0x41, 0x41, 0x45, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x4d, 0x41, 0x41, 0x67, 0x41, + 0x6e, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x51, 0x41, 0x41, 0x67, 0x42, 0x49, 0x41, 0x41, 0x45, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x55, 0x41, 0x43, 0x77, 0x41, 0x47, + 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x59, + 0x41, 0x41, 0x67, 0x41, 0x74, 0x41, 0x41, 0x45, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x6f, 0x41, 0x47, 0x67, 0x42, 0x4f, 0x41, + 0x41, 0x4d, 0x41, 0x41, 0x51, 0x51, 0x4a, 0x41, 0x41, 0x45, 0x41, + 0x42, 0x41, 0x41, 0x43, 0x41, 0x41, 0x4d, 0x41, 0x41, 0x51, 0x51, + 0x4a, 0x41, 0x41, 0x49, 0x41, 0x44, 0x67, 0x41, 0x36, 0x41, 0x41, + 0x4d, 0x41, 0x41, 0x51, 0x51, 0x4a, 0x41, 0x41, 0x4d, 0x41, 0x42, + 0x41, 0x41, 0x70, 0x41, 0x41, 0x4d, 0x41, 0x41, 0x51, 0x51, 0x4a, + 0x41, 0x41, 0x51, 0x41, 0x42, 0x41, 0x42, 0x4b, 0x41, 0x41, 0x4d, + 0x41, 0x41, 0x51, 0x51, 0x4a, 0x41, 0x41, 0x55, 0x41, 0x46, 0x67, + 0x41, 0x52, 0x41, 0x41, 0x4d, 0x41, 0x41, 0x51, 0x51, 0x4a, 0x41, + 0x41, 0x59, 0x41, 0x42, 0x41, 0x41, 0x76, 0x41, 0x41, 0x4d, 0x41, + 0x41, 0x51, 0x51, 0x4a, 0x41, 0x41, 0x6f, 0x41, 0x4e, 0x41, 0x42, + 0x6f, 0x5a, 0x6d, 0x45, 0x41, 0x5a, 0x67, 0x42, 0x68, 0x56, 0x6d, + 0x56, 0x79, 0x63, 0x32, 0x6c, 0x76, 0x62, 0x69, 0x41, 0x78, 0x4c, + 0x6a, 0x41, 0x41, 0x56, 0x67, 0x42, 0x6c, 0x41, 0x48, 0x49, 0x41, + 0x63, 0x77, 0x42, 0x70, 0x41, 0x47, 0x38, 0x41, 0x62, 0x67, 0x41, + 0x67, 0x41, 0x44, 0x45, 0x41, 0x4c, 0x67, 0x41, 0x77, 0x5a, 0x6d, + 0x45, 0x41, 0x5a, 0x67, 0x42, 0x68, 0x5a, 0x6d, 0x45, 0x41, 0x5a, + 0x67, 0x42, 0x68, 0x55, 0x6d, 0x56, 0x6e, 0x64, 0x57, 0x78, 0x68, + 0x63, 0x67, 0x42, 0x53, 0x41, 0x47, 0x55, 0x41, 0x5a, 0x77, 0x42, + 0x31, 0x41, 0x47, 0x77, 0x41, 0x59, 0x51, 0x42, 0x79, 0x5a, 0x6d, + 0x45, 0x41, 0x5a, 0x67, 0x42, 0x68, 0x52, 0x6d, 0x39, 0x75, 0x64, + 0x43, 0x42, 0x6e, 0x5a, 0x57, 0x35, 0x6c, 0x63, 0x6d, 0x46, 0x30, + 0x5a, 0x57, 0x51, 0x67, 0x59, 0x6e, 0x6b, 0x67, 0x53, 0x57, 0x4e, + 0x76, 0x54, 0x57, 0x39, 0x76, 0x62, 0x69, 0x34, 0x41, 0x52, 0x67, + 0x42, 0x76, 0x41, 0x47, 0x34, 0x41, 0x64, 0x41, 0x41, 0x67, 0x41, + 0x47, 0x63, 0x41, 0x5a, 0x51, 0x42, 0x75, 0x41, 0x47, 0x55, 0x41, + 0x63, 0x67, 0x42, 0x68, 0x41, 0x48, 0x51, 0x41, 0x5a, 0x51, 0x42, + 0x6b, 0x41, 0x43, 0x41, 0x41, 0x59, 0x67, 0x42, 0x35, 0x41, 0x43, + 0x41, 0x41, 0x53, 0x51, 0x42, 0x6a, 0x41, 0x47, 0x38, 0x41, 0x54, + 0x51, 0x42, 0x76, 0x41, 0x47, 0x38, 0x41, 0x62, 0x67, 0x41, 0x75, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x77, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, + 0x41, 0x41, 0x3d, 0x3d, 0x29, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, + 0x74, 0x28, 0x27, 0x77, 0x6f, 0x66, 0x66, 0x27, 0x29, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x66, 0x6f, 0x6e, + 0x74, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3a, 0x20, 0x6e, 0x6f, + 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x7d, 0x5b, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x5e, 0x3d, 0x22, 0x66, 0x61, 0x2d, 0x22, 0x5d, 0x2c, 0x5b, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x2a, 0x3d, 0x22, 0x20, 0x66, 0x61, + 0x2d, 0x22, 0x5d, 0x7b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x66, 0x61, + 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x27, 0x66, 0x61, 0x27, 0x20, 0x21, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x61, 0x6e, 0x74, 0x3b, 0x73, + 0x70, 0x65, 0x61, 0x6b, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3a, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, + 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x6e, 0x6f, 0x72, 0x6d, + 0x61, 0x6c, 0x3b, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x76, 0x61, 0x72, + 0x69, 0x61, 0x6e, 0x74, 0x3a, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x3b, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x6c, + 0x69, 0x6e, 0x65, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, + 0x31, 0x3b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x69, + 0x6e, 0x67, 0x3a, 0x61, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x69, 0x61, + 0x73, 0x65, 0x64, 0x3b, 0x2d, 0x6d, 0x6f, 0x7a, 0x2d, 0x6f, 0x73, + 0x78, 0x2d, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x6d, 0x6f, 0x6f, + 0x74, 0x68, 0x69, 0x6e, 0x67, 0x3a, 0x67, 0x72, 0x61, 0x79, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x73, 0x70, + 0x69, 0x6e, 0x7b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, + 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x66, + 0x61, 0x2d, 0x73, 0x70, 0x69, 0x6e, 0x20, 0x32, 0x73, 0x20, 0x69, + 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, 0x20, 0x6c, 0x69, 0x6e, + 0x65, 0x61, 0x72, 0x3b, 0x61, 0x6e, 0x69, 0x6d, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x66, 0x61, 0x2d, 0x73, 0x70, 0x69, 0x6e, 0x20, + 0x32, 0x73, 0x20, 0x69, 0x6e, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x65, + 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x7d, 0x40, 0x2d, 0x77, + 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x6b, 0x65, 0x79, 0x66, 0x72, + 0x61, 0x6d, 0x65, 0x73, 0x20, 0x22, 0x66, 0x61, 0x2d, 0x73, 0x70, + 0x69, 0x6e, 0x22, 0x7b, 0x30, 0x25, 0x7b, 0x2d, 0x77, 0x65, 0x62, + 0x6b, 0x69, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, + 0x72, 0x6d, 0x3a, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x30, + 0x64, 0x65, 0x67, 0x29, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x3a, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, + 0x30, 0x64, 0x65, 0x67, 0x29, 0x3b, 0x7d, 0x31, 0x30, 0x30, 0x25, + 0x7b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x72, 0x6f, 0x74, + 0x61, 0x74, 0x65, 0x28, 0x33, 0x35, 0x39, 0x64, 0x65, 0x67, 0x29, + 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, + 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x33, 0x35, 0x39, 0x64, + 0x65, 0x67, 0x29, 0x3b, 0x7d, 0x7d, 0x40, 0x6b, 0x65, 0x79, 0x66, + 0x72, 0x61, 0x6d, 0x65, 0x73, 0x20, 0x22, 0x66, 0x61, 0x2d, 0x73, + 0x70, 0x69, 0x6e, 0x22, 0x7b, 0x30, 0x25, 0x7b, 0x2d, 0x77, 0x65, + 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, + 0x6f, 0x72, 0x6d, 0x3a, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, + 0x30, 0x64, 0x65, 0x67, 0x29, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, + 0x28, 0x30, 0x64, 0x65, 0x67, 0x29, 0x3b, 0x7d, 0x31, 0x30, 0x30, + 0x25, 0x7b, 0x2d, 0x77, 0x65, 0x62, 0x6b, 0x69, 0x74, 0x2d, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x3a, 0x72, 0x6f, + 0x74, 0x61, 0x74, 0x65, 0x28, 0x33, 0x35, 0x39, 0x64, 0x65, 0x67, + 0x29, 0x3b, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, + 0x3a, 0x72, 0x6f, 0x74, 0x61, 0x74, 0x65, 0x28, 0x33, 0x35, 0x39, + 0x64, 0x65, 0x67, 0x29, 0x3b, 0x7d, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x2d, 0x6f, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x39, 0x36, 0x22, 0x3b, 0x7d, + 0x2e, 0x66, 0x61, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x30, 0x37, 0x22, 0x7d, 0x2e, + 0x66, 0x61, 0x2d, 0x74, 0x68, 0x2d, 0x6c, 0x61, 0x72, 0x67, 0x65, + 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x30, 0x39, + 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x74, 0x68, 0x2d, 0x6c, 0x69, + 0x73, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, + 0x30, 0x62, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, + 0x30, 0x63, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x6c, 0x6f, + 0x73, 0x65, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, + 0x30, 0x64, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x72, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, + 0x30, 0x30, 0x64, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, + 0x30, 0x30, 0x64, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x6f, + 0x67, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x31, + 0x33, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x67, 0x65, 0x61, 0x72, + 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x31, 0x33, + 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x66, 0x69, 0x6c, 0x65, 0x2d, + 0x6f, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x31, + 0x36, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x6c, 0x6f, 0x63, + 0x6b, 0x2d, 0x6f, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, + 0x30, 0x31, 0x37, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x72, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x30, 0x32, 0x31, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x6c, 0x69, 0x73, 0x74, 0x2d, 0x61, 0x6c, 0x74, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x32, 0x32, 0x22, 0x7d, 0x2e, + 0x66, 0x61, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x3a, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x33, 0x61, 0x22, 0x7d, 0x2e, 0x66, + 0x61, 0x2d, 0x6d, 0x61, 0x70, 0x2d, 0x6d, 0x61, 0x72, 0x6b, 0x65, + 0x72, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x34, + 0x31, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x2d, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x2d, 0x6f, 0x3a, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x34, 0x36, 0x22, + 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x68, 0x65, 0x76, 0x72, 0x6f, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, + 0x22, 0x5c, 0x66, 0x30, 0x35, 0x33, 0x22, 0x7d, 0x2e, 0x66, 0x61, + 0x2d, 0x63, 0x68, 0x65, 0x76, 0x72, 0x6f, 0x6e, 0x2d, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, + 0x30, 0x35, 0x34, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x65, 0x78, + 0x63, 0x6c, 0x61, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x74, + 0x72, 0x69, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x3a, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x37, 0x31, 0x22, 0x7d, 0x2e, 0x66, + 0x61, 0x2d, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x3a, 0x62, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x37, 0x31, 0x22, 0x7d, + 0x2e, 0x66, 0x61, 0x2d, 0x62, 0x61, 0x72, 0x2d, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, + 0x38, 0x30, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x62, 0x61, 0x72, + 0x2d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x6f, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x38, 0x30, 0x22, 0x7d, 0x2e, + 0x66, 0x61, 0x2d, 0x63, 0x6f, 0x67, 0x73, 0x3a, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x38, 0x35, 0x22, 0x7d, 0x2e, 0x66, + 0x61, 0x2d, 0x67, 0x65, 0x61, 0x72, 0x73, 0x3a, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x38, 0x35, 0x22, 0x7d, 0x2e, 0x66, + 0x61, 0x2d, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2d, + 0x6c, 0x69, 0x6e, 0x6b, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, + 0x66, 0x30, 0x38, 0x65, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x62, + 0x65, 0x6c, 0x6c, 0x2d, 0x6f, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x30, 0x61, 0x32, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x30, 0x63, 0x30, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x75, 0x73, 0x65, 0x72, 0x73, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x30, 0x63, 0x30, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x62, 0x61, 0x72, 0x73, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, + 0x66, 0x30, 0x63, 0x39, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x6e, + 0x61, 0x76, 0x69, 0x63, 0x6f, 0x6e, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, + 0x22, 0x5c, 0x66, 0x30, 0x63, 0x39, 0x22, 0x7d, 0x2e, 0x66, 0x61, + 0x2d, 0x72, 0x65, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x63, 0x39, 0x22, 0x7d, 0x2e, + 0x66, 0x61, 0x2d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x63, 0x65, 0x22, 0x7d, 0x2e, + 0x66, 0x61, 0x2d, 0x63, 0x61, 0x72, 0x65, 0x74, 0x2d, 0x64, 0x6f, + 0x77, 0x6e, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, + 0x64, 0x37, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x61, 0x72, + 0x65, 0x74, 0x2d, 0x75, 0x70, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x30, 0x64, 0x38, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x63, 0x61, 0x72, 0x65, 0x74, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x64, 0x39, 0x22, + 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x61, 0x72, 0x65, 0x74, 0x2d, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x30, 0x64, 0x61, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x73, 0x6f, 0x72, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, + 0x66, 0x30, 0x64, 0x63, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x75, + 0x6e, 0x73, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x3a, 0x62, 0x65, 0x66, + 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x64, 0x63, 0x22, 0x7d, 0x2e, 0x66, + 0x61, 0x2d, 0x64, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x30, 0x65, 0x34, + 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x74, 0x61, 0x63, 0x68, 0x6f, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x30, 0x65, 0x34, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x75, 0x62, 0x6c, + 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, + 0x22, 0x5c, 0x66, 0x31, 0x30, 0x30, 0x22, 0x7d, 0x2e, 0x66, 0x61, + 0x2d, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x75, 0x62, + 0x6c, 0x65, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x31, 0x30, 0x31, 0x22, 0x7d, 0x2e, + 0x66, 0x61, 0x2d, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2d, 0x6c, 0x65, + 0x66, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x31, + 0x30, 0x34, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x61, 0x6e, 0x67, + 0x6c, 0x65, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x31, 0x30, 0x35, 0x22, 0x7d, 0x2e, + 0x66, 0x61, 0x2d, 0x64, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x3a, + 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x31, 0x30, 0x38, 0x22, + 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, + 0x2d, 0x6f, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x31, + 0x30, 0x63, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, + 0x63, 0x6c, 0x65, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, + 0x31, 0x31, 0x31, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x63, 0x6f, + 0x64, 0x65, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x31, + 0x32, 0x31, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x66, 0x69, 0x6c, + 0x65, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x31, 0x35, + 0x62, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x66, 0x69, 0x6c, 0x65, + 0x2d, 0x74, 0x65, 0x78, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x31, 0x35, 0x63, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, + 0x22, 0x5c, 0x66, 0x31, 0x61, 0x30, 0x22, 0x7d, 0x2e, 0x66, 0x61, + 0x2d, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x2d, 0x6f, 0x2d, 0x6e, + 0x6f, 0x74, 0x63, 0x68, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, + 0x66, 0x31, 0x63, 0x65, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x62, + 0x65, 0x6c, 0x6c, 0x2d, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x2d, 0x6f, + 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x31, 0x66, 0x37, + 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, 0x61, 0x72, 0x65, 0x61, 0x2d, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x3a, 0x62, 0x65, 0x66, 0x6f, 0x72, + 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x22, + 0x5c, 0x66, 0x31, 0x66, 0x65, 0x22, 0x7d, 0x2e, 0x66, 0x61, 0x2d, + 0x63, 0x68, 0x72, 0x6f, 0x6d, 0x65, 0x3a, 0x62, 0x65, 0x66, 0x6f, + 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, + 0x22, 0x5c, 0x66, 0x32, 0x36, 0x38, 0x22, 0x7d, 0x2e, 0x66, 0x61, + 0x2d, 0x68, 0x61, 0x73, 0x68, 0x74, 0x61, 0x67, 0x3a, 0x62, 0x65, + 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x32, 0x39, 0x32, 0x22, 0x7d, 0x2e, + 0x66, 0x61, 0x2d, 0x71, 0x75, 0x65, 0x73, 0x74, 0x69, 0x6f, 0x6e, + 0x2d, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x2d, 0x6f, 0x3a, 0x62, + 0x65, 0x66, 0x6f, 0x72, 0x65, 0x7b, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x3a, 0x22, 0x5c, 0x66, 0x32, 0x39, 0x63, 0x22, 0x7d, + 0x00 +}; + +const int fa_css_length = 18459; diff --git a/goaccess++/src/gdashboard.c b/goaccess++/src/gdashboard.c new file mode 100644 index 0000000..64d15ff --- /dev/null +++ b/goaccess++/src/gdashboard.c @@ -0,0 +1,1510 @@ +/** + * gdashboard.c -- goaccess main dashboard + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _XOPEN_SOURCE 700 + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <regex.h> + +#include "gdashboard.h" + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#include "color.h" +#include "error.h" +#include "gstorage.h" +#include "util.h" +#include "xmalloc.h" + +static GFind find_t; + +/* Reset find indices */ +void +reset_find (void) +{ + if (find_t.pattern != NULL && *find_t.pattern != '\0') + free (find_t.pattern); + + find_t.look_in_sub = 0; + find_t.module = 0; + find_t.next_idx = 0; /* next total index */ + find_t.next_parent_idx = 0; /* next parent index */ + find_t.next_sub_idx = 0; /* next sub item index */ + find_t.pattern = NULL; +} + +/* Allocate memory for a new GDash instance. + * + * On success, the newly allocated GDash is returned . */ +GDash * +new_gdash (void) +{ + GDash *dash = xmalloc (sizeof (GDash)); + memset (dash, 0, sizeof *dash); + dash->total_alloc = 0; + + return dash; +} + +/* Allocate memory for a new GDashData instance. + * + * On success, the newly allocated GDashData is returned . */ +GDashData * +new_gdata (uint32_t size) +{ + GDashData *data = xcalloc (size, sizeof (GDashData)); + + return data; +} + +/* Free memory allocated for a GDashData instance. Includes malloc'd + * strings. */ +static void +free_dashboard_data (GDashData item) +{ + if (item.metrics == NULL) + return; + + if (item.metrics->data) + free (item.metrics->data); + if (item.metrics->bw.sbw) + free (item.metrics->bw.sbw); + if (conf.serve_usecs && item.metrics->avgts.sts) + free (item.metrics->avgts.sts); + if (conf.serve_usecs && item.metrics->cumts.sts) + free (item.metrics->cumts.sts); + if (conf.serve_usecs && item.metrics->maxts.sts) + free (item.metrics->maxts.sts); + free (item.metrics); +} + +/* Free memory allocated for a GDash instance, and nested structure + * data. */ +void +free_dashboard (GDash * dash) +{ + GModule module; + int j; + size_t idx = 0; + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + for (j = 0; j < dash->module[module].alloc_data; j++) { + free_dashboard_data (dash->module[module].data[j]); + } + free (dash->module[module].data); + } + free (dash); +} + +/* Get the current panel/module given the `Y` offset (position) in the + * terminal dashboard. + * + * If not found, 0 is returned. + * If found, the module number is returned . */ +static GModule +get_find_current_module (GDash * dash, int offset) +{ + GModule module; + size_t idx = 0; + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + /* set current module */ + if (dash->module[module].pos_y == offset) + return module; + /* we went over by one module, set current - 1 */ + if (dash->module[module].pos_y > offset) + return module - 1; + } + + return 0; +} + +/* Get the number of rows that a collapsed dashboard panel contains. + * + * On success, the number of rows is returned. */ +int +get_num_collapsed_data_rows (void) +{ + /* The default number of rows is fixed */ + int size = DASH_COLLAPSED - DASH_NON_DATA; + /* If no column names, then add the number of rows occupied by the + * column values to the default number */ + return conf.no_column_names ? size + DASH_COL_ROWS : size; +} + +/* Get the number of rows that an expanded dashboard panel contains. + * + * On success, the number of rows is returned. */ +int +get_num_expanded_data_rows (void) +{ + /* The default number of rows is fixed */ + int size = DASH_EXPANDED - DASH_NON_DATA; + /* If no column names, then add the number of rows occupied by the + * column values to the default number */ + return conf.no_column_names ? size + DASH_COL_ROWS : size; +} + +/* Get the Y position of the terminal dashboard where data rows + * (metrics) start. + * + * On success, the Y position is returned. */ +static int +get_data_pos_rows (void) +{ + return conf.no_column_names ? DASH_DATA_POS - DASH_COL_ROWS : DASH_DATA_POS; +} + +/* Get the initial X position of the terminal dashboard where metrics + * and data columns start. + * + * On success, the X position is returned. */ +static int +get_xpos (void) +{ + return DASH_INIT_X; +} + +/* Determine which module should be expanded given the current mouse + * position. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +int +set_module_from_mouse_event (GScroll * gscroll, GDash * dash, int y) +{ + int module = 0; + int offset = y - MAX_HEIGHT_HEADER - MAX_HEIGHT_FOOTER + 1; + if (gscroll->expanded) { + module = get_find_current_module (dash, offset); + } else { + offset += gscroll->dash; + module = offset / DASH_COLLAPSED; + } + + if (module >= TOTAL_MODULES) + module = TOTAL_MODULES - 1; + else if (module < 0) + module = 0; + + if ((int) gscroll->current == module) + return 1; + + gscroll->current = module; + return 0; +} + +/* Allocate a new string for a sub item on the terminal dashboard. + * + * On error, NULL is returned. + * On success, the newly allocated string is returned. */ +static char * +render_child_node (const char *data) +{ + char *buf; + int len = 0; + + /* chars to use based on encoding used */ +#ifdef HAVE_LIBNCURSESW + const char *bend = "\xe2\x94\x9c"; + const char *horz = "\xe2\x94\x80"; +#else + const char *bend = "|"; + const char *horz = "`-"; +#endif + + if (data == NULL || *data == '\0') + return NULL; + + len = snprintf (NULL, 0, " %s%s %s", bend, horz, data); + buf = xmalloc (len + 3); + sprintf (buf, " %s%s %s", bend, horz, data); + + return buf; +} + +/* Get a string of bars given current hits, maximum hit & xpos. + * + * On success, the newly allocated string representing the chart is + * returned. */ +static char * +get_bars (int n, int max, int x) +{ + int w, h; + float len = 0.0; + + getmaxyx (stdscr, h, w); + (void) h; /* avoid lint warning */ + + len = ((((float) n) / max)); + len *= (w - x); + if (len < 1) + len = 1; + return char_repeat (len, '|'); +} + +/* Set largest hits metric (length of the integer). */ +static void +set_max_hit_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = intlen (idata->metrics->hits); + int llen = strlen (MTRC_HITS_LBL); + + if (vlen > meta->hits_len) + meta->hits_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->hits_len) + meta->hits_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_hit_perc_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = intlen (idata->metrics->hits_perc); + int llen = strlen (MTRC_HITS_PERC_LBL); + + if (vlen > meta->hits_perc_len) + meta->hits_perc_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->hits_perc_len) + meta->hits_perc_len = llen; +} + +/* Set largest hits metric (length of the integer). */ +static void +set_max_visitors_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = intlen (idata->metrics->visitors); + int llen = strlen (MTRC_VISITORS_SHORT_LBL); + + if (vlen > meta->visitors_len) + meta->visitors_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->visitors_len) + meta->visitors_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_visitors_perc_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = intlen (idata->metrics->visitors_perc); + int llen = strlen (MTRC_VISITORS_PERC_LBL); + + if (vlen > meta->visitors_perc_len) + meta->visitors_perc_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->visitors_perc_len) + meta->visitors_perc_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_bw_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = strlen (idata->metrics->bw.sbw); + int llen = strlen (MTRC_BW_LBL); + + if (vlen > meta->bw_len) + meta->bw_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->bw_len) + meta->bw_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_avgts_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = 0, llen = 0; + + if (!conf.serve_usecs || !idata->metrics->avgts.sts) + return; + + vlen = strlen (idata->metrics->avgts.sts); + llen = strlen (MTRC_AVGTS_LBL); + + if (vlen > meta->avgts_len) + meta->avgts_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->avgts_len) + meta->avgts_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_cumts_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = 0, llen = 0; + + if (!conf.serve_usecs || !idata->metrics->cumts.sts) + return; + + vlen = strlen (idata->metrics->cumts.sts); + llen = strlen (MTRC_AVGTS_LBL); + + if (vlen > meta->cumts_len) + meta->cumts_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->cumts_len) + meta->cumts_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_maxts_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = 0, llen = 0; + + if (!conf.serve_usecs || !idata->metrics->maxts.sts) + return; + + vlen = strlen (idata->metrics->maxts.sts); + llen = strlen (MTRC_AVGTS_LBL); + + if (vlen > meta->maxts_len) + meta->maxts_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->maxts_len) + meta->maxts_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_method_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = 0, llen = 0; + + if (!conf.append_method || !idata->metrics->method) + return; + + vlen = strlen (idata->metrics->method); + llen = strlen (MTRC_METHODS_SHORT_LBL); + + if (vlen > meta->method_len) + meta->method_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->method_len) + meta->method_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_protocol_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = 0, llen = 0; + + if (!conf.append_protocol || !idata->metrics->protocol) + return; + + vlen = strlen (idata->metrics->protocol); + llen = strlen (MTRC_PROTOCOLS_SHORT_LBL); + + if (vlen > meta->protocol_len) + meta->protocol_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->protocol_len) + meta->protocol_len = llen; +} + +/* Get the percent integer length. */ +static void +set_max_data_len (GDashMeta * meta, GDashData * idata) +{ + int vlen = 0, llen = 0; + + vlen = strlen (idata->metrics->data); + llen = strlen (MTRC_DATA_LBL); + + if (vlen > meta->data_len) + meta->data_len = vlen; + + /* if outputting with column names, then determine if the value is + * longer than the length of the column name */ + if (llen > meta->data_len) + meta->data_len = llen; +} + +static void +set_max_values (GDashMeta * meta, GMetrics * metrics) +{ + if (metrics->hits > meta->max_hits) + meta->max_hits = metrics->hits; + if (metrics->visitors > meta->max_visitors) + meta->max_visitors = metrics->visitors; +} + +static void +set_metrics_len (GDashMeta * meta, GDashData * idata) +{ + /* integer-based length */ + set_max_hit_len (meta, idata); + set_max_hit_perc_len (meta, idata); + set_max_visitors_len (meta, idata); + set_max_visitors_perc_len (meta, idata); + + /* string-based length */ + set_max_bw_len (meta, idata); + set_max_avgts_len (meta, idata); + set_max_cumts_len (meta, idata); + set_max_maxts_len (meta, idata); + + set_max_method_len (meta, idata); + set_max_protocol_len (meta, idata); + set_max_data_len (meta, idata); +} + +/* Render host's panel selected row */ +static void +render_data_hosts (WINDOW * win, GDashRender render, char *value, int x) +{ + char *padded_data; + + padded_data = left_pad_str (value, x); + draw_header (win, padded_data, "%s", render.y, 0, render.w, color_selected); + free (padded_data); +} + +/* Set panel's date on the given buffer + * + * On error, '---' placeholder is returned. + * On success, the formatted date is returned. */ +static char * +set_visitors_date (const char *value) +{ + return get_visitors_date (value, conf.spec_date_time_num_format, + conf.spec_date_time_format); +} + +static char * +get_fixed_fmt_width (int w, char type) +{ + char *fmt = xmalloc (snprintf (NULL, 0, "%%%d%c", w, type) + 1); + sprintf (fmt, "%%%d%c", w, type); + + return fmt; +} + +/* Render the 'total' label on each panel */ +static void +render_total_label (WINDOW * win, GDashModule * data, int y, + GColors * (*func) (void)) +{ + char *s; + int win_h, win_w, total, ht_size; + + total = data->holder_size; + ht_size = data->ht_size; + + s = xmalloc (snprintf (NULL, 0, "%s: %d/%d", GEN_TOTAL, total, ht_size) + 1); + getmaxyx (win, win_h, win_w); + (void) win_h; + + sprintf (s, "%s: %d/%d", GEN_TOTAL, total, ht_size); + draw_header (win, s, "%s", y, win_w - strlen (s) - 2, win_w, func); + free (s); +} + +/* Render panel bar graph */ +static void +render_bars (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color (COLOR_BARS); + WINDOW *win = render.win; + char *bar; + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + + bar = get_bars (data->data[idx].metrics->hits, data->meta.max_hits, *x); + if (sel) + draw_header (win, bar, "%s", y, *x, w, color_selected); + else { + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%s", bar); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + free (bar); +} + +/* Render the data metric for each panel */ +static void +render_data (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_DATA, data->module); + WINDOW *win = render.win; + + char *date = NULL, *value = NULL, *buf = NULL; + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + int date_len = 0; + + value = substring (data->data[idx].metrics->data, 0, w - *x); + if (data->module == VISITORS) { + date = set_visitors_date (value); + date_len = strlen (date); + } + + if (sel && data->module == HOSTS && data->data[idx].is_subitem) { + render_data_hosts (win, render, value, *x); + } else if (sel) { + buf = data->module == VISITORS ? date : value; + draw_header (win, buf, "%s", y, *x, w, color_selected); + } else { + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%s", data->module == VISITORS ? date : value); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + + *x += data->module == VISITORS ? date_len : data->meta.data_len; + *x += DASH_SPACE; + free (value); + free (date); +} + +/* Render the method metric for each panel + * + * On error, no method is rendered and it returns. + * On success, method is rendered. */ +static void +render_method (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_MTHD, data->module); + WINDOW *win = render.win; + + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + char *method = data->data[idx].metrics->method; + + if (method == NULL || *method == '\0') + return; + + if (sel) { + /* selected state */ + draw_header (win, method, "%s", y, *x, w, color_selected); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%s", method); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + + *x += data->meta.method_len + DASH_SPACE; +} + +/* Render the protocol metric for each panel + * + * On error, no protocol is rendered and it returns. + * On success, protocol is rendered. */ +static void +render_proto (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_PROT, data->module); + WINDOW *win = render.win; + + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + char *protocol = data->data[idx].metrics->protocol; + + if (protocol == NULL || *protocol == '\0') + return; + + if (sel) { + /* selected state */ + draw_header (win, protocol, "%s", y, *x, w, color_selected); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%s", protocol); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + + *x += REQ_PROTO_LEN - 1 + DASH_SPACE; +} + +/* Render the average time served metric for each panel */ +static void +render_avgts (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_AVGTS, data->module); + WINDOW *win = render.win; + + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + char *avgts = data->data[idx].metrics->avgts.sts; + + if (data->module == HOSTS && data->data[idx].is_subitem) + goto out; + + if (sel) { + /* selected state */ + draw_header (win, avgts, "%9s", y, *x, w, color_selected); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%9s", avgts); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + +out: + *x += DASH_SRV_TM_LEN + DASH_SPACE; +} + +/* Render the cumulative time served metric for each panel */ +static void +render_cumts (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_CUMTS, data->module); + WINDOW *win = render.win; + + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + char *cumts = data->data[idx].metrics->cumts.sts; + + if (data->module == HOSTS && data->data[idx].is_subitem) + goto out; + + if (sel) { + /* selected state */ + draw_header (win, cumts, "%9s", y, *x, w, color_selected); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%9s", cumts); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + +out: + *x += DASH_SRV_TM_LEN + DASH_SPACE; +} + +/* Render the maximum time served metric for each panel */ +static void +render_maxts (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_MAXTS, data->module); + WINDOW *win = render.win; + + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + char *maxts = data->data[idx].metrics->maxts.sts; + + if (data->module == HOSTS && data->data[idx].is_subitem) + goto out; + + if (sel) { + /* selected state */ + draw_header (win, maxts, "%9s", y, *x, w, color_selected); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%9s", maxts); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + +out: + *x += DASH_SRV_TM_LEN + DASH_SPACE; +} + +/* Render the bandwidth metric for each panel */ +static void +render_bw (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_BW, data->module); + WINDOW *win = render.win; + + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + char *bw = data->data[idx].metrics->bw.sbw; + + if (data->module == HOSTS && data->data[idx].is_subitem) + goto out; + + if (sel) { + char *fw = get_fixed_fmt_width (data->meta.bw_len, 's'); + /* selected state */ + draw_header (win, bw, fw, y, *x, w, color_selected); + free (fw); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%*s", data->meta.bw_len, bw); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + +out: + *x += data->meta.bw_len + DASH_SPACE; +} + +/* Render a percent metric */ +static void +render_percent (GDashRender render, GColors * color, float perc, int len, int x) +{ + WINDOW *win = render.win; + char *percent; + int y = render.y, w = render.w, sel = render.sel; + + if (sel) { + /* selected state */ + percent = float2str (perc, len); + draw_header (win, percent, "%s%%", y, x, w, color_selected); + free (percent); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, x, "%*.2f%%", len, perc); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } +} + +/* Render the hits percent metric for each panel */ +static void +render_hits_percent (GDashModule * data, GDashRender render, int *x) +{ + GColorItem item = COLOR_MTRC_HITS_PERC; + GColors *color; + int l = data->meta.hits_perc_len + 3, idx = render.idx; + + if (data->module == HOSTS && data->data[idx].is_subitem) + goto out; + + if (data->meta.max_hits == data->data[idx].metrics->hits) + item = COLOR_MTRC_HITS_PERC_MAX; + + color = get_color_by_item_module (item, data->module); + render_percent (render, color, data->data[idx].metrics->hits_perc, l, *x); + +out: + *x += l + 1 + DASH_SPACE; +} + +/* Render the visitors percent metric for each panel */ +static void +render_visitors_percent (GDashModule * data, GDashRender render, int *x) +{ + GColorItem item = COLOR_MTRC_VISITORS_PERC; + GColors *color; + int l = data->meta.visitors_perc_len + 3, idx = render.idx; + + if (data->module == HOSTS && data->data[idx].is_subitem) + goto out; + + if (data->meta.max_visitors == data->data[idx].metrics->visitors) + item = COLOR_MTRC_VISITORS_PERC_MAX; + + color = get_color_by_item_module (item, data->module); + render_percent (render, color, data->data[idx].metrics->visitors_perc, l, *x); + +out: + *x += l + 1 + DASH_SPACE; +} + +/* Render the hits metric for each panel */ +static void +render_hits (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_HITS, data->module); + WINDOW *win = render.win; + + char *hits; + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + int len = data->meta.hits_len; + + if (data->module == HOSTS && data->data[idx].is_subitem) + goto out; + + if (sel) { + /* selected state */ + hits = int2str (data->data[idx].metrics->hits, len); + draw_header (win, hits, " %s", y, 0, w, color_selected); + free (hits); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%*d", len, data->data[idx].metrics->hits); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + +out: + *x += len + DASH_SPACE; +} + +/* Render the visitors metric for each panel */ +static void +render_visitors (GDashModule * data, GDashRender render, int *x) +{ + GColors *color = get_color_by_item_module (COLOR_MTRC_VISITORS, data->module); + WINDOW *win = render.win; + + char *visitors; + int y = render.y, w = render.w, idx = render.idx, sel = render.sel; + int len = data->meta.visitors_len; + + if (data->module == HOSTS && data->data[idx].is_subitem) + goto out; + + if (sel) { + /* selected state */ + visitors = int2str (data->data[idx].metrics->visitors, len); + draw_header (win, visitors, "%s", y, *x, w, color_selected); + free (visitors); + } else { + /* regular state */ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, "%*d", len, data->data[idx].metrics->visitors); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + } + +out: + *x += len + DASH_SPACE; +} + +/* Render the header row for each panel */ +static void +render_header (WINDOW * win, GDashModule * data, GModule cur_module, int *y) +{ + GColors *(*func) (void); + char ind; + char *hd; + int k, w, h; + + getmaxyx (win, h, w); + (void) h; + + k = data->module + 1; + ind = cur_module == data->module ? '>' : ' '; + func = cur_module == data->module && + conf.hl_header ? color_panel_active : color_panel_header; + hd = xmalloc (snprintf (NULL, 0, "%c %d - %s", ind, k, data->head) + 1); + sprintf (hd, "%c %d - %s", ind, k, data->head); + + draw_header (win, hd, " %s", (*y), 0, w, func); + free (hd); + + render_total_label (win, data, (*y), func); + data->pos_y = (*y); + (*y)++; +} + +/* Render the description row for each panel */ +static void +render_description (WINDOW * win, GDashModule * data, int *y) +{ + int w, h; + + getmaxyx (win, h, w); + (void) h; + + draw_header (win, data->desc, " %s", (*y), 0, w, color_panel_desc); + + data->pos_y = (*y); + (*y)++; + (*y)++; /* add empty line underneath description */ +} + +/* Render available metrics per panel. + * ###TODO: Have the abilitity to display metrics in specific order */ +static void +render_metrics (GDashModule * data, GDashRender render, int expanded) +{ + int x = get_xpos (); + GModule module = data->module; + const GOutput *output = output_lookup (module); + + /* basic metrics */ + if (output->hits) + render_hits (data, render, &x); + if (output->percent) + render_hits_percent (data, render, &x); + if (output->visitors) + render_visitors (data, render, &x); + if (output->percent) + render_visitors_percent (data, render, &x); + + /* render bandwidth if available */ + if (conf.bandwidth && output->bw) + render_bw (data, render, &x); + + /* render avgts, cumts and maxts if available */ + if (output->avgts && conf.serve_usecs) + render_avgts (data, render, &x); + if (output->cumts && conf.serve_usecs) + render_cumts (data, render, &x); + if (output->maxts && conf.serve_usecs) + render_maxts (data, render, &x); + + /* render request method if available */ + if (output->method && conf.append_method) + render_method (data, render, &x); + /* render request protocol if available */ + if (output->protocol && conf.append_protocol) + render_proto (data, render, &x); + if (output->data) + render_data (data, render, &x); + + /* skip graph bars if module is expanded and we have sub nodes */ + if ((output->graph && !expanded) || (output->sub_graph && expanded)) + render_bars (data, render, &x); +} + +/* Render a dashboard row. */ +static void +render_data_line (WINDOW * win, GDashModule * data, int *y, int j, + GScroll * gscroll) +{ + GDashRender render; + GModule module = data->module; + int expanded = 0, sel = 0; + int w, h; + + getmaxyx (win, h, w); + (void) h; + + if (gscroll->expanded && module == gscroll->current) + expanded = 1; + + if (j >= data->idx_data) + goto out; + + sel = expanded && j == gscroll->module[module].scroll ? 1 : 0; + + render.win = win; + render.y = *y; + render.w = w; + render.idx = j; + render.sel = sel; + + render_metrics (data, render, expanded); + +out: + (*y)++; +} + +/* Render a dashed line underneath the metric label. */ +static void +print_horizontal_dash (WINDOW * win, int y, int x, int len) +{ + mvwprintw (win, y, x, "%.*s", len, "----------------"); +} + +/* Render left-aligned column label. */ +static void +lprint_col (WINDOW * win, int y, int *x, int len, const char *fmt, + const char *str) +{ + GColors *color = get_color (COLOR_PANEL_COLS); + + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, fmt, str); + print_horizontal_dash (win, y + 1, *x, len); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + + *x += len + DASH_SPACE; +} + +/* Render right-aligned column label. */ +static void +rprint_col (WINDOW * win, int y, int *x, int len, const char *fmt, + const char *str) +{ + GColors *color = get_color (COLOR_PANEL_COLS); + + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, *x, fmt, len, str); + print_horizontal_dash (win, y + 1, *x, len); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + + *x += len + DASH_SPACE; +} + +/* Render column names for available metrics. + * ###TODO: Have the abilitity to display metrics in specific order */ +static void +render_cols (WINDOW * win, GDashModule * data, int *y) +{ + GModule module = data->module; + const GOutput *output = output_lookup (module); + int x = get_xpos (); + + if (data->idx_data == 0 || conf.no_column_names) + return; + + if (output->hits) + lprint_col (win, *y, &x, data->meta.hits_len, "%s", MTRC_HITS_LBL); + + if (output->percent) + rprint_col (win, *y, &x, data->meta.hits_perc_len + 4, "%*s", + MTRC_HITS_PERC_LBL); + + if (output->visitors) + rprint_col (win, *y, &x, data->meta.visitors_len, "%*s", + MTRC_VISITORS_SHORT_LBL); + + if (output->percent) + rprint_col (win, *y, &x, data->meta.visitors_perc_len + 4, "%*s", + MTRC_VISITORS_PERC_LBL); + + if (output->bw && conf.bandwidth) + rprint_col (win, *y, &x, data->meta.bw_len, "%*s", MTRC_BW_LBL); + + if (output->avgts && conf.serve_usecs) + rprint_col (win, *y, &x, DASH_SRV_TM_LEN, "%*s", MTRC_AVGTS_LBL); + + if (output->cumts && conf.serve_usecs) + rprint_col (win, *y, &x, DASH_SRV_TM_LEN, "%*s", MTRC_CUMTS_LBL); + + if (output->maxts && conf.serve_usecs) + rprint_col (win, *y, &x, DASH_SRV_TM_LEN, "%*s", MTRC_MAXTS_LBL); + + if (output->method && conf.append_method) + lprint_col (win, *y, &x, data->meta.method_len, "%s", + MTRC_METHODS_SHORT_LBL); + + if (output->protocol && conf.append_protocol) + lprint_col (win, *y, &x, 8, "%s", MTRC_PROTOCOLS_SHORT_LBL); + + if (output->data) + lprint_col (win, *y, &x, 4, "%s", MTRC_DATA_LBL); +} + +/* Iterate over all dashboard data and render its content. */ +static void +render_content (WINDOW * win, GDashModule * data, int *y, int *offset, + int *total, GScroll * gscroll) +{ + GModule module = data->module; + int i, j, size, h, w, data_pos = get_data_pos_rows (); + + getmaxyx (win, h, w); + (void) w; + + size = data->dash_size; + for (i = *offset, j = 0; i < size; i++) { + /* header */ + if ((i % size) == DASH_HEAD_POS) { + render_header (win, data, gscroll->current, y); + } else if ((i % size) == DASH_EMPTY_POS && conf.no_column_names) { + /* if no column names, print panel description */ + render_description (win, data, y); + } else if ((i % size) == DASH_EMPTY_POS || (i % size) == size - 1) { + /* blank lines */ + (*y)++; + } else if ((i % size) == DASH_DASHES_POS && !conf.no_column_names) { + /* account for already printed dash lines under columns */ + (*y)++; + } else if ((i % size) == DASH_COLS_POS && !conf.no_column_names) { + /* column headers lines */ + render_cols (win, data, y); + (*y)++; + } else if ((i % size) >= data_pos || (i % size) <= size - 2) { + /* account for 2 lines at the header and 2 blank lines */ + j = ((i % size) - data_pos) + gscroll->module[module].offset; + /* actual data */ + render_data_line (win, data, y, j, gscroll); + } else { + /* everything else should be empty */ + (*y)++; + } + (*total)++; + if (*y >= h) + break; + } +} + +/* Entry point to render the terminal dashboard. */ +void +display_content (WINDOW * win, GDash * dash, GScroll * gscroll) +{ + GModule module; + int j = 0; + size_t idx = 0; + + int y = 0, offset = 0, total = 0; + int dash_scroll = gscroll->dash; + + werase (win); + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + offset = 0; + for (j = 0; j < dash->module[module].dash_size; j++) { + if (dash_scroll > total) { + offset++; + total++; + } + } + /* used module */ + dash->module[module].module = module; + + render_content (win, &dash->module[module], &y, &offset, &total, gscroll); + } + wrefresh (win); +} + +/* Reset the scroll and offset fields for each panel/module. */ +void +reset_scroll_offsets (GScroll * gscroll) +{ + GModule module; + size_t idx = 0; + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + gscroll->module[module].scroll = 0; + gscroll->module[module].offset = 0; + } +} + +/* Compile the regular expression and see if it's valid. + * + * If unable to compile, an error as described in <regex.h>. + * Upon successful completion, function returns 0. */ +static int +regexp_init (regex_t * regex, const char *pattern) +{ + int y, x, rc; + char buf[REGEX_ERROR]; + + getmaxyx (stdscr, y, x); + rc = regcomp (regex, pattern, REG_EXTENDED | (find_t.icase ? REG_ICASE : 0)); + /* something went wrong */ + if (rc != 0) { + regerror (rc, regex, buf, sizeof (buf)); + draw_header (stdscr, buf, "%s", y - 1, 0, x, color_error); + refresh (); + return 1; + } + return 0; +} + +/* Set the dashboard scroll and offset based on the search index. */ +static void +perform_find_dash_scroll (GScroll * gscroll, GModule module) +{ + int *scrll, *offset; + int exp_size = get_num_expanded_data_rows (); + + /* reset gscroll offsets if we are changing module */ + if (gscroll->current != module) + reset_scroll_offsets (gscroll); + + scrll = &gscroll->module[module].scroll; + offset = &gscroll->module[module].offset; + + (*scrll) = find_t.next_idx; + if (*scrll >= exp_size && *scrll >= *offset + exp_size) + (*offset) = (*scrll) < exp_size - 1 ? 0 : (*scrll) - exp_size + 1; + + gscroll->current = module; + gscroll->dash = get_module_index (module) * DASH_COLLAPSED; + gscroll->expanded = 1; + find_t.module = module; +} + +/* Find the searched item within the given sub list. + * + * If not found, the GFind structure is reset and 1 is returned. + * If found, a GFind structure is set and 0 is returned. */ +static int +find_next_sub_item (GSubList * sub_list, regex_t * regex) +{ + GSubItem *iter; + int i = 0, rc; + + if (sub_list == NULL) + goto out; + + for (iter = sub_list->head; iter; iter = iter->next) { + if (i >= find_t.next_sub_idx) { + rc = regexec (regex, iter->metrics->data, 0, NULL, 0); + if (rc == 0) { + find_t.next_idx++; + find_t.next_sub_idx = (1 + i); + return 0; + } + find_t.next_idx++; + } + i++; + } +out: + find_t.next_parent_idx++; + find_t.next_sub_idx = 0; + find_t.look_in_sub = 0; + + return 1; +} + +/* Perform a forward search across all modules. + * + * On error or if not found, 1 is returned. + * On success or if found, a GFind structure is set and 0 is returned. */ +int +perform_next_find (GHolder * h, GScroll * gscroll) +{ + GModule module; + GSubList *sub_list; + regex_t regex; + char buf[REGEX_ERROR], *data; + int y, x, j, n, rc; + size_t idx = 0; + + getmaxyx (stdscr, y, x); + + if (find_t.pattern == NULL || *find_t.pattern == '\0') + return 1; + + /* compile and initialize regexp */ + if (regexp_init (®ex, find_t.pattern)) + return 1; + + /* use last find_t.module and start search */ + idx = find_t.module; + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + n = h[module].idx; + for (j = find_t.next_parent_idx; j < n; j++, find_t.next_idx++) { + data = h[module].items[j].metrics->data; + + rc = regexec (®ex, data, 0, NULL, 0); + /* error matching against the precompiled pattern buffer */ + if (rc != 0 && rc != REG_NOMATCH) { + regerror (rc, ®ex, buf, sizeof (buf)); + draw_header (stdscr, buf, "%s", y - 1, 0, x, color_error); + refresh (); + regfree (®ex); + return 1; + } + /* a match was found (data level) */ + else if (rc == 0 && !find_t.look_in_sub) { + find_t.look_in_sub = 1; + perform_find_dash_scroll (gscroll, module); + goto out; + } + /* look at sub list nodes */ + else { + sub_list = h[module].items[j].sub_list; + if (find_next_sub_item (sub_list, ®ex) == 0) { + perform_find_dash_scroll (gscroll, module); + goto out; + } + } + } + + /* reset find */ + find_t.next_idx = 0; + find_t.next_parent_idx = 0; + find_t.next_sub_idx = 0; + + if (find_t.module != module) { + reset_scroll_offsets (gscroll); + gscroll->expanded = 0; + } + if (module == TOTAL_MODULES - 1) { + find_t.module = 0; + goto out; + } + } + +out: + regfree (®ex); + return 0; +} + +/* Render a find dialog. + * + * On error or if no query is set, 1 is returned. + * On success, the dialog is rendered and 0 is returned. */ +int +render_find_dialog (WINDOW * main_win, GScroll * gscroll) +{ + int y, x, valid = 1; + int w = FIND_DLG_WIDTH; + int h = FIND_DLG_HEIGHT; + char *query = NULL; + WINDOW *win; + + getmaxyx (stdscr, y, x); + + win = newwin (h, w, (y - h) / 2, (x - w) / 2); + keypad (win, TRUE); + wborder (win, '|', '|', '-', '-', '+', '+', '+', '+'); + draw_header (win, FIND_HEAD, " %s", 1, 1, w - 2, color_panel_header); + mvwprintw (win, 2, 1, " %s", FIND_DESC); + + find_t.icase = 0; + query = input_string (win, 4, 2, w - 3, "", 1, &find_t.icase); + if (query != NULL && *query != '\0') { + reset_scroll_offsets (gscroll); + reset_find (); + find_t.pattern = xstrdup (query); + valid = 0; + } + if (query != NULL) + free (query); + touchwin (main_win); + close_win (win); + wrefresh (main_win); + + return valid; +} + +static void +set_dash_metrics (GDash ** dash, GMetrics * metrics, GModule module, + int is_subitem) +{ + GDashData *idata = NULL; + GDashMeta *meta = NULL; + char *data = NULL; + int *idx; + + if (!metrics->data) + return; + + idx = &(*dash)->module[module].idx_data; + idata = &(*dash)->module[module].data[(*idx)]; + meta = &(*dash)->module[module].meta; + + idata->metrics = new_gmetrics (); + idata->is_subitem = is_subitem; + + data = is_subitem ? render_child_node (metrics->data) : metrics->data; + + /* set maximum values so far for hits/visitors */ + set_max_values (meta, metrics); + + idata->metrics->hits = metrics->hits; + idata->metrics->hits_perc = get_percentage (meta->max_hits, metrics->hits); + idata->metrics->visitors = metrics->visitors; + idata->metrics->visitors_perc = + get_percentage (meta->max_visitors, metrics->visitors); + idata->metrics->bw.sbw = filesize_str (metrics->bw.nbw); + idata->metrics->data = xstrdup (data); + + if (conf.append_method && metrics->method) + idata->metrics->method = metrics->method; + if (conf.append_protocol && metrics->protocol) + idata->metrics->protocol = metrics->protocol; + + if (!conf.serve_usecs) + goto out; + + idata->metrics->avgts.sts = usecs_to_str (metrics->avgts.nts); + idata->metrics->cumts.sts = usecs_to_str (metrics->cumts.nts); + idata->metrics->maxts.sts = usecs_to_str (metrics->maxts.nts); + +out: + if (is_subitem) + free (data); + + set_metrics_len (meta, idata); + + (*idx)++; +} + +/* Add an item from a sub list to the dashboard. + * + * If no items on the sub list, the function returns. + * On success, sub list data is set into the dashboard structure. */ +static void +add_sub_item_to_dash (GDash ** dash, GHolderItem item, GModule module, int *i) +{ + GSubList *sub_list = item.sub_list; + GSubItem *iter; + + if (sub_list == NULL) + return; + + for (iter = sub_list->head; iter; iter = iter->next, (*i)++) { + set_dash_metrics (dash, iter->metrics, module, 1); + } +} + +/* Add a first level item to dashboard. + * + * On success, data is set into the dashboard structure. */ +static void +add_item_to_dash (GDash ** dash, GHolderItem item, GModule module) +{ + set_dash_metrics (dash, item.metrics, module, 0); +} + +/* Load holder's data into the dashboard structure. */ +void +load_data_to_dash (GHolder * h, GDash * dash, GModule module, GScroll * gscroll) +{ + int alloc_size = 0; + int i, j; + + alloc_size = dash->module[module].alloc_data; + if (gscroll->expanded && module == gscroll->current) + alloc_size += h->sub_items_size; + + dash->module[module].alloc_data = alloc_size; + dash->module[module].data = new_gdata (alloc_size); + dash->module[module].holder_size = h->holder_size; + memset (&dash->module[module].meta, 0, sizeof (GDashData)); + + for (i = 0, j = 0; i < alloc_size; i++) { + if (h->items[j].metrics->data == NULL) + continue; + + add_item_to_dash (&dash, h->items[j], module); + if (gscroll->expanded && module == gscroll->current && h->sub_items_size) + add_sub_item_to_dash (&dash, h->items[j], module, &i); + j++; + } +} diff --git a/goaccess++/src/gdashboard.h b/goaccess++/src/gdashboard.h new file mode 100644 index 0000000..314651a --- /dev/null +++ b/goaccess++/src/gdashboard.h @@ -0,0 +1,142 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef GDASHBOARD_H_INCLUDED +#define GDASHBOARD_H_INCLUDED + +#include <stdint.h> + +#include "ui.h" + +/* *INDENT-OFF* */ +#define DASH_HEAD_POS 0 /* position of header line */ +#define DASH_EMPTY_POS 1 /* empty line position */ +#define DASH_COLS_POS 2 /* position of column names */ +#define DASH_DASHES_POS 3 /* position of dashes under column names */ +#define DASH_DATA_POS 4 /* data line position */ + +#define DASH_NON_DATA 5 /* number of rows without data stats */ +#define DASH_COL_ROWS 2 /* number of rows for column values + dashed lines */ + +#define DASH_COLLAPSED 12 /* number of rows per panel (collapsed) */ +#define DASH_EXPANDED 32 /* number of rows per panel (expanded) */ + +#define DASH_INIT_X 1 /* start position (x-axis) */ + +#define DASH_BW_LEN 11 /* max bandwidth string length, e.g., 151.69 MiB */ +#define DASH_SRV_TM_LEN 9 /* max time served length, e.g., 483.00 us */ +#define DASH_SPACE 1 /* space between columns (metrics) */ + +/* Common render data line fields */ +typedef struct GDashRender_ +{ + WINDOW *win; + int y; + int w; + int idx; + int sel; +} GDashRender; + +/* Dashboard panel item */ +typedef struct GDashData_ +{ + GMetrics *metrics; + short is_subitem; +} GDashData; + +/* Dashboard panel meta data */ +typedef struct GDashMeta_ +{ + int max_hits; /* maximum value on the hits column */ + int max_visitors; /* maximum value on the visitors column */ + + /* determine the maximum metric's length of these metrics */ + /* for instance, 1022 is the max value for the hits column and its length = 4 */ + int hits_len; + int hits_perc_len; + int visitors_len; + int visitors_perc_len; + int bw_len; + int avgts_len; + int cumts_len; + int maxts_len; + int method_len; + int protocol_len; + int data_len; +} GDashMeta; + +/* Dashboard panel */ +typedef struct GDashModule_ +{ + GDashData *data; /* data metrics */ + GModule module; /* module */ + GDashMeta meta; /* meta data */ + + const char *head; /* panel header */ + const char *desc; /* panel description */ + + int alloc_data; /* number of data items allocated. */ + /* e.g., MAX_CHOICES or holder size */ + int dash_size; /* dashboard size */ + int holder_size; /* hash table size */ + int ht_size; /* hash table size */ + int idx_data; /* idx data */ + + unsigned short pos_y; /* dashboard current Y position */ +} GDashModule; + +/* Dashboard */ +typedef struct GDash_ +{ + int total_alloc; /* number of allocated dashboard lines */ + GDashModule module[TOTAL_MODULES]; +} GDash; + +/* Function Prototypes */ +GDashData *new_gdata (uint32_t size); +GDash *new_gdash (void); +int get_num_collapsed_data_rows(void); +int get_num_expanded_data_rows(void); +int perform_next_find (GHolder * h, GScroll * scroll); +int render_find_dialog (WINDOW * main_win, GScroll * scroll); +int set_module_from_mouse_event (GScroll *scroll, GDash *dash, int y); +uint32_t get_ht_size_by_module (GModule module); +void display_content (WINDOW * win, GDash * dash, GScroll * scroll); +void free_dashboard (GDash * dash); +void load_data_to_dash (GHolder * h, GDash * dash, GModule module, GScroll * scroll); +void reset_find (void); +void reset_scroll_offsets (GScroll * scroll); + +/* *INDENT-ON* */ + +#endif diff --git a/goaccess++/src/gdashboard.o b/goaccess++/src/gdashboard.o new file mode 100644 index 0000000..a1351c7 Binary files /dev/null and b/goaccess++/src/gdashboard.o differ diff --git a/goaccess++/src/gdns.c b/goaccess++/src/gdns.c new file mode 100644 index 0000000..3287394 --- /dev/null +++ b/goaccess++/src/gdns.c @@ -0,0 +1,296 @@ +/** + * gdns.c -- hosts resolver + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _MULTI_THREADED +#ifdef __FreeBSD__ +#include <sys/socket.h> +#endif + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <pthread.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <ctype.h> +#include <errno.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <time.h> +#include <unistd.h> + +#include "gdns.h" + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#include "error.h" +#include "goaccess.h" +#include "util.h" +#include "xmalloc.h" + +GDnsThread gdns_thread; +static GDnsQueue *gdns_queue; + +/* Initialize the queue. */ +void +gqueue_init (GDnsQueue * q, int capacity) +{ + q->head = 0; + q->tail = -1; + q->size = 0; + q->capacity = capacity; +} + +/* Get the current size of queue. + * + * Returns the size of the queue. */ +int +gqueue_size (GDnsQueue * q) +{ + return q->size; +} + +/* Determine if the queue is empty. + * + * Returns true if empty, otherwise false. */ +int +gqueue_empty (GDnsQueue * q) +{ + return q->size == 0; +} + +/* Determine if the queue is full. + * + * Returns true if full, otherwise false. */ +int +gqueue_full (GDnsQueue * q) +{ + return q->size == q->capacity; +} + +/* Free the queue. */ +void +gqueue_destroy (GDnsQueue * q) +{ + free (q); +} + +/* Add at the end of the queue a string item. + * + * If the queue is full, -1 is returned. + * If added to the queue, 0 is returned. */ +int +gqueue_enqueue (GDnsQueue * q, char *item) +{ + if (gqueue_full (q)) + return -1; + + q->tail = (q->tail + 1) % q->capacity; + strcpy (q->buffer[q->tail], item); + q->size++; + return 0; +} + +/* Find a string item in the queue. + * + * If the queue is empty, or the item is not in the queue, 0 is returned. + * If found, 1 is returned. */ +int +gqueue_find (GDnsQueue * q, const char *item) +{ + int i; + if (gqueue_empty (q)) + return 0; + + for (i = 0; i < q->size; i++) { + if (strcmp (item, q->buffer[i]) == 0) + return 1; + } + return 0; +} + +/* Remove a string item from the head of the queue. + * + * If the queue is empty, NULL is returned. + * If removed, the string item is returned. */ +char * +gqueue_dequeue (GDnsQueue * q) +{ + char *item; + if (gqueue_empty (q)) + return NULL; + + item = q->buffer[q->head]; + q->head = (q->head + 1) % q->capacity; + q->size--; + return item; +} + +/* Get the corresponding hostname given an IP address. + * + * On error, a string error message is returned. + * On success, a malloc'd hostname is returned. */ +static char * +reverse_host (const struct sockaddr *a, socklen_t length) +{ + char h[H_SIZE]; + int flags, st; + + flags = NI_NAMEREQD; + st = getnameinfo (a, length, h, H_SIZE, NULL, 0, flags); + if (!st) + return alloc_string (h); + return alloc_string (gai_strerror (st)); +} + +/* Determine if IPv4 or IPv6 and resolve. + * + * On error, NULL is returned. + * On success, a malloc'd hostname is returned. */ +char * +reverse_ip (char *str) +{ + union + { + struct sockaddr addr; + struct sockaddr_in6 addr6; + struct sockaddr_in addr4; + } a; + + if (str == NULL || *str == '\0') + return NULL; + + memset (&a, 0, sizeof (a)); + if (1 == inet_pton (AF_INET, str, &a.addr4.sin_addr)) { + a.addr4.sin_family = AF_INET; + return reverse_host (&a.addr, sizeof (a.addr4)); + } else if (1 == inet_pton (AF_INET6, str, &a.addr6.sin6_addr)) { + a.addr6.sin6_family = AF_INET6; + return reverse_host (&a.addr, sizeof (a.addr6)); + } + return NULL; +} + +/* Producer - Resolve an IP address and add it to the queue. */ +void +dns_resolver (char *addr) +{ + pthread_mutex_lock (&gdns_thread.mutex); + /* queue is not full and the IP address is not in the queue */ + if (!gqueue_full (gdns_queue) && !gqueue_find (gdns_queue, addr)) { + /* add the IP to the queue */ + gqueue_enqueue (gdns_queue, addr); + pthread_cond_broadcast (&gdns_thread.not_empty); + } + pthread_mutex_unlock (&gdns_thread.mutex); +} + +/* Consumer - Once an IP has been resolved, add it to dwithe hostnames + * hash structure. */ +static void +dns_worker (void GO_UNUSED (*ptr_data)) +{ + char *ip = NULL, *host = NULL; + + while (1) { + pthread_mutex_lock (&gdns_thread.mutex); + /* wait until an item has been added to the queue */ + while (gqueue_empty (gdns_queue)) + pthread_cond_wait (&gdns_thread.not_empty, &gdns_thread.mutex); + + ip = gqueue_dequeue (gdns_queue); + + pthread_mutex_unlock (&gdns_thread.mutex); + host = reverse_ip (ip); + pthread_mutex_lock (&gdns_thread.mutex); + + if (!active_gdns) { + if (host) + free (host); + break; + } + + /* insert the corresponding IP -> hostname map */ + if (host != NULL && active_gdns) { + ht_insert_hostname (ip, host); + free (host); + } + + pthread_cond_signal (&gdns_thread.not_full); + pthread_mutex_unlock (&gdns_thread.mutex); + } +} + +/* Initialize queue and dns thread */ +void +gdns_init (void) +{ + gdns_queue = xmalloc (sizeof (GDnsQueue)); + gqueue_init (gdns_queue, QUEUE_SIZE); + + if (pthread_cond_init (&(gdns_thread.not_empty), NULL)) + FATAL ("Failed init thread condition"); + + if (pthread_cond_init (&(gdns_thread.not_full), NULL)) + FATAL ("Failed init thread condition"); + + if (pthread_mutex_init (&(gdns_thread.mutex), NULL)) + FATAL ("Failed init thread mutex"); +} + +/* Destroy (free) queue */ +void +gdns_free_queue (void) +{ + gqueue_destroy (gdns_queue); +} + +/* Create a DNS thread and make it active */ +void +gdns_thread_create (void) +{ + int th; + + active_gdns = 1; + th = pthread_create (&(gdns_thread.thread), NULL, (void *) &dns_worker, NULL); + if (th) + FATAL ("Return code from pthread_create(): %d", th); + pthread_detach (gdns_thread.thread); +} diff --git a/goaccess++/src/gdns.h b/goaccess++/src/gdns.h new file mode 100644 index 0000000..97d8b25 --- /dev/null +++ b/goaccess++/src/gdns.h @@ -0,0 +1,70 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef GDNS_H_INCLUDED +#define GDNS_H_INCLUDED + +#define H_SIZE 1025 +#define QUEUE_SIZE 400 + +typedef struct GDnsThread_ +{ + pthread_cond_t not_empty; /* not empty queue condition */ + pthread_cond_t not_full; /* not full queue condition */ + pthread_mutex_t mutex; + pthread_t thread; +} GDnsThread; + +typedef struct GDnsQueue_ +{ + int head; /* index to head of queue */ + int tail; /* index to tail of queue */ + int size; /* queue size */ + int capacity; /* length at most */ + char buffer[QUEUE_SIZE][H_SIZE]; /* data item */ +} GDnsQueue; + +extern GDnsThread gdns_thread; + +char *gqueue_dequeue (GDnsQueue * q); +char *reverse_ip (char *str); +int gqueue_empty (GDnsQueue * q); +int gqueue_enqueue (GDnsQueue * q, char *item); +int gqueue_find (GDnsQueue * q, const char *item); +int gqueue_full (GDnsQueue * q); +int gqueue_size (GDnsQueue * q); +void dns_resolver (char *addr); +void gdns_free_queue (void); +void gdns_init (void); +void gdns_queue_free (void); +void gdns_thread_create (void); +void gqueue_destroy (GDnsQueue * q); +void gqueue_init (GDnsQueue * q, int capacity); + +#endif diff --git a/goaccess++/src/gdns.o b/goaccess++/src/gdns.o new file mode 100644 index 0000000..465c8b5 Binary files /dev/null and b/goaccess++/src/gdns.o differ diff --git a/goaccess++/src/geoip1.c b/goaccess++/src/geoip1.c new file mode 100644 index 0000000..588d994 --- /dev/null +++ b/goaccess++/src/geoip1.c @@ -0,0 +1,439 @@ +/** + * geoip.c -- implementation of GeoIP + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_LIBGEOIP +#include <GeoIP.h> +#include <GeoIPCity.h> +#endif + +#include "geoip1.h" + +#include "error.h" +#include "util.h" + +static GeoIP *geo_location_data; + +/* Determine if we have a valid geoip resource. + * + * If the geoip resource is NULL, 0 is returned. + * If the geoip resource is valid and malloc'd, 1 is returned. */ +int +is_geoip_resource (void) +{ + return geo_location_data != NULL ? 1 : 0; +} + +/* Free up GeoIP resources */ +void +geoip_free (void) +{ + if (!is_geoip_resource ()) + return; + + GeoIP_delete (geo_location_data); + GeoIP_cleanup (); +} + +/* Open the given GeoLocation database and set its charset. + * + * On error, it aborts. + * On success, a new geolocation structure is returned. */ +static GeoIP * +geoip_open_db (const char *db) +{ + GeoIP *geoip; + geoip = GeoIP_open (db, GEOIP_MEMORY_CACHE); + + if (geoip == NULL) + FATAL ("Unable to open GeoIP database: %s\n", db); + + GeoIP_set_charset (geoip, GEOIP_CHARSET_UTF8); + LOG_DEBUG (("Opened GeoIP City database: %s\n", db)); + + return geoip; +} + +/* Set up and open GeoIP database */ +void +init_geoip (void) +{ + /* open custom city GeoIP database */ + if (conf.geoip_database != NULL) + geo_location_data = geoip_open_db (conf.geoip_database); + /* fall back to legacy GeoIP database */ + else + geo_location_data = GeoIP_new (conf.geo_db); +} + +/* Get continent name concatenated with code. + * + * If continent not found, "Unknown" is returned. + * On success, the continent code & name is returned . */ +static const char * +get_continent_name_and_code (const char *continentid) +{ + if (memcmp (continentid, "NA", 2) == 0) + return "NA North America"; + else if (memcmp (continentid, "OC", 2) == 0) + return "OC Oceania"; + else if (memcmp (continentid, "EU", 2) == 0) + return "EU Europe"; + else if (memcmp (continentid, "SA", 2) == 0) + return "SA South America"; + else if (memcmp (continentid, "AF", 2) == 0) + return "AF Africa"; + else if (memcmp (continentid, "AN", 2) == 0) + return "AN Antarctica"; + else if (memcmp (continentid, "AS", 2) == 0) + return "AS Asia"; + else + return "-- Unknown"; +} + +/* Compose a string with the country name and code and store it in the + * given buffer. */ +static void +geoip_set_country (const char *country, const char *code, char *loc) +{ + if (country && code) + snprintf (loc, COUNTRY_LEN, "%s %s", code, country); + else + snprintf (loc, COUNTRY_LEN, "%s", "Unknown"); +} + +/* Compose a string with the city name and state/region and store it + * in the given buffer. */ +static void +geoip_set_city (const char *city, const char *region, char *loc) +{ + snprintf (loc, CITY_LEN, "%s, %s", city ? city : "N/A City", + region ? region : "N/A Region"); +} + +/* Compose a string with the continent name and store it in the given + * buffer. */ +static void +geoip_set_continent (const char *continent, char *loc) +{ + if (continent) + snprintf (loc, CONTINENT_LEN, "%s", + get_continent_name_and_code (continent)); + else + snprintf (loc, CONTINENT_LEN, "%s", "Unknown"); +} + +/* Get detailed information found in the GeoIP Database about the + * given IPv4 or IPv6. + * + * On error, NULL is returned + * On success, GeoIPRecord structure is returned */ +static GeoIPRecord * +get_geoip_record (const char *addr, GTypeIP type_ip) +{ + GeoIPRecord *rec = NULL; + + if (TYPE_IPV4 == type_ip) + rec = GeoIP_record_by_name (geo_location_data, addr); + else if (TYPE_IPV6 == type_ip) + rec = GeoIP_record_by_name_v6 (geo_location_data, addr); + + return rec; +} + +/* Set country data by record into the given `location` buffer based + * on the IP version. */ +static void +geoip_set_country_by_record (const char *ip, char *location, GTypeIP type_ip) +{ + GeoIPRecord *rec = NULL; + const char *country = NULL, *code = NULL, *addr = ip; + + if (conf.geoip_database == NULL || geo_location_data == NULL) + return; + + /* Custom GeoIP database */ + if ((rec = get_geoip_record (addr, type_ip))) { + country = rec->country_name; + code = rec->country_code; + } + + geoip_set_country (country, code, location); + if (rec != NULL) { + GeoIPRecord_delete (rec); + } +} + +/* Get the GeoIP location id by name. + * + * On error, 0 is returned + * On success, the GeoIP location id is returned */ +static int +geoip_get_geoid (const char *addr, GTypeIP type_ip) +{ + int geoid = 0; + + if (TYPE_IPV4 == type_ip) + geoid = GeoIP_id_by_name (geo_location_data, addr); + else if (TYPE_IPV6 == type_ip) + geoid = GeoIP_id_by_name_v6 (geo_location_data, addr); + + return geoid; +} + +/* Get the country name by GeoIP location id. + * + * On error, NULL is returned + * On success, the country name is returned */ +static const char * +geoip_get_country_by_geoid (const char *addr, GTypeIP type_ip) +{ + const char *country = NULL; + + if (TYPE_IPV4 == type_ip) + country = GeoIP_country_name_by_name (geo_location_data, addr); + else if (TYPE_IPV6 == type_ip) + country = GeoIP_country_name_by_name_v6 (geo_location_data, addr); + + return country; +} + +/* Set country data by geoid into the given `location` buffer based on + * the IP version. */ +static void +geoip_set_country_by_geoid (const char *ip, char *location, GTypeIP type_ip) +{ + const char *country = NULL, *code = NULL, *addr = ip; + int geoid = 0; + + if (!is_geoip_resource ()) + return; + + if (!(country = geoip_get_country_by_geoid (addr, type_ip))) + goto out; + + /* return two letter country code */ + if (!(geoid = geoip_get_geoid (addr, type_ip))) + goto out; + code = GeoIP_code_by_id (geoid); + +out: + geoip_set_country (country, code, location); +} + +/* Set country data by geoid or record into the given `location` buffer + * based on the IP version and currently used database edition. */ +void +geoip_get_country (const char *ip, char *location, GTypeIP type_ip) +{ + unsigned char rec = GeoIP_database_edition (geo_location_data); + + switch (rec) { + case GEOIP_COUNTRY_EDITION: + if (TYPE_IPV4 == type_ip) + geoip_set_country_by_geoid (ip, location, TYPE_IPV4); + else + geoip_set_country (NULL, NULL, location); + break; + case GEOIP_COUNTRY_EDITION_V6: + if (TYPE_IPV6 == type_ip) + geoip_set_country_by_geoid (ip, location, TYPE_IPV6); + else + geoip_set_country (NULL, NULL, location); + break; + case GEOIP_CITY_EDITION_REV0: + case GEOIP_CITY_EDITION_REV1: + if (TYPE_IPV4 == type_ip) + geoip_set_country_by_record (ip, location, TYPE_IPV4); + else + geoip_set_country (NULL, NULL, location); + break; + case GEOIP_CITY_EDITION_REV0_V6: + case GEOIP_CITY_EDITION_REV1_V6: + if (TYPE_IPV6 == type_ip) + geoip_set_country_by_record (ip, location, TYPE_IPV6); + else + geoip_set_country (NULL, NULL, location); + break; + } +} + +/* Set continent data by record into the given `location` buffer based + * on the IP version. */ +static void +geoip_set_continent_by_record (const char *ip, char *location, GTypeIP type_ip) +{ + GeoIPRecord *rec = NULL; + const char *continent = NULL, *addr = ip; + + if (conf.geoip_database == NULL || geo_location_data == NULL) + return; + + /* Custom GeoIP database */ + if ((rec = get_geoip_record (addr, type_ip))) + continent = rec->continent_code; + + geoip_set_continent (continent, location); + if (rec != NULL) { + GeoIPRecord_delete (rec); + } +} + +/* Set continent data by geoid into the given `location` buffer based + * on the IP version. */ +static void +geoip_set_continent_by_geoid (const char *ip, char *location, GTypeIP type_ip) +{ + const char *continent = NULL, *addr = ip; + int geoid = 0; + + if (!is_geoip_resource ()) + return; + + if (!(geoid = geoip_get_geoid (addr, type_ip))) + goto out; + continent = GeoIP_continent_by_id (geoid); + +out: + geoip_set_continent (continent, location); +} + +/* Set continent data by geoid or record into the given `location` buffer + * based on the IP version and currently used database edition. */ +void +geoip_get_continent (const char *ip, char *location, GTypeIP type_ip) +{ + unsigned char rec = GeoIP_database_edition (geo_location_data); + + switch (rec) { + case GEOIP_COUNTRY_EDITION: + if (TYPE_IPV4 == type_ip) + geoip_set_continent_by_geoid (ip, location, TYPE_IPV4); + else + geoip_set_continent (NULL, location); + break; + case GEOIP_COUNTRY_EDITION_V6: + if (TYPE_IPV6 == type_ip) + geoip_set_continent_by_geoid (ip, location, TYPE_IPV6); + else + geoip_set_continent (NULL, location); + break; + case GEOIP_CITY_EDITION_REV0: + case GEOIP_CITY_EDITION_REV1: + if (TYPE_IPV4 == type_ip) + geoip_set_continent_by_record (ip, location, TYPE_IPV4); + else + geoip_set_continent (NULL, location); + break; + case GEOIP_CITY_EDITION_REV0_V6: + case GEOIP_CITY_EDITION_REV1_V6: + if (TYPE_IPV6 == type_ip) + geoip_set_continent_by_record (ip, location, TYPE_IPV6); + else + geoip_set_continent (NULL, location); + break; + } +} + +/* Set city data by record into the given `location` buffer based on + * the IP version. */ +static void +geoip_set_city_by_record (const char *ip, char *location, GTypeIP type_ip) +{ + GeoIPRecord *rec = NULL; + const char *city = NULL, *region = NULL, *addr = ip; + + /* Custom GeoIP database */ + if ((rec = get_geoip_record (addr, type_ip))) { + city = rec->city; + region = rec->region; + } + + geoip_set_city (city, region, location); + if (rec != NULL) { + GeoIPRecord_delete (rec); + } +} + +/* Set city data by geoid or record into the given `location` buffer + * based on the IP version and currently used database edition. + * It uses the custom GeoIP database - i.e., GeoLiteCity.dat */ +void +geoip_get_city (const char *ip, char *location, GTypeIP type_ip) +{ + unsigned char rec = GeoIP_database_edition (geo_location_data); + + if (conf.geoip_database == NULL || geo_location_data == NULL) + return; + + switch (rec) { + case GEOIP_CITY_EDITION_REV0: + case GEOIP_CITY_EDITION_REV1: + if (TYPE_IPV4 == type_ip) + geoip_set_city_by_record (ip, location, TYPE_IPV4); + else + geoip_set_city (NULL, NULL, location); + break; + case GEOIP_CITY_EDITION_REV0_V6: + case GEOIP_CITY_EDITION_REV1_V6: + if (TYPE_IPV6 == type_ip) + geoip_set_city_by_record (ip, location, TYPE_IPV6); + else + geoip_set_city (NULL, NULL, location); + break; + } +} + +/* Entry point to set GeoIP location into the corresponding buffers, + * (continent, country, city). + * + * On error, 1 is returned + * On success, buffers are set and 0 is returned */ +int +set_geolocation (char *host, char *continent, char *country, char *city) +{ + int type_ip = 0; + + if (!is_geoip_resource ()) + return 1; + + if (invalid_ipaddr (host, &type_ip)) + return 1; + + geoip_get_country (host, country, type_ip); + geoip_get_continent (host, continent, type_ip); + if (conf.geoip_database) + geoip_get_city (host, city, type_ip); + + return 0; +} diff --git a/goaccess++/src/geoip1.h b/goaccess++/src/geoip1.h new file mode 100644 index 0000000..6fbb100 --- /dev/null +++ b/goaccess++/src/geoip1.h @@ -0,0 +1,58 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef GEOIP_H_INCLUDED +#define GEOIP_H_INCLUDED + +#include "commons.h" + +#define CITY_LEN 47 + 1 /* max string length for a city */ +#define CONTINENT_LEN 47 + 1 /* max string length for a country */ +#define COUNTRY_LEN 48 + 3 /* Country + two-letter Code */ + +typedef struct GLocation_ +{ + char city[CITY_LEN]; + char continent[CONTINENT_LEN]; + int hits; +} GLocation; + +int is_geoip_resource (void); +int set_geolocation (char *host, char *continent, char *country, char *city); +void geoip_free (void); +void geoip_get_city (const char *ip, char *location, GTypeIP type_ip); +void geoip_get_continent (const char *ip, char *location, GTypeIP type_ip); +void geoip_get_country (const char *ip, char *location, GTypeIP type_ip); +void init_geoip (void); + +#endif // for #ifndef GEOIP_H diff --git a/goaccess++/src/geoip1.o b/goaccess++/src/geoip1.o new file mode 100644 index 0000000..a3dce92 Binary files /dev/null and b/goaccess++/src/geoip1.o differ diff --git a/goaccess++/src/geoip2.c b/goaccess++/src/geoip2.c new file mode 100644 index 0000000..724998d --- /dev/null +++ b/goaccess++/src/geoip2.c @@ -0,0 +1,297 @@ +/** + * geoip2.c -- implementation of GeoIP2 + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#ifdef HAVE_LIBMAXMINDDB +#include <maxminddb.h> +#endif + +#include "geoip1.h" + +#include "error.h" +#include "util.h" +#include "xmalloc.h" + +/* should be reused across lookups */ +int geoip_city_type = 0; +static MMDB_s *mmdb = NULL; + +/* Determine if we have a valid geoip resource. + * + * If the geoip resource is NULL, 0 is returned. + * If the geoip resource is valid and malloc'd, 1 is returned. */ +int +is_geoip_resource (void) +{ + return mmdb != NULL ? 1 : 0; +} + +/* Free up GeoIP resources */ +void +geoip_free (void) +{ + if (!is_geoip_resource ()) + return; + + MMDB_close (mmdb); + free (mmdb); + mmdb = NULL; +} + +/* Open the given GeoIP2 database. + * + * On error, it aborts. + * On success, a new geolocation structure is set. */ +void +init_geoip (void) +{ + const char *fn = conf.geoip_database; + int status = 0; + + if (fn == NULL) + return; + + /* open custom city GeoIP database */ + mmdb = xcalloc (1, sizeof (MMDB_s)); + if ((status = MMDB_open (fn, MMDB_MODE_MMAP, mmdb)) != MMDB_SUCCESS) { + free (mmdb); + FATAL ("Unable to open GeoIP2 database: %s\n", fn); + } + + if (strcmp (mmdb->metadata.database_type, "GeoLite2-City") == 0) + geoip_city_type = 1; +} + +/* Look up an IP address that is passed in as a null-terminated string. + * + * On error, it aborts. + * If no entry is found, 1 is returned. + * On success, MMDB_lookup_result_s struct is set and 0 is returned. */ +static int +geoip_lookup (MMDB_lookup_result_s * res, const char *ip) +{ + int gai_err, mmdb_err; + + *res = MMDB_lookup_string (mmdb, ip, &gai_err, &mmdb_err); + if (0 != gai_err) + return 1; + + if (MMDB_SUCCESS != mmdb_err) + FATAL ("Error from libmaxminddb: %s\n", MMDB_strerror (mmdb_err)); + + if (!(*res).found_entry) + return 1; + + return 0; +} + +/* Get continent name concatenated with code. + * + * If continent not found, "Unknown" is returned. + * On success, the continent code & name is returned . */ +static const char * +get_continent_name_and_code (const char *continentid) +{ + if (memcmp (continentid, "NA", 2) == 0) + return "NA North America"; + else if (memcmp (continentid, "OC", 2) == 0) + return "OC Oceania"; + else if (memcmp (continentid, "EU", 2) == 0) + return "EU Europe"; + else if (memcmp (continentid, "SA", 2) == 0) + return "SA South America"; + else if (memcmp (continentid, "AF", 2) == 0) + return "AF Africa"; + else if (memcmp (continentid, "AN", 2) == 0) + return "AN Antarctica"; + else if (memcmp (continentid, "AS", 2) == 0) + return "AS Asia"; + else + return "-- Unknown"; +} + +/* Compose a string with the country name and code and store it in the + * given buffer. */ +static void +geoip_set_country (const char *country, const char *code, char *loc) +{ + if (country && code) + snprintf (loc, COUNTRY_LEN, "%s %s", code, country); + else + snprintf (loc, COUNTRY_LEN, "%s", "Unknown"); +} + +/* Compose a string with the city name and state/region and store it + * in the given buffer. */ +static void +geoip_set_city (const char *city, const char *region, char *loc) +{ + snprintf (loc, CITY_LEN, "%s, %s", city ? city : "N/A City", + region ? region : "N/A Region"); +} + +/* Compose a string with the continent name and store it in the given + * buffer. */ +static void +geoip_set_continent (const char *continent, char *loc) +{ + if (continent) + snprintf (loc, CONTINENT_LEN, "%s", + get_continent_name_and_code (continent)); + else + snprintf (loc, CONTINENT_LEN, "%s", "Unknown"); +} + +/* A wrapper to fetch the looked up result set. + * + * On error, it aborts. + * If no data is found, NULL is returned. + * On success, the fetched value is returned. */ +static char * +get_value (MMDB_lookup_result_s res, ...) +{ + MMDB_entry_data_s entry_data; + char *value = NULL; + int status = 0; + va_list keys; + va_start (keys, res); + + status = MMDB_vget_value (&res.entry, &entry_data, keys); + va_end (keys); + + if (status != MMDB_SUCCESS) + return NULL; + + if (!entry_data.has_data) + return NULL; + + if (entry_data.type != MMDB_DATA_TYPE_UTF8_STRING) + FATAL ("Invalid data UTF8 GeoIP2 data %d:\n", entry_data.type); + + if ((value = strndup (entry_data.utf8_string, entry_data.data_size)) == NULL) + FATAL ("Unable to allocate buffer %s: ", strerror (errno)); + + return value; +} + +/* A wrapper to fetch the looked up result and set the city and region. + * + * If no data is found, NULL is set. + * On success, the fetched value is set. */ +static void +geoip_query_city (MMDB_lookup_result_s res, char *location) +{ + char *city = NULL, *region = NULL; + + if (res.found_entry) { + city = get_value (res, "city", "names", "en", NULL); + region = get_value (res, "subdivisions", "0", "names", "en", NULL); + } + geoip_set_city (city, region, location); +} + +/* A wrapper to fetch the looked up result and set the country and code. + * + * If no data is found, NULL is set. + * On success, the fetched value is set. */ +static void +geoip_query_country (MMDB_lookup_result_s res, char *location) +{ + char *country = NULL, *code = NULL; + + if (res.found_entry) { + country = get_value (res, "country", "names", "en", NULL); + code = get_value (res, "country", "iso_code", NULL); + } + geoip_set_country (country, code, location); +} + +/* A wrapper to fetch the looked up result and set the continent code. + * + * If no data is found, NULL is set. + * On success, the fetched value is set. */ +static void +geoip_query_continent (MMDB_lookup_result_s res, char *location) +{ + char *code = NULL; + + if (res.found_entry) + code = get_value (res, "continent", "code", NULL); + geoip_set_continent (code, location); +} + +/* Set country data by record into the given `location` buffer */ +void +geoip_get_country (const char *ip, char *location, GO_UNUSED GTypeIP type_ip) +{ + MMDB_lookup_result_s res; + + geoip_lookup (&res, ip); + geoip_query_country (res, location); +} + +/* A wrapper to fetch the looked up result and set the continent. */ +void +geoip_get_continent (const char *ip, char *location, GO_UNUSED GTypeIP type_ip) +{ + MMDB_lookup_result_s res; + + geoip_lookup (&res, ip); + geoip_query_continent (res, location); +} + +/* Entry point to set GeoIP location into the corresponding buffers, + * (continent, country, city). + * + * On error, 1 is returned + * On success, buffers are set and 0 is returned */ +int +set_geolocation (char *host, char *continent, char *country, char *city) +{ + MMDB_lookup_result_s res; + + if (!is_geoip_resource ()) + return 1; + + geoip_lookup (&res, host); + geoip_query_country (res, country); + geoip_query_continent (res, continent); + if (geoip_city_type) + geoip_query_city (res, city); + + return 0; +} diff --git a/goaccess++/src/gholder.c b/goaccess++/src/gholder.c new file mode 100644 index 0000000..27939c6 --- /dev/null +++ b/goaccess++/src/gholder.c @@ -0,0 +1,673 @@ +/** + * gholder.c -- data structure to hold raw data + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#ifdef HAVE_GEOLOCATION +#include "geoip1.h" +#endif + +#include "gholder.h" + +#include "error.h" +#include "gdns.h" +#include "util.h" +#include "xmalloc.h" + +typedef struct GPanel_ +{ + GModule module; + void (*insert) (GRawDataItem item, GHolder * h, GRawDataType type, + const struct GPanel_ *); + void (*holder_callback) (GHolder * h); + void (*lookup) (GRawDataItem item); +} GPanel; + +static void add_data_to_holder (GRawDataItem item, GHolder * h, + GRawDataType type, const GPanel * panel); +static void add_host_to_holder (GRawDataItem item, GHolder * h, + GRawDataType type, const GPanel * panel); +static void add_root_to_holder (GRawDataItem item, GHolder * h, + GRawDataType type, const GPanel * panel); +static void add_host_child_to_holder (GHolder * h); + +/* *INDENT-OFF* */ +static GPanel paneling[] = { + {VISITORS , add_data_to_holder, NULL} , + {REQUESTS , add_data_to_holder, NULL} , + {REQUESTS_STATIC , add_data_to_holder, NULL} , + {NOT_FOUND , add_data_to_holder, NULL} , + {HOSTS , add_host_to_holder, add_host_child_to_holder} , + {OS , add_root_to_holder, NULL} , + {BROWSERS , add_root_to_holder, NULL} , + {VISIT_TIMES , add_data_to_holder, NULL} , + {VIRTUAL_HOSTS , add_data_to_holder, NULL} , + {REFERRERS , add_data_to_holder, NULL} , + {REFERRING_SITES , add_data_to_holder, NULL} , + {KEYPHRASES , add_data_to_holder, NULL} , + {STATUS_CODES , add_root_to_holder, NULL} , + {REMOTE_USER , add_data_to_holder, NULL} , +#ifdef HAVE_GEOLOCATION + {GEO_LOCATION , add_root_to_holder, NULL} , +#endif +}; +/* *INDENT-ON* */ + +/* Get a panel from the GPanel structure given a module. + * + * On error, or if not found, NULL is returned. + * On success, the panel value is returned. */ +static GPanel * +panel_lookup (GModule module) +{ + int i, num_panels = ARRAY_SIZE (paneling); + + for (i = 0; i < num_panels; i++) { + if (paneling[i].module == module) + return &paneling[i]; + } + return NULL; +} + +/* Allocate memory for a new GHolder instance. + * + * On success, the newly allocated GHolder is returned . */ +GHolder * +new_gholder (uint32_t size) +{ + GHolder *holder = xmalloc (size * sizeof (GHolder)); + memset (holder, 0, size * sizeof *holder); + + return holder; +} + +/* Allocate memory for a new GHolderItem instance. + * + * On success, the newly allocated GHolderItem is returned . */ +static GHolderItem * +new_gholder_item (uint32_t size) +{ + GHolderItem *item = xcalloc (size, sizeof (GHolderItem)); + + return item; +} + +/* Allocate memory for a new double linked-list GSubList instance. + * + * On success, the newly allocated GSubList is returned . */ +static GSubList * +new_gsublist (void) +{ + GSubList *sub_list = xmalloc (sizeof (GSubList)); + sub_list->head = NULL; + sub_list->tail = NULL; + sub_list->size = 0; + + return sub_list; +} + +/* Allocate memory for a new double linked-list GSubItem node. + * + * On success, the newly allocated GSubItem is returned . */ +static GSubItem * +new_gsubitem (GModule module, GMetrics * nmetrics) +{ + GSubItem *sub_item = xmalloc (sizeof (GSubItem)); + + sub_item->metrics = nmetrics; + sub_item->module = module; + sub_item->prev = NULL; + sub_item->next = NULL; + + return sub_item; +} + +/* Add an item to the end of a given sub list. */ +static void +add_sub_item_back (GSubList * sub_list, GModule module, GMetrics * nmetrics) +{ + GSubItem *sub_item = new_gsubitem (module, nmetrics); + if (sub_list->tail) { + sub_list->tail->next = sub_item; + sub_item->prev = sub_list->tail; + sub_list->tail = sub_item; + } else { + sub_list->head = sub_item; + sub_list->tail = sub_item; + } + sub_list->size++; +} + +/* Delete the entire given sub list. */ +static void +delete_sub_list (GSubList * sub_list) +{ + GSubItem *item = NULL; + GSubItem *next = NULL; + + if (sub_list != NULL && sub_list->size == 0) + goto clear; + if (sub_list->size == 0) + return; + + for (item = sub_list->head; item; item = next) { + next = item->next; + free (item->metrics->data); + free (item->metrics); + free (item); + } +clear: + sub_list->head = NULL; + sub_list->size = 0; + free (sub_list); +} + +/* Free malloc'd holder fields. */ +static void +free_holder_data (GHolderItem item) +{ + if (item.sub_list != NULL) + delete_sub_list (item.sub_list); + if (item.metrics->data != NULL) + free (item.metrics->data); + if (item.metrics->method != NULL) + free (item.metrics->method); + if (item.metrics->protocol != NULL) + free (item.metrics->protocol); + if (item.metrics != NULL) + free (item.metrics); +} + +/* Free all memory allocated in holder for a given module. */ +void +free_holder_by_module (GHolder ** holder, GModule module) +{ + int j; + + if ((*holder) == NULL) + return; + + for (j = 0; j < (*holder)[module].idx; j++) { + free_holder_data ((*holder)[module].items[j]); + } + free ((*holder)[module].items); + + (*holder)[module].holder_size = 0; + (*holder)[module].idx = 0; + (*holder)[module].sub_items_size = 0; +} + +/* Free all memory allocated in holder for all modules. */ +void +free_holder (GHolder ** holder) +{ + GModule module; + int j; + size_t idx = 0; + + if ((*holder) == NULL) + return; + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + for (j = 0; j < (*holder)[module].idx; j++) { + free_holder_data ((*holder)[module].items[j]); + } + free ((*holder)[module].items); + } + free (*holder); + (*holder) = NULL; +} + +/* Iterate over holder and get the key index. + * + * If the key does not exist, -1 is returned. + * On success, the key in holder is returned . */ +static int +get_item_idx_in_holder (GHolder * holder, const char *k) +{ + int i; + if (holder == NULL) + return KEY_NOT_FOUND; + if (holder->idx == 0) + return KEY_NOT_FOUND; + if (k == NULL || *k == '\0') + return KEY_NOT_FOUND; + + for (i = 0; i < holder->idx; i++) { + if (strcmp (k, holder->items[i].metrics->data) == 0) + return i; + } + + return KEY_NOT_FOUND; +} + +/* Copy linked-list items to an array, sort, and move them back to the + * list. Should be faster than sorting the list */ +static void +sort_sub_list (GHolder * h, GSort sort) +{ + GHolderItem *arr; + GSubItem *iter; + GSubList *sub_list; + int i, j, k; + + /* iterate over root-level nodes */ + for (i = 0; i < h->idx; i++) { + sub_list = h->items[i].sub_list; + if (sub_list == NULL) + continue; + + arr = new_gholder_item (sub_list->size); + + /* copy items from the linked-list into an array */ + for (j = 0, iter = sub_list->head; iter; iter = iter->next, j++) { + arr[j].metrics = new_gmetrics (); + + arr[j].metrics->bw.nbw = iter->metrics->bw.nbw; + arr[j].metrics->data = xstrdup (iter->metrics->data); + arr[j].metrics->hits = iter->metrics->hits; + arr[j].metrics->id = iter->metrics->id; + arr[j].metrics->visitors = iter->metrics->visitors; + if (conf.serve_usecs) { + arr[j].metrics->avgts.nts = iter->metrics->avgts.nts; + arr[j].metrics->cumts.nts = iter->metrics->cumts.nts; + arr[j].metrics->maxts.nts = iter->metrics->maxts.nts; + } + } + sort_holder_items (arr, j, sort); + delete_sub_list (sub_list); + + sub_list = new_gsublist (); + for (k = 0; k < j; k++) { + if (k > 0) + sub_list = h->items[i].sub_list; + + add_sub_item_back (sub_list, h->module, arr[k].metrics); + h->items[i].sub_list = sub_list; + } + free (arr); + } +} + +/* Set the data metric field for the host panel. + * + * On success, the data field/metric is set. */ +static int +set_host_child_metrics (char *data, uint8_t id, GMetrics ** nmetrics) +{ + GMetrics *metrics; + + metrics = new_gmetrics (); + metrics->data = xstrdup (data); + metrics->id = id; + *nmetrics = metrics; + + return 0; +} + +/* Set host panel data, including sub items. + * + * On success, the host panel data is set. */ +static void +set_host_sub_list (GHolder * h, GSubList * sub_list) +{ + GMetrics *nmetrics; +#ifdef HAVE_GEOLOCATION + char city[CITY_LEN] = ""; + char continent[CONTINENT_LEN] = ""; + char country[COUNTRY_LEN] = ""; +#endif + + char *host = h->items[h->idx].metrics->data, *hostname = NULL; +#ifdef HAVE_GEOLOCATION + /* add geolocation child nodes */ + set_geolocation (host, continent, country, city); + + /* country */ + if (country[0] != '\0') { + set_host_child_metrics (country, MTRC_ID_COUNTRY, &nmetrics); + add_sub_item_back (sub_list, h->module, nmetrics); + h->items[h->idx].sub_list = sub_list; + h->sub_items_size++; + + /* flag only */ + conf.has_geocountry = 1; + } + + /* city */ + if (city[0] != '\0') { + set_host_child_metrics (city, MTRC_ID_CITY, &nmetrics); + add_sub_item_back (sub_list, h->module, nmetrics); + h->items[h->idx].sub_list = sub_list; + h->sub_items_size++; + + /* flag only */ + conf.has_geocity = 1; + } +#endif + + /* hostname */ + if (conf.enable_html_resolver && conf.output_stdout) { + hostname = reverse_ip (host); + set_host_child_metrics (hostname, MTRC_ID_HOSTNAME, &nmetrics); + add_sub_item_back (sub_list, h->module, nmetrics); + h->items[h->idx].sub_list = sub_list; + h->sub_items_size++; + free (hostname); + } +} + +/* Set host panel data, including sub items. + * + * On success, the host panel data is set. */ +static void +add_host_child_to_holder (GHolder * h) +{ + GMetrics *nmetrics; + GSubList *sub_list = new_gsublist (); + + char *ip = h->items[h->idx].metrics->data; + char *hostname = NULL; + int n = h->sub_items_size; + + /* add child nodes */ + set_host_sub_list (h, sub_list); + + pthread_mutex_lock (&gdns_thread.mutex); + hostname = ht_get_hostname (ip); + pthread_mutex_unlock (&gdns_thread.mutex); + + /* determine if we have the IP's hostname */ + if (!hostname) { + dns_resolver (ip); + } else if (hostname) { + set_host_child_metrics (hostname, MTRC_ID_HOSTNAME, &nmetrics); + add_sub_item_back (sub_list, h->module, nmetrics); + h->items[h->idx].sub_list = sub_list; + h->sub_items_size++; + free (hostname); + } + + /* did not add any items */ + if (n == h->sub_items_size) + free (sub_list); +} + +/* Given a GRawDataType, set the data and hits value. + * + * On error, no values are set and 1 is returned. + * On success, the data and hits values are set and 0 is returned. */ +static int +set_data_hits_keys (GModule module, GRawDataItem item, GRawDataType type, + char **data, int *hits) +{ + if (type == INTEGER) { + if (!(*data = ht_get_datamap (module, item.key))) + return 1; + *hits = item.value.ivalue; + } else if (type == STRING) { + if (!(*hits = ht_get_hits (module, item.key))) + return 1; + *data = xstrdup (item.value.svalue); + } + return 0; +} + +/* Given a data item, store it into a holder structure. */ +static void +set_data_holder_metrics (GRawDataItem item, GHolder * h, char *data, int hits) +{ + char *method = NULL, *protocol = NULL; + int visitors = 0; + uint64_t bw = 0, cumts = 0, maxts = 0; + + bw = ht_get_bw (h->module, item.key); + cumts = ht_get_cumts (h->module, item.key); + maxts = ht_get_maxts (h->module, item.key); + visitors = ht_get_visitors (h->module, item.key); + + h->items[h->idx].metrics = new_gmetrics (); + h->items[h->idx].metrics->hits = hits; + h->items[h->idx].metrics->data = data; + h->items[h->idx].metrics->visitors = visitors; + h->items[h->idx].metrics->bw.nbw = bw; + h->items[h->idx].metrics->avgts.nts = cumts / hits; + h->items[h->idx].metrics->cumts.nts = cumts; + h->items[h->idx].metrics->maxts.nts = maxts; + + if (conf.append_method) { + method = ht_get_method (h->module, item.key); + h->items[h->idx].metrics->method = method; + } + + if (conf.append_protocol) { + protocol = ht_get_protocol (h->module, item.key); + h->items[h->idx].metrics->protocol = protocol; + } +} + +/* A wrapper to set a host item */ +static void +set_host (GRawDataItem item, GHolder * h, const GPanel * panel, char *data, + int hits) +{ + set_data_holder_metrics (item, h, xstrdup (data), hits); + if (panel->holder_callback) + panel->holder_callback (h); + h->idx++; +} + +/* Set all panel data. This will set data for panels that do not + * contain sub items. A function pointer is used for post data set. */ +static void +add_data_to_holder (GRawDataItem item, GHolder * h, GRawDataType type, + const GPanel * panel) +{ + char *data = NULL; + int hits = 0; + + if (set_data_hits_keys (h->module, item, type, &data, &hits) == 1) + return; + + set_data_holder_metrics (item, h, data, hits); + if (panel->holder_callback) + panel->holder_callback (h); + + h->idx++; +} + +/* Set all panel data. This will set data for panels that do not + * contain sub items. A function pointer is used for post data set. */ +static void +add_host_to_holder (GRawDataItem item, GHolder * h, GRawDataType type, + const GPanel * panel) +{ + char buf4[INET_ADDRSTRLEN]; + char buf6[INET6_ADDRSTRLEN]; + char *data = NULL; + int hits = 0; + unsigned i; + + struct in6_addr addr6, mask6, nwork6; + struct in_addr addr4, mask4, nwork4; + + const char *m4 = "255.255.255.0"; + const char *m6 = "ffff:ffff:ffff:ffff:0000:0000:0000:0000"; + + if (set_data_hits_keys (h->module, item, type, &data, &hits) == 1) + return; + + if (!conf.anonymize_ip) { + add_data_to_holder (item, h, type, panel); + free (data); + return; + } + + if (1 == inet_pton (AF_INET, data, &addr4)) { + if (1 == inet_pton (AF_INET, m4, &mask4)) { + memset (buf4, 0, sizeof *buf4); + nwork4.s_addr = addr4.s_addr & mask4.s_addr; + + if (inet_ntop (AF_INET, &nwork4, buf4, INET_ADDRSTRLEN) != NULL) { + set_host (item, h, panel, buf4, hits); + free (data); + } + } + } else if (1 == inet_pton (AF_INET6, data, &addr6)) { + if (1 == inet_pton (AF_INET6, m6, &mask6)) { + memset (buf6, 0, sizeof *buf6); + for (i = 0; i < 16; i++) { + nwork6.s6_addr[i] = addr6.s6_addr[i] & mask6.s6_addr[i]; + } + + if (inet_ntop (AF_INET6, &nwork6, buf6, INET6_ADDRSTRLEN) != NULL) { + set_host (item, h, panel, buf6, hits); + free (data); + } + } + } +} + +/* Set all root panel data. This will set the root nodes. */ +static int +set_root_metrics (GRawDataItem item, GRawDataType type, GModule module, + GMetrics ** nmetrics) +{ + GMetrics *metrics; + char *data = NULL; + uint64_t bw = 0, cumts = 0, maxts = 0; + int hits = 0, visitors = 0; + + if (set_data_hits_keys (module, item, type, &data, &hits) == 1) + return 1; + + bw = ht_get_bw (module, item.key); + cumts = ht_get_cumts (module, item.key); + maxts = ht_get_maxts (module, item.key); + visitors = ht_get_visitors (module, item.key); + + metrics = new_gmetrics (); + metrics->avgts.nts = cumts / hits; + metrics->cumts.nts = cumts; + metrics->maxts.nts = maxts; + metrics->bw.nbw = bw; + metrics->data = data; + metrics->hits = hits; + metrics->visitors = visitors; + *nmetrics = metrics; + + return 0; +} + +/* Set all root panel data, including sub list items. */ +static void +add_root_to_holder (GRawDataItem item, GHolder * h, GRawDataType type, + GO_UNUSED const GPanel * panel) +{ + GSubList *sub_list; + GMetrics *metrics, *nmetrics; + char *root = NULL; + int root_idx = KEY_NOT_FOUND, idx = 0; + + if (set_root_metrics (item, type, h->module, &nmetrics) == 1) + return; + + if (!(root = (ht_get_root (h->module, item.key)))) + return; + + /* add data as a child node into holder */ + if (KEY_NOT_FOUND == (root_idx = get_item_idx_in_holder (h, root))) { + idx = h->idx; + sub_list = new_gsublist (); + metrics = new_gmetrics (); + + h->items[idx].metrics = metrics; + h->items[idx].metrics->data = root; + h->idx++; + } else { + sub_list = h->items[root_idx].sub_list; + metrics = h->items[root_idx].metrics; + + idx = root_idx; + free (root); + } + + add_sub_item_back (sub_list, h->module, nmetrics); + h->items[idx].sub_list = sub_list; + + h->items[idx].metrics = metrics; + h->items[idx].metrics->cumts.nts += nmetrics->cumts.nts; + h->items[idx].metrics->bw.nbw += nmetrics->bw.nbw; + h->items[idx].metrics->hits += nmetrics->hits; + h->items[idx].metrics->visitors += nmetrics->visitors; + h->items[idx].metrics->avgts.nts = + h->items[idx].metrics->cumts.nts / h->items[idx].metrics->hits; + if (nmetrics->maxts.nts > h->items[idx].metrics->maxts.nts) + h->items[idx].metrics->maxts.nts = nmetrics->maxts.nts; + + h->sub_items_size++; +} + +/* Load raw data into our holder structure */ +void +load_holder_data (GRawData * raw_data, GHolder * h, GModule module, GSort sort) +{ + int i, size = 0, max_choices = get_max_choices (); + const GPanel *panel = panel_lookup (module); + + size = raw_data->size; + h->holder_size = size > max_choices ? max_choices : size; + h->ht_size = size; + h->idx = 0; + h->module = module; + h->sub_items_size = 0; + h->items = new_gholder_item (h->holder_size); + + for (i = 0; i < h->holder_size; i++) { + panel->insert (raw_data->items[i], h, raw_data->type, panel); + } + sort_holder_items (h->items, h->idx, sort); + if (h->sub_items_size) + sort_sub_list (h, sort); + free_raw_data (raw_data); +} diff --git a/goaccess++/src/gholder.h b/goaccess++/src/gholder.h new file mode 100644 index 0000000..b5c05bc --- /dev/null +++ b/goaccess++/src/gholder.h @@ -0,0 +1,49 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef GHOLDER_H_INCLUDED +#define GHOLDER_H_INCLUDED + +#define MTRC_ID_COUNTRY 0 +#define MTRC_ID_CITY 1 +#define MTRC_ID_HOSTNAME 2 + +#include "commons.h" +#include "sort.h" + +/* Function Prototypes */ +GHolder *new_gholder (uint32_t size); +void *add_hostname_node (void *ptr_holder); +void free_holder_by_module (GHolder ** holder, GModule module); +void free_holder (GHolder ** holder); +void load_holder_data (GRawData * raw_data, GHolder * h, GModule module, + GSort sort); +void load_host_to_holder (GHolder * h, char *ip); + +#endif // for #ifndef GHOLDER_H diff --git a/goaccess++/src/gholder.o b/goaccess++/src/gholder.o new file mode 100644 index 0000000..672f809 Binary files /dev/null and b/goaccess++/src/gholder.o differ diff --git a/goaccess++/src/gkhash.c b/goaccess++/src/gkhash.c new file mode 100644 index 0000000..8dcfba8 --- /dev/null +++ b/goaccess++/src/gkhash.c @@ -0,0 +1,1610 @@ +/** + * gkhash.c -- default hash table functions + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "gkhash.h" + +#include "error.h" +#include "sort.h" +#include "util.h" +#include "xmalloc.h" + +/* Hash tables storage */ +static GKHashStorage *gkh_storage; + +/* *INDENT-OFF* */ +/* Hash tables used across the whole app */ +static khash_t (is32) *ht_agent_vals = NULL; +static khash_t (si32) *ht_agent_keys = NULL; +static khash_t (si32) *ht_unique_keys = NULL; +static khash_t (ss32) *ht_hostnames = NULL; +/* *INDENT-ON* */ +static GKHashStorage * +new_gkhstorage (uint32_t size) +{ + GKHashStorage *storage = xcalloc (size, sizeof (GKHashStorage)); + return storage; +} + +/* Initialize a new int key - int value hash table */ +static +khash_t (ii32) * +new_ii32_ht (void) +{ + khash_t (ii32) * h = kh_init (ii32); + return h; +} + +/* Initialize a new int key - string value hash table */ +static +khash_t (is32) * +new_is32_ht (void) +{ + khash_t (is32) * h = kh_init (is32); + return h; +} + +/* Initialize a new int key - uint64_t value hash table */ +static +khash_t (iu64) * +new_iu64_ht (void) +{ + khash_t (iu64) * h = kh_init (iu64); + return h; +} + +/* Initialize a new string key - int value hash table */ +static +khash_t (si32) * +new_si32_ht (void) +{ + khash_t (si32) * h = kh_init (si32); + return h; +} + +/* Initialize a new string key - string value hash table */ +static +khash_t (ss32) * +new_ss32_ht (void) +{ + khash_t (ss32) * h = kh_init (ss32); + return h; +} + +/* Initialize a new int key - int value hash table */ +static +khash_t (igsl) * +new_igsl_ht (void) +{ + khash_t (igsl) * h = kh_init (igsl); + return h; +} + +/* Initialize a new int key - uint64_t value hash table */ +static +khash_t (su64) * +new_su64_ht (void) +{ + khash_t (su64) * h = kh_init (su64); + return h; +} + +/* Destroys both the hash structure and the keys for a + * string key - int value hash */ +static void +des_si32_free (khash_t (si32) * hash) +{ + khint_t k; + if (!hash) + return; + + for (k = 0; k < kh_end (hash); ++k) { + if (kh_exist (hash, k)) { + free ((char *) kh_key (hash, k)); + } + } + + kh_destroy (si32, hash); +} + +/* Destroys both the hash structure and its string values */ +static void +des_is32_free (khash_t (is32) * hash) +{ + khint_t k; + if (!hash) + return; + + for (k = 0; k < kh_end (hash); ++k) { + if (kh_exist (hash, k)) { + free ((char *) kh_value (hash, k)); + } + } + + kh_destroy (is32, hash); +} + +/* Destroys both the hash structure and its string + * keys and string values */ +static void +des_ss32_free (khash_t (ss32) * hash) +{ + khint_t k; + if (!hash) + return; + + for (k = 0; k < kh_end (hash); ++k) { + if (kh_exist (hash, k)) { + free ((char *) kh_key (hash, k)); + free ((char *) kh_value (hash, k)); + } + } + + kh_destroy (ss32, hash); +} + +/* Destroys the hash structure */ +static void +des_ii32 (khash_t (ii32) * hash) +{ + if (!hash) + return; + kh_destroy (ii32, hash); +} + +/* Destroys both the hash structure and its GSLList + * values */ +static void +des_igsl_free (khash_t (igsl) * hash) +{ + khint_t k; + void *list = NULL; + if (!hash) + return; + + for (k = 0; k < kh_end (hash); ++k) { + if (kh_exist (hash, k) && (list = kh_value (hash, k))) { + list_remove_nodes (list); + } + } + + kh_destroy (igsl, hash); +} + +/* Destroys both the hash structure and the keys for a + * string key - uint64_t value hash */ +static void +des_su64_free (khash_t (su64) * hash) +{ + if (!hash) + return; + + kh_destroy (su64, hash); +} + +/* Destroys the hash structure */ +static void +des_iu64 (khash_t (iu64) * hash) +{ + if (!hash) + return; + kh_destroy (iu64, hash); +} + +/* Initialize map & metric hashes */ +static void +init_tables (GModule module) +{ + int n = 0, i; + /* *INDENT-OFF* */ + GKHashMetric metrics[] = { + {MTRC_KEYMAP , MTRC_TYPE_SI32 , {.si32 = new_si32_ht ()}} , + {MTRC_ROOTMAP , MTRC_TYPE_IS32 , {.is32 = new_is32_ht ()}} , + {MTRC_DATAMAP , MTRC_TYPE_IS32 , {.is32 = new_is32_ht ()}} , + {MTRC_UNIQMAP , MTRC_TYPE_SI32 , {.si32 = new_si32_ht ()}} , + {MTRC_ROOT , MTRC_TYPE_II32 , {.ii32 = new_ii32_ht ()}} , + {MTRC_HITS , MTRC_TYPE_II32 , {.ii32 = new_ii32_ht ()}} , + {MTRC_VISITORS , MTRC_TYPE_II32 , {.ii32 = new_ii32_ht ()}} , + {MTRC_BW , MTRC_TYPE_IU64 , {.iu64 = new_iu64_ht ()}} , + {MTRC_CUMTS , MTRC_TYPE_IU64 , {.iu64 = new_iu64_ht ()}} , + {MTRC_MAXTS , MTRC_TYPE_IU64 , {.iu64 = new_iu64_ht ()}} , + {MTRC_METHODS , MTRC_TYPE_IS32 , {.is32 = new_is32_ht ()}} , + {MTRC_PROTOCOLS , MTRC_TYPE_IS32 , {.is32 = new_is32_ht ()}} , + {MTRC_AGENTS , MTRC_TYPE_IGSL , {.igsl = new_igsl_ht ()}} , + {MTRC_METADATA , MTRC_TYPE_SU64 , {.su64 = new_su64_ht ()}} , + }; + /* *INDENT-ON* */ + + n = ARRAY_SIZE (metrics); + for (i = 0; i < n; i++) { + gkh_storage[module].metrics[i] = metrics[i]; + } +} + +/* Initialize hash tables */ +void +init_storage (void) +{ + GModule module; + size_t idx = 0; + + /* Hashes used across the whole app (not per module) */ + ht_agent_keys = (khash_t (si32) *) new_si32_ht (); + ht_agent_vals = (khash_t (is32) *) new_is32_ht (); + ht_hostnames = (khash_t (ss32) *) new_ss32_ht (); + ht_unique_keys = (khash_t (si32) *) new_si32_ht (); + + gkh_storage = new_gkhstorage (TOTAL_MODULES); + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + gkh_storage[module].module = module; + init_tables (module); + } +} + +static void +free_metric_type (GKHashMetric mtrc) +{ + /* Determine the hash structure type */ + switch (mtrc.type) { + case MTRC_TYPE_II32: + des_ii32 (mtrc.ii32); + break; + case MTRC_TYPE_IS32: + des_is32_free (mtrc.is32); + break; + case MTRC_TYPE_IU64: + des_iu64 (mtrc.iu64); + break; + case MTRC_TYPE_SI32: + des_si32_free (mtrc.si32); + break; + case MTRC_TYPE_SS32: + des_ss32_free (mtrc.ss32); + break; + case MTRC_TYPE_IGSL: + des_igsl_free (mtrc.igsl); + break; + case MTRC_TYPE_SU64: + des_su64_free (mtrc.su64); + break; + } +} + +/* Destroys the hash structure allocated metrics */ +static void +free_metrics (GModule module) +{ + int i; + GKHashMetric mtrc; + + for (i = 0; i < GSMTRC_TOTAL; i++) { + mtrc = gkh_storage[module].metrics[i]; + free_metric_type (mtrc); + } +} + +/* Destroys the hash structure and its content */ +void +free_storage (void) +{ + size_t idx = 0; + + des_is32_free (ht_agent_vals); + des_si32_free (ht_agent_keys); + des_si32_free (ht_unique_keys); + des_ss32_free (ht_hostnames); + + if (!gkh_storage) + return; + + FOREACH_MODULE (idx, module_list) { + free_metrics (module_list[idx]); + } + free (gkh_storage); +} + +/* Given a module and a metric, get the hash table + * + * On error, or if table is not found, NULL is returned. + * On success the hash structure pointer is returned. */ +static void * +get_hash (GModule module, GSMetric metric) +{ + void *hash = NULL; + int i; + GKHashMetric mtrc; + + for (i = 0; i < GSMTRC_TOTAL; i++) { + if (hash != NULL) + break; + + mtrc = gkh_storage[module].metrics[i]; + if (mtrc.metric != metric) + continue; + + /* Determine the hash structure type */ + switch (mtrc.type) { + case MTRC_TYPE_II32: + hash = mtrc.ii32; + break; + case MTRC_TYPE_IS32: + hash = mtrc.is32; + break; + case MTRC_TYPE_IU64: + hash = mtrc.iu64; + break; + case MTRC_TYPE_SI32: + hash = mtrc.si32; + break; + case MTRC_TYPE_SS32: + hash = mtrc.ss32; + break; + case MTRC_TYPE_IGSL: + hash = mtrc.igsl; + break; + case MTRC_TYPE_SU64: + hash = mtrc.su64; + break; + } + } + + return hash; +} + +/* Insert a string key and the corresponding int value. + * Note: If the key exists, the value is not replaced. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +static int +ins_si32 (khash_t (si32) * hash, const char *key, int value) +{ + khint_t k; + int ret; + char *dupkey = NULL; + + if (!hash) + return -1; + + dupkey = xstrdup (key); + k = kh_put (si32, hash, dupkey, &ret); + /* operation failed, or key exists */ + if (ret == -1 || ret == 0) { + free (dupkey); + return -1; + } + + kh_val (hash, k) = value; + + return 0; +} + +/* Insert an int key and the corresponding string value. + * Note: If the key exists, the value is not replaced. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +static int +ins_is32 (khash_t (is32) * hash, int key, const char *value) +{ + khint_t k; + int ret; + + if (!hash) + return -1; + + k = kh_put (is32, hash, key, &ret); + if (ret == -1 || ret == 0) + return -1; + + kh_val (hash, k) = xstrdup (value); + + return 0; +} + +/* Insert a string key and the corresponding string value. + * Note: If the key exists, the value is not replaced. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +static int +ins_ss32 (khash_t (ss32) * hash, const char *key, const char *value) +{ + khint_t k; + int ret; + char *dupkey = NULL; + + if (!hash) + return -1; + + dupkey = xstrdup (key); + k = kh_put (ss32, hash, dupkey, &ret); + /* operation failed, or key exists */ + if (ret == -1 || ret == 0) { + free (dupkey); + return -1; + } + + kh_val (hash, k) = xstrdup (value); + + return 0; +} + +/* Insert an int key and an int value + * Note: If the key exists, its value is replaced by the given value. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +ins_ii32 (khash_t (ii32) * hash, int key, int value) +{ + khint_t k; + int ret; + + if (!hash) + return -1; + + k = kh_put (ii32, hash, key, &ret); + if (ret == -1) + return -1; + + kh_val (hash, k) = value; + + return 0; +} + +/* Insert an int key and a uint64_t value + * Note: If the key exists, its value is replaced by the given value. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +ins_iu64 (khash_t (iu64) * hash, int key, uint64_t value) +{ + khint_t k; + int ret; + + if (!hash) + return -1; + + k = kh_put (iu64, hash, key, &ret); + if (ret == -1) + return -1; + + kh_val (hash, k) = value; + + return 0; +} + +/* Increase an int value given an int key. + * Note: If the key exists, its value is increased by the given inc. + * + * On error, -1 is returned. + * On success the inserted value is returned */ +static int +inc_ii32 (khash_t (ii32) * hash, int key, int inc) +{ + khint_t k; + int ret, value = inc; + + if (!hash) + return -1; + + k = kh_get (ii32, hash, key); + /* key found, increment current value by the given `inc` */ + if (k != kh_end (hash)) + value = kh_val (hash, k) + inc; + + k = kh_put (ii32, hash, key, &ret); + if (ret == -1) + return -1; + + kh_val (hash, k) = value; + + return value; +} + +/* Increase a uint64_t value given a string key. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +inc_su64 (khash_t (su64) * hash, const char *key, uint64_t inc) +{ + khint_t k; + int ret; + uint64_t value = inc; + + if (!hash) + return -1; + + k = kh_get (su64, hash, key); + /* key not found, set new value to the given `inc` */ + if (k == kh_end (hash)) { + k = kh_put (su64, hash, key, &ret); + /* operation failed */ + if (ret == -1) + return -1; + } else { + value = kh_val (hash, k) + inc; + } + + kh_val (hash, k) = value; + + return 0; +} + +/* Increase a uint64_t value given an int key. + * Note: If the key exists, its value is increased by the given inc. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +inc_iu64 (khash_t (iu64) * hash, int key, uint64_t inc) +{ + khint_t k; + int ret; + uint64_t value = inc; + + if (!hash) + return -1; + + k = kh_get (iu64, hash, key); + /* key found, increment current value by the given `inc` */ + if (k != kh_end (hash)) + value = (uint64_t) kh_val (hash, k) + inc; + + k = kh_put (iu64, hash, key, &ret); + if (ret == -1) + return -1; + + kh_val (hash, k) = value; + + return 0; +} + +/* Insert a string key and auto increment int value. + * + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +static int +ins_si32_ai (khash_t (si32) * hash, const char *key) +{ + int size = 0, value = 0; + + if (!hash) + return -1; + + size = kh_size (hash); + /* the auto increment value starts at SIZE (hash table) + 1 */ + value = size > 0 ? size + 1 : 1; + + if (ins_si32 (hash, key, value) == -1) + return -1; + + return value; +} + +/* Compare if the given needle is in the haystack + * + * if equal, 1 is returned, else 0 */ +static int +find_int_key_in_list (void *data, void *needle) +{ + return (*(int *) data) == (*(int *) needle) ? 1 : 0; +} + +/* Insert an int key and the corresponding GSLList (Single linked-list) value. + * Note: If the key exists within the list, the value is not appended. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +ins_igsl (khash_t (igsl) * hash, int key, int value) +{ + khint_t k; + GSLList *list, *match; + int ret; + + if (!hash) + return -1; + + k = kh_get (igsl, hash, key); + /* key found, check if key exists within the list */ + if (k != kh_end (hash) && (list = kh_val (hash, k))) { + if ((match = list_find (list, find_int_key_in_list, &value))) + return 0; + list = list_insert_prepend (list, int2ptr (value)); + } else { + list = list_create (int2ptr (value)); + } + + k = kh_put (igsl, hash, key, &ret); + if (ret == -1) + return -1; + + kh_val (hash, k) = list; + + return 0; +} + +/* Get the int value of a given string key. + * + * On error, -1 is returned. + * On success the int value for the given key is returned */ +static int +get_si32 (khash_t (si32) * hash, const char *key) +{ + khint_t k; + + if (!hash) + return -1; + + k = kh_get (si32, hash, key); + /* key found, return current value */ + if (k != kh_end (hash)) + return kh_val (hash, k); + + return -1; +} + +/* Get the string value of a given int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +static char * +get_is32 (khash_t (is32) * hash, int key) +{ + khint_t k; + char *value = NULL; + + if (!hash) + return NULL; + + k = kh_get (is32, hash, key); + /* key found, return current value */ + if (k != kh_end (hash) && (value = kh_val (hash, k))) + return xstrdup (value); + + return NULL; +} + +/* Get the string value of a given string key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +static char * +get_ss32 (khash_t (ss32) * hash, const char *key) +{ + khint_t k; + char *value = NULL; + + if (!hash) + return NULL; + + k = kh_get (ss32, hash, key); + /* key found, return current value */ + if (k != kh_end (hash) && (value = kh_val (hash, k))) + return xstrdup (value); + + return NULL; +} + +/* Get the int value of a given int key. + * + * If key is not found, 0 is returned. + * On error, -1 is returned. + * On success the int value for the given key is returned */ +static int +get_ii32 (khash_t (ii32) * hash, int key) +{ + khint_t k; + int value = 0; + + if (!hash) + return -1; + + k = kh_get (ii32, hash, key); + /* key found, return current value */ + if (k != kh_end (hash) && (value = kh_val (hash, k))) + return value; + + return 0; +} + +/* Get the uint64_t value of a given int key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +static uint64_t +get_iu64 (khash_t (iu64) * hash, int key) +{ + khint_t k; + uint64_t value = 0; + + if (!hash) + return 0; + + k = kh_get (iu64, hash, key); + /* key found, return current value */ + if (k != kh_end (hash) && (value = kh_val (hash, k))) + return value; + + return 0; +} + +/* Get the GSLList value of a given int key. + * + * On error, or if key is not found, NULL is returned. + * On success the GSLList value for the given key is returned */ +static GSLList * +get_igsl (khash_t (igsl) * hash, int key) +{ + khint_t k; + GSLList *list = NULL; + + if (!hash) + return NULL; + + k = kh_get (igsl, hash, key); + /* key found, return current value */ + if (k != kh_end (hash) && (list = kh_val (hash, k))) + return list; + + return NULL; +} + +/* Get the uint64_t value of a given string key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +static uint64_t +get_su64 (khash_t (su64) * hash, const char *key) +{ + khint_t k; + uint64_t val = 0; + + if (!hash) + return 0; + + k = kh_get (su64, hash, key); + /* key found, return current value */ + if (k != kh_end (hash) && (val = kh_val (hash, k))) + return val; + + return 0; +} + +/* Iterate over all the key/value pairs for the given hash structure + * and set the maximum and minimum values found on an integer key and + * integer value. + * + * Note: This are expensive calls since it has to iterate over all + * key-value pairs + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +static void +get_ii32_min_max (khash_t (ii32) * hash, int *min, int *max) +{ + khint_t k; + int curvalue = 0, i; + + for (i = 0, k = kh_begin (hash); k != kh_end (hash); ++k) { + if (!kh_exist (hash, k)) + continue; + + curvalue = kh_value (hash, k); + if (i++ == 0) + *min = curvalue; + if (curvalue > *max) + *max = curvalue; + if (curvalue < *min) + *min = curvalue; + } +} + +/* Iterate over all the key/value pairs for the given hash structure + * and set the maximum and minimum values found on an integer key and + * a uint64_t value. + * + * Note: This are expensive calls since it has to iterate over all + * key-value pairs + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +static void +get_iu64_min_max (khash_t (iu64) * hash, uint64_t * min, uint64_t * max) +{ + khint_t k; + uint64_t curvalue = 0; + int i; + + for (i = 0, k = kh_begin (hash); k != kh_end (hash); ++k) { + if (!kh_exist (hash, k)) + continue; + + curvalue = kh_value (hash, k); + if (i++ == 0) + *min = curvalue; + if (curvalue > *max) + *max = curvalue; + if (curvalue < *min) + *min = curvalue; + } +} + +/* Insert a unique visitor key string (IP/DATE/UA), mapped to an auto + * incremented value. + * + * If the given key exists, its value is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_unique_key (const char *key) +{ + int value = -1; + khash_t (si32) * hash = ht_unique_keys; + + if (!hash) + return -1; + + if ((value = get_si32 (hash, key)) != -1) + return value; + + return ins_si32_ai (hash, key); +} + +/* Insert a user agent key string, mapped to an auto incremented value. + * + * If the given key exists, its value is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_agent_key (const char *key) +{ + int value = -1; + khash_t (si32) * hash = ht_agent_keys; + + if (!hash) + return -1; + + if ((value = get_si32 (hash, key)) != -1) + return value; + + return ins_si32_ai (hash, key); +} + +/* Insert a user agent int key, mapped to a user agent string value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_agent_value (int key, const char *value) +{ + khash_t (is32) * hash = ht_agent_vals; + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert a keymap string key. + * + * If the given key exists, its value is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_keymap (GModule module, const char *key) +{ + int value = -1; + khash_t (si32) * hash = get_hash (module, MTRC_KEYMAP); + + if (!hash) + return -1; + + if ((value = get_si32 (hash, key)) != -1) + return value; + + return ins_si32_ai (hash, key); +} + +/* Insert a datamap int key and string value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_datamap (GModule module, int key, const char *value) +{ + khash_t (is32) * hash = get_hash (module, MTRC_DATAMAP); + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert a rootmap int key from the keymap store mapped to its string value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_rootmap (GModule module, int key, const char *value) +{ + khash_t (is32) * hash = get_hash (module, MTRC_ROOTMAP); + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert a uniqmap string key. + * + * If the given key exists, 0 is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_uniqmap (GModule module, const char *key) +{ + int value = -1; + khash_t (si32) * hash = get_hash (module, MTRC_UNIQMAP); + + if (!hash) + return -1; + + if ((value = get_si32 (hash, key)) != -1) + return 0; + + return ins_si32_ai (hash, key); +} + +/* Insert a data int key mapped to the corresponding int root key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_root (GModule module, int key, int value) +{ + khash_t (ii32) * hash = get_hash (module, MTRC_ROOT); + + if (!hash) + return -1; + + return ins_ii32 (hash, key, value); +} + +/* Insert meta data counters from a string key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_meta_data (GModule module, const char *key, uint64_t value) +{ + khash_t (su64) * hash = get_hash (module, MTRC_METADATA); + + if (!hash) + return -1; + + return inc_su64 (hash, key, value); +} + +/* Increases hits counter from an int key. + * + * On error, -1 is returned. + * On success the inserted value is returned */ +int +ht_insert_hits (GModule module, int key, int inc) +{ + khash_t (ii32) * hash = get_hash (module, MTRC_HITS); + + if (!hash) + return -1; + + return inc_ii32 (hash, key, inc); +} + +/* Increases visitors counter from an int key. + * + * On error, -1 is returned. + * On success the inserted value is returned */ +int +ht_insert_visitor (GModule module, int key, int inc) +{ + khash_t (ii32) * hash = get_hash (module, MTRC_VISITORS); + + if (!hash) + return -1; + + return inc_ii32 (hash, key, inc); +} + +/* Increases bandwidth counter from an int key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_bw (GModule module, int key, uint64_t inc) +{ + khash_t (iu64) * hash = get_hash (module, MTRC_BW); + + if (!hash) + return -1; + + return inc_iu64 (hash, key, inc); +} + +/* Increases cumulative time served counter from an int key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_cumts (GModule module, int key, uint64_t inc) +{ + khash_t (iu64) * hash = get_hash (module, MTRC_CUMTS); + + if (!hash) + return -1; + + return inc_iu64 (hash, key, inc); +} + +/* Insert the maximum time served counter from an int key. + * Note: it compares the current value with the given value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_maxts (GModule module, int key, uint64_t value) +{ + uint64_t curvalue = 0; + khash_t (iu64) * hash = get_hash (module, MTRC_MAXTS); + + if (!hash) + return -1; + + if ((curvalue = get_iu64 (hash, key)) < value) + ins_iu64 (hash, key, value); + + return 0; +} + +/* Insert a method given an int key and string value. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +int +ht_insert_method (GModule module, int key, const char *value) +{ + khash_t (is32) * hash = get_hash (module, MTRC_METHODS); + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert a protocol given an int key and string value. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +int +ht_insert_protocol (GModule module, int key, const char *value) +{ + khash_t (is32) * hash = get_hash (module, MTRC_PROTOCOLS); + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert an agent for a hostname given an int key and int value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_agent (GModule module, int key, int value) +{ + khash_t (igsl) * hash = get_hash (module, MTRC_AGENTS); + + if (!hash) + return -1; + + return ins_igsl (hash, key, value); +} + +/* Insert an IP hostname mapped to the corresponding hostname. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +int +ht_insert_hostname (const char *ip, const char *host) +{ + khash_t (ss32) * hash = ht_hostnames; + + if (!hash) + return -1; + + return ins_ss32 (hash, ip, host); +} + +/* Get the number of elements in a datamap. + * + * Return -1 if the operation fails, else number of elements. */ +uint32_t +ht_get_size_datamap (GModule module) +{ + khash_t (is32) * hash = get_hash (module, MTRC_DATAMAP); + + if (!hash) + return 0; + + return kh_size (hash); +} + +/* Get the number of elements in a uniqmap. + * + * On error, 0 is returned. + * On success the number of elements in MTRC_UNIQMAP is returned */ +uint32_t +ht_get_size_uniqmap (GModule module) +{ + khash_t (is32) * hash = get_hash (module, MTRC_UNIQMAP); + + if (!hash) + return 0; + + return kh_size (hash); +} + +/* Get the string data value of a given int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_datamap (GModule module, int key) +{ + khash_t (is32) * hash = get_hash (module, MTRC_DATAMAP); + + if (!hash) + return NULL; + + return get_is32 (hash, key); +} + +/* Get the int value from MTRC_KEYMAP given a string key. + * + * On error, -1 is returned. + * On success the int value for the given key is returned */ +int +ht_get_keymap (GModule module, const char *key) +{ + khash_t (si32) * hash = get_hash (module, MTRC_KEYMAP); + + if (!hash) + return -1; + + return get_si32 (hash, key); +} + +/* Get the int value from MTRC_UNIQMAP given a string key. + * + * On error, -1 is returned. + * On success the int value for the given key is returned */ +int +ht_get_uniqmap (GModule module, const char *key) +{ + khash_t (si32) * hash = get_hash (module, MTRC_UNIQMAP); + + if (!hash) + return -1; + + return get_si32 (hash, key); +} + +/* Get the string root from MTRC_ROOTMAP given an int data key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_root (GModule module, int key) +{ + int root_key = 0; + khash_t (ii32) * hashroot = get_hash (module, MTRC_ROOT); + khash_t (is32) * hashrootmap = get_hash (module, MTRC_ROOTMAP); + + if (!hashroot || !hashrootmap) + return NULL; + + /* not found */ + if ((root_key = get_ii32 (hashroot, key)) == 0) + return NULL; + + return get_is32 (hashrootmap, root_key); +} + +/* Get the int visitors value from MTRC_VISITORS given an int key. + * + * If key is not found, 0 is returned. + * On error, -1 is returned. + * On success the int value for the given key is returned */ +int +ht_get_visitors (GModule module, int key) +{ + khash_t (ii32) * hash = get_hash (module, MTRC_VISITORS); + + if (!hash) + return -1; + + return get_ii32 (hash, key); +} + +/* Get the int visitors value from MTRC_VISITORS given an int key. + * + * If key is not found, 0 is returned. + * On error, -1 is returned. + * On success the int value for the given key is returned */ +int +ht_get_hits (GModule module, int key) +{ + khash_t (ii32) * hash = get_hash (module, MTRC_HITS); + + if (!hash) + return -1; + + return get_ii32 (hash, key); +} + +/* Get the uint64_t value from MTRC_BW given an int key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_bw (GModule module, int key) +{ + khash_t (iu64) * hash = get_hash (module, MTRC_BW); + + if (!hash) + return 0; + + return get_iu64 (hash, key); +} + +/* Get the uint64_t value from MTRC_CUMTS given an int key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_cumts (GModule module, int key) +{ + khash_t (iu64) * hash = get_hash (module, MTRC_CUMTS); + + if (!hash) + return 0; + + return get_iu64 (hash, key); +} + +/* Get the uint64_t value from MTRC_MAXTS given an int key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_maxts (GModule module, int key) +{ + khash_t (iu64) * hash = get_hash (module, MTRC_MAXTS); + + if (!hash) + return 0; + + return get_iu64 (hash, key); +} + +/* Get the string value from MTRC_METHODS given an int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_method (GModule module, int key) +{ + khash_t (is32) * hash = get_hash (module, MTRC_METHODS); + + if (!hash) + return NULL; + + return get_is32 (hash, key); +} + +/* Get the string value from MTRC_PROTOCOLS given an int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_protocol (GModule module, int key) +{ + khash_t (is32) * hash = get_hash (module, MTRC_PROTOCOLS); + + if (!hash) + return NULL; + + return get_is32 (hash, key); +} + +/* Get the string value from ht_hostnames given a string key (IP). + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_hostname (const char *host) +{ + khash_t (ss32) * hash = ht_hostnames; + + if (!hash) + return NULL; + + return get_ss32 (hash, host); +} + +/* Get the string value from ht_agent_vals (user agent) given an int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_host_agent_val (int key) +{ + khash_t (is32) * hash = ht_agent_vals; + + if (!hash) + return NULL; + + return get_is32 (hash, key); +} + +/* Get the list value from MTRC_AGENTS given an int key. + * + * On error, or if key is not found, NULL is returned. + * On success the GSLList value for the given key is returned */ +GSLList * +ht_get_host_agent_list (GModule module, int key) +{ + khash_t (igsl) * hash = get_hash (module, MTRC_AGENTS); + GSLList *list; + + if ((list = get_igsl (hash, key))) + return list; + return NULL; +} + +/* Get the meta data uint64_t from MTRC_METADATA given a string key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_meta_data (GModule module, const char *key) +{ + khash_t (su64) * hash = get_hash (module, MTRC_METADATA); + + return get_su64 (hash, key); +} + +/* Set the maximum and minimum values found on an integer key and + * integer value found on the MTRC_VISITORS hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_hits_min_max (GModule module, int *min, int *max) +{ + khash_t (ii32) * hash = get_hash (module, MTRC_HITS); + + if (!hash) + return; + + get_ii32_min_max (hash, min, max); +} + +/* Set the maximum and minimum values found on an integer key and + * integer value found on the MTRC_VISITORS hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_visitors_min_max (GModule module, int *min, int *max) +{ + khash_t (ii32) * hash = get_hash (module, MTRC_VISITORS); + + if (!hash) + return; + + get_ii32_min_max (hash, min, max); +} + +/* Set the maximum and minimum values found on an integer key and + * a uint64_t value found on the MTRC_BW hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_bw_min_max (GModule module, uint64_t * min, uint64_t * max) +{ + khash_t (iu64) * hash = get_hash (module, MTRC_BW); + + if (!hash) + return; + + get_iu64_min_max (hash, min, max); +} + +/* Set the maximum and minimum values found on an integer key and + * a uint64_t value found on the MTRC_CUMTS hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_cumts_min_max (GModule module, uint64_t * min, uint64_t * max) +{ + khash_t (iu64) * hash = get_hash (module, MTRC_CUMTS); + + if (!hash) + return; + + get_iu64_min_max (hash, min, max); +} + +/* Set the maximum and minimum values found on an integer key and + * a uint64_t value found on the MTRC_MAXTS hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_maxts_min_max (GModule module, uint64_t * min, uint64_t * max) +{ + khash_t (iu64) * hash = get_hash (module, MTRC_MAXTS); + + if (!hash) + return; + + get_iu64_min_max (hash, min, max); +} + +/* A wrapper to initialize a raw data structure. + * + * On success a GRawData structure is returned. */ +static GRawData * +init_new_raw_data (GModule module, uint32_t ht_size) +{ + GRawData *raw_data; + + raw_data = new_grawdata (); + raw_data->idx = 0; + raw_data->module = module; + raw_data->size = ht_size; + raw_data->items = new_grawdata_item (ht_size); + + return raw_data; +} + +/* Store the key/value pairs from a hash table into raw_data and sorts + * the hits (numeric) value. + * + * On error, NULL is returned. + * On success the GRawData sorted is returned */ +static GRawData * +parse_raw_num_data (GModule module) +{ + GRawData *raw_data; + khiter_t key; + uint32_t ht_size = 0; + + khash_t (ii32) * hash = get_hash (module, MTRC_HITS); + if (!hash) + return NULL; + + ht_size = kh_size (hash); + raw_data = init_new_raw_data (module, ht_size); + raw_data->type = INTEGER; + for (key = kh_begin (hash); key != kh_end (hash); ++key) { + if (!kh_exist (hash, key)) + continue; + + raw_data->items[raw_data->idx].key = kh_key (hash, key); + raw_data->items[raw_data->idx].value.ivalue = kh_value (hash, key); + raw_data->idx++; + } + + sort_raw_num_data (raw_data, raw_data->idx); + + return raw_data; +} + +/* Store the key/value pairs from a hash table into raw_data and sorts + * the data (string) value. + * + * On error, NULL is returned. + * On success the GRawData sorted is returned */ +static GRawData * +parse_raw_str_data (GModule module) +{ + GRawData *raw_data; + khiter_t key; + uint32_t ht_size = 0; + + khash_t (is32) * hash = get_hash (module, MTRC_DATAMAP); + if (!hash) + return NULL; + + ht_size = kh_size (hash); + raw_data = init_new_raw_data (module, ht_size); + raw_data->type = STRING; + for (key = kh_begin (hash); key != kh_end (hash); ++key) { + if (!kh_exist (hash, key)) + continue; + + raw_data->items[raw_data->idx].key = kh_key (hash, key); + raw_data->items[raw_data->idx].value.svalue = kh_value (hash, key); + raw_data->idx++; + } + + sort_raw_str_data (raw_data, raw_data->idx); + + return raw_data; +} + +/* Entry point to load the raw data from the data store into our + * GRawData structure. + * + * On error, NULL is returned. + * On success the GRawData sorted is returned */ +GRawData * +parse_raw_data (GModule module) +{ + GRawData *raw_data; + + switch (module) { + case VISITORS: + raw_data = parse_raw_str_data (module); + break; + default: + raw_data = parse_raw_num_data (module); + } + return raw_data; +} diff --git a/goaccess++/src/gkhash.h b/goaccess++/src/gkhash.h new file mode 100644 index 0000000..38e36d2 --- /dev/null +++ b/goaccess++/src/gkhash.h @@ -0,0 +1,250 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef GKHASH_H_INCLUDED +#define GKHASH_H_INCLUDED + +#include <stdint.h> + +#include "gslist.h" +#include "gstorage.h" +#include "khash.h" +#include "parser.h" + +/* int keys, int payload */ +KHASH_MAP_INIT_INT (ii32, int); +/* int keys, string payload */ +KHASH_MAP_INIT_INT (is32, char *); +/* int keys, uint64_t payload */ +KHASH_MAP_INIT_INT (iu64, uint64_t); +/* string keys, int payload */ +KHASH_MAP_INIT_STR (si32, int); +/* string keys, string payload */ +KHASH_MAP_INIT_STR (ss32, char *); +/* int keys, GSLList payload */ +KHASH_MAP_INIT_INT (igsl, GSLList *); +/* string keys, uint64_t payload */ +KHASH_MAP_INIT_STR (su64, uint64_t); + +/* Metrics Storage */ + +/* Maps keys (string) to numeric values (integer). + * This mitigates the issue of having multiple stores + * with the same string key, and therefore, avoids unnecessary + * memory usage (in most cases). + * + * HEAD|/index.php -> 1 + * POST|/index.php -> 2 + * Windows XP -> 3 + * Ubuntu 10.10 -> 4 + * GET|Ubuntu 10.10 -> 5 + * Linux -> 6 + * 26/Dec/2014 -> 7 + * Windows -> 8 + */ +/*khash_t(si32) MTRC_KEYMAP */ + +/* Maps integer keys of root elements from the keymap hash + * to actual string values. + * + * 6 -> Linux + * 8 -> Windows + */ +/*khash_t(is32) MTRC_ROOTMAP */ + +/* Maps integer keys of data elements from the keymap hash + * to actual string values. + * + * 1 -> /index.php + * 2 -> /index.php + * 3 -> Windows XP + * 4 -> Ubuntu 10.10 + * 5 -> Ubuntu 10.10 + * 7 -> 26/Dec/2014 + */ +/*khash_t(is32) MTRC_DATAMAP */ + +/* Maps a string key made from the integer key of the + * IP/date/UA and the integer key from the data field of + * each module to numeric autoincremented values. e.g., "1|4" + * => 1 -> unique visitor key (concatenated) with 4 -> data + * key. + * + * "1|4" -> 1 + * "1|5" -> 2 + */ +/*khash_t(si32) MTRC_UNIQMAP */ + +/* Maps integer key from the keymap hash to the number of + * hits. + * + * 1 -> 10934 + * 2 -> 3231 + * 3 -> 500 + * 4 -> 201 + * 5 -> 206 + */ +/*khash_t(ii32) MTRC_HITS */ + +/* Maps numeric keys made from the uniqmap store to autoincremented values + * (counter). + * 10 -> 100 + * 40 -> 56 + */ +/*khash_t(ii32) MTRC_VISITORS */ + +/* Maps numeric data keys to bandwidth (in bytes). + * 1 -> 1024 + * 2 -> 2048 + */ +/*khash_t(iu64) MTRC_BW */ + +/* Maps numeric data keys to cumulative time served (in usecs/msecs). + * 1 -> 187 + * 2 -> 208 + */ +/*khash_t(iu64) MTRC_CUMTS */ + +/* Maps numeric data keys to max time served (in usecs/msecs). + * 1 -> 1287 + * 2 -> 2308 + */ +/*khash_t(iu64) MTRC_MAXTS */ + +/* Maps numeric data keys to string values. + * 1 -> GET + * 2 -> POST + */ +/*khash_t(is32) MTRC_METHODS */ + +/* Maps numeric data keys to string values. + * 1 -> HTTP/1.1 + * 2 -> HTTP/1.0 + */ +/*khash_t(is32) MTRC_PROTOCOLS */ + +/* Maps numeric unique user-agent keys to the + * corresponding numeric value. + * 1 -> 3 + * 2 -> 4 + */ +/*khash_t(igsl) MTRC_AGENTS */ + +/* Enumerated Storage Metrics */ +typedef enum GSMetricType_ +{ + /* int key - int val */ + MTRC_TYPE_II32, + /* int key - string val */ + MTRC_TYPE_IS32, + /* int key - uint64_t val */ + MTRC_TYPE_IU64, + /* string key - int val */ + MTRC_TYPE_SI32, + /* string key - string val */ + MTRC_TYPE_SS32, + /* int key - GSLList val */ + MTRC_TYPE_IGSL, + /* string key - uint64_t val */ + MTRC_TYPE_SU64, +} GSMetricType; + +typedef struct GKHashMetric_ +{ + GSMetric metric; + GSMetricType type; + union + { + khash_t (ii32) * ii32; + khash_t (is32) * is32; + khash_t (iu64) * iu64; + khash_t (si32) * si32; + khash_t (ss32) * ss32; + khash_t (igsl) * igsl; + khash_t (su64) * su64; + }; +} GKHashMetric; + +/* Data Storage per module */ +typedef struct GKHashStorage_ +{ + GModule module; + GKHashMetric metrics[GSMTRC_TOTAL]; +} GKHashStorage; + +void free_storage (void); +void init_storage (void); + +int ht_insert_agent_key (const char *key); +int ht_insert_agent_value (int key, const char *value); +int ht_insert_unique_key (const char *key); + +int ht_insert_agent (GModule module, int key, int value); +int ht_insert_bw (GModule module, int key, uint64_t inc); +int ht_insert_cumts (GModule module, int key, uint64_t inc); +int ht_insert_datamap (GModule module, int key, const char *value); +int ht_insert_hits (GModule module, int key, int inc); +int ht_insert_hostname (const char *ip, const char *host); +int ht_insert_keymap (GModule module, const char *key); +int ht_insert_maxts (GModule module, int key, uint64_t value); +int ht_insert_meta_data (GModule module, const char *key, uint64_t value); +int ht_insert_method (GModule module, int key, const char *value); +int ht_insert_protocol (GModule module, int key, const char *value); +int ht_insert_root (GModule module, int key, int value); +int ht_insert_rootmap (GModule module, int key, const char *value); +int ht_insert_uniqmap (GModule module, const char *key); +int ht_insert_visitor (GModule module, int key, int inc); + +uint32_t ht_get_size_datamap (GModule module); +uint32_t ht_get_size_uniqmap (GModule module); + +char *ht_get_datamap (GModule module, int key); +char *ht_get_host_agent_val (int key); +char *ht_get_hostname (const char *host); +char *ht_get_method (GModule module, int key); +char *ht_get_protocol (GModule module, int key); +char *ht_get_root (GModule module, int key); +GSLList *ht_get_host_agent_list (GModule module, int key); +int ht_get_hits (GModule module, int key); +int ht_get_keymap (GModule module, const char *key); +int ht_get_uniqmap (GModule module, const char *key); +int ht_get_visitors (GModule module, int key); +uint64_t ht_get_bw (GModule module, int key); +uint64_t ht_get_cumts (GModule module, int key); +uint64_t ht_get_maxts (GModule module, int key); +uint64_t ht_get_meta_data (GModule module, const char *key); +void ht_get_bw_min_max (GModule module, uint64_t * min, uint64_t * max); +void ht_get_cumts_min_max (GModule module, uint64_t * min, uint64_t * max); +void ht_get_hits_min_max (GModule module, int *min, int *max); +void ht_get_maxts_min_max (GModule module, uint64_t * min, uint64_t * max); +void ht_get_visitors_min_max (GModule module, int *min, int *max); + +GRawData *parse_raw_data (GModule module); + +#endif // for #ifndef GKHASH_H diff --git a/goaccess++/src/gkhash.o b/goaccess++/src/gkhash.o new file mode 100644 index 0000000..b6609c6 Binary files /dev/null and b/goaccess++/src/gkhash.o differ diff --git a/goaccess++/src/gmenu.c b/goaccess++/src/gmenu.c new file mode 100644 index 0000000..80eed29 --- /dev/null +++ b/goaccess++/src/gmenu.c @@ -0,0 +1,150 @@ +/** + * gmenu.c -- goaccess menus + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "gmenu.h" + +#include "xmalloc.h" +#include "ui.h" + +/* Allocate memory for a new GMenu instance. + * + * On success, the newly allocated GMenu is returned . */ +GMenu * +new_gmenu (WINDOW * parent, int h, int w, int y, int x) +{ + GMenu *menu = xmalloc (sizeof (GMenu)); + + memset (menu, 0, sizeof *menu); + menu->count = 0; + menu->idx = 0; + menu->multiple = 0; + menu->selectable = 0; + menu->start = 0; + menu->status = 0; + + menu->h = h; + menu->w = w; + menu->x = x; + menu->y = y; + menu->win = derwin (parent, menu->h, menu->w, menu->y, menu->x); + + return menu; +} + +/* Render actual menu item */ +static void +draw_menu_item (GMenu * menu, char *s, int x, int y, int w, int checked, + GColors * (*func) (void)) +{ + char check, *lbl = NULL; + + if (menu->selectable) { + check = checked ? 'x' : ' '; + lbl = xmalloc (snprintf (NULL, 0, "[%c] %s", check, s) + 1); + sprintf (lbl, "[%c] %s", check, s); + draw_header (menu->win, lbl, "%s", y, x, w, (*func)); + free (lbl); + } else { + draw_header (menu->win, s, "%s", y, x, w, (*func)); + } +} + +/* Displays a menu to its associated window. + * + * On error, 1 is returned. + * On success, the newly created menu is added to the window and 0 is + * returned. */ +int +post_gmenu (GMenu * menu) +{ + GColors *(*func) (void); + int i = 0, j = 0, start, end, height, total, checked = 0; + + if (menu == NULL) + return 1; + + werase (menu->win); + + height = menu->h; + start = menu->start; + total = menu->size; + end = height < total ? start + height : total; + + for (i = start; i < end; i++, j++) { + func = i == menu->idx ? color_selected : color_default; + checked = menu->items[i].checked ? 1 : 0; + draw_menu_item (menu, menu->items[i].name, 0, j, menu->w, checked, func); + } + wrefresh (menu->win); + + return 0; +} + +/* Main work horse of the menu system processing input events */ +void +gmenu_driver (GMenu * menu, int c) +{ + int i; + + switch (c) { + case REQ_DOWN: + if (menu->idx >= menu->size - 1) + break; + ++menu->idx; + if (menu->idx >= menu->h && menu->idx >= menu->start + menu->h) + menu->start++; + post_gmenu (menu); + break; + case REQ_UP: + if (menu->idx <= 0) + break; + --menu->idx; + if (menu->idx < menu->start) + --menu->start; + post_gmenu (menu); + break; + case REQ_SEL: + if (!menu->multiple) { + for (i = 0; i < menu->size; i++) + menu->items[i].checked = 0; + } + if (menu->items[menu->idx].checked) + menu->items[menu->idx].checked = 0; + else + menu->items[menu->idx].checked = 1; + post_gmenu (menu); + break; + } +} diff --git a/goaccess++/src/gmenu.h b/goaccess++/src/gmenu.h new file mode 100644 index 0000000..0ab7383 --- /dev/null +++ b/goaccess++/src/gmenu.h @@ -0,0 +1,87 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifdef HAVE_NCURSESW_NCURSES_H +#include <ncursesw/ncurses.h> +#elif HAVE_NCURSES_NCURSES_H +#include <ncurses/ncurses.h> +#elif HAVE_NCURSES_H +#include <ncurses.h> +#elif HAVE_CURSES_H +#include <curses.h> +#endif + +#ifndef GMENU_H_INCLUDED +#define GMENU_H_INCLUDED + +enum ACTION +{ + REQ_DOWN, + REQ_UP, + REQ_SEL +}; + +typedef struct GMenu_ GMenu; +typedef struct GItem_ GItem; + +/* Menu Item */ +struct GItem_ +{ + char *name; + int checked; +}; + +/* Menu Panel */ +struct GMenu_ +{ + WINDOW *win; + + int count; + int size; + int idx; + int start; + int h; + int w; + int x; + int y; + unsigned short multiple; + unsigned short selectable; + unsigned short status; + GItem *items; +}; + +GMenu *new_gmenu (WINDOW * parent, int h, int w, int y, int x); +int post_gmenu (GMenu * menu); +void gmenu_driver (GMenu * menu, int c); + +#endif diff --git a/goaccess++/src/gmenu.o b/goaccess++/src/gmenu.o new file mode 100644 index 0000000..c8313d3 Binary files /dev/null and b/goaccess++/src/gmenu.o differ diff --git a/goaccess++/src/goaccess.c b/goaccess++/src/goaccess.c new file mode 100644 index 0000000..60d610f --- /dev/null +++ b/goaccess++/src/goaccess.c @@ -0,0 +1,1537 @@ +/** + * goaccess.c -- main log analyzer + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#include <assert.h> +#include <ctype.h> +#include <errno.h> + +#include <locale.h> + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <fcntl.h> +#include <pthread.h> +#include <signal.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#ifdef HAVE_GEOLOCATION +#include "geoip1.h" +#endif + +#include "browsers.h" +#include "csv.h" +#include "error.h" +#include "gdashboard.h" +#include "gdns.h" +#include "gholder.h" +#include "goaccess.h" +#include "gwsocket.h" +#include "json.h" +#include "options.h" +#include "output.h" +#include "util.h" +#include "websocket.h" +#include "xmalloc.h" + +GConf conf = { + .append_method = 1, + .append_protocol = 1, + .hl_header = 1, + .num_tests = 10, +}; + +/* Loading/Spinner */ +GSpinner *parsing_spinner; +/* active reverse dns flag */ +int active_gdns = 0; + +/* WebSocket server - writer and reader threads */ +static GWSWriter *gwswriter; +static GWSReader *gwsreader; +/* Dashboard data structure */ +static GDash *dash; +/* Data holder structure */ +static GHolder *holder; +/* Log line properties structure */ +static GLog *glog; +/* Old signal mask */ +static sigset_t oldset; +/* Curses windows */ +static WINDOW *header_win, *main_win; + +static int main_win_height = 0; + +/* *INDENT-OFF* */ +static GScroll gscroll = { + { + {0, 0}, /* visitors {scroll, offset} */ + {0, 0}, /* requests {scroll, offset} */ + {0, 0}, /* req static {scroll, offset} */ + {0, 0}, /* not found {scroll, offset} */ + {0, 0}, /* hosts {scroll, offset} */ + {0, 0}, /* os {scroll, offset} */ + {0, 0}, /* browsers {scroll, offset} */ + {0, 0}, /* visit times {scroll, offset} */ + {0, 0}, /* referrers {scroll, offset} */ + {0, 0}, /* ref sites {scroll, offset} */ + {0, 0}, /* keywords {scroll, offset} */ +#ifdef HAVE_GEOLOCATION + {0, 0}, /* geolocation {scroll, offset} */ +#endif + {0, 0}, /* status {scroll, offset} */ + }, + 0, /* current module */ + 0, /* main dashboard scroll */ + 0, /* expanded flag */ +}; +/* *INDENT-ON* */ + +/* Free malloc'd holder */ +static void +house_keeping_holder (void) +{ + /* REVERSE DNS THREAD */ + pthread_mutex_lock (&gdns_thread.mutex); + + /* kill dns pthread */ + active_gdns = 0; + /* clear holder structure */ + free_holder (&holder); + /* clear reverse dns queue */ + gdns_free_queue (); + /* clear the whole storage */ + free_storage (); + + pthread_mutex_unlock (&gdns_thread.mutex); +} + +/* Free malloc'd data across the whole program */ +static void +house_keeping (void) +{ +#ifdef TCB_MEMHASH + /* free malloc'd int values on the agent list */ + if (conf.list_agents) + free_agent_list (); +#endif + + house_keeping_holder (); + + /* DASHBOARD */ + if (dash && !conf.output_stdout) { + free_dashboard (dash); + reset_find (); + } + + /* GEOLOCATION */ +#ifdef HAVE_GEOLOCATION + geoip_free (); +#endif + + /* LOGGER */ + if (glog->pipe) + fclose (glog->pipe); + free_logerrors (glog); + free (glog); + + /* INVALID REQUESTS */ + if (conf.invalid_requests_log) { + LOG_DEBUG (("Closing invalid requests log.\n")); + invalid_log_close (); + } + + /* CONFIGURATION */ + free_formats (); + free_browsers_hash (); + if (conf.debug_log) { + LOG_DEBUG (("Bye.\n")); + dbg_log_close (); + } + + /* clear spinner */ + free (parsing_spinner); + /* free colors */ + free_color_lists (); + /* free cmd arguments */ + free_cmd_args (); + /* WebSocket writer */ + free (gwswriter); + /* WebSocket reader */ + free (gwsreader); +} + +/* Open the pidfile whose name is specified in the given path and write + * the daemonized given pid. */ +static void +write_pid_file (const char *path, pid_t pid) +{ + FILE *pidfile; + + if (!path) + return; + + if ((pidfile = fopen (path, "w"))) { + fprintf (pidfile, "%d", pid); + fclose (pidfile); + } else { + FATAL ("Unable to open the specified pid file. %s", strerror (errno)); + } +} + +/* Set GoAccess to run as a daemon */ +static void +daemonize (void) +{ + pid_t pid, sid; + int fd; + + /* Clone ourselves to make a child */ + pid = fork (); + + if (pid < 0) + exit (EXIT_FAILURE); + if (pid > 0) { + write_pid_file (conf.pidfile, pid); + printf ("Daemonized GoAccess: %d\n", pid); + exit (EXIT_SUCCESS); + } + + umask (0); + /* attempt to create our own process group */ + sid = setsid (); + if (sid < 0) { + LOG_DEBUG (("Unable to setsid: %s.\n", strerror (errno))); + exit (EXIT_FAILURE); + } + + /* set the working directory to the root directory. + * requires the user to specify absolute paths */ + if (chdir ("/") < 0) { + LOG_DEBUG (("Unable to set chdir: %s.\n", strerror (errno))); + exit (EXIT_FAILURE); + } + + /* redirect fd's 0,1,2 to /dev/null */ + /* Note that the user will need to use --debug-file for log output */ + if ((fd = open ("/dev/null", O_RDWR, 0)) == -1) { + LOG_DEBUG (("Unable to open /dev/null: %s.\n", strerror (errno))); + exit (EXIT_FAILURE); + } + + dup2 (fd, STDIN_FILENO); + dup2 (fd, STDOUT_FILENO); + dup2 (fd, STDERR_FILENO); + if (fd > STDERR_FILENO) { + close (fd); + } +} + +/* Extract data from the given module hash structure and allocate + + * load data from the hash table into an instance of GHolder */ +static void +allocate_holder_by_module (GModule module) +{ + GRawData *raw_data; + + /* extract data from the corresponding hash table */ + raw_data = parse_raw_data (module); + if (!raw_data) { + LOG_DEBUG (("raw data is NULL for module: %d.\n", module)); + return; + } + + load_holder_data (raw_data, holder + module, module, module_sort[module]); +} + +/* Iterate over all modules/panels and extract data from hash + * structures and load it into an instance of GHolder */ +static void +allocate_holder (void) +{ + size_t idx = 0; + + holder = new_gholder (TOTAL_MODULES); + FOREACH_MODULE (idx, module_list) { + allocate_holder_by_module (module_list[idx]); + } +} + +/* Extract data from the modules GHolder structure and load it into + * the terminal dashboard */ +static void +allocate_data_by_module (GModule module, int col_data) +{ + int size = 0, max_choices = get_max_choices (); + + dash->module[module].head = module_to_head (module); + dash->module[module].desc = module_to_desc (module); + + size = holder[module].idx; + if (gscroll.expanded && module == gscroll.current) { + size = size > max_choices ? max_choices : holder[module].idx; + } else { + size = holder[module].idx > col_data ? col_data : holder[module].idx; + } + + dash->module[module].alloc_data = size; /* data allocated */ + dash->module[module].ht_size = holder[module].ht_size; /* hash table size */ + dash->module[module].idx_data = 0; + dash->module[module].pos_y = 0; + + if (gscroll.expanded && module == gscroll.current) + dash->module[module].dash_size = DASH_EXPANDED; + else + dash->module[module].dash_size = DASH_COLLAPSED; + dash->total_alloc += dash->module[module].dash_size; + + pthread_mutex_lock (&gdns_thread.mutex); + load_data_to_dash (&holder[module], dash, module, &gscroll); + pthread_mutex_unlock (&gdns_thread.mutex); +} + +/* Iterate over all modules/panels and extract data from GHolder + * structure and load it into the terminal dashboard */ +static void +allocate_data (void) +{ + GModule module; + int col_data = get_num_collapsed_data_rows (); + size_t idx = 0; + + dash = new_gdash (); + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + allocate_data_by_module (module, col_data); + } +} + +/* A wrapper to render all windows within the dashboard. */ +static void +render_screens (void) +{ + GColors *color = get_color (COLOR_DEFAULT); + int row, col, chg = 0; + + getmaxyx (stdscr, row, col); + term_size (main_win, &main_win_height); + + generate_time (); + chg = glog->processed - glog->offset; + + draw_header (stdscr, "", "%s", row - 1, 0, col, color_default); + + wattron (stdscr, color->attr | COLOR_PAIR (color->pair->idx)); + mvaddstr (row - 1, 1, T_HELP_ENTER); + mvprintw (row - 1, 30, "%d - %s", chg, asctime (now_tm)); + mvaddstr (row - 1, col - 21, T_QUIT); + mvprintw (row - 1, col - 5, "%s", GO_VERSION); + wattroff (stdscr, color->attr | COLOR_PAIR (color->pair->idx)); + + refresh (); + + /* call general stats header */ + display_general (header_win, glog, holder); + wrefresh (header_win); + + /* display active label based on current module */ + update_active_module (header_win, gscroll.current); + + display_content (main_win, dash, &gscroll); +} + +/* Collapse the current expanded module */ +static void +collapse_current_module (void) +{ + if (!gscroll.expanded) + return; + + gscroll.expanded = 0; + reset_scroll_offsets (&gscroll); + free_dashboard (dash); + allocate_data (); + render_screens (); +} + +/* Display message a the bottom of the terminal dashboard that panel + * is disabled */ +static void +disabled_panel_msg (GModule module) +{ + const char *lbl = module_to_label (module); + int row, col; + + getmaxyx (stdscr, row, col); + draw_header (stdscr, lbl, ERR_PANEL_DISABLED, row - 1, 0, col, color_error); +} + +/* Set the current module/panel */ +static void +set_module_to (GScroll * scrll, GModule module) +{ + if (get_module_index (module) == -1) { + disabled_panel_msg (module); + return; + } + + /* scroll to panel */ + if (!conf.no_tab_scroll) + gscroll.dash = get_module_index (module) * DASH_COLLAPSED; + + /* reset expanded module */ + collapse_current_module (); + scrll->current = module; + render_screens (); +} + +/* Scroll expanded module or terminal dashboard to the top */ +static void +scroll_to_first_line (void) +{ + if (!gscroll.expanded) + gscroll.dash = 0; + else { + gscroll.module[gscroll.current].scroll = 0; + gscroll.module[gscroll.current].offset = 0; + } +} + +/* Scroll expanded module or terminal dashboard to the last row */ +static void +scroll_to_last_line (void) +{ + int exp_size = get_num_expanded_data_rows (); + int scrll = 0, offset = 0; + + if (!gscroll.expanded) + gscroll.dash = dash->total_alloc - main_win_height; + else { + scrll = dash->module[gscroll.current].idx_data - 1; + if (scrll >= exp_size && scrll >= offset + exp_size) + offset = scrll < exp_size - 1 ? 0 : scrll - exp_size + 1; + gscroll.module[gscroll.current].scroll = scrll; + gscroll.module[gscroll.current].offset = offset; + } +} + +/* Load the user-agent window given the selected IP */ +static void +load_ip_agent_list (void) +{ + int type_ip = 0; + /* make sure we have a valid IP */ + int sel = gscroll.module[gscroll.current].scroll; + GDashData item = dash->module[HOSTS].data[sel]; + + if (!invalid_ipaddr (item.metrics->data, &type_ip)) + load_agent_list (main_win, item.metrics->data); +} + +/* Expand the selected module */ +static void +expand_current_module (void) +{ + if (gscroll.expanded && gscroll.current == HOSTS) { + load_ip_agent_list (); + return; + } + + /* expanded, nothing to do... */ + if (gscroll.expanded) + return; + + reset_scroll_offsets (&gscroll); + gscroll.expanded = 1; + + free_holder_by_module (&holder, gscroll.current); + free_dashboard (dash); + allocate_holder_by_module (gscroll.current); + allocate_data (); +} + +/* Expand the clicked module/panel given the Y event coordinate. */ +static void +expand_module_from_ypos (int y) +{ + /* ignore header/footer clicks */ + if (y < MAX_HEIGHT_HEADER || y == LINES - 1) + return; + + if (set_module_from_mouse_event (&gscroll, dash, y)) + return; + + reset_scroll_offsets (&gscroll); + gscroll.expanded = 1; + + free_holder_by_module (&holder, gscroll.current); + free_dashboard (dash); + allocate_holder_by_module (gscroll.current); + allocate_data (); + + render_screens (); +} + +/* Expand the clicked module/panel */ +static void +expand_on_mouse_click (void) +{ + int ok_mouse; + MEVENT event; + + ok_mouse = getmouse (&event); + if (!conf.mouse_support || ok_mouse != OK) + return; + + if (event.bstate & BUTTON1_CLICKED) + expand_module_from_ypos (event.y); +} + +/* Scroll dowm expanded module to the last row */ +static void +scroll_down_expanded_module (void) +{ + int exp_size = get_num_expanded_data_rows (); + int *scroll_ptr, *offset_ptr; + + scroll_ptr = &gscroll.module[gscroll.current].scroll; + offset_ptr = &gscroll.module[gscroll.current].offset; + + if (!gscroll.expanded) + return; + if (*scroll_ptr >= dash->module[gscroll.current].idx_data - 1) + return; + ++(*scroll_ptr); + if (*scroll_ptr >= exp_size && *scroll_ptr >= *offset_ptr + exp_size) + ++(*offset_ptr); +} + +/* Scroll up expanded module */ +static void +scroll_up_expanded_module (void) +{ + int *scroll_ptr, *offset_ptr; + + scroll_ptr = &gscroll.module[gscroll.current].scroll; + offset_ptr = &gscroll.module[gscroll.current].offset; + + if (!gscroll.expanded) + return; + if (*scroll_ptr <= 0) + return; + --(*scroll_ptr); + if (*scroll_ptr < *offset_ptr) + --(*offset_ptr); +} + +/* Scroll up terminal dashboard */ +static void +scroll_up_dashboard (void) +{ + gscroll.dash--; +} + +/* Page up expanded module */ +static void +page_up_module (void) +{ + int exp_size = get_num_expanded_data_rows (); + int *scroll_ptr, *offset_ptr; + + scroll_ptr = &gscroll.module[gscroll.current].scroll; + offset_ptr = &gscroll.module[gscroll.current].offset; + + if (!gscroll.expanded) + return; + /* decrease scroll and offset by exp_size */ + *scroll_ptr -= exp_size; + if (*scroll_ptr < 0) + *scroll_ptr = 0; + + if (*scroll_ptr < *offset_ptr) + *offset_ptr -= exp_size; + if (*offset_ptr <= 0) + *offset_ptr = 0; +} + +/* Page down expanded module */ +static void +page_down_module (void) +{ + int exp_size = get_num_expanded_data_rows (); + int *scroll_ptr, *offset_ptr; + + scroll_ptr = &gscroll.module[gscroll.current].scroll; + offset_ptr = &gscroll.module[gscroll.current].offset; + + if (!gscroll.expanded) + return; + + *scroll_ptr += exp_size; + if (*scroll_ptr >= dash->module[gscroll.current].idx_data - 1) + *scroll_ptr = dash->module[gscroll.current].idx_data - 1; + if (*scroll_ptr >= exp_size && *scroll_ptr >= *offset_ptr + exp_size) + *offset_ptr += exp_size; + if (*offset_ptr + exp_size >= dash->module[gscroll.current].idx_data - 1) + *offset_ptr = dash->module[gscroll.current].idx_data - exp_size; + if (*scroll_ptr < exp_size - 1) + *offset_ptr = 0; +} + +/* Create a new find dialog window and render it. Upon closing the + * window, dashboard is refreshed. */ +static void +render_search_dialog (int search) +{ + if (render_find_dialog (main_win, &gscroll)) + return; + + pthread_mutex_lock (&gdns_thread.mutex); + search = perform_next_find (holder, &gscroll); + pthread_mutex_unlock (&gdns_thread.mutex); + if (search != 0) + return; + + free_dashboard (dash); + allocate_data (); + render_screens (); +} + +/* Search for the next occurrence within the dashboard structure */ +static void +search_next_match (int search) +{ + pthread_mutex_lock (&gdns_thread.mutex); + search = perform_next_find (holder, &gscroll); + pthread_mutex_unlock (&gdns_thread.mutex); + if (search != 0) + return; + + free_dashboard (dash); + allocate_data (); + render_screens (); +} + +/* Update holder structure and dashboard screen */ +static void +tail_term (void) +{ + pthread_mutex_lock (&gdns_thread.mutex); + free_holder (&holder); + pthread_cond_broadcast (&gdns_thread.not_empty); + pthread_mutex_unlock (&gdns_thread.mutex); + + free_dashboard (dash); + allocate_holder (); + allocate_data (); + + term_size (main_win, &main_win_height); + render_screens (); +} + +static void +tail_html (void) +{ + char *json = NULL; + + pthread_mutex_lock (&gdns_thread.mutex); + free_holder (&holder); + pthread_cond_broadcast (&gdns_thread.not_empty); + pthread_mutex_unlock (&gdns_thread.mutex); + + allocate_holder (); + + pthread_mutex_lock (&gdns_thread.mutex); + json = get_json (glog, holder, 0); + pthread_mutex_unlock (&gdns_thread.mutex); + + if (json == NULL) + return; + + broadcast_holder (gwswriter->fd, json, strlen (json)); + free (json); +} + +/* Fast-forward latest JSON data when client connection is opened. */ +static void +fast_forward_client (int listener) +{ + char *json = NULL; + + pthread_mutex_lock (&gdns_thread.mutex); + json = get_json (glog, holder, 0); + pthread_mutex_unlock (&gdns_thread.mutex); + + if (json == NULL) + return; + + pthread_mutex_lock (&gwswriter->mutex); + send_holder_to_client (gwswriter->fd, listener, json, strlen (json)); + pthread_mutex_unlock (&gwswriter->mutex); + free (json); +} + +/* Start reading data coming from the client side through the + * WebSocket server. */ +void +read_client (void *ptr_data) +{ + GWSReader *reader = (GWSReader *) ptr_data; + fd_set rfds, wfds; + + FD_ZERO (&rfds); + FD_ZERO (&wfds); + + /* check we have a fifo for reading */ + if (reader->fd == -1) + return; + + pthread_mutex_lock (&reader->mutex); + set_self_pipe (reader->self_pipe); + pthread_mutex_unlock (&reader->mutex); + + while (1) { + /* select(2) will block */ + if (read_fifo (reader, rfds, wfds, fast_forward_client)) + break; + } + close (reader->fd); +} + +/* Parse tailed lines */ +static void +parse_tail_follow (FILE * fp) +{ +#ifdef WITH_GETLINE + char *buf = NULL; +#else + char buf[LINE_BUFFER] = { 0 }; +#endif + +#ifdef WITH_GETLINE + while ((buf = fgetline (fp)) != NULL) { +#else + while (fgets (buf, LINE_BUFFER, fp) != NULL) { +#endif + pthread_mutex_lock (&gdns_thread.mutex); + parse_log (&glog, buf, 0); + pthread_mutex_unlock (&gdns_thread.mutex); +#ifdef WITH_GETLINE + free (buf); +#endif + } +} + +/* Process appended log data */ +static void +perform_tail_follow (uint64_t * size1, const char *fn) +{ + FILE *fp = NULL; + uint64_t size2 = 0; + + if (fn[0] == '-' && fn[1] == '\0') { + parse_tail_follow (glog->pipe); + goto out; + } + if (glog->load_from_disk_only) + return; + + size2 = file_size (fn); + + /* file hasn't changed */ + if (size2 == *size1) + return; + + if (!(fp = fopen (fn, "r"))) + FATAL ("Unable to read log file %s.", strerror (errno)); + + if (!fseeko (fp, *size1, SEEK_SET)) + parse_tail_follow (fp); + fclose (fp); + + *size1 = size2; + +out: + + if (!conf.output_stdout) + tail_term (); + else + tail_html (); + + usleep (200000); /* 0.2 seconds */ +} + +/* Entry point to start processing the HTML output */ +static void +process_html (const char *filename) +{ + uint64_t *size1 = NULL; + int i = 0; + + /* render report */ + pthread_mutex_lock (&gdns_thread.mutex); + output_html (glog, holder, filename); + pthread_mutex_unlock (&gdns_thread.mutex); + /* not real time? */ + if (!conf.real_time_html) + return; + /* ignore loading from disk */ + if (glog->load_from_disk_only) + return; + + pthread_mutex_lock (&gwswriter->mutex); + gwswriter->fd = open_fifoin (); + pthread_mutex_unlock (&gwswriter->mutex); + + /* open fifo for write */ + if (gwswriter->fd == -1) + return; + + size1 = xcalloc (conf.filenames_idx, sizeof (uint64_t)); + for (i = 0; i < conf.filenames_idx; ++i) { + if (conf.filenames[i][0] == '-' && conf.filenames[i][1] == '\0') + size1[i] = 0; + else + size1[i] = file_size (conf.filenames[i]); + } + + set_ready_state (); + while (1) { + if (conf.stop_processing) + break; + + for (i = 0; i < conf.filenames_idx; ++i) + perform_tail_follow (&size1[i], conf.filenames[i]); /* 0.2 secs */ + usleep (800000); /* 0.8 secs */ + } + close (gwswriter->fd); + free (size1); +} + +/* Iterate over available panels and advance the panel pointer. */ +static int +next_module (void) +{ + int next = -1; + + if ((next = get_next_module (gscroll.current)) == -1) + return 1; + + gscroll.current = next; + if (!conf.no_tab_scroll) + gscroll.dash = get_module_index (gscroll.current) * DASH_COLLAPSED; + + return 0; +} + +/* Iterate over available panels and rewind the panel pointer. */ +static int +previous_module (void) +{ + int prev = -1; + + if ((prev = get_prev_module (gscroll.current)) == -1) + return 1; + + gscroll.current = prev; + if (!conf.no_tab_scroll) + gscroll.dash = get_module_index (gscroll.current) * DASH_COLLAPSED; + + return 0; +} + +/* Perform several curses operations upon resizing the terminal. */ +static void +window_resize (void) +{ + endwin (); + refresh (); + werase (header_win); + werase (main_win); + werase (stdscr); + term_size (main_win, &main_win_height); + refresh (); + render_screens (); +} + +/* Create a new sort dialog window and render it. Upon closing the + * window, dashboard is refreshed. */ +static void +render_sort_dialog (void) +{ + load_sort_win (main_win, gscroll.current, &module_sort[gscroll.current]); + + pthread_mutex_lock (&gdns_thread.mutex); + free_holder (&holder); + pthread_cond_broadcast (&gdns_thread.not_empty); + pthread_mutex_unlock (&gdns_thread.mutex); + + free_dashboard (dash); + allocate_holder (); + allocate_data (); + render_screens (); +} + +/* Interfacing with the keyboard */ +static void +get_keys (void) +{ + int search = 0; + int c, quit = 1, i; + uint64_t *size1 = NULL; + + if (!glog->load_from_disk_only && conf.filenames_idx) { + size1 = xcalloc (conf.filenames_idx, sizeof (uint64_t)); + for (i = 0; i < conf.filenames_idx; ++i) { + if (conf.filenames[i][0] == '-' && conf.filenames[i][1] == '\0') + size1[i] = 0; + else + size1[i] = file_size (conf.filenames[i]); + } + } + + while (quit) { + if (conf.stop_processing) + break; + c = wgetch (stdscr); + switch (c) { + case 'q': /* quit */ + if (!gscroll.expanded) { + quit = 0; + break; + } + collapse_current_module (); + break; + case KEY_F (1): + case '?': + case 'h': + load_help_popup (main_win); + render_screens (); + break; + case 49: /* 1 */ + /* reset expanded module */ + set_module_to (&gscroll, VISITORS); + break; + case 50: /* 2 */ + /* reset expanded module */ + set_module_to (&gscroll, REQUESTS); + break; + case 51: /* 3 */ + /* reset expanded module */ + set_module_to (&gscroll, REQUESTS_STATIC); + break; + case 52: /* 4 */ + /* reset expanded module */ + set_module_to (&gscroll, NOT_FOUND); + break; + case 53: /* 5 */ + /* reset expanded module */ + set_module_to (&gscroll, HOSTS); + break; + case 54: /* 6 */ + /* reset expanded module */ + set_module_to (&gscroll, OS); + break; + case 55: /* 7 */ + /* reset expanded module */ + set_module_to (&gscroll, BROWSERS); + break; + case 56: /* 8 */ + /* reset expanded module */ + set_module_to (&gscroll, VISIT_TIMES); + break; + case 57: /* 9 */ + /* reset expanded module */ + set_module_to (&gscroll, VIRTUAL_HOSTS); + break; + case 48: /* 0 */ + /* reset expanded module */ + set_module_to (&gscroll, REFERRERS); + break; + case 33: /* shift + 1 */ + /* reset expanded module */ + set_module_to (&gscroll, REFERRING_SITES); + break; + case 34: /* shift + 2 */ + /* reset expanded module */ + set_module_to (&gscroll, KEYPHRASES); + break; + case 35: /* Shift + 3 */ + /* reset expanded module */ + set_module_to (&gscroll, STATUS_CODES); + break; + case 36: /* Shift + 3 */ + /* reset expanded module */ + set_module_to (&gscroll, REMOTE_USER); + break; +#ifdef HAVE_GEOLOCATION + case 37: /* Shift + 4 */ + /* reset expanded module */ + set_module_to (&gscroll, GEO_LOCATION); + break; +#endif + case 9: /* TAB */ + /* reset expanded module */ + collapse_current_module (); + if (next_module () == 0) + render_screens (); + break; + case 353: /* Shift TAB */ + /* reset expanded module */ + collapse_current_module (); + if (previous_module () == 0) + render_screens (); + break; + case 'g': /* g = top */ + scroll_to_first_line (); + display_content (main_win, dash, &gscroll); + break; + case 'G': /* G = down */ + scroll_to_last_line (); + display_content (main_win, dash, &gscroll); + break; + /* expand dashboard module */ + case KEY_RIGHT: + case 0x0a: + case 0x0d: + case 32: /* ENTER */ + case 79: /* o */ + case 111: /* O */ + case KEY_ENTER: + expand_current_module (); + display_content (main_win, dash, &gscroll); + break; + case KEY_DOWN: /* scroll main dashboard */ + if ((gscroll.dash + main_win_height) < dash->total_alloc) { + gscroll.dash++; + display_content (main_win, dash, &gscroll); + } + break; + case KEY_MOUSE: /* handles mouse events */ + expand_on_mouse_click (); + break; + case 106: /* j - DOWN expanded module */ + scroll_down_expanded_module (); + display_content (main_win, dash, &gscroll); + break; + /* scroll up main_win */ + case KEY_UP: + if (gscroll.dash > 0) { + scroll_up_dashboard (); + display_content (main_win, dash, &gscroll); + } + break; + case 2: /* ^ b - page up */ + case 339: /* ^ PG UP */ + page_up_module (); + display_content (main_win, dash, &gscroll); + break; + case 6: /* ^ f - page down */ + case 338: /* ^ PG DOWN */ + page_down_module (); + display_content (main_win, dash, &gscroll); + break; + case 107: /* k - UP expanded module */ + scroll_up_expanded_module (); + display_content (main_win, dash, &gscroll); + break; + case 'n': + search_next_match (search); + break; + case '/': + render_search_dialog (search); + break; + case 99: /* c */ + if (conf.no_color) + break; + load_schemes_win (main_win); + free_dashboard (dash); + allocate_data (); + set_wbkgd (main_win, header_win); + render_screens (); + break; + case 115: /* s */ + render_sort_dialog (); + break; + case 269: + case KEY_RESIZE: + window_resize (); + break; + default: + for (i = 0; i < conf.filenames_idx; ++i) + perform_tail_follow (&size1[i], conf.filenames[i]); + break; + } + } + free (size1); +} + +/* Set general/overall statistics when loading data from the on-disk + * storage. i.e., --load-from-disk */ +static void +set_general_stats (void) +{ + glog->valid = glog->processed = glog->invalid = glog->excluded_ip = 0; + +#ifdef TCB_BTREE + glog->excluded_ip = ht_get_genstats ("excluded_ip"); + glog->invalid = ht_get_genstats ("failed_requests"); + glog->processed = ht_get_genstats ("total_requests"); + glog->resp_size = ht_get_genstats_bw ("bandwidth"); + glog->valid = ht_get_genstats ("valid_requests"); + + if (glog->resp_size > 0) + conf.bandwidth = 1; + if (ht_get_genstats ("serve_usecs")) + conf.serve_usecs = 1; +#endif +} + +/* Store accumulated processing time + * Note: As we store with time_t second resolution, + * if elapsed time == 0, we will bump it to 1. + */ +#ifdef TCB_BTREE +static void +set_accumulated_time (void) +{ + if (conf.store_accumulated_time) { + time_t elapsed = end_proc - start_proc; + elapsed = (!elapsed) ? !elapsed : elapsed; + ht_insert_genstats_accumulated_time (elapsed); + } +} +#endif + +/* Execute the following calls right before we start the main + * processing/parsing loop */ +static void +init_processing (void) +{ + /* perform some additional checks before parsing panels */ + verify_panels (); + /* initialize storage */ + init_storage (); + if (conf.load_from_disk) + set_general_stats (); + set_spec_date_format (); +} + +/* Determine the type of output, i.e., JSON, CSV, HTML */ +static void +standard_output (void) +{ + char *csv = NULL, *json = NULL, *html = NULL; + + /* CSV */ + if (find_output_type (&csv, "csv", 1) == 0) + output_csv (glog, holder, csv); + /* JSON */ + if (find_output_type (&json, "json", 1) == 0) + output_json (glog, holder, json); + /* HTML */ + if (find_output_type (&html, "html", 1) == 0 || conf.output_format_idx == 0) + process_html (html); + + free (csv); + free (html); + free (json); +} + +/* Output to a terminal */ +static void +curses_output (void) +{ + allocate_data (); + if (!conf.skip_term_resolver) + gdns_thread_create (); + + render_screens (); + /* will loop in here */ + get_keys (); +} + +/* Set locale */ +static void +set_locale (void) +{ + char *loc_ctype; + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + loc_ctype = getenv ("LC_CTYPE"); + if (loc_ctype != NULL) + setlocale (LC_CTYPE, loc_ctype); + else if ((loc_ctype = getenv ("LC_ALL"))) + setlocale (LC_CTYPE, loc_ctype); + else + setlocale (LC_CTYPE, ""); +} + +/* Attempt to get the current name of a terminal or fallback to /dev/tty + * + * On error, -1 is returned + * On success, the new file descriptor is returned */ +static int +open_term (char **buf) +{ + const char *term = "/dev/tty"; + + if (!isatty (STDERR_FILENO) || (term = ttyname (STDERR_FILENO)) == 0) { + if (!isatty (STDOUT_FILENO) || (term = ttyname (STDOUT_FILENO)) == 0) { + if (!isatty (STDIN_FILENO) || (term = ttyname (STDIN_FILENO)) == 0) { + term = "/dev/tty"; + } + } + } + *buf = xstrdup (term); + + return open (term, O_RDONLY); +} + +/* Determine if reading from a pipe, and duplicate file descriptors so + * it doesn't get in the way of curses' normal reading stdin for + * wgetch() */ +static void +set_pipe_stdin (void) +{ + char *term = NULL; + FILE *pipe = stdin; + int fd1, fd2; + + /* If unable to open a terminal, yet data is being piped, then it's + * probably from the cron. + * + * Note: If used from the cron, it will require the + * user to use a single dash to parse piped data such as: + * cat access.log | goaccess - */ + if ((fd1 = open_term (&term)) == -1) + goto out; + + if ((fd2 = dup (fileno (stdin))) == -1) + FATAL ("Unable to dup stdin: %s", strerror (errno)); + + pipe = fdopen (fd2, "r"); + if (freopen (term, "r", stdin) == 0) + FATAL ("Unable to open input from TTY"); + if (fileno (stdin) != 0) + (void) dup2 (fileno (stdin), 0); + + add_dash_filename (); + /* no need to set it as non-blocking since we are simply outputting a + * static report */ + if (conf.output_stdout && !conf.real_time_html) + goto out; + + /* Using select(), poll(), or epoll(), etc may be a better choice... */ + if (fcntl (fd2, F_SETFL, fcntl (fd2, F_GETFL, 0) | O_NONBLOCK) == -1) + FATAL ("Unable to set fd as non-blocking: %s.", strerror (errno)); +out: + + glog->pipe = pipe; + free (term); +} + +/* Determine if we are getting data from the stdin, and where are we + * outputting to. */ +static void +set_io (void) +{ + /* For backwards compatibility, check if we are not outputting to a + * terminal or if an output format was supplied */ + if (!isatty (STDOUT_FILENO) || conf.output_format_idx > 0) + conf.output_stdout = 1; + /* dup fd if data piped */ + if (!isatty (STDIN_FILENO)) + set_pipe_stdin (); + /* No data piped, no file was used and not loading from disk */ + if (!conf.filenames_idx && !conf.read_stdin && !conf.load_from_disk) + cmd_help (); +} + +/* Process command line options and set some default options. */ +static void +parse_cmd_line (int argc, char **argv) +{ + read_option_args (argc, argv); + set_default_static_files (); +} + +/* Set up signal handlers. */ +static void +setup_signal_handlers (void) +{ + struct sigaction act; + + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = sigsegv_handler; + + sigaction (SIGSEGV, &act, NULL); +} + +static void +handle_signal_action (int sig_number) +{ + switch (sig_number) { + case SIGTERM: + case SIGINT: + fprintf (stderr, "\nSIGINT caught!\n"); + fprintf (stderr, "Closing GoAccess...\n"); + + stop_ws_server (gwswriter, gwsreader); + conf.stop_processing = 1; + break; + case SIGPIPE: + fprintf (stderr, "SIGPIPE caught!\n"); + /* ignore it */ + break; + } +} + +static void +setup_thread_signals (void) +{ + struct sigaction act; + + act.sa_handler = handle_signal_action; + sigemptyset (&act.sa_mask); + act.sa_flags = 0; + + sigaction (SIGINT, &act, NULL); + sigaction (SIGPIPE, &act, NULL); + sigaction (SIGTERM, &act, NULL); + + /* Restore old signal mask for the main thread */ + pthread_sigmask (SIG_SETMASK, &oldset, NULL); +} + +static void +block_thread_signals (void) +{ + /* Avoid threads catching SIGINT/SIGPIPE/SIGTERM and handle them in + * main thread */ + sigset_t sigset; + sigemptyset (&sigset); + sigaddset (&sigset, SIGINT); + sigaddset (&sigset, SIGPIPE); + sigaddset (&sigset, SIGTERM); + pthread_sigmask (SIG_BLOCK, &sigset, &oldset); +} + +/* Initialize various types of data. */ +static void +initializer (void) +{ + /* initialize modules and set first */ + gscroll.current = init_modules (); + /* setup to use the current locale */ + set_locale (); + + parse_browsers_file (); + +#ifdef HAVE_GEOLOCATION + init_geoip (); +#endif + + /* init glog */ + glog = init_log (); + + set_io (); + set_signal_data (glog); + + /* init parsing spinner */ + parsing_spinner = new_gspinner (); + parsing_spinner->processed = &glog->processed; +} + +static void +set_standard_output (void) +{ + int html = 0; + gwswriter = new_gwswriter (); + gwsreader = new_gwsreader (); + + /* HTML */ + if (find_output_type (NULL, "html", 0) == 0 || conf.output_format_idx == 0) + html = 1; + + /* Spawn WebSocket server threads */ + if (html && conf.real_time_html) { + /* open fifo for read */ + if ((gwsreader->fd = open_fifoout ()) == -1) { + LOG (("Unable to open FIFO for read.\n")); + return; + } + + if (conf.daemonize) + daemonize (); + setup_ws_server (gwswriter, gwsreader); + } + setup_thread_signals (); + + /* Spawn progress spinner thread */ + ui_spinner_create (parsing_spinner); +} + +/* Set up curses. */ +static void +set_curses (int *quit) +{ + const char *err_log = NULL; + + setup_thread_signals (); + set_input_opts (); + if (conf.no_color || has_colors () == FALSE) { + conf.color_scheme = NO_COLOR; + conf.no_color = 1; + } else { + start_color (); + } + init_colors (0); + init_windows (&header_win, &main_win); + set_curses_spinner (parsing_spinner); + + /* Display configuration dialog if missing formats and not piping data in */ + if (!conf.read_stdin && (verify_formats () || conf.load_conf_dlg)) { + refresh (); + *quit = render_confdlg (glog, parsing_spinner); + clear (); + } + /* Piping data in without log/date/time format */ + else if (conf.read_stdin && (err_log = verify_formats ())) { + FATAL ("%s", err_log); + } + /* straight parsing */ + else { + ui_spinner_create (parsing_spinner); + } +} + +/* Where all begins... */ +int +main (int argc, char **argv) +{ + int quit = 0, ret = 0; + + block_thread_signals (); + setup_signal_handlers (); + + /* command line/config options */ + verify_global_config (argc, argv); + parse_conf_file (&argc, &argv); + parse_cmd_line (argc, argv); + + initializer (); + + /* ignore outputting, process only */ + if (conf.process_and_exit) { + } + /* set stdout */ + else if (conf.output_stdout) { + set_standard_output (); + } + /* set curses */ + else { + set_curses (&quit); + } + + /* no log/date/time format set */ + if (quit) + goto clean; + + init_processing (); + /* main processing event */ + time (&start_proc); + if ((ret = parse_log (&glog, NULL, 0))) { + end_spinner (); + goto clean; + } + if (conf.stop_processing) + goto clean; + glog->offset = glog->processed; + + /* init reverse lookup thread */ + gdns_init (); + parse_initial_sort (); + allocate_holder (); + + end_spinner (); + time (&end_proc); + + /* ignore outputting, process only */ + if (conf.process_and_exit) { +#ifdef TCB_BTREE + set_accumulated_time (); +#endif + } + /* stdout */ + else if (conf.output_stdout) { + standard_output (); + } + /* curses */ + else { + curses_output (); + } + + /* clean */ +clean: + /* done, restore tty modes and reset terminal into + * non-visual mode */ + if (!conf.output_stdout) + endwin (); + + /* unable to process valid data */ + if (ret) + output_logerrors (glog); + + house_keeping (); + + return ret ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/goaccess++/src/goaccess.h b/goaccess++/src/goaccess.h new file mode 100644 index 0000000..7772d3e --- /dev/null +++ b/goaccess++/src/goaccess.h @@ -0,0 +1,40 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef GOACCESS_H_INCLUDED +#define GOACCESS_H_INCLUDED + +#include "ui.h" + +extern GSpinner *parsing_spinner; +extern int active_gdns; /* kill dns pthread flag */ + +void read_client (void *ptr_data); + +#endif diff --git a/goaccess++/src/goaccess.o b/goaccess++/src/goaccess.o new file mode 100644 index 0000000..15664fe Binary files /dev/null and b/goaccess++/src/goaccess.o differ diff --git a/goaccess++/src/gslist.c b/goaccess++/src/gslist.c new file mode 100644 index 0000000..e73d7b7 --- /dev/null +++ b/goaccess++/src/gslist.c @@ -0,0 +1,166 @@ +/** + * gslist.c -- A Singly link list implementation + * _______ _______ __ __ + * / ____/ | / / ___/____ _____/ /_____ / /_ + * / / __ | | /| / /\__ \/ __ \/ ___/ //_/ _ \/ __/ + * / /_/ / | |/ |/ /___/ / /_/ / /__/ ,< / __/ /_ + * \____/ |__/|__//____/\____/\___/_/|_|\___/\__/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#include "gslist.h" +#include "xmalloc.h" + +/* Instantiate a new Single linked-list node. + * + * On error, aborts if node can't be malloc'd. + * On success, the GSLList node. */ +GSLList * +list_create (void *data) +{ + GSLList *node = xmalloc (sizeof (GSLList)); + node->data = data; + node->next = NULL; + + return node; +} + +/* Create and insert a node after a given node. + * + * On error, aborts if node can't be malloc'd. + * On success, the newly created node. */ +GSLList * +list_insert_append (GSLList * node, void *data) +{ + GSLList *newnode; + newnode = list_create (data); + newnode->next = node->next; + node->next = newnode; + + return newnode; +} + +/* Create and insert a node in front of the list. + * + * On error, aborts if node can't be malloc'd. + * On success, the newly created node. */ +GSLList * +list_insert_prepend (GSLList * list, void *data) +{ + GSLList *newnode; + newnode = list_create (data); + newnode->next = list; + + return newnode; +} + +/* Find a node given a pointer to a function that compares them. + * + * If comparison fails, NULL is returned. + * On success, the existing node is returned. */ +GSLList * +list_find (GSLList * node, int (*func) (void *, void *), void *data) +{ + while (node) { + if (func (node->data, data) > 0) + return node; + node = node->next; + } + + return NULL; +} + +/* Remove all nodes from the list. + * + * On success, 0 is returned. */ +int +list_remove_nodes (GSLList * list) +{ + GSLList *tmp; + while (list != NULL) { + tmp = list->next; + if (list->data) + free (list->data); + free (list); + list = tmp; + } + + return 0; +} + +/* Remove the given node from the list. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +int +list_remove_node (GSLList ** list, GSLList * node) +{ + GSLList **current = list, *next = NULL; + for (; *current; current = &(*current)->next) { + if ((*current) != node) + continue; + + next = (*current)->next; + if ((*current)->data) + free ((*current)->data); + free (*current); + *current = next; + return 0; + } + return 1; +} + +/* Iterate over the single linked-list and call function pointer. + * + * If function pointer does not return 0, -1 is returned. + * On success, 0 is returned. */ +int +list_foreach (GSLList * node, int (*func) (void *, void *), void *user_data) +{ + while (node) { + if (func (node->data, user_data) != 0) + return -1; + node = node->next; + } + + return 0; +} + +/* Count the number of elements on the linked-list. + * + * On success, the number of elements is returned. */ +int +list_count (GSLList * node) +{ + int count = 0; + while (node != 0) { + count++; + node = node->next; + } + return count; +} diff --git a/goaccess++/src/gslist.h b/goaccess++/src/gslist.h new file mode 100644 index 0000000..6108051 --- /dev/null +++ b/goaccess++/src/gslist.h @@ -0,0 +1,51 @@ +/** + * _______ _______ __ __ + * / ____/ | / / ___/____ _____/ /_____ / /_ + * / / __ | | /| / /\__ \/ __ \/ ___/ //_/ _ \/ __/ + * / /_/ / | |/ |/ /___/ / /_/ / /__/ ,< / __/ /_ + * \____/ |__/|__//____/\____/\___/_/|_|\___/\__/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef GSLIST_H_INCLUDED +#define GSLIST_H_INCLUDED + +/* Generic Single linked-list */ +typedef struct GSLList_ +{ + void *data; + struct GSLList_ *next; +} GSLList; + +/* single linked-list */ +GSLList *list_create (void *data); +GSLList *list_find (GSLList * node, int (*func) (void *, void *), void *data); +GSLList *list_insert_append (GSLList * node, void *data); +GSLList *list_insert_prepend (GSLList * list, void *data); +int list_count (GSLList * list); +int list_foreach (GSLList * node, int (*func) (void *, void *), + void *user_data); +int list_remove_node (GSLList ** list, GSLList * node); +int list_remove_nodes (GSLList * list); + +#endif // for #ifndef GSLIST_H diff --git a/goaccess++/src/gslist.o b/goaccess++/src/gslist.o new file mode 100644 index 0000000..c5e675f Binary files /dev/null and b/goaccess++/src/gslist.o differ diff --git a/goaccess++/src/gstorage.c b/goaccess++/src/gstorage.c new file mode 100644 index 0000000..b6934c1 --- /dev/null +++ b/goaccess++/src/gstorage.c @@ -0,0 +1,140 @@ +/** + * gstorage.c -- common storage handling + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <stdio.h> +#if !defined __SUNPRO_C +#include <stdint.h> +#endif +#include <stdlib.h> +#include <string.h> + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#include "gstorage.h" + +#include "error.h" +#include "xmalloc.h" + +/* Allocate memory for a new GMetrics instance. + * + * On success, the newly allocated GMetrics is returned . */ +GMetrics * +new_gmetrics (void) +{ + GMetrics *metrics = xcalloc (1, sizeof (GMetrics)); + + return metrics; +} + +/* Allocate space off the heap to store an int. + * + * On success, the newly allocated pointer is returned . */ +int * +int2ptr (int val) +{ + int *ptr = xmalloc (sizeof (int)); + *ptr = val; + + return ptr; +} + +/* Allocate space off the heap to store a uint64_t. + * + * On success, the newly allocated pointer is returned . */ +uint64_t * +uint642ptr (uint64_t val) +{ + uint64_t *ptr = xmalloc (sizeof (uint64_t)); + *ptr = val; + + return ptr; +} + +/* Set the module totals to calculate percentages. */ +void +set_module_totals (GModule module, GPercTotals * totals) +{ + totals->bw = ht_get_meta_data (module, "bytes"); + totals->hits = ht_get_meta_data (module, "hits"); + totals->visitors = ht_get_meta_data (module, "visitors"); +} + +/* Set numeric metrics for each request given raw data. + * + * On success, numeric metrics are set into the given structure. */ +void +set_data_metrics (GMetrics * ometrics, GMetrics ** nmetrics, GPercTotals totals) +{ + GMetrics *metrics; + + /* determine percentages for certain fields */ + float hits_perc = get_percentage (totals.hits, ometrics->hits); + float visitors_perc = get_percentage (totals.visitors, ometrics->visitors); + float bw_perc = get_percentage (totals.bw, ometrics->bw.nbw); + + metrics = new_gmetrics (); + + /* basic fields */ + metrics->id = ometrics->id; + metrics->hits = ometrics->hits; + metrics->visitors = ometrics->visitors; + + /* percentage fields */ + metrics->hits_perc = hits_perc < 0 ? 0 : hits_perc; + metrics->bw_perc = bw_perc < 0 ? 0 : bw_perc; + metrics->visitors_perc = visitors_perc < 0 ? 0 : visitors_perc; + + /* bandwidth field */ + metrics->bw.nbw = ometrics->bw.nbw; + + /* time served fields */ + if (conf.serve_usecs && ometrics->hits > 0) { + metrics->avgts.nts = ometrics->avgts.nts; + metrics->cumts.nts = ometrics->cumts.nts; + metrics->maxts.nts = ometrics->maxts.nts; + } + + /* method field */ + if (conf.append_method && ometrics->method) + metrics->method = ometrics->method; + + /* protocol field */ + if (conf.append_protocol && ometrics->protocol) + metrics->protocol = ometrics->protocol; + + /* data field */ + metrics->data = ometrics->data; + + *nmetrics = metrics; +} diff --git a/goaccess++/src/gstorage.h b/goaccess++/src/gstorage.h new file mode 100644 index 0000000..ea826f0 --- /dev/null +++ b/goaccess++/src/gstorage.h @@ -0,0 +1,68 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef GSTORAGE_H_INCLUDED +#define GSTORAGE_H_INCLUDED + +#include "commons.h" + +/* Total number of storage metrics (GSMetric) */ +#define GSMTRC_TOTAL 14 + +/* Enumerated Storage Metrics */ +typedef enum GSMetric_ +{ + MTRC_KEYMAP, + MTRC_ROOTMAP, + MTRC_DATAMAP, + MTRC_UNIQMAP, + MTRC_ROOT, + MTRC_HITS, + MTRC_VISITORS, + MTRC_BW, + MTRC_CUMTS, + MTRC_MAXTS, + MTRC_METHODS, + MTRC_PROTOCOLS, + MTRC_AGENTS, + MTRC_METADATA, +} GSMetric; + +GMetrics *new_gmetrics (void); + +int *int2ptr (int val); +uint64_t *uint642ptr (uint64_t val); + +void *get_storage_metric_by_module (GModule module, GSMetric metric); +void *get_storage_metric (GModule module, GSMetric metric); +void set_data_metrics (GMetrics * ometrics, GMetrics ** nmetrics, + GPercTotals totals); +void set_module_totals (GModule module, GPercTotals * totals); + +#endif // for #ifndef GSTORAGE_H diff --git a/goaccess++/src/gstorage.o b/goaccess++/src/gstorage.o new file mode 100644 index 0000000..6f13465 Binary files /dev/null and b/goaccess++/src/gstorage.o differ diff --git a/goaccess++/src/gwsocket.c b/goaccess++/src/gwsocket.c new file mode 100644 index 0000000..4b809e0 --- /dev/null +++ b/goaccess++/src/gwsocket.c @@ -0,0 +1,410 @@ +/** + * gwsocket.c -- An interface to send/recv data from/to Web Socket Server + * _______ _______ __ __ + * / ____/ | / / ___/____ _____/ /_____ / /_ + * / / __ | | /| / /\__ \/ __ \/ ___/ //_/ _ \/ __/ + * / /_/ / | |/ |/ /___/ / /_/ / /__/ ,< / __/ /_ + * \____/ |__/|__//____/\____/\___/_/|_|\___/\__/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <stdio.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "gwsocket.h" + +#include "commons.h" +#include "error.h" +#include "goaccess.h" +#include "json.h" +#include "parser.h" +#include "settings.h" +#include "websocket.h" +#include "xmalloc.h" + +/* Allocate memory for a new GWSReader instance. + * + * On success, the newly allocated GWSReader is returned. */ +GWSReader * +new_gwsreader (void) +{ + GWSReader *reader = xmalloc (sizeof (GWSReader)); + memset (reader, 0, sizeof *reader); + + return reader; +} + +/* Allocate memory for a new GWSWriter instance. + * + * On success, the newly allocated GWSWriter is returned. */ +GWSWriter * +new_gwswriter (void) +{ + GWSWriter *writer = xmalloc (sizeof (GWSWriter)); + memset (writer, 0, sizeof *writer); + + return writer; +} + +/* Write the JSON data to a pipe. + * + * If unable to write bytes, -1 is returned. + * On success, the number of written bytes is returned . */ +static int +write_holder (int fd, const char *buf, int len) +{ + int i, ret = 0; + + for (i = 0; i < len;) { + ret = write (fd, buf + i, len - i); + if (ret < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } else { + i += ret; + } + } + + return i; +} + +/* Clear an incoming FIFO packet and header data. */ +static void +clear_fifo_packet (GWSReader * gwserver) +{ + memset (gwserver->hdr, 0, sizeof (gwserver->hdr)); + gwserver->hlen = 0; + + if (gwserver->packet == NULL) + return; + + if (gwserver->packet->data) + free (gwserver->packet->data); + free (gwserver->packet); + gwserver->packet = NULL; +} + +/* Pack the JSON data into a network byte order and writes it to a + * pipe. + * + * On success, 0 is returned . */ +int +broadcast_holder (int fd, const char *buf, int len) +{ + char *p = NULL, *ptr = NULL; + + p = calloc (sizeof (uint32_t) * 3, sizeof (char)); + + ptr = p; + ptr += pack_uint32 (ptr, 0); + ptr += pack_uint32 (ptr, 0x01); + ptr += pack_uint32 (ptr, len); + + write_holder (fd, p, sizeof (uint32_t) * 3); + write_holder (fd, buf, len); + free (p); + + return 0; +} + +/* Pack the JSON data into a network byte order and write it to a + * pipe. + * + * On success, 0 is returned . */ +int +send_holder_to_client (int fd, int listener, const char *buf, int len) +{ + char *p = NULL, *ptr = NULL; + + p = calloc (sizeof (uint32_t) * 3, sizeof (char)); + + ptr = p; + ptr += pack_uint32 (ptr, listener); + ptr += pack_uint32 (ptr, 0x01); + ptr += pack_uint32 (ptr, len); + + write_holder (fd, p, sizeof (uint32_t) * 3); + write_holder (fd, buf, len); + free (p); + + return 0; +} + +/* Attempt to read data from the named pipe on strict mode. + * Note: For now it only reads on new connections, i.e., onopen. + * + * If there's less data than requested, 0 is returned + * If the thread is done, 1 is returned */ +int +read_fifo (GWSReader * gwsreader, fd_set rfds, fd_set wfds, void (*f) (int)) +{ + WSPacket **pa = &gwsreader->packet; + char *ptr; + int bytes = 0, readh = 0, need = 0, fd = gwsreader->fd, max = 0; + uint32_t listener = 0, type = 0, size = 0; + + FD_ZERO (&rfds); + FD_ZERO (&wfds); + /* self-pipe trick to stop the event loop */ + FD_SET (gwsreader->self_pipe[0], &rfds); + /* fifo */ + FD_SET (fd, &rfds); + max = MAX (fd, gwsreader->self_pipe[0]); + + if (select (max + 1, &rfds, &wfds, NULL, NULL) == -1) { + switch (errno) { + case EINTR: + break; + default: + FATAL ("Unable to select: %s.", strerror (errno)); + } + } + /* handle self-pipe trick */ + if (FD_ISSET (gwsreader->self_pipe[0], &rfds)) + return 1; + if (!FD_ISSET (fd, &rfds)) { + LOG (("No file descriptor set on read_message()\n")); + return 0; + } + + readh = gwsreader->hlen; /* read from header so far */ + need = HDR_SIZE - readh; /* need to read */ + if (need > 0) { + if ((bytes = + ws_read_fifo (fd, gwsreader->hdr, &gwsreader->hlen, readh, need)) < 0) + return 0; + if (bytes != need) + return 0; + } + + /* unpack size, and type */ + ptr = gwsreader->hdr; + ptr += unpack_uint32 (ptr, &listener); + ptr += unpack_uint32 (ptr, &type); + ptr += unpack_uint32 (ptr, &size); + + if ((*pa) == NULL) { + (*pa) = xcalloc (1, sizeof (WSPacket)); + (*pa)->type = type; + (*pa)->size = size; + (*pa)->data = xcalloc (size, sizeof (char)); + } + + readh = (*pa)->len; /* read from payload so far */ + need = (*pa)->size - readh; /* need to read */ + if (need > 0) { + if ((bytes = ws_read_fifo (fd, (*pa)->data, &(*pa)->len, readh, need)) < 0) + return 0; + if (bytes != need) + return 0; + } + clear_fifo_packet (gwsreader); + /* fast forward JSON data to the given client */ + (*f) (listener); + + return 0; +} + +/* Callback once a new connection is established + * + * It writes to a named pipe a header containing the socket, the + * message type, the payload's length and the actual payload */ +static int +onopen (WSPipeOut * pipeout, WSClient * client) +{ + uint32_t hsize = sizeof (uint32_t) * 3; + char *hdr = calloc (hsize, sizeof (char)); + char *ptr = hdr; + + ptr += pack_uint32 (ptr, client->listener); + ptr += pack_uint32 (ptr, WS_OPCODE_TEXT); + ptr += pack_uint32 (ptr, INET6_ADDRSTRLEN); + + ws_write_fifo (pipeout, hdr, hsize); + ws_write_fifo (pipeout, client->remote_ip, INET6_ADDRSTRLEN); + free (hdr); + + return 0; +} + +/* Done parsing, clear out line and set status message. */ +void +set_ready_state (void) +{ + fprintf (stderr, "\33[2K\r"); + fprintf (stderr, "%s\n", INFO_WS_READY_FOR_CONN); +} + +/* Open the named pipe where the websocket server writes to. + * + * If unable to open, -1 is returned. + * On success, return the new file descriptor is returned . */ +int +open_fifoout (void) +{ + const char *fifo = conf.fifo_out ? conf.fifo_out : WS_PIPEOUT; + int fdfifo; + + /* open fifo for reading before writing */ + ws_setfifo (fifo); + if ((fdfifo = open (fifo, O_RDWR | O_NONBLOCK)) == -1) + return -1; + + return fdfifo; +} + +/* Open the named pipe where the websocket server reads from. + * + * If unable to open, -1 is returned. + * On success, return the new file descriptor is returned . */ +int +open_fifoin (void) +{ + const char *fifo = conf.fifo_in ? conf.fifo_in : WS_PIPEIN; + int fdfifo; + + if ((fdfifo = open (fifo, O_WRONLY | O_NONBLOCK)) == -1) + return -1; + + return fdfifo; +} + +/* Set the self-pipe trick to handle select(2). */ +void +set_self_pipe (int *self_pipe) +{ + /* Initialize self pipe. */ + if (pipe (self_pipe) == -1) + FATAL ("Unable to create pipe: %s.", strerror (errno)); + + /* make the read and write pipe non-blocking */ + set_nonblocking (self_pipe[0]); + set_nonblocking (self_pipe[1]); +} + +/* Close the WebSocket server and clean up. */ +void +stop_ws_server (GWSWriter * gwswriter, GWSReader * gwsreader) +{ + pthread_t writer, reader; + WSServer *server = NULL; + + if (!gwsreader || !gwswriter) + return; + if (!(server = gwswriter->server)) + return; + + pthread_mutex_lock (&gwsreader->mutex); + if ((write (gwsreader->self_pipe[1], "x", 1)) == -1 && errno != EAGAIN) + LOG (("Unable to write to self pipe on pipeout.\n")); + pthread_mutex_unlock (&gwsreader->mutex); + + pthread_mutex_lock (&gwswriter->mutex); + /* if it fails to write, force stop */ + if ((write (server->self_pipe[1], "x", 1)) == -1 && errno != EAGAIN) + ws_stop (server); + pthread_mutex_unlock (&gwswriter->mutex); + + reader = gwsreader->thread; + if (pthread_join (reader, NULL) != 0) + LOG (("Unable to join thread: %d %s\n", reader, strerror (errno))); + + writer = gwswriter->thread; + if (pthread_join (writer, NULL) != 0) + LOG (("Unable to join thread: %d %s\n", writer, strerror (errno))); +} + +/* Start the WebSocket server and initialize default options. */ +static void +start_server (void *ptr_data) +{ + GWSWriter *writer = (GWSWriter *) ptr_data; + + writer->server->onopen = onopen; + set_self_pipe (writer->server->self_pipe); + + /* select(2) will block in here */ + ws_start (writer->server); + fprintf (stderr, "Stopping WebSocket server...\n"); + ws_stop (writer->server); +} + +/* Read and set the WebSocket config options. */ +static void +set_ws_opts (void) +{ + ws_set_config_strict (1); + if (conf.addr) + ws_set_config_host (conf.addr); + if (conf.fifo_in) + ws_set_config_pipein (conf.fifo_in); + if (conf.fifo_out) + ws_set_config_pipeout (conf.fifo_out); + if (conf.origin) + ws_set_config_origin (conf.origin); + if (conf.port) + ws_set_config_port (conf.port); + if (conf.sslcert) + ws_set_config_sslcert (conf.sslcert); + if (conf.sslkey) + ws_set_config_sslkey (conf.sslkey); +} + +/* Setup and start the WebSocket threads. */ +int +setup_ws_server (GWSWriter * gwswriter, GWSReader * gwsreader) +{ + int id; + pthread_t *thread; + + if (pthread_mutex_init (&gwswriter->mutex, NULL)) + FATAL ("Failed init gwswriter mutex"); + if (pthread_mutex_init (&gwsreader->mutex, NULL)) + FATAL ("Failed init gwsreader mutex"); + + /* send WS data thread */ + thread = &gwswriter->thread; + + /* pre-init the websocket server, to ensure the FIFOs are created */ + if ((gwswriter->server = ws_init ("0.0.0.0", "7890", set_ws_opts)) == NULL) + FATAL ("Failed init websocket"); + + id = pthread_create (&(*thread), NULL, (void *) &start_server, gwswriter); + if (id) + FATAL ("Return code from pthread_create(): %d", id); + + /* read WS data thread */ + thread = &gwsreader->thread; + id = pthread_create (&(*thread), NULL, (void *) &read_client, gwsreader); + if (id) + FATAL ("Return code from pthread_create(): %d", id); + + return 0; +} diff --git a/goaccess++/src/gwsocket.h b/goaccess++/src/gwsocket.h new file mode 100644 index 0000000..267f60c --- /dev/null +++ b/goaccess++/src/gwsocket.h @@ -0,0 +1,74 @@ +/** + * _______ _______ __ __ + * / ____/ | / / ___/____ _____/ /_____ / /_ + * / / __ | | /| / /\__ \/ __ \/ ___/ //_/ _ \/ __/ + * / /_/ / | |/ |/ /___/ / /_/ / /__/ ,< / __/ /_ + * \____/ |__/|__//____/\____/\___/_/|_|\___/\__/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef GWSOCKET_H_INCLUDED +#define GWSOCKET_H_INCLUDED + +#define GW_VERSION "0.1" + +#include <pthread.h> +#include "websocket.h" + +typedef struct GWSReader_ +{ + int fd; + int self_pipe[2]; /* self-pipe */ + + pthread_mutex_t mutex; /* Mutex fifo out */ + pthread_t thread; /* Thread fifo in */ + + WSPacket *packet; /* FIFO data's buffer */ + char hdr[HDR_SIZE]; /* FIFO header's buffer */ + int hlen; /* header length */ +} GWSReader; + +typedef struct GWSWriter_ +{ + int fd; + + pthread_mutex_t mutex; /* Mutex fifo in */ + pthread_t thread; /* Thread fifo out */ + + WSServer *server; /* WebSocket server */ +} GWSWriter; + +GWSReader *new_gwsreader (void); +GWSWriter *new_gwswriter (void); +int broadcast_holder (int fd, const char *buf, int len); +int open_fifoin (void); +int open_fifoout (void); +int read_fifo (GWSReader * gwsreader, fd_set rfds, fd_set wfds, + void (*f) (int)); +int send_holder_to_client (int fd, int listener, const char *buf, int len); +int setup_ws_server (GWSWriter * gwswriter, GWSReader * gwsreader); +void set_ready_state (void); +void set_self_pipe (int *self_pipe); +void stop_ws_server (GWSWriter * gwswriter, GWSReader * gwsreader); + +#endif // for #ifndef GWSOCKET_H diff --git a/goaccess++/src/gwsocket.o b/goaccess++/src/gwsocket.o new file mode 100644 index 0000000..0ef04bb Binary files /dev/null and b/goaccess++/src/gwsocket.o differ diff --git a/goaccess++/src/hoganjs.h b/goaccess++/src/hoganjs.h new file mode 100644 index 0000000..bd36089 --- /dev/null +++ b/goaccess++/src/hoganjs.h @@ -0,0 +1,782 @@ +const char hogan_js[8555] = { + 0x2f, 0x2a, 0x2a, 0x2a, 0x20, 0x40, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69, 0x67, + 0x68, 0x74, 0x20, 0x32, 0x30, 0x31, 0x32, 0x20, 0x54, 0x77, 0x69, + 0x74, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x2a, + 0x20, 0x40, 0x6c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x20, 0x68, + 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x61, + 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x6c, + 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x2f, 0x4c, 0x49, 0x43, + 0x45, 0x4e, 0x53, 0x45, 0x2d, 0x32, 0x2e, 0x30, 0x2e, 0x74, 0x78, + 0x74, 0x2a, 0x2f, 0x76, 0x61, 0x72, 0x20, 0x48, 0x6f, 0x67, 0x61, + 0x6e, 0x3d, 0x7b, 0x7d, 0x3b, 0x21, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, + 0x65, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x26, 0x26, 0x22, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, + 0x6f, 0x66, 0x20, 0x6e, 0x26, 0x26, 0x28, 0x76, 0x6f, 0x69, 0x64, + 0x20, 0x30, 0x21, 0x3d, 0x3d, 0x6e, 0x5b, 0x74, 0x5d, 0x3f, 0x69, + 0x3d, 0x6e, 0x5b, 0x74, 0x5d, 0x3a, 0x65, 0x26, 0x26, 0x6e, 0x2e, + 0x67, 0x65, 0x74, 0x26, 0x26, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, + 0x66, 0x20, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x26, 0x26, 0x28, 0x69, + 0x3d, 0x6e, 0x2e, 0x67, 0x65, 0x74, 0x28, 0x74, 0x29, 0x29, 0x29, + 0x2c, 0x69, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x69, 0x2c, + 0x72, 0x2c, 0x73, 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x28, 0x29, 0x7b, 0x7d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x29, 0x7b, 0x7d, + 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x74, 0x2c, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x74, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x75, 0x2c, 0x63, 0x3d, 0x6e, 0x65, 0x77, + 0x20, 0x61, 0x3b, 0x63, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x3d, 0x6e, + 0x65, 0x77, 0x20, 0x6f, 0x2c, 0x63, 0x2e, 0x73, 0x75, 0x62, 0x73, + 0x54, 0x65, 0x78, 0x74, 0x3d, 0x7b, 0x7d, 0x2c, 0x63, 0x2e, 0x62, + 0x75, 0x66, 0x3d, 0x22, 0x22, 0x2c, 0x69, 0x3d, 0x69, 0x7c, 0x7c, + 0x7b, 0x7d, 0x2c, 0x63, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x53, + 0x75, 0x62, 0x73, 0x3d, 0x69, 0x2c, 0x63, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x54, 0x65, 0x78, 0x74, 0x3d, 0x73, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x75, 0x20, 0x69, 0x6e, 0x20, 0x6e, 0x29, 0x69, 0x5b, 0x75, + 0x5d, 0x7c, 0x7c, 0x28, 0x69, 0x5b, 0x75, 0x5d, 0x3d, 0x6e, 0x5b, + 0x75, 0x5d, 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x75, 0x20, 0x69, + 0x6e, 0x20, 0x69, 0x29, 0x63, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x5b, + 0x75, 0x5d, 0x3d, 0x69, 0x5b, 0x75, 0x5d, 0x3b, 0x72, 0x3d, 0x72, + 0x7c, 0x7c, 0x7b, 0x7d, 0x2c, 0x63, 0x2e, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x3d, 0x72, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x75, 0x20, 0x69, 0x6e, 0x20, 0x65, + 0x29, 0x72, 0x5b, 0x75, 0x5d, 0x7c, 0x7c, 0x28, 0x72, 0x5b, 0x75, + 0x5d, 0x3d, 0x65, 0x5b, 0x75, 0x5d, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x75, 0x20, 0x69, 0x6e, 0x20, 0x72, 0x29, 0x63, 0x2e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5b, 0x75, 0x5d, 0x3d, + 0x72, 0x5b, 0x75, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x63, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x69, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x6e, 0x75, + 0x6c, 0x6c, 0x3d, 0x3d, 0x3d, 0x74, 0x7c, 0x7c, 0x76, 0x6f, 0x69, + 0x64, 0x20, 0x30, 0x3d, 0x3d, 0x3d, 0x74, 0x3f, 0x22, 0x22, 0x3a, + 0x74, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x72, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x74, 0x3d, 0x69, 0x28, 0x74, 0x29, 0x2c, 0x6c, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x28, 0x74, 0x29, 0x3f, 0x74, 0x2e, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x73, 0x2c, 0x22, 0x26, + 0x61, 0x6d, 0x70, 0x3b, 0x22, 0x29, 0x2e, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x28, 0x61, 0x2c, 0x22, 0x26, 0x6c, 0x74, 0x3b, + 0x22, 0x29, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, + 0x6f, 0x2c, 0x22, 0x26, 0x67, 0x74, 0x3b, 0x22, 0x29, 0x2e, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x75, 0x2c, 0x22, 0x26, + 0x23, 0x33, 0x39, 0x3b, 0x22, 0x29, 0x2e, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x28, 0x63, 0x2c, 0x22, 0x26, 0x71, 0x75, 0x6f, + 0x74, 0x3b, 0x22, 0x29, 0x3a, 0x74, 0x7d, 0x74, 0x2e, 0x54, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, + 0x69, 0x29, 0x7b, 0x74, 0x3d, 0x74, 0x7c, 0x7c, 0x7b, 0x7d, 0x2c, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x3d, 0x74, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x7c, 0x7c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x2c, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x3d, 0x65, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3d, + 0x69, 0x7c, 0x7c, 0x7b, 0x7d, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x74, 0x65, 0x78, 0x74, 0x3d, 0x6e, 0x7c, 0x7c, 0x22, 0x22, 0x2c, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, + 0x6c, 0x73, 0x3d, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, + 0x6c, 0x73, 0x7c, 0x7c, 0x7b, 0x7d, 0x2c, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x75, 0x62, 0x73, 0x3d, 0x74, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x7c, 0x7c, 0x7b, 0x7d, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x62, 0x75, 0x66, 0x3d, 0x22, 0x22, 0x7d, 0x2c, 0x74, 0x2e, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x7b, 0x72, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x22, 0x7d, 0x2c, 0x76, 0x3a, + 0x72, 0x2c, 0x74, 0x3a, 0x69, 0x2c, 0x72, 0x65, 0x6e, 0x64, 0x65, + 0x72, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x72, 0x69, 0x28, + 0x5b, 0x74, 0x5d, 0x2c, 0x6e, 0x7c, 0x7c, 0x7b, 0x7d, 0x2c, 0x65, + 0x29, 0x7d, 0x2c, 0x72, 0x69, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x72, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7d, 0x2c, + 0x65, 0x70, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, + 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x61, 0x6c, 0x73, 0x5b, 0x74, 0x5d, 0x2c, 0x72, 0x3d, 0x6e, 0x5b, + 0x69, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x3b, 0x69, 0x66, 0x28, + 0x69, 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x26, + 0x26, 0x69, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x3d, 0x3d, 0x72, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x2e, 0x69, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x3b, 0x69, 0x66, 0x28, 0x22, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3d, 0x3d, 0x74, 0x79, + 0x70, 0x65, 0x6f, 0x66, 0x20, 0x72, 0x29, 0x7b, 0x69, 0x66, 0x28, + 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x29, 0x74, 0x68, 0x72, + 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x28, 0x22, 0x4e, 0x6f, 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x69, + 0x6c, 0x65, 0x72, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x2e, 0x22, 0x29, 0x3b, 0x72, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x28, 0x72, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x21, 0x72, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x75, 0x6c, + 0x6c, 0x3b, 0x69, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5b, 0x74, 0x5d, 0x2e, + 0x62, 0x61, 0x73, 0x65, 0x3d, 0x72, 0x2c, 0x69, 0x2e, 0x73, 0x75, + 0x62, 0x73, 0x29, 0x7b, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x54, 0x65, 0x78, 0x74, 0x7c, 0x7c, 0x28, 0x6e, 0x2e, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x54, 0x65, 0x78, 0x74, 0x3d, 0x7b, 0x7d, 0x29, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6b, 0x65, 0x79, 0x20, 0x69, 0x6e, + 0x20, 0x69, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x29, 0x6e, 0x2e, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x54, 0x65, 0x78, 0x74, 0x5b, 0x6b, 0x65, + 0x79, 0x5d, 0x7c, 0x7c, 0x28, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x63, + 0x6b, 0x54, 0x65, 0x78, 0x74, 0x5b, 0x6b, 0x65, 0x79, 0x5d, 0x3d, + 0x76, 0x6f, 0x69, 0x64, 0x20, 0x30, 0x21, 0x3d, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x75, + 0x62, 0x26, 0x26, 0x6e, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x54, + 0x65, 0x78, 0x74, 0x5b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x53, 0x75, 0x62, 0x5d, 0x3f, 0x6e, 0x2e, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x54, 0x65, 0x78, 0x74, 0x5b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, + 0x75, 0x62, 0x5d, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x29, 0x3b, 0x72, 0x3d, 0x65, 0x28, 0x72, 0x2c, 0x69, + 0x2e, 0x73, 0x75, 0x62, 0x73, 0x2c, 0x69, 0x2e, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x73, 0x74, 0x61, 0x63, 0x6b, 0x53, 0x75, 0x62, 0x73, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x50, 0x61, + 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2c, 0x6e, 0x2e, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x54, 0x65, 0x78, 0x74, 0x29, 0x7d, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x70, + 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5b, 0x74, 0x5d, 0x2e, + 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x3d, 0x72, 0x2c, + 0x72, 0x7d, 0x2c, 0x72, 0x70, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x69, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x65, 0x70, 0x28, 0x74, 0x2c, 0x65, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3f, 0x72, 0x2e, 0x72, + 0x69, 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x69, 0x29, 0x3a, 0x22, 0x22, + 0x7d, 0x2c, 0x72, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x69, 0x3d, 0x74, 0x5b, 0x74, 0x2e, 0x6c, 0x65, + 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x3b, 0x69, 0x66, 0x28, + 0x21, 0x66, 0x28, 0x69, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x65, 0x28, 0x74, 0x2c, + 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x29, 0x3b, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x30, 0x3b, 0x72, 0x3c, + 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x72, 0x2b, + 0x2b, 0x29, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x69, 0x5b, + 0x72, 0x5d, 0x29, 0x2c, 0x65, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x74, + 0x68, 0x69, 0x73, 0x29, 0x2c, 0x74, 0x2e, 0x70, 0x6f, 0x70, 0x28, + 0x29, 0x7d, 0x2c, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x69, 0x2c, + 0x72, 0x2c, 0x73, 0x2c, 0x61, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, + 0x6f, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x28, + 0x74, 0x29, 0x26, 0x26, 0x30, 0x3d, 0x3d, 0x3d, 0x74, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3f, 0x21, 0x31, 0x3a, 0x28, 0x22, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, + 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x74, 0x26, 0x26, 0x28, + 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x73, 0x28, 0x74, + 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x69, 0x2c, 0x72, 0x2c, 0x73, 0x2c, + 0x61, 0x29, 0x29, 0x2c, 0x6f, 0x3d, 0x21, 0x21, 0x74, 0x2c, 0x21, + 0x69, 0x26, 0x26, 0x6f, 0x26, 0x26, 0x6e, 0x26, 0x26, 0x6e, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x22, 0x6f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x74, 0x3f, 0x74, 0x3a, 0x6e, 0x5b, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x29, 0x2c, 0x6f, 0x29, 0x7d, + 0x2c, 0x64, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x65, 0x2c, 0x69, 0x2c, 0x72, 0x29, 0x7b, 0x76, + 0x61, 0x72, 0x20, 0x73, 0x2c, 0x61, 0x3d, 0x74, 0x2e, 0x73, 0x70, + 0x6c, 0x69, 0x74, 0x28, 0x22, 0x2e, 0x22, 0x29, 0x2c, 0x6f, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x28, 0x61, 0x5b, 0x30, 0x5d, + 0x2c, 0x65, 0x2c, 0x69, 0x2c, 0x72, 0x29, 0x2c, 0x75, 0x3d, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x65, 0x74, 0x2c, 0x63, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b, 0x69, 0x66, 0x28, 0x22, 0x2e, + 0x22, 0x3d, 0x3d, 0x3d, 0x74, 0x26, 0x26, 0x66, 0x28, 0x65, 0x5b, + 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x32, 0x5d, + 0x29, 0x29, 0x6f, 0x3d, 0x65, 0x5b, 0x65, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x3b, 0x65, 0x6c, 0x73, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, + 0x31, 0x3b, 0x6c, 0x3c, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x6c, 0x2b, 0x2b, 0x29, 0x73, 0x3d, 0x6e, 0x28, 0x61, + 0x5b, 0x6c, 0x5d, 0x2c, 0x6f, 0x2c, 0x75, 0x29, 0x2c, 0x76, 0x6f, + 0x69, 0x64, 0x20, 0x30, 0x21, 0x3d, 0x3d, 0x73, 0x3f, 0x28, 0x63, + 0x3d, 0x6f, 0x2c, 0x6f, 0x3d, 0x73, 0x29, 0x3a, 0x6f, 0x3d, 0x22, + 0x22, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x26, + 0x26, 0x21, 0x6f, 0x3f, 0x21, 0x31, 0x3a, 0x28, 0x72, 0x7c, 0x7c, + 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x21, + 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x6f, 0x7c, 0x7c, + 0x28, 0x65, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x63, 0x29, 0x2c, + 0x6f, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x76, 0x28, 0x6f, + 0x2c, 0x65, 0x2c, 0x69, 0x29, 0x2c, 0x65, 0x2e, 0x70, 0x6f, 0x70, + 0x28, 0x29, 0x29, 0x2c, 0x6f, 0x29, 0x7d, 0x2c, 0x66, 0x3a, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x65, + 0x2c, 0x69, 0x2c, 0x72, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, + 0x61, 0x72, 0x20, 0x73, 0x3d, 0x21, 0x31, 0x2c, 0x61, 0x3d, 0x6e, + 0x75, 0x6c, 0x6c, 0x2c, 0x6f, 0x3d, 0x21, 0x31, 0x2c, 0x75, 0x3d, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x65, 0x74, 0x2c, + 0x63, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, + 0x31, 0x3b, 0x63, 0x3e, 0x3d, 0x30, 0x3b, 0x63, 0x2d, 0x2d, 0x29, + 0x69, 0x66, 0x28, 0x61, 0x3d, 0x65, 0x5b, 0x63, 0x5d, 0x2c, 0x73, + 0x3d, 0x6e, 0x28, 0x74, 0x2c, 0x61, 0x2c, 0x75, 0x29, 0x2c, 0x76, + 0x6f, 0x69, 0x64, 0x20, 0x30, 0x21, 0x3d, 0x3d, 0x73, 0x29, 0x7b, + 0x6f, 0x3d, 0x21, 0x30, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x7d, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x3f, 0x28, 0x72, + 0x7c, 0x7c, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x21, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x73, + 0x7c, 0x7c, 0x28, 0x73, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, + 0x76, 0x28, 0x73, 0x2c, 0x65, 0x2c, 0x69, 0x29, 0x29, 0x2c, 0x73, + 0x29, 0x3a, 0x72, 0x3f, 0x21, 0x31, 0x3a, 0x22, 0x22, 0x7d, 0x2c, + 0x6c, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x72, 0x2c, 0x73, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x64, 0x65, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x73, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x64, 0x65, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x65, 0x72, 0x73, 0x3d, 0x73, 0x2c, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x62, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, + 0x74, 0x28, 0x69, 0x28, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, + 0x6e, 0x2c, 0x72, 0x29, 0x29, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x29, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x64, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, + 0x72, 0x73, 0x3d, 0x61, 0x2c, 0x21, 0x31, 0x7d, 0x2c, 0x63, 0x74, + 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x61, 0x6d, 0x62, + 0x64, 0x61, 0x29, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, + 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x4c, 0x61, + 0x6d, 0x62, 0x64, 0x61, 0x20, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, + 0x65, 0x73, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x2e, 0x22, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x2e, 0x63, 0x6f, 0x6d, 0x70, + 0x69, 0x6c, 0x65, 0x28, 0x74, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x2e, 0x72, 0x65, + 0x6e, 0x64, 0x65, 0x72, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7d, 0x2c, + 0x62, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x62, 0x75, 0x66, + 0x2b, 0x3d, 0x74, 0x7d, 0x2c, 0x66, 0x6c, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, + 0x20, 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x62, 0x75, 0x66, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x62, 0x75, 0x66, 0x3d, 0x22, 0x22, 0x2c, 0x74, 0x7d, + 0x2c, 0x6d, 0x73, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x69, 0x2c, 0x72, + 0x2c, 0x73, 0x2c, 0x61, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, + 0x2c, 0x75, 0x3d, 0x6e, 0x5b, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x2c, 0x63, 0x3d, 0x74, 0x2e, 0x63, + 0x61, 0x6c, 0x6c, 0x28, 0x75, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x63, + 0x3f, 0x69, 0x3f, 0x21, 0x30, 0x3a, 0x28, 0x6f, 0x3d, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x75, + 0x62, 0x26, 0x26, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x75, 0x62, + 0x73, 0x54, 0x65, 0x78, 0x74, 0x26, 0x26, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x73, 0x75, 0x62, 0x73, 0x54, 0x65, 0x78, 0x74, 0x5b, 0x74, + 0x68, 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, + 0x75, 0x62, 0x5d, 0x3f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x75, + 0x62, 0x73, 0x54, 0x65, 0x78, 0x74, 0x5b, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x75, 0x62, 0x5d, + 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x2c, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6c, 0x73, 0x28, 0x63, 0x2c, 0x75, + 0x2c, 0x65, 0x2c, 0x6f, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x28, 0x72, 0x2c, 0x73, 0x29, 0x2c, 0x61, 0x29, + 0x29, 0x3a, 0x63, 0x7d, 0x2c, 0x6d, 0x76, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x6e, 0x5b, 0x6e, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x2c, + 0x73, 0x3d, 0x74, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x72, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3d, 0x3d, 0x74, 0x79, 0x70, + 0x65, 0x6f, 0x66, 0x20, 0x73, 0x3f, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x63, 0x74, 0x28, 0x69, 0x28, 0x73, 0x2e, 0x63, 0x61, 0x6c, 0x6c, + 0x28, 0x72, 0x29, 0x29, 0x2c, 0x72, 0x2c, 0x65, 0x29, 0x3a, 0x73, + 0x7d, 0x2c, 0x73, 0x75, 0x62, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x2c, 0x69, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x5b, 0x74, 0x5d, 0x3b, 0x72, + 0x26, 0x26, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x53, 0x75, 0x62, 0x3d, 0x74, 0x2c, 0x72, 0x28, + 0x6e, 0x2c, 0x65, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x69, 0x29, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x53, 0x75, 0x62, 0x3d, 0x21, 0x31, 0x29, 0x7d, 0x7d, 0x3b, + 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x2f, 0x26, 0x2f, 0x67, 0x2c, + 0x61, 0x3d, 0x2f, 0x3c, 0x2f, 0x67, 0x2c, 0x6f, 0x3d, 0x2f, 0x3e, + 0x2f, 0x67, 0x2c, 0x75, 0x3d, 0x2f, 0x5c, 0x27, 0x2f, 0x67, 0x2c, + 0x63, 0x3d, 0x2f, 0x5c, 0x22, 0x2f, 0x67, 0x2c, 0x6c, 0x3d, 0x2f, + 0x5b, 0x26, 0x3c, 0x3e, 0x5c, 0x22, 0x5c, 0x27, 0x5d, 0x2f, 0x2c, + 0x66, 0x3d, 0x41, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x69, 0x73, 0x41, + 0x72, 0x72, 0x61, 0x79, 0x7c, 0x7c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x22, 0x5b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x20, + 0x41, 0x72, 0x72, 0x61, 0x79, 0x5d, 0x22, 0x3d, 0x3d, 0x3d, 0x4f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x74, 0x79, 0x70, 0x65, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x74, 0x29, 0x7d, + 0x7d, 0x28, 0x22, 0x75, 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, + 0x64, 0x22, 0x21, 0x3d, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, + 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x3f, 0x65, 0x78, 0x70, + 0x6f, 0x72, 0x74, 0x73, 0x3a, 0x48, 0x6f, 0x67, 0x61, 0x6e, 0x29, + 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, + 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x22, 0x7d, 0x22, 0x3d, 0x3d, 0x3d, + 0x74, 0x2e, 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x28, + 0x74, 0x2e, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, + 0x31, 0x29, 0x26, 0x26, 0x28, 0x74, 0x2e, 0x6e, 0x3d, 0x74, 0x2e, + 0x6e, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x28, 0x30, 0x2c, 0x74, 0x2e, 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x2d, 0x31, 0x29, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x74, 0x72, 0x69, + 0x6d, 0x3f, 0x74, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x3a, + 0x74, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, + 0x5e, 0x5c, 0x73, 0x2a, 0x7c, 0x5c, 0x73, 0x2a, 0x24, 0x2f, 0x67, + 0x2c, 0x22, 0x22, 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x69, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, + 0x7b, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, + 0x74, 0x28, 0x65, 0x29, 0x21, 0x3d, 0x74, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x41, 0x74, 0x28, 0x30, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x21, 0x31, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x69, 0x3d, 0x31, 0x2c, 0x72, 0x3d, 0x74, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x72, 0x3e, 0x69, 0x3b, 0x69, + 0x2b, 0x2b, 0x29, 0x69, 0x66, 0x28, 0x6e, 0x2e, 0x63, 0x68, 0x61, + 0x72, 0x41, 0x74, 0x28, 0x65, 0x2b, 0x69, 0x29, 0x21, 0x3d, 0x74, + 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x69, 0x29, 0x29, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x31, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x21, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x28, 0x6e, 0x2c, 0x65, 0x2c, + 0x69, 0x2c, 0x6f, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x75, 0x3d, + 0x5b, 0x5d, 0x2c, 0x63, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6c, + 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x66, 0x3d, 0x6e, 0x75, 0x6c, + 0x6c, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x3d, 0x69, 0x5b, 0x69, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x3b, + 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x3b, + 0x29, 0x7b, 0x69, 0x66, 0x28, 0x66, 0x3d, 0x6e, 0x2e, 0x73, 0x68, + 0x69, 0x66, 0x74, 0x28, 0x29, 0x2c, 0x6c, 0x26, 0x26, 0x22, 0x3c, + 0x22, 0x3d, 0x3d, 0x6c, 0x2e, 0x74, 0x61, 0x67, 0x26, 0x26, 0x21, + 0x28, 0x66, 0x2e, 0x74, 0x61, 0x67, 0x20, 0x69, 0x6e, 0x20, 0x6b, + 0x29, 0x29, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, + 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x49, 0x6c, 0x6c, + 0x65, 0x67, 0x61, 0x6c, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, + 0x74, 0x20, 0x69, 0x6e, 0x20, 0x3c, 0x20, 0x73, 0x75, 0x70, 0x65, + 0x72, 0x20, 0x74, 0x61, 0x67, 0x2e, 0x22, 0x29, 0x3b, 0x69, 0x66, + 0x28, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x73, 0x5b, 0x66, 0x2e, 0x74, + 0x61, 0x67, 0x5d, 0x3c, 0x3d, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x73, + 0x2e, 0x24, 0x7c, 0x7c, 0x73, 0x28, 0x66, 0x2c, 0x6f, 0x29, 0x29, + 0x69, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x66, 0x29, 0x2c, 0x66, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x3d, 0x72, 0x28, 0x6e, 0x2c, + 0x66, 0x2e, 0x74, 0x61, 0x67, 0x2c, 0x69, 0x2c, 0x6f, 0x29, 0x3b, + 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x69, 0x66, 0x28, 0x22, 0x2f, 0x22, + 0x3d, 0x3d, 0x66, 0x2e, 0x74, 0x61, 0x67, 0x29, 0x7b, 0x69, 0x66, + 0x28, 0x30, 0x3d, 0x3d, 0x3d, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x29, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, + 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x43, 0x6c, + 0x6f, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x61, 0x67, 0x20, 0x77, + 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x20, 0x6f, 0x70, 0x65, 0x6e, + 0x65, 0x72, 0x3a, 0x20, 0x2f, 0x22, 0x2b, 0x66, 0x2e, 0x6e, 0x29, + 0x3b, 0x69, 0x66, 0x28, 0x63, 0x3d, 0x69, 0x2e, 0x70, 0x6f, 0x70, + 0x28, 0x29, 0x2c, 0x66, 0x2e, 0x6e, 0x21, 0x3d, 0x63, 0x2e, 0x6e, + 0x26, 0x26, 0x21, 0x61, 0x28, 0x66, 0x2e, 0x6e, 0x2c, 0x63, 0x2e, + 0x6e, 0x2c, 0x6f, 0x29, 0x29, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, + 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, + 0x4e, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x3a, 0x20, 0x22, 0x2b, 0x63, 0x2e, 0x6e, 0x2b, 0x22, + 0x20, 0x76, 0x73, 0x2e, 0x20, 0x22, 0x2b, 0x66, 0x2e, 0x6e, 0x29, + 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x2e, 0x65, + 0x6e, 0x64, 0x3d, 0x66, 0x2e, 0x69, 0x2c, 0x75, 0x7d, 0x22, 0x5c, + 0x6e, 0x22, 0x3d, 0x3d, 0x66, 0x2e, 0x74, 0x61, 0x67, 0x26, 0x26, + 0x28, 0x66, 0x2e, 0x6c, 0x61, 0x73, 0x74, 0x3d, 0x30, 0x3d, 0x3d, + 0x6e, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7c, 0x7c, 0x22, + 0x5c, 0x6e, 0x22, 0x3d, 0x3d, 0x6e, 0x5b, 0x30, 0x5d, 0x2e, 0x74, + 0x61, 0x67, 0x29, 0x7d, 0x75, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x66, 0x29, 0x7d, 0x69, 0x66, 0x28, 0x69, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x3e, 0x30, 0x29, 0x74, 0x68, 0x72, 0x6f, 0x77, + 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, + 0x22, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6c, + 0x6f, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x61, 0x67, 0x3a, 0x20, + 0x22, 0x2b, 0x69, 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x2e, 0x6e, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x28, + 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, + 0x72, 0x20, 0x65, 0x3d, 0x30, 0x2c, 0x69, 0x3d, 0x6e, 0x2e, 0x6c, + 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69, 0x3e, 0x65, 0x3b, 0x65, + 0x2b, 0x2b, 0x29, 0x69, 0x66, 0x28, 0x6e, 0x5b, 0x65, 0x5d, 0x2e, + 0x6f, 0x3d, 0x3d, 0x74, 0x2e, 0x6e, 0x29, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x3d, 0x22, 0x23, + 0x22, 0x2c, 0x21, 0x30, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x61, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, + 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, + 0x30, 0x2c, 0x72, 0x3d, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x3b, 0x72, 0x3e, 0x69, 0x3b, 0x69, 0x2b, 0x2b, 0x29, 0x69, + 0x66, 0x28, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x63, 0x3d, 0x3d, 0x74, + 0x26, 0x26, 0x65, 0x5b, 0x69, 0x5d, 0x2e, 0x6f, 0x3d, 0x3d, 0x6e, + 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, 0x30, 0x7d, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x28, 0x74, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, 0x3d, 0x5b, 0x5d, 0x3b, + 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x20, 0x69, + 0x6e, 0x20, 0x74, 0x29, 0x6e, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, + 0x27, 0x22, 0x27, 0x2b, 0x63, 0x28, 0x65, 0x29, 0x2b, 0x27, 0x22, + 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x63, 0x2c, 0x70, 0x2c, 0x74, 0x2c, 0x69, 0x29, 0x20, 0x7b, 0x27, + 0x2b, 0x74, 0x5b, 0x65, 0x5d, 0x2b, 0x22, 0x7d, 0x22, 0x29, 0x3b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x7b, 0x20, 0x22, 0x2b, + 0x6e, 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x2c, 0x22, 0x29, + 0x2b, 0x22, 0x20, 0x7d, 0x22, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x6e, 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x2e, + 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x29, 0x6e, 0x2e, + 0x70, 0x75, 0x73, 0x68, 0x28, 0x27, 0x22, 0x27, 0x2b, 0x63, 0x28, + 0x65, 0x29, 0x2b, 0x27, 0x22, 0x3a, 0x7b, 0x6e, 0x61, 0x6d, 0x65, + 0x3a, 0x22, 0x27, 0x2b, 0x63, 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5b, 0x65, 0x5d, 0x2e, 0x6e, 0x61, + 0x6d, 0x65, 0x29, 0x2b, 0x27, 0x22, 0x2c, 0x20, 0x27, 0x2b, 0x75, + 0x28, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, + 0x5b, 0x65, 0x5d, 0x29, 0x2b, 0x22, 0x7d, 0x22, 0x29, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x70, 0x61, 0x72, 0x74, 0x69, + 0x61, 0x6c, 0x73, 0x3a, 0x20, 0x7b, 0x22, 0x2b, 0x6e, 0x2e, 0x6a, + 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x2b, 0x22, 0x7d, + 0x2c, 0x20, 0x73, 0x75, 0x62, 0x73, 0x3a, 0x20, 0x22, 0x2b, 0x6f, + 0x28, 0x74, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x29, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x74, 0x29, + 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x72, + 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x6d, 0x2c, 0x22, 0x5c, + 0x5c, 0x5c, 0x5c, 0x22, 0x29, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x28, 0x76, 0x2c, 0x27, 0x5c, 0x5c, 0x22, 0x27, 0x29, + 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x62, 0x2c, + 0x22, 0x5c, 0x5c, 0x6e, 0x22, 0x29, 0x2e, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x28, 0x64, 0x2c, 0x22, 0x5c, 0x5c, 0x72, 0x22, + 0x29, 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x78, + 0x2c, 0x22, 0x5c, 0x5c, 0x75, 0x32, 0x30, 0x32, 0x38, 0x22, 0x29, + 0x2e, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x77, 0x2c, + 0x22, 0x5c, 0x5c, 0x75, 0x32, 0x30, 0x32, 0x39, 0x22, 0x29, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x28, + 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7e, 0x74, + 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x4f, 0x66, 0x28, 0x22, 0x2e, + 0x22, 0x29, 0x3f, 0x22, 0x64, 0x22, 0x3a, 0x22, 0x66, 0x22, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x28, + 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x65, 0x3d, + 0x22, 0x3c, 0x22, 0x2b, 0x28, 0x6e, 0x2e, 0x70, 0x72, 0x65, 0x66, + 0x69, 0x78, 0x7c, 0x7c, 0x22, 0x22, 0x29, 0x2c, 0x69, 0x3d, 0x65, + 0x2b, 0x74, 0x2e, 0x6e, 0x2b, 0x79, 0x2b, 0x2b, 0x3b, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x2e, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x5b, 0x69, 0x5d, 0x3d, 0x7b, 0x6e, 0x61, + 0x6d, 0x65, 0x3a, 0x74, 0x2e, 0x6e, 0x2c, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x3a, 0x7b, 0x7d, 0x7d, 0x2c, 0x6e, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x2b, 0x3d, 0x27, 0x74, 0x2e, 0x62, 0x28, + 0x74, 0x2e, 0x72, 0x70, 0x28, 0x22, 0x27, 0x2b, 0x63, 0x28, 0x69, + 0x29, 0x2b, 0x27, 0x22, 0x2c, 0x63, 0x2c, 0x70, 0x2c, 0x22, 0x27, + 0x2b, 0x28, 0x74, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x7c, + 0x7c, 0x22, 0x22, 0x29, 0x2b, 0x27, 0x22, 0x29, 0x29, 0x3b, 0x27, + 0x2c, 0x69, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x68, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x2b, 0x3d, 0x22, 0x74, 0x2e, 0x62, 0x28, 0x74, + 0x2e, 0x74, 0x28, 0x74, 0x2e, 0x22, 0x2b, 0x6c, 0x28, 0x74, 0x2e, + 0x6e, 0x29, 0x2b, 0x27, 0x28, 0x22, 0x27, 0x2b, 0x63, 0x28, 0x74, + 0x2e, 0x6e, 0x29, 0x2b, 0x27, 0x22, 0x2c, 0x63, 0x2c, 0x70, 0x2c, + 0x30, 0x29, 0x29, 0x29, 0x3b, 0x27, 0x7d, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x70, 0x28, 0x74, 0x29, 0x7b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x74, 0x2e, 0x62, 0x28, 0x22, + 0x2b, 0x74, 0x2b, 0x22, 0x29, 0x3b, 0x22, 0x7d, 0x76, 0x61, 0x72, + 0x20, 0x67, 0x3d, 0x2f, 0x5c, 0x53, 0x2f, 0x2c, 0x76, 0x3d, 0x2f, + 0x5c, 0x22, 0x2f, 0x67, 0x2c, 0x62, 0x3d, 0x2f, 0x5c, 0x6e, 0x2f, + 0x67, 0x2c, 0x64, 0x3d, 0x2f, 0x5c, 0x72, 0x2f, 0x67, 0x2c, 0x6d, + 0x3d, 0x2f, 0x5c, 0x5c, 0x2f, 0x67, 0x2c, 0x78, 0x3d, 0x2f, 0x5c, + 0x75, 0x32, 0x30, 0x32, 0x38, 0x2f, 0x2c, 0x77, 0x3d, 0x2f, 0x5c, + 0x75, 0x32, 0x30, 0x32, 0x39, 0x2f, 0x3b, 0x74, 0x2e, 0x74, 0x61, + 0x67, 0x73, 0x3d, 0x7b, 0x22, 0x23, 0x22, 0x3a, 0x31, 0x2c, 0x22, + 0x5e, 0x22, 0x3a, 0x32, 0x2c, 0x22, 0x3c, 0x22, 0x3a, 0x33, 0x2c, + 0x24, 0x3a, 0x34, 0x2c, 0x22, 0x2f, 0x22, 0x3a, 0x35, 0x2c, 0x22, + 0x21, 0x22, 0x3a, 0x36, 0x2c, 0x22, 0x3e, 0x22, 0x3a, 0x37, 0x2c, + 0x22, 0x3d, 0x22, 0x3a, 0x38, 0x2c, 0x5f, 0x76, 0x3a, 0x39, 0x2c, + 0x22, 0x7b, 0x22, 0x3a, 0x31, 0x30, 0x2c, 0x22, 0x26, 0x22, 0x3a, + 0x31, 0x31, 0x2c, 0x5f, 0x74, 0x3a, 0x31, 0x32, 0x7d, 0x2c, 0x74, + 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x72, 0x2c, 0x73, 0x29, 0x7b, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x28, 0x29, 0x7b, + 0x6d, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x30, 0x26, + 0x26, 0x28, 0x78, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x74, + 0x61, 0x67, 0x3a, 0x22, 0x5f, 0x74, 0x22, 0x2c, 0x74, 0x65, 0x78, + 0x74, 0x3a, 0x6e, 0x65, 0x77, 0x20, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x28, 0x6d, 0x29, 0x7d, 0x29, 0x2c, 0x6d, 0x3d, 0x22, 0x22, + 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, + 0x6f, 0x28, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x6e, 0x3d, 0x21, 0x30, 0x2c, 0x65, 0x3d, 0x79, 0x3b, 0x65, + 0x3c, 0x78, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x65, + 0x2b, 0x2b, 0x29, 0x69, 0x66, 0x28, 0x6e, 0x3d, 0x74, 0x2e, 0x74, + 0x61, 0x67, 0x73, 0x5b, 0x78, 0x5b, 0x65, 0x5d, 0x2e, 0x74, 0x61, + 0x67, 0x5d, 0x3c, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x73, 0x2e, 0x5f, + 0x76, 0x7c, 0x7c, 0x22, 0x5f, 0x74, 0x22, 0x3d, 0x3d, 0x78, 0x5b, + 0x65, 0x5d, 0x2e, 0x74, 0x61, 0x67, 0x26, 0x26, 0x6e, 0x75, 0x6c, + 0x6c, 0x3d, 0x3d, 0x3d, 0x78, 0x5b, 0x65, 0x5d, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x28, 0x67, 0x29, + 0x2c, 0x21, 0x6e, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x21, + 0x31, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x7d, + 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x75, 0x28, + 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x61, 0x28, 0x29, + 0x2c, 0x74, 0x26, 0x26, 0x6f, 0x28, 0x29, 0x29, 0x66, 0x6f, 0x72, + 0x28, 0x76, 0x61, 0x72, 0x20, 0x65, 0x2c, 0x69, 0x3d, 0x79, 0x3b, + 0x69, 0x3c, 0x78, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, + 0x69, 0x2b, 0x2b, 0x29, 0x78, 0x5b, 0x69, 0x5d, 0x2e, 0x74, 0x65, + 0x78, 0x74, 0x26, 0x26, 0x28, 0x28, 0x65, 0x3d, 0x78, 0x5b, 0x69, + 0x2b, 0x31, 0x5d, 0x29, 0x26, 0x26, 0x22, 0x3e, 0x22, 0x3d, 0x3d, + 0x65, 0x2e, 0x74, 0x61, 0x67, 0x26, 0x26, 0x28, 0x65, 0x2e, 0x69, + 0x6e, 0x64, 0x65, 0x6e, 0x74, 0x3d, 0x78, 0x5b, 0x69, 0x5d, 0x2e, + 0x74, 0x65, 0x78, 0x74, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x28, 0x29, 0x29, 0x2c, 0x78, 0x2e, 0x73, 0x70, 0x6c, + 0x69, 0x63, 0x65, 0x28, 0x69, 0x2c, 0x31, 0x29, 0x29, 0x3b, 0x65, + 0x6c, 0x73, 0x65, 0x20, 0x6e, 0x7c, 0x7c, 0x78, 0x2e, 0x70, 0x75, + 0x73, 0x68, 0x28, 0x7b, 0x74, 0x61, 0x67, 0x3a, 0x22, 0x5c, 0x6e, + 0x22, 0x7d, 0x29, 0x3b, 0x77, 0x3d, 0x21, 0x31, 0x2c, 0x79, 0x3d, + 0x78, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7d, 0x66, 0x75, + 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x63, 0x28, 0x74, 0x2c, + 0x6e, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x22, 0x3d, + 0x22, 0x2b, 0x53, 0x2c, 0x72, 0x3d, 0x74, 0x2e, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x4f, 0x66, 0x28, 0x69, 0x2c, 0x6e, 0x29, 0x2c, 0x73, + 0x3d, 0x65, 0x28, 0x74, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x28, 0x74, 0x2e, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x4f, 0x66, 0x28, 0x22, 0x3d, 0x22, 0x2c, 0x6e, 0x29, 0x2b, 0x31, + 0x2c, 0x72, 0x29, 0x29, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, + 0x22, 0x20, 0x22, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x54, 0x3d, 0x73, 0x5b, 0x30, 0x5d, 0x2c, 0x53, 0x3d, 0x73, + 0x5b, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, + 0x5d, 0x2c, 0x72, 0x2b, 0x69, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x2d, 0x31, 0x7d, 0x76, 0x61, 0x72, 0x20, 0x6c, 0x3d, 0x72, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2c, 0x66, 0x3d, 0x30, + 0x2c, 0x68, 0x3d, 0x31, 0x2c, 0x70, 0x3d, 0x32, 0x2c, 0x76, 0x3d, + 0x66, 0x2c, 0x62, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x64, 0x3d, + 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0x6d, 0x3d, 0x22, 0x22, 0x2c, 0x78, + 0x3d, 0x5b, 0x5d, 0x2c, 0x77, 0x3d, 0x21, 0x31, 0x2c, 0x6b, 0x3d, + 0x30, 0x2c, 0x79, 0x3d, 0x30, 0x2c, 0x54, 0x3d, 0x22, 0x7b, 0x7b, + 0x22, 0x2c, 0x53, 0x3d, 0x22, 0x7d, 0x7d, 0x22, 0x3b, 0x66, 0x6f, + 0x72, 0x28, 0x73, 0x26, 0x26, 0x28, 0x73, 0x3d, 0x73, 0x2e, 0x73, + 0x70, 0x6c, 0x69, 0x74, 0x28, 0x22, 0x20, 0x22, 0x29, 0x2c, 0x54, + 0x3d, 0x73, 0x5b, 0x30, 0x5d, 0x2c, 0x53, 0x3d, 0x73, 0x5b, 0x31, + 0x5d, 0x29, 0x2c, 0x6b, 0x3d, 0x30, 0x3b, 0x6c, 0x3e, 0x6b, 0x3b, + 0x6b, 0x2b, 0x2b, 0x29, 0x76, 0x3d, 0x3d, 0x66, 0x3f, 0x69, 0x28, + 0x54, 0x2c, 0x72, 0x2c, 0x6b, 0x29, 0x3f, 0x28, 0x2d, 0x2d, 0x6b, + 0x2c, 0x61, 0x28, 0x29, 0x2c, 0x76, 0x3d, 0x68, 0x29, 0x3a, 0x22, + 0x5c, 0x6e, 0x22, 0x3d, 0x3d, 0x72, 0x2e, 0x63, 0x68, 0x61, 0x72, + 0x41, 0x74, 0x28, 0x6b, 0x29, 0x3f, 0x75, 0x28, 0x77, 0x29, 0x3a, + 0x6d, 0x2b, 0x3d, 0x72, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, + 0x28, 0x6b, 0x29, 0x3a, 0x76, 0x3d, 0x3d, 0x68, 0x3f, 0x28, 0x6b, + 0x2b, 0x3d, 0x54, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, + 0x31, 0x2c, 0x64, 0x3d, 0x74, 0x2e, 0x74, 0x61, 0x67, 0x73, 0x5b, + 0x72, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x6b, 0x2b, + 0x31, 0x29, 0x5d, 0x2c, 0x62, 0x3d, 0x64, 0x3f, 0x72, 0x2e, 0x63, + 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, 0x6b, 0x2b, 0x31, 0x29, 0x3a, + 0x22, 0x5f, 0x76, 0x22, 0x2c, 0x22, 0x3d, 0x22, 0x3d, 0x3d, 0x62, + 0x3f, 0x28, 0x6b, 0x3d, 0x63, 0x28, 0x72, 0x2c, 0x6b, 0x29, 0x2c, + 0x76, 0x3d, 0x66, 0x29, 0x3a, 0x28, 0x64, 0x26, 0x26, 0x6b, 0x2b, + 0x2b, 0x2c, 0x76, 0x3d, 0x70, 0x29, 0x2c, 0x77, 0x3d, 0x6b, 0x29, + 0x3a, 0x69, 0x28, 0x53, 0x2c, 0x72, 0x2c, 0x6b, 0x29, 0x3f, 0x28, + 0x78, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x7b, 0x74, 0x61, 0x67, + 0x3a, 0x62, 0x2c, 0x6e, 0x3a, 0x65, 0x28, 0x6d, 0x29, 0x2c, 0x6f, + 0x74, 0x61, 0x67, 0x3a, 0x54, 0x2c, 0x63, 0x74, 0x61, 0x67, 0x3a, + 0x53, 0x2c, 0x69, 0x3a, 0x22, 0x2f, 0x22, 0x3d, 0x3d, 0x62, 0x3f, + 0x77, 0x2d, 0x54, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, + 0x6b, 0x2b, 0x53, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7d, + 0x29, 0x2c, 0x6d, 0x3d, 0x22, 0x22, 0x2c, 0x6b, 0x2b, 0x3d, 0x53, + 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x2c, 0x76, + 0x3d, 0x66, 0x2c, 0x22, 0x7b, 0x22, 0x3d, 0x3d, 0x62, 0x26, 0x26, + 0x28, 0x22, 0x7d, 0x7d, 0x22, 0x3d, 0x3d, 0x53, 0x3f, 0x6b, 0x2b, + 0x2b, 0x3a, 0x6e, 0x28, 0x78, 0x5b, 0x78, 0x2e, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x2d, 0x31, 0x5d, 0x29, 0x29, 0x29, 0x3a, 0x6d, + 0x2b, 0x3d, 0x72, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x41, 0x74, 0x28, + 0x6b, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x75, + 0x28, 0x77, 0x2c, 0x21, 0x30, 0x29, 0x2c, 0x78, 0x7d, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x6b, 0x3d, 0x7b, 0x5f, 0x74, 0x3a, 0x21, 0x30, + 0x2c, 0x22, 0x5c, 0x6e, 0x22, 0x3a, 0x21, 0x30, 0x2c, 0x24, 0x3a, + 0x21, 0x30, 0x2c, 0x22, 0x2f, 0x22, 0x3a, 0x21, 0x30, 0x7d, 0x3b, + 0x74, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x22, 0x7b, 0x63, + 0x6f, 0x64, 0x65, 0x3a, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x28, 0x63, 0x2c, 0x70, 0x2c, 0x69, 0x29, 0x20, + 0x7b, 0x20, 0x22, 0x2b, 0x74, 0x2e, 0x77, 0x72, 0x61, 0x70, 0x4d, + 0x61, 0x69, 0x6e, 0x28, 0x6e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x29, + 0x2b, 0x22, 0x20, 0x7d, 0x2c, 0x22, 0x2b, 0x75, 0x28, 0x6e, 0x29, + 0x2b, 0x22, 0x7d, 0x22, 0x7d, 0x3b, 0x76, 0x61, 0x72, 0x20, 0x79, + 0x3d, 0x30, 0x3b, 0x74, 0x2e, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x6e, 0x2c, 0x65, 0x2c, 0x69, 0x29, 0x7b, 0x79, 0x3d, 0x30, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x7b, 0x63, 0x6f, 0x64, + 0x65, 0x3a, 0x22, 0x22, 0x2c, 0x73, 0x75, 0x62, 0x73, 0x3a, 0x7b, + 0x7d, 0x2c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x3a, + 0x7b, 0x7d, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x74, 0x2e, 0x77, 0x61, 0x6c, 0x6b, 0x28, 0x6e, 0x2c, 0x72, 0x29, + 0x2c, 0x69, 0x2e, 0x61, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x3f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x69, 0x66, 0x79, 0x28, 0x72, 0x2c, 0x65, 0x2c, 0x69, 0x29, + 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x6b, 0x65, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x72, 0x2c, 0x65, + 0x2c, 0x69, 0x29, 0x7d, 0x2c, 0x74, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x4d, 0x61, 0x69, 0x6e, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x27, 0x76, 0x61, 0x72, 0x20, 0x74, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x3b, 0x74, 0x2e, 0x62, 0x28, 0x69, 0x3d, 0x69, 0x7c, 0x7c, + 0x22, 0x22, 0x29, 0x3b, 0x27, 0x2b, 0x74, 0x2b, 0x22, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x2e, 0x66, 0x6c, 0x28, 0x29, + 0x3b, 0x22, 0x7d, 0x2c, 0x74, 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x3d, 0x74, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, + 0x61, 0x74, 0x65, 0x2c, 0x74, 0x2e, 0x6d, 0x61, 0x6b, 0x65, 0x54, + 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x2c, 0x65, + 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x74, 0x68, 0x69, + 0x73, 0x2e, 0x6d, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x72, 0x74, 0x69, + 0x61, 0x6c, 0x73, 0x28, 0x74, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x69, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x3d, 0x6e, + 0x65, 0x77, 0x20, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x22, 0x63, 0x22, 0x2c, 0x22, 0x70, 0x22, 0x2c, 0x22, 0x69, + 0x22, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x77, 0x72, 0x61, 0x70, + 0x4d, 0x61, 0x69, 0x6e, 0x28, 0x74, 0x2e, 0x63, 0x6f, 0x64, 0x65, + 0x29, 0x29, 0x2c, 0x6e, 0x65, 0x77, 0x20, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x28, 0x69, + 0x2c, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2c, 0x65, 0x29, 0x7d, + 0x2c, 0x74, 0x2e, 0x6d, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x74, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6e, + 0x2c, 0x65, 0x3d, 0x7b, 0x73, 0x75, 0x62, 0x73, 0x3a, 0x7b, 0x7d, + 0x2c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x3a, 0x74, + 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2c, 0x6e, + 0x61, 0x6d, 0x65, 0x3a, 0x74, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x7d, + 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x65, + 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x29, 0x65, + 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5b, 0x6e, + 0x5d, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x6b, 0x65, + 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x28, 0x65, 0x2e, + 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x5b, 0x6e, 0x5d, + 0x29, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6e, 0x20, 0x69, 0x6e, 0x20, + 0x74, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x29, 0x65, 0x2e, 0x73, 0x75, + 0x62, 0x73, 0x5b, 0x6e, 0x5d, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x46, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x22, 0x63, 0x22, + 0x2c, 0x22, 0x70, 0x22, 0x2c, 0x22, 0x74, 0x22, 0x2c, 0x22, 0x69, + 0x22, 0x2c, 0x74, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x5b, 0x6e, 0x5d, + 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x7d, + 0x2c, 0x74, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x67, 0x65, 0x6e, 0x3d, + 0x7b, 0x22, 0x23, 0x22, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x65, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x2b, 0x3d, 0x22, 0x69, 0x66, 0x28, 0x74, 0x2e, + 0x73, 0x28, 0x74, 0x2e, 0x22, 0x2b, 0x6c, 0x28, 0x6e, 0x2e, 0x6e, + 0x29, 0x2b, 0x27, 0x28, 0x22, 0x27, 0x2b, 0x63, 0x28, 0x6e, 0x2e, + 0x6e, 0x29, 0x2b, 0x27, 0x22, 0x2c, 0x63, 0x2c, 0x70, 0x2c, 0x31, + 0x29, 0x2c, 0x63, 0x2c, 0x70, 0x2c, 0x30, 0x2c, 0x27, 0x2b, 0x6e, + 0x2e, 0x69, 0x2b, 0x22, 0x2c, 0x22, 0x2b, 0x6e, 0x2e, 0x65, 0x6e, + 0x64, 0x2b, 0x27, 0x2c, 0x22, 0x27, 0x2b, 0x6e, 0x2e, 0x6f, 0x74, + 0x61, 0x67, 0x2b, 0x22, 0x20, 0x22, 0x2b, 0x6e, 0x2e, 0x63, 0x74, + 0x61, 0x67, 0x2b, 0x27, 0x22, 0x29, 0x29, 0x7b, 0x74, 0x2e, 0x72, + 0x73, 0x28, 0x63, 0x2c, 0x70, 0x2c, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x63, 0x2c, 0x70, 0x2c, 0x74, 0x29, 0x7b, + 0x27, 0x2c, 0x74, 0x2e, 0x77, 0x61, 0x6c, 0x6b, 0x28, 0x6e, 0x2e, + 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x65, 0x29, 0x2c, 0x65, 0x2e, + 0x63, 0x6f, 0x64, 0x65, 0x2b, 0x3d, 0x22, 0x7d, 0x29, 0x3b, 0x63, + 0x2e, 0x70, 0x6f, 0x70, 0x28, 0x29, 0x3b, 0x7d, 0x22, 0x7d, 0x2c, + 0x22, 0x5e, 0x22, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x65, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x2b, 0x3d, 0x22, 0x69, 0x66, 0x28, 0x21, 0x74, 0x2e, + 0x73, 0x28, 0x74, 0x2e, 0x22, 0x2b, 0x6c, 0x28, 0x6e, 0x2e, 0x6e, + 0x29, 0x2b, 0x27, 0x28, 0x22, 0x27, 0x2b, 0x63, 0x28, 0x6e, 0x2e, + 0x6e, 0x29, 0x2b, 0x27, 0x22, 0x2c, 0x63, 0x2c, 0x70, 0x2c, 0x31, + 0x29, 0x2c, 0x63, 0x2c, 0x70, 0x2c, 0x31, 0x2c, 0x30, 0x2c, 0x30, + 0x2c, 0x22, 0x22, 0x29, 0x29, 0x7b, 0x27, 0x2c, 0x74, 0x2e, 0x77, + 0x61, 0x6c, 0x6b, 0x28, 0x6e, 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x73, + 0x2c, 0x65, 0x29, 0x2c, 0x65, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x2b, + 0x3d, 0x22, 0x7d, 0x3b, 0x22, 0x7d, 0x2c, 0x22, 0x3e, 0x22, 0x3a, + 0x66, 0x2c, 0x22, 0x3c, 0x22, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x76, 0x61, + 0x72, 0x20, 0x69, 0x3d, 0x7b, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, + 0x6c, 0x73, 0x3a, 0x7b, 0x7d, 0x2c, 0x63, 0x6f, 0x64, 0x65, 0x3a, + 0x22, 0x22, 0x2c, 0x73, 0x75, 0x62, 0x73, 0x3a, 0x7b, 0x7d, 0x2c, + 0x69, 0x6e, 0x50, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x3a, 0x21, + 0x30, 0x7d, 0x3b, 0x74, 0x2e, 0x77, 0x61, 0x6c, 0x6b, 0x28, 0x6e, + 0x2e, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x2c, 0x69, 0x29, 0x3b, 0x76, + 0x61, 0x72, 0x20, 0x72, 0x3d, 0x65, 0x2e, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x5b, 0x66, 0x28, 0x6e, 0x2c, 0x65, 0x29, + 0x5d, 0x3b, 0x72, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x3d, 0x69, 0x2e, + 0x73, 0x75, 0x62, 0x73, 0x2c, 0x72, 0x2e, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x3d, 0x69, 0x2e, 0x70, 0x61, 0x72, 0x74, + 0x69, 0x61, 0x6c, 0x73, 0x7d, 0x2c, 0x24, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, 0x2c, 0x65, 0x29, 0x7b, + 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x7b, 0x73, 0x75, 0x62, 0x73, + 0x3a, 0x7b, 0x7d, 0x2c, 0x63, 0x6f, 0x64, 0x65, 0x3a, 0x22, 0x22, + 0x2c, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x3a, 0x65, + 0x2e, 0x70, 0x61, 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2c, 0x70, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x3a, 0x6e, 0x2e, 0x6e, 0x7d, 0x3b, + 0x74, 0x2e, 0x77, 0x61, 0x6c, 0x6b, 0x28, 0x6e, 0x2e, 0x6e, 0x6f, + 0x64, 0x65, 0x73, 0x2c, 0x69, 0x29, 0x2c, 0x65, 0x2e, 0x73, 0x75, + 0x62, 0x73, 0x5b, 0x6e, 0x2e, 0x6e, 0x5d, 0x3d, 0x69, 0x2e, 0x63, + 0x6f, 0x64, 0x65, 0x2c, 0x65, 0x2e, 0x69, 0x6e, 0x50, 0x61, 0x72, + 0x74, 0x69, 0x61, 0x6c, 0x7c, 0x7c, 0x28, 0x65, 0x2e, 0x63, 0x6f, + 0x64, 0x65, 0x2b, 0x3d, 0x27, 0x74, 0x2e, 0x73, 0x75, 0x62, 0x28, + 0x22, 0x27, 0x2b, 0x63, 0x28, 0x6e, 0x2e, 0x6e, 0x29, 0x2b, 0x27, + 0x22, 0x2c, 0x63, 0x2c, 0x70, 0x2c, 0x69, 0x29, 0x3b, 0x27, 0x29, + 0x7d, 0x2c, 0x22, 0x5c, 0x6e, 0x22, 0x3a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x6e, + 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x2b, 0x3d, 0x70, 0x28, 0x27, 0x22, + 0x5c, 0x5c, 0x6e, 0x22, 0x27, 0x2b, 0x28, 0x74, 0x2e, 0x6c, 0x61, + 0x73, 0x74, 0x3f, 0x22, 0x22, 0x3a, 0x22, 0x20, 0x2b, 0x20, 0x69, + 0x22, 0x29, 0x29, 0x7d, 0x2c, 0x5f, 0x76, 0x3a, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, + 0x6e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x2b, 0x3d, 0x22, 0x74, 0x2e, + 0x62, 0x28, 0x74, 0x2e, 0x76, 0x28, 0x74, 0x2e, 0x22, 0x2b, 0x6c, + 0x28, 0x74, 0x2e, 0x6e, 0x29, 0x2b, 0x27, 0x28, 0x22, 0x27, 0x2b, + 0x63, 0x28, 0x74, 0x2e, 0x6e, 0x29, 0x2b, 0x27, 0x22, 0x2c, 0x63, + 0x2c, 0x70, 0x2c, 0x30, 0x29, 0x29, 0x29, 0x3b, 0x27, 0x7d, 0x2c, + 0x5f, 0x74, 0x3a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, 0x6e, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x2b, 0x3d, 0x70, 0x28, 0x27, 0x22, 0x27, 0x2b, 0x63, 0x28, + 0x74, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x29, 0x2b, 0x27, 0x22, 0x27, + 0x29, 0x7d, 0x2c, 0x22, 0x7b, 0x22, 0x3a, 0x68, 0x2c, 0x22, 0x26, + 0x22, 0x3a, 0x68, 0x7d, 0x2c, 0x74, 0x2e, 0x77, 0x61, 0x6c, 0x6b, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x65, 0x29, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x76, 0x61, 0x72, + 0x20, 0x69, 0x2c, 0x72, 0x3d, 0x30, 0x2c, 0x73, 0x3d, 0x6e, 0x2e, + 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x73, 0x3e, 0x72, 0x3b, + 0x72, 0x2b, 0x2b, 0x29, 0x69, 0x3d, 0x74, 0x2e, 0x63, 0x6f, 0x64, + 0x65, 0x67, 0x65, 0x6e, 0x5b, 0x6e, 0x5b, 0x72, 0x5d, 0x2e, 0x74, + 0x61, 0x67, 0x5d, 0x2c, 0x69, 0x26, 0x26, 0x69, 0x28, 0x6e, 0x5b, + 0x72, 0x5d, 0x2c, 0x65, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x65, 0x7d, 0x2c, 0x74, 0x2e, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, + 0x74, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x65, 0x3d, 0x65, 0x7c, 0x7c, 0x7b, 0x7d, 0x2c, + 0x72, 0x28, 0x74, 0x2c, 0x22, 0x22, 0x2c, 0x5b, 0x5d, 0x2c, 0x65, + 0x2e, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x67, + 0x73, 0x7c, 0x7c, 0x5b, 0x5d, 0x29, 0x7d, 0x2c, 0x74, 0x2e, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x3d, 0x7b, 0x7d, 0x2c, 0x74, 0x2e, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x4b, 0x65, 0x79, 0x3d, 0x66, 0x75, 0x6e, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x74, 0x2c, 0x6e, 0x29, 0x7b, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b, 0x74, 0x2c, 0x21, 0x21, + 0x6e, 0x2e, 0x61, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, + 0x21, 0x21, 0x6e, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, + 0x4c, 0x61, 0x6d, 0x62, 0x64, 0x61, 0x2c, 0x6e, 0x2e, 0x64, 0x65, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x21, 0x21, + 0x6e, 0x2e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x47, 0x65, 0x74, 0x5d, + 0x2e, 0x6a, 0x6f, 0x69, 0x6e, 0x28, 0x22, 0x7c, 0x7c, 0x22, 0x29, + 0x7d, 0x2c, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, + 0x3d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6e, + 0x2c, 0x65, 0x29, 0x7b, 0x65, 0x3d, 0x65, 0x7c, 0x7c, 0x7b, 0x7d, + 0x3b, 0x76, 0x61, 0x72, 0x20, 0x69, 0x3d, 0x74, 0x2e, 0x63, 0x61, + 0x63, 0x68, 0x65, 0x4b, 0x65, 0x79, 0x28, 0x6e, 0x2c, 0x65, 0x29, + 0x2c, 0x72, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x61, 0x63, + 0x68, 0x65, 0x5b, 0x69, 0x5d, 0x3b, 0x69, 0x66, 0x28, 0x72, 0x29, + 0x7b, 0x76, 0x61, 0x72, 0x20, 0x73, 0x3d, 0x72, 0x2e, 0x70, 0x61, + 0x72, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x3b, 0x66, 0x6f, 0x72, 0x28, + 0x76, 0x61, 0x72, 0x20, 0x61, 0x20, 0x69, 0x6e, 0x20, 0x73, 0x29, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x73, 0x5b, 0x61, 0x5d, + 0x2e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x3b, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x7d, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x72, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x70, 0x61, 0x72, 0x73, 0x65, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x73, 0x63, 0x61, 0x6e, 0x28, 0x6e, 0x2c, 0x65, + 0x2e, 0x64, 0x65, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x73, + 0x29, 0x2c, 0x6e, 0x2c, 0x65, 0x29, 0x2c, 0x6e, 0x2c, 0x65, 0x29, + 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x61, 0x63, 0x68, 0x65, + 0x5b, 0x69, 0x5d, 0x3d, 0x72, 0x7d, 0x7d, 0x28, 0x22, 0x75, 0x6e, + 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x21, 0x3d, 0x74, + 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x3f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x3a, + 0x48, 0x6f, 0x67, 0x61, 0x6e, 0x29, 0x3b, 0x00 +}; + +const int hogan_js_length = 8555; diff --git a/goaccess++/src/json.c b/goaccess++/src/json.c new file mode 100644 index 0000000..cefbde1 --- /dev/null +++ b/goaccess++/src/json.c @@ -0,0 +1,1251 @@ +/** + * output.c -- output json to the standard output stream + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#include <errno.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <time.h> +#include <unistd.h> +#include <inttypes.h> + +#include "json.h" + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#include "error.h" +#include "settings.h" +#include "ui.h" +#include "util.h" +#include "websocket.h" +#include "xmalloc.h" + +typedef struct GPanel_ +{ + GModule module; + void (*render) (GJSON * json, GHolder * h, GPercTotals totals, + const struct GPanel_ *); + void (*subitems) (GJSON * json, GHolderItem * item, GPercTotals totals, + int size, int iisp); +} GPanel; + +/* number of new lines (applicable fields) */ +static int nlines = 0; +/* escape HTML in JSON data values */ +static int escape_html_output = 0; + +static void print_json_data (GJSON * json, GHolder * h, GPercTotals totals, + const struct GPanel_ *); +static void print_json_host_items (GJSON * json, GHolderItem * item, + GPercTotals totals, int size, int iisp); +static void print_json_sub_items (GJSON * json, GHolderItem * item, + GPercTotals totals, int size, int iisp); + +/* *INDENT-OFF* */ +static GPanel paneling[] = { + {VISITORS , print_json_data , NULL } , + {REQUESTS , print_json_data , NULL } , + {REQUESTS_STATIC , print_json_data , NULL } , + {NOT_FOUND , print_json_data , NULL } , + {HOSTS , print_json_data , print_json_host_items } , + {OS , print_json_data , print_json_sub_items } , + {BROWSERS , print_json_data , print_json_sub_items } , + {VISIT_TIMES , print_json_data , NULL } , + {VIRTUAL_HOSTS , print_json_data , NULL } , + {REFERRERS , print_json_data , NULL } , + {REFERRING_SITES , print_json_data , NULL } , + {KEYPHRASES , print_json_data , NULL } , + {STATUS_CODES , print_json_data , print_json_sub_items } , + {REMOTE_USER , print_json_data , NULL } , +#ifdef HAVE_GEOLOCATION + {GEO_LOCATION , print_json_data , print_json_sub_items } , +#endif +}; +/* *INDENT-ON* */ + +/* Get panel output data for the given module. + * + * If not found, NULL is returned. + * On success, panel data is returned . */ +static GPanel * +panel_lookup (GModule module) +{ + int i, num_panels = ARRAY_SIZE (paneling); + + for (i = 0; i < num_panels; i++) { + if (paneling[i].module == module) + return &paneling[i]; + } + return NULL; +} + +/* Allocate memory for a new GJSON instance. + * + * On success, the newly allocated GJSON is returned . */ +static GJSON * +new_gjson (void) +{ + GJSON *json = xcalloc (1, sizeof (GJSON)); + + return json; +} + +/* Free malloc'd GJSON resources. */ +static void +free_json (GJSON * json) +{ + if (!json) + return; + + free (json->buf); + free (json); +} + +/* Set number of new lines when --json-pretty-print is used. */ +void +set_json_nlines (int newline) +{ + nlines = newline; +} + +/* Make sure that we have enough storage to write "len" bytes at the + * current offset. */ +static void +set_json_buffer (GJSON * json, int len) +{ + char *tmp = NULL; + /* Maintain a null byte at the end of the buffer */ + size_t need = json->offset + len + 1, newlen = 0; + + if (need <= json->size) + return; + + if (json->size == 0) { + newlen = INIT_BUF_SIZE; + } else { + newlen = json->size; + newlen += newlen / 2; /* resize by 3/2 */ + } + + if (newlen < need) + newlen = need; + + tmp = realloc (json->buf, newlen); + if (tmp == NULL) { + free_json (json); + FATAL (("Unable to realloc JSON buffer.\n")); + } + json->buf = tmp; + json->size = newlen; +} + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +/* A wrapper function to write a formatted string and expand the + * buffer if necessary. + * + * On success, data is outputted. */ +static void +pjson (GJSON * json, const char *fmt, ...) +{ + int len = 0; + va_list args; + + va_start (args, fmt); + if ((len = vsnprintf (NULL, 0, fmt, args)) < 0) + FATAL (("Unable to write JSON formatted data.\n")); + va_end (args); + + /* malloc/realloc buffer as needed */ + set_json_buffer (json, len); + + va_start (args, fmt); /* restart args */ + vsprintf (json->buf + json->offset, fmt, args); + va_end (args); + json->offset += len; +} + +/* A wrapper function to output a formatted string to a file pointer. + * + * On success, data is outputted. */ +void +fpjson (FILE * fp, const char *fmt, ...) +{ + va_list args; + + va_start (args, fmt); + vfprintf (fp, fmt, args); + va_end (args); +} + +#pragma GCC diagnostic warning "-Wformat-nonliteral" + +/* Escape all other characters accordingly. */ +static void +escape_json_other (GJSON * json, char **s) +{ + /* Since JSON data is bootstrapped into the HTML document of a report, + * then we perform the following four translations in case weird stuff + * is put into the document. + * + * Note: The following scenario assumes that the user manually makes + * the HTML report a PHP file (GoAccess doesn't allow the creation of a + * PHP file): + * + * /index.html<?php eval(base_decode('iZWNobyAiPGgxPkhFTExPPC9oMT4iOw=='));?> + */ + if (escape_html_output) { + switch (**s) { + case '\'': + pjson (json, "'"); + return; + case '&': + pjson (json, "&"); + return; + case '<': + pjson (json, "<"); + return; + case '>': + pjson (json, ">"); + return; + } + } + + if ((uint8_t) ** s <= 0x1f) { + /* Control characters (U+0000 through U+001F) */ + char buf[8]; + snprintf (buf, sizeof buf, "\\u%04x", **s); + pjson (json, "%s", buf); + } else if ((uint8_t) ** s == 0xe2 && (uint8_t) * (*s + 1) == 0x80 && + (uint8_t) * (*s + 2) == 0xa8) { + /* Line separator (U+2028) - 0xE2 0x80 0xA8 */ + pjson (json, "\\u2028"); + *s += 2; + } else if ((uint8_t) ** s == 0xe2 && (uint8_t) * (*s + 1) == 0x80 && + (uint8_t) * (*s + 2) == 0xa9) { + /* Paragraph separator (U+2019) - 0xE2 0x80 0xA9 */ + pjson (json, "\\u2029"); + *s += 2; + } else { + char buf[2]; + snprintf (buf, sizeof buf, "%c", **s); + pjson (json, "%s", buf); + } +} + +/* Escape and write to a valid JSON buffer. + * + * On success, escaped JSON data is outputted. */ +static void +escape_json_output (GJSON * json, char *s) +{ + while (*s) { + switch (*s) { + /* These are required JSON special characters that need to be escaped. */ + case '"': + pjson (json, "\\\""); + break; + case '\\': + pjson (json, "\\\\"); + break; + case '\b': + pjson (json, "\\b"); + break; + case '\f': + pjson (json, "\\f"); + break; + case '\n': + pjson (json, "\\n"); + break; + case '\r': + pjson (json, "\\r"); + break; + case '\t': + pjson (json, "\\t"); + break; + case '/': + pjson (json, "\\/"); + break; + default: + escape_json_other (json, &s); + break; + } + s++; + } +} + +/* Write to a buffer a JSON a key/value pair. */ +static void +pskeysval (GJSON * json, const char *key, const char *val, int sp, int last) +{ + if (!last) + pjson (json, "%.*s\"%s\": \"%s\",%.*s", sp, TAB, key, val, nlines, NL); + else + pjson (json, "%.*s\"%s\": \"%s\"", sp, TAB, key, val); +} + +/* Output a JSON string key, array value pair. */ +void +fpskeyaval (FILE * fp, const char *key, const char *val, int sp, int last) +{ + if (!last) + fpjson (fp, "%.*s\"%s\": %s,%.*s", sp, TAB, key, val, nlines, NL); + else + fpjson (fp, "%.*s\"%s\": %s", sp, TAB, key, val); +} + +/* Output a JSON a key/value pair. */ +void +fpskeysval (FILE * fp, const char *key, const char *val, int sp, int last) +{ + if (!last) + fpjson (fp, "%.*s\"%s\": \"%s\",%.*s", sp, TAB, key, val, nlines, NL); + else + fpjson (fp, "%.*s\"%s\": \"%s\"", sp, TAB, key, val); +} + +/* Write to a buffer a JSON string key, int value pair. */ +static void +pskeyival (GJSON * json, const char *key, int val, int sp, int last) +{ + if (!last) + pjson (json, "%.*s\"%s\": %d,%.*s", sp, TAB, key, val, nlines, NL); + else + pjson (json, "%.*s\"%s\": %d", sp, TAB, key, val); +} + +/* Output a JSON string key, int value pair. */ +void +fpskeyival (FILE * fp, const char *key, int val, int sp, int last) +{ + if (!last) + fpjson (fp, "%.*s\"%s\": %d,%.*s", sp, TAB, key, val, nlines, NL); + else + fpjson (fp, "%.*s\"%s\": %d", sp, TAB, key, val); +} + +/* Write to a buffer a JSON string key, uint64_t value pair. */ +static void +pskeyu64val (GJSON * json, const char *key, uint64_t val, int sp, int last) +{ + if (!last) + pjson (json, "%.*s\"%s\": %" PRIu64 ",%.*s", sp, TAB, key, val, nlines, NL); + else + pjson (json, "%.*s\"%s\": %" PRIu64 "", sp, TAB, key, val); +} + +/* Write to a buffer a JSON string key, int value pair. */ +static void +pskeyfval (GJSON * json, const char *key, float val, int sp, int last) +{ + if (!last) + pjson (json, "%.*s\"%s\": \"%4.2f\",%.*s", sp, TAB, key, val, nlines, NL); + else + pjson (json, "%.*s\"%s\": \"%4.2f\"", sp, TAB, key, val); +} + +/* Write to a buffer the open block item object. */ +static void +popen_obj (GJSON * json, int iisp) +{ + /* open data metric block */ + pjson (json, "%.*s{%.*s", iisp, TAB, nlines, NL); +} + +/* Output the open block item object. */ +void +fpopen_obj (FILE * fp, int iisp) +{ + /* open data metric block */ + fpjson (fp, "%.*s{%.*s", iisp, TAB, nlines, NL); +} + +/* Write to a buffer a JSON open object attribute. */ +static void +popen_obj_attr (GJSON * json, const char *attr, int sp) +{ + /* open object attribute */ + pjson (json, "%.*s\"%s\": {%.*s", sp, TAB, attr, nlines, NL); +} + +/* Output a JSON open object attribute. */ +void +fpopen_obj_attr (FILE * fp, const char *attr, int sp) +{ + /* open object attribute */ + fpjson (fp, "%.*s\"%s\": {%.*s", sp, TAB, attr, nlines, NL); +} + +/* Close JSON object. */ +static void +pclose_obj (GJSON * json, int iisp, int last) +{ + if (!last) + pjson (json, "%.*s%.*s},%.*s", nlines, NL, iisp, TAB, nlines, NL); + else + pjson (json, "%.*s%.*s}", nlines, NL, iisp, TAB); +} + +/* Close JSON object. */ +void +fpclose_obj (FILE * fp, int iisp, int last) +{ + if (!last) + fpjson (fp, "%.*s%.*s},%.*s", nlines, NL, iisp, TAB, nlines, NL); + else + fpjson (fp, "%.*s%.*s}", nlines, NL, iisp, TAB); +} + +/* Write to a buffer a JSON open array attribute. */ +static void +popen_arr_attr (GJSON * json, const char *attr, int sp) +{ + /* open object attribute */ + pjson (json, "%.*s\"%s\": [%.*s", sp, TAB, attr, nlines, NL); +} + +/* Output a JSON open array attribute. */ +void +fpopen_arr_attr (FILE * fp, const char *attr, int sp) +{ + /* open object attribute */ + fpjson (fp, "%.*s\"%s\": [%.*s", sp, TAB, attr, nlines, NL); +} + +/* Close the data array. */ +static void +pclose_arr (GJSON * json, int sp, int last) +{ + if (!last) + pjson (json, "%.*s%.*s],%.*s", nlines, NL, sp, TAB, nlines, NL); + else + pjson (json, "%.*s%.*s]", nlines, NL, sp, TAB); +} + +/* Close the data array. */ +void +fpclose_arr (FILE * fp, int sp, int last) +{ + if (!last) + fpjson (fp, "%.*s%.*s],%.*s", nlines, NL, sp, TAB, nlines, NL); + else + fpjson (fp, "%.*s%.*s]", nlines, NL, sp, TAB); +} + +/* Write to a buffer the date and time for the overall object. */ +static void +poverall_datetime (GJSON * json, int sp) +{ + char now[DATE_TIME]; + + generate_time (); + strftime (now, DATE_TIME, "%Y-%m-%d %H:%M:%S %z", now_tm); + + pskeysval (json, OVERALL_DATETIME, now, sp, 0); +} + +/* Write to a buffer the date and time for the overall object. */ +static void +poverall_start_end_date (GJSON * json, GHolder * h, int sp) +{ + char *start = NULL, *end = NULL; + + if (h->idx == 0 || get_start_end_parsing_dates (h, &start, &end, "%d/%b/%Y")) + return; + + pskeysval (json, OVERALL_STARTDATE, start, sp, 0); + pskeysval (json, OVERALL_ENDDATE, end, sp, 0); + + free (end); + free (start); +} + +/* Write to a buffer date and time for the overall object. */ +static void +poverall_requests (GJSON * json, GLog * glog, int sp) +{ + pskeyival (json, OVERALL_REQ, glog->processed, sp, 0); +} + +/* Write to a buffer the number of valid requests under the overall + * object. */ +static void +poverall_valid_reqs (GJSON * json, GLog * glog, int sp) +{ + pskeyival (json, OVERALL_VALID, glog->valid, sp, 0); +} + +/* Write to a buffer the number of invalid requests under the overall + * object. */ +static void +poverall_invalid_reqs (GJSON * json, GLog * glog, int sp) +{ + pskeyival (json, OVERALL_FAILED, glog->invalid, sp, 0); +} + +/* Write to a buffer the total processed time under the overall + * object. */ +static void +poverall_processed_time (GJSON * json, int sp) +{ + uint64_t elapsed_proc = end_proc - start_proc; + +#ifdef TCB_BTREE + if (conf.store_accumulated_time) + elapsed_proc = (uint64_t) ht_get_genstats ("accumulated_time"); +#endif + + pskeyu64val (json, OVERALL_GENTIME, elapsed_proc, sp, 0); +} + +/* Write to a buffer the total number of unique visitors under the + * overall object. */ +static void +poverall_visitors (GJSON * json, int sp) +{ + pskeyival (json, OVERALL_VISITORS, ht_get_size_uniqmap (VISITORS), sp, 0); +} + +/* Write to a buffer the total number of unique files under the + * overall object. */ +static void +poverall_files (GJSON * json, int sp) +{ + pskeyival (json, OVERALL_FILES, ht_get_size_datamap (REQUESTS), sp, 0); +} + +/* Write to a buffer the total number of excluded requests under the + * overall object. */ +static void +poverall_excluded (GJSON * json, GLog * glog, int sp) +{ + pskeyival (json, OVERALL_EXCL_HITS, glog->excluded_ip, sp, 0); +} + +/* Write to a buffer the number of referrers under the overall object. */ +static void +poverall_refs (GJSON * json, int sp) +{ + pskeyival (json, OVERALL_REF, ht_get_size_datamap (REFERRERS), sp, 0); +} + +/* Write to a buffer the number of not found (404s) under the overall + * object. */ +static void +poverall_notfound (GJSON * json, int sp) +{ + pskeyival (json, OVERALL_NOTFOUND, ht_get_size_datamap (NOT_FOUND), sp, 0); +} + +/* Write to a buffer the number of static files (jpg, pdf, etc) under + * the overall object. */ +static void +poverall_static_files (GJSON * json, int sp) +{ + pskeyival (json, OVERALL_STATIC, ht_get_size_datamap (REQUESTS_STATIC), sp, + 0); +} + +/* Write to a buffer the size of the log being parsed under the + * overall object. */ +static void +poverall_log_size (GJSON * json, int sp) +{ + pjson (json, "%.*s\"%s\": %jd,%.*s", sp, TAB, OVERALL_LOGSIZE, + (intmax_t) get_log_sizes (), nlines, NL); +} + +/* Write to a buffer the total bandwidth consumed under the overall + * object. */ +static void +poverall_bandwidth (GJSON * json, GLog * glog, int sp) +{ + pskeyu64val (json, OVERALL_BANDWIDTH, glog->resp_size, sp, 0); +} + +static void +poverall_log_path (GJSON * json, int idx, int isp) +{ + pjson (json, "%.*s\"", isp, TAB); + if (conf.filenames[idx][0] == '-' && conf.filenames[idx][1] == '\0') + pjson (json, "STDIN"); + else + escape_json_output (json, (char *) conf.filenames[idx]); + pjson (json, conf.filenames_idx - 1 != idx ? "\",\n" : "\""); +} + +/* Write to a buffer the path of the log being parsed under the + * overall object. */ +static void +poverall_log (GJSON * json, int sp) +{ + int idx, isp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_arr_attr (json, OVERALL_LOG, sp); + for (idx = 0; idx < conf.filenames_idx; ++idx) + poverall_log_path (json, idx, isp); + pclose_arr (json, sp, 1); +} + +/* Write to a buffer hits data. */ +static void +phits (GJSON * json, GMetrics * nmetrics, int sp) +{ + int isp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_obj_attr (json, "hits", sp); + /* print hits */ + pskeyival (json, "count", nmetrics->hits, isp, 0); + /* print hits percent */ + pskeyfval (json, "percent", nmetrics->hits_perc, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Write to a buffer visitors data. */ +static void +pvisitors (GJSON * json, GMetrics * nmetrics, int sp) +{ + int isp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_obj_attr (json, "visitors", sp); + /* print visitors */ + pskeyival (json, "count", nmetrics->visitors, isp, 0); + /* print visitors percent */ + pskeyfval (json, "percent", nmetrics->visitors_perc, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Write to a buffer bandwidth data. */ +static void +pbw (GJSON * json, GMetrics * nmetrics, int sp) +{ + int isp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + if (!conf.bandwidth) + return; + + popen_obj_attr (json, "bytes", sp); + /* print bandwidth */ + pskeyu64val (json, "count", nmetrics->bw.nbw, isp, 0); + /* print bandwidth percent */ + pskeyfval (json, "percent", nmetrics->bw_perc, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Write to a buffer average time served data. */ +static void +pavgts (GJSON * json, GMetrics * nmetrics, int sp) +{ + if (!conf.serve_usecs) + return; + pskeyu64val (json, "avgts", nmetrics->avgts.nts, sp, 0); +} + +/* Write to a buffer cumulative time served data. */ +static void +pcumts (GJSON * json, GMetrics * nmetrics, int sp) +{ + if (!conf.serve_usecs) + return; + pskeyu64val (json, "cumts", nmetrics->cumts.nts, sp, 0); +} + +/* Write to a buffer maximum time served data. */ +static void +pmaxts (GJSON * json, GMetrics * nmetrics, int sp) +{ + if (!conf.serve_usecs) + return; + pskeyu64val (json, "maxts", nmetrics->maxts.nts, sp, 0); +} + +/* Write to a buffer request method data. */ +static void +pmethod (GJSON * json, GMetrics * nmetrics, int sp) +{ + /* request method */ + if (conf.append_method && nmetrics->method) { + pskeysval (json, "method", nmetrics->method, sp, 0); + } +} + +/* Write to a buffer protocol method data. */ +static void +pprotocol (GJSON * json, GMetrics * nmetrics, int sp) +{ + /* request protocol */ + if (conf.append_protocol && nmetrics->protocol) { + pskeysval (json, "protocol", nmetrics->protocol, sp, 0); + } +} + +/* Write to a buffer the hits meta data object. */ +static void +pmeta_data_unique (GJSON * json, int ht_size, int sp) +{ + int isp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_obj_attr (json, "data", sp); + pskeyu64val (json, "unique", ht_size, isp, 1); + pclose_obj (json, sp, 1); +} + +/* Write to a buffer the hits meta data object. */ +static void +pmeta_data_hits (GJSON * json, GModule module, int sp) +{ + int isp = 0; + int max = 0, min = 0; + + ht_get_hits_min_max (module, &min, &max); + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_obj_attr (json, "hits", sp); + pskeyu64val (json, "count", ht_get_meta_data (module, "hits"), isp, 0); + pskeyival (json, "max", max, isp, 0); + pskeyival (json, "min", min, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Write to a buffer the visitors meta data object. */ +static void +pmeta_data_visitors (GJSON * json, GModule module, int sp) +{ + int isp = 0; + int max = 0, min = 0; + + ht_get_visitors_min_max (module, &min, &max); + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_obj_attr (json, "visitors", sp); + pskeyu64val (json, "count", ht_get_meta_data (module, "visitors"), isp, 0); + pskeyival (json, "max", max, isp, 0); + pskeyival (json, "min", min, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Write to a buffer the bytes meta data object. */ +static void +pmeta_data_bw (GJSON * json, GModule module, int sp) +{ + int isp = 0; + uint64_t max = 0, min = 0; + + if (!conf.bandwidth) + return; + + ht_get_bw_min_max (module, &min, &max); + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_obj_attr (json, "bytes", sp); + pskeyu64val (json, "count", ht_get_meta_data (module, "bytes"), isp, 0); + pskeyu64val (json, "max", max, isp, 0); + pskeyu64val (json, "min", min, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Write to a buffer the average of the average time served meta data + * object. */ +static void +pmeta_data_avgts (GJSON * json, GModule module, int sp) +{ + int isp = 0; + uint64_t avg = 0, hits = 0, cumts = 0; + + if (!conf.serve_usecs) + return; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + cumts = ht_get_meta_data (module, "cumts"); + hits = ht_get_meta_data (module, "hits"); + if (hits > 0) + avg = cumts / hits; + + popen_obj_attr (json, "avgts", sp); + pskeyu64val (json, "avg", avg, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Write to a buffer the cumulative time served meta data object. */ +static void +pmeta_data_cumts (GJSON * json, GModule module, int sp) +{ + int isp = 0; + uint64_t max = 0, min = 0; + + if (!conf.serve_usecs) + return; + + ht_get_cumts_min_max (module, &min, &max); + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_obj_attr (json, "cumts", sp); + pskeyu64val (json, "count", ht_get_meta_data (module, "cumts"), isp, 0); + pskeyu64val (json, "max", max, isp, 0); + pskeyu64val (json, "min", min, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Write to a buffer the maximum time served meta data object. */ +static void +pmeta_data_maxts (GJSON * json, GModule module, int sp) +{ + int isp = 0; + uint64_t max = 0, min = 0; + + if (!conf.serve_usecs) + return; + + ht_get_maxts_min_max (module, &min, &max); + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + popen_obj_attr (json, "maxts", sp); + pskeyu64val (json, "count", ht_get_meta_data (module, "maxts"), isp, 0); + pskeyu64val (json, "max", max, isp, 0); + pskeyu64val (json, "min", min, isp, 1); + pclose_obj (json, sp, 0); +} + +/* Entry point to output panel's metadata. */ +static void +print_meta_data (GJSON * json, GHolder * h, int sp) +{ + int isp = 0, iisp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1, iisp = sp + 2; + + popen_obj_attr (json, "metadata", isp); + + pmeta_data_avgts (json, h->module, iisp); + pmeta_data_cumts (json, h->module, iisp); + pmeta_data_maxts (json, h->module, iisp); + pmeta_data_bw (json, h->module, iisp); + pmeta_data_visitors (json, h->module, iisp); + pmeta_data_hits (json, h->module, iisp); + pmeta_data_unique (json, h->ht_size, iisp); + + pclose_obj (json, isp, 0); +} + +/* A wrapper function to ouput data metrics per panel. */ +static void +print_json_block (GJSON * json, GMetrics * nmetrics, int sp) +{ + /* print hits */ + phits (json, nmetrics, sp); + /* print visitors */ + pvisitors (json, nmetrics, sp); + /* print bandwidth */ + pbw (json, nmetrics, sp); + + /* print time served metrics */ + pavgts (json, nmetrics, sp); + pcumts (json, nmetrics, sp); + pmaxts (json, nmetrics, sp); + + /* print protocol/method */ + pmethod (json, nmetrics, sp); + pprotocol (json, nmetrics, sp); + + /* data metric */ + pjson (json, "%.*s\"data\": \"", sp, TAB); + escape_json_output (json, nmetrics->data); + pjson (json, "\""); +} + +/* Add the given user agent value into our array of GAgents. + * + * On error, 1 is returned. + * On success, the user agent is added to the array and 0 is returned. */ +static int +fill_host_agents (void *val, void *user_data) +{ + GAgents *agents = user_data; + char *agent = ht_get_host_agent_val ((*(int *) val)); + + if (agent == NULL) + return 1; + + agents->items[agents->size].agent = agent; + agents->size++; + + return 0; +} + +/* Iterate over the list of agents */ +static void +load_host_agents (void *list, void *user_data, GO_UNUSED int count) +{ + GSLList *lst = list; + GAgents *agents = user_data; + + agents->items = new_gagent_item (count); + list_foreach (lst, fill_host_agents, agents); +} + +/* A wrapper function to ouput an array of user agents for each host. */ +static void +process_host_agents (GJSON * json, GHolderItem * item, int iisp) +{ + GAgents *agents = new_gagents (); + int i, n = 0, iiisp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + iiisp = iisp + 1; + + if (set_host_agents (item->metrics->data, load_host_agents, agents) == 1) + return; + + pjson (json, ",%.*s%.*s\"items\": [%.*s", nlines, NL, iisp, TAB, nlines, NL); + + n = agents->size > 10 ? 10 : agents->size; + for (i = 0; i < n; ++i) { + pjson (json, "%.*s\"", iiisp, TAB); + escape_json_output (json, agents->items[i].agent); + if (i == n - 1) + pjson (json, "\""); + else + pjson (json, "\",%.*s", nlines, NL); + } + + pclose_arr (json, iisp, 1); + + /* clean stuff up */ + free_agents_array (agents); +} + +/* A wrapper function to ouput children nodes. */ +static void +print_json_sub_items (GJSON * json, GHolderItem * item, GPercTotals totals, + int size, int iisp) +{ + GMetrics *nmetrics; + GSubItem *iter; + GSubList *sl = item->sub_list; + int i = 0, iiisp = 0, iiiisp = 0; + + /* no sub items, nothing to output */ + if (size == 0) + return; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + iiisp = iisp + 1, iiiisp = iiisp + 1; + + if (sl == NULL) + return; + + pjson (json, ",%.*s%.*s\"items\": [%.*s", nlines, NL, iisp, TAB, nlines, NL); + for (iter = sl->head; iter; iter = iter->next, i++) { + set_data_metrics (iter->metrics, &nmetrics, totals); + + popen_obj (json, iiisp); + print_json_block (json, nmetrics, iiiisp); + pclose_obj (json, iiisp, (i == sl->size - 1)); + free (nmetrics); + } + pclose_arr (json, iisp, 1); +} + +/* A wrapper function to ouput geolocation fields for the given host. */ +static void +print_json_host_geo (GJSON * json, GSubList * sl, int iisp) +{ + GSubItem *iter; + int i; + static const char *key[] = { + "country", + "city", + "hostname", + }; + + pjson (json, ",%.*s", nlines, NL); + + /* Iterate over child properties (country, city, etc) and print them out */ + for (i = 0, iter = sl->head; iter; iter = iter->next, i++) { + pjson (json, "%.*s\"%s\": \"", iisp, TAB, key[iter->metrics->id]); + escape_json_output (json, iter->metrics->data); + pjson (json, (i != sl->size - 1) ? "\",%.*s" : "\"", nlines, NL); + } +} + +/* Ouput Geolocation data and the IP's hostname. */ +static void +print_json_host_items (GJSON * json, GHolderItem * item, GPercTotals totals, + int size, int iisp) +{ + (void) totals; + /* print geolocation fields */ + if (size > 0 && item->sub_list != NULL) + print_json_host_geo (json, item->sub_list, iisp); + + /* print list of user agents */ + if (conf.list_agents) + process_host_agents (json, item, iisp); +} + +/* Ouput data and determine if there are children nodes. */ +static void +print_data_metrics (GJSON * json, GHolder * h, GPercTotals totals, int sp, + const struct GPanel_ *panel) +{ + GMetrics *nmetrics; + int i, isp = 0, iisp = 0, iiisp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1, iisp = sp + 2, iiisp = sp + 3; + + popen_arr_attr (json, "data", isp); + /* output data metrics */ + for (i = 0; i < h->idx; i++) { + set_data_metrics (h->items[i].metrics, &nmetrics, totals); + + /* open data metric block */ + popen_obj (json, iisp); + /* output data metric block */ + print_json_block (json, nmetrics, iiisp); + /* if there are children nodes, spit them out */ + if (panel->subitems) + panel->subitems (json, h->items + i, totals, h->sub_items_size, iiisp); + /* close data metric block */ + pclose_obj (json, iisp, (i == h->idx - 1)); + + free (nmetrics); + } + pclose_arr (json, isp, 1); +} + +/* Entry point to ouput data metrics per panel. */ +static void +print_json_data (GJSON * json, GHolder * h, GPercTotals totals, + const struct GPanel_ *panel) +{ + int sp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + sp = 1; + + /* output open panel attribute */ + popen_obj_attr (json, module_to_id (h->module), sp); + /* output panel metadata */ + print_meta_data (json, h, sp); + /* output panel data */ + print_data_metrics (json, h, totals, sp, panel); + /* output close panel attribute */ + pclose_obj (json, sp, 1); +} + +/* Get the number of available panels. + * + * On success, the total number of available panels is returned . */ +static int +num_panels (void) +{ + size_t idx = 0, npanels = 0; + + FOREACH_MODULE (idx, module_list) + npanels++; + + return npanels; +} + +/* Write to a buffer overall data. */ +static void +print_json_summary (GJSON * json, GLog * glog, GHolder * holder) +{ + int sp = 0, isp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + sp = 1, isp = 2; + + popen_obj_attr (json, GENER_ID, sp); + /* generated start/end date */ + poverall_start_end_date (json, holder, isp); + /* generated date time */ + poverall_datetime (json, isp); + /* total requests */ + poverall_requests (json, glog, isp); + /* valid requests */ + poverall_valid_reqs (json, glog, isp); + /* invalid requests */ + poverall_invalid_reqs (json, glog, isp); + /* generated time */ + poverall_processed_time (json, isp); + /* visitors */ + poverall_visitors (json, isp); + /* files */ + poverall_files (json, isp); + /* excluded hits */ + poverall_excluded (json, glog, isp); + /* referrers */ + poverall_refs (json, isp); + /* not found */ + poverall_notfound (json, isp); + /* static files */ + poverall_static_files (json, isp); + /* log size */ + poverall_log_size (json, isp); + /* bandwidth */ + poverall_bandwidth (json, glog, isp); + /* log path */ + poverall_log (json, isp); + pclose_obj (json, sp, num_panels () > 0 ? 0 : 1); +} + +/* Iterate over all panels and generate json output. */ +static GJSON * +init_json_output (GLog * glog, GHolder * holder) +{ + GJSON *json = NULL; + GModule module; + GPercTotals totals; + const GPanel *panel = NULL; + size_t idx = 0, npanels = num_panels (), cnt = 0; + + json = new_gjson (); + + popen_obj (json, 0); + print_json_summary (json, glog, holder); + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + if (!(panel = panel_lookup (module))) + continue; + + set_module_totals (module, &totals); + panel->render (json, holder + module, totals, panel); + pjson (json, (cnt++ != npanels - 1) ? ",%.*s" : "%.*s", nlines, NL); + } + + pclose_obj (json, 0, 1); + + return json; +} + +/* Open and write to a dynamically sized output buffer. + * + * On success, the newly allocated buffer is returned . */ +char * +get_json (GLog * glog, GHolder * holder, int escape_html) +{ + GJSON *json = NULL; + char *buf = NULL; + + if (holder == NULL) + return NULL; + + escape_html_output = escape_html; + if ((json = init_json_output (glog, holder)) && json->size > 0) { + buf = xstrdup (json->buf); + free_json (json); + } + + return buf; +} + +/* Entry point to generate a json report writing it to the fp */ +void +output_json (GLog * glog, GHolder * holder, const char *filename) +{ + GJSON *json = NULL; + FILE *fp; + + if (filename != NULL) + fp = fopen (filename, "w"); + else + fp = stdout; + + if (!fp) + FATAL ("Unable to open JSON file: %s.", strerror (errno)); + + /* use new lines to prettify output */ + if (conf.json_pretty_print) + nlines = 1; + + /* spit it out */ + if ((json = init_json_output (glog, holder)) && json->size > 0) { + fprintf (fp, "%s", json->buf); + free_json (json); + } + + fclose (fp); +} diff --git a/goaccess++/src/json.h b/goaccess++/src/json.h new file mode 100644 index 0000000..2d042f2 --- /dev/null +++ b/goaccess++/src/json.h @@ -0,0 +1,65 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef JSON_H_INCLUDED +#define JSON_H_INCLUDED + +#define TAB "\t\t\t\t\t\t\t\t\t\t\t" +#define NL "\n\n\n" + +#include "parser.h" + +typedef struct GJSON_ +{ + char *buf; /* pointer to buffer */ + size_t size; /* size of malloc'd buffer */ + size_t offset; /* current write offset */ +} GJSON; + +char *get_json (GLog * glog, GHolder * holder, int escape_html); + +void output_json (GLog * glog, GHolder * holder, const char *filename); +void set_json_nlines (int nl); + +void fpskeyival (FILE * fp, const char *key, int val, int sp, int last); +void fpskeysval (FILE * fp, const char *key, const char *val, int sp, int last); +void fpskeyaval (FILE * fp, const char *key, const char *val, int sp, int last); + +void fpclose_arr (FILE * fp, int sp, int last); +void fpclose_obj (FILE * fp, int iisp, int last); +void fpjson (FILE * fp, const char *fmt, ...); +void fpopen_arr_attr (FILE * fp, const char *attr, int sp); +void fpopen_obj_attr (FILE * fp, const char *attr, int sp); +void fpopen_obj (FILE * fp, int iisp); + +#endif diff --git a/goaccess++/src/json.o b/goaccess++/src/json.o new file mode 100644 index 0000000..1094e7c Binary files /dev/null and b/goaccess++/src/json.o differ diff --git a/goaccess++/src/khash.h b/goaccess++/src/khash.h new file mode 100644 index 0000000..0708bd5 --- /dev/null +++ b/goaccess++/src/khash.h @@ -0,0 +1,675 @@ +/* The MIT License + + Copyright (c) 2008, 2009, 2011 by Attractive Chaos <attractor@live.co.uk> + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + An example: + +#include "khash.h" +KHASH_MAP_INIT_INT(32, char) +int main() { + int ret, is_missing; + khiter_t k; + khash_t(32) *h = kh_init(32); + k = kh_put(32, h, 5, &ret); + kh_value(h, k) = 10; + k = kh_get(32, h, 10); + is_missing = (k == kh_end(h)); + k = kh_get(32, h, 5); + kh_del(32, h, k); + for (k = kh_begin(h); k != kh_end(h); ++k) + if (kh_exist(h, k)) kh_value(h, k) = 1; + kh_destroy(32, h); + return 0; +} +*/ + +/* + 2013-05-02 (0.2.8): + + * Use quadratic probing. When the capacity is power of 2, stepping function + i*(i+1)/2 guarantees to traverse each bucket. It is better than double + hashing on cache performance and is more robust than linear probing. + + In theory, double hashing should be more robust than quadratic probing. + However, my implementation is probably not for large hash tables, because + the second hash function is closely tied to the first hash function, + which reduce the effectiveness of double hashing. + + Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php + + 2011-12-29 (0.2.7): + + * Minor code clean up; no actual effect. + + 2011-09-16 (0.2.6): + + * The capacity is a power of 2. This seems to dramatically improve the + speed for simple keys. Thank Zilong Tan for the suggestion. Reference: + + - http://code.google.com/p/ulib/ + - http://nothings.org/computer/judy/ + + * Allow to optionally use linear probing which usually has better + performance for random input. Double hashing is still the default as it + is more robust to certain non-random input. + + * Added Wang's integer hash function (not used by default). This hash + function is more robust to certain non-random input. + + 2011-02-14 (0.2.5): + + * Allow to declare global functions. + + 2009-09-26 (0.2.4): + + * Improve portability + + 2008-09-19 (0.2.3): + + * Corrected the example + * Improved interfaces + + 2008-09-11 (0.2.2): + + * Improved speed a little in kh_put() + + 2008-09-10 (0.2.1): + + * Added kh_clear() + * Fixed a compiling error + + 2008-09-02 (0.2.0): + + * Changed to token concatenation which increases flexibility. + + 2008-08-31 (0.1.2): + + * Fixed a bug in kh_get(), which has not been tested previously. + + 2008-08-31 (0.1.1): + + * Added destructor +*/ + + +#ifndef __AC_KHASH_H +#define __AC_KHASH_H + +/*! + @header + + Generic hash table library. + */ + +#define AC_VERSION_KHASH_H "0.2.8" + +#include <stdlib.h> +#include <string.h> +#include <limits.h> + +/* compiler specific configuration */ + +#if UINT_MAX == 0xffffffffu +typedef unsigned int khint32_t; +#elif ULONG_MAX == 0xffffffffu +typedef unsigned long khint32_t; +#endif + +#if ULONG_MAX == ULLONG_MAX +typedef unsigned long khint64_t; +#else +typedef unsigned long long khint64_t; +#endif + +#ifndef kh_inline +#ifdef _MSC_VER +#define kh_inline __inline +#else +#define kh_inline inline +#endif +#endif /* kh_inline */ + +#ifndef klib_unused +#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3) +#define klib_unused __attribute__ ((__unused__)) +#else +#define klib_unused +#endif +#endif /* klib_unused */ + +typedef khint32_t khint_t; +typedef khint_t khiter_t; + +#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) +#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) +#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) +#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) +#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) +#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) +#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) + +#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#ifndef kcalloc +#define kcalloc(N,Z) calloc(N,Z) +#endif +#ifndef kmalloc +#define kmalloc(Z) malloc(Z) +#endif +#ifndef krealloc +#define krealloc(P,Z) realloc(P,Z) +#endif +#ifndef kfree +#define kfree(P) free(P) +#endif + +static const double __ac_HASH_UPPER = 0.77; + +#define __KHASH_TYPE(name, khkey_t, khval_t) \ + typedef struct kh_##name##_s { \ + khint_t n_buckets, size, n_occupied, upper_bound; \ + khint32_t *flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; + +#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ + extern kh_##name##_t *kh_init_##name(void); \ + extern void kh_destroy_##name(kh_##name##_t *h); \ + extern void kh_clear_##name(kh_##name##_t *h); \ + extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ + extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ + extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ + extern void kh_del_##name(kh_##name##_t *h, khint_t x); \ + +#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + SCOPE kh_##name##_t *kh_init_##name(void) { \ + return (kh_##name##_t*) kcalloc(1, sizeof(kh_##name##_t)); \ + } \ + SCOPE void kh_destroy_##name(kh_##name##_t *h) \ + { \ + if (h) { \ + kfree ((void *) h->keys); \ + kfree (h->flags); \ + kfree ((void *) h->vals); \ + kfree (h); \ + } \ + } \ + SCOPE void kh_clear_##name(kh_##name##_t *h) \ + { \ + if (h && h->flags) { \ + memset (h->flags, 0xaa, __ac_fsize (h->n_buckets) * sizeof (khint32_t)); \ + h->size = h->n_occupied = 0; \ + } \ + } \ + SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ + { \ + if (h->n_buckets) { \ + khint_t k, i, last, mask, step = 0; \ + mask = h->n_buckets - 1; \ + k = __hash_func (key); \ + i = k & mask; \ + last = i; \ + while (!__ac_isempty (h->flags, i) && \ + (__ac_isdel (h->flags, i) || !__hash_equal (h->keys[i], key))) { \ + i = (i + (++step)) & mask; \ + if (i == last) \ + return h->n_buckets; \ + } \ + return __ac_iseither (h->flags, i) ? h->n_buckets : i; \ + } else \ + return 0; \ + } \ + SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ + { \ + /* This function uses 0.25*n_buckets bytes of working space instead of */ \ + /* [sizeof(key_t+val_t)+.25]*n_buckets. */ \ + khint32_t *new_flags = 0; \ + khint_t j = 1; \ + { \ + kroundup32 (new_n_buckets); \ + if (new_n_buckets < 4) \ + new_n_buckets = 4; \ + if (h->size >= (khint_t) (new_n_buckets * __ac_HASH_UPPER + 0.5)) \ + j = 0; /* requested size is too small */ \ + else { /* hash table size to be changed (shrink or expand); rehash */ \ + new_flags = (khint32_t *) kmalloc (__ac_fsize (new_n_buckets) * sizeof (khint32_t)); \ + if (!new_flags) \ + return -1; \ + memset (new_flags, 0xaa, __ac_fsize (new_n_buckets) * sizeof (khint32_t)); \ + if (h->n_buckets < new_n_buckets) { /* expand */ \ + khkey_t *new_keys = (khkey_t *) krealloc ((void *) h->keys, new_n_buckets * sizeof (khkey_t)); \ + if (!new_keys) { \ + kfree (new_flags); \ + return -1; \ + } \ + h->keys = new_keys; \ + if (kh_is_map) { \ + khval_t *new_vals = (khval_t *) krealloc ((void *) h->vals, new_n_buckets * sizeof (khval_t)); \ + if (!new_vals) { \ + kfree (new_flags); \ + return -1; \ + } \ + h->vals = new_vals; \ + } \ + } /* otherwise shrink */ \ + } \ + } \ + if (j) { /* rehashing is needed */ \ + for (j = 0; j != h->n_buckets; ++j) { \ + if (__ac_iseither (h->flags, j) == 0) { \ + khkey_t key = h->keys[j]; \ + khval_t val; \ + khint_t new_mask; \ + new_mask = new_n_buckets - 1; \ + if (kh_is_map) \ + val = h->vals[j]; \ + __ac_set_isdel_true (h->flags, j); \ + while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \ + khint_t k, i, step = 0; \ + k = __hash_func (key); \ + i = k & new_mask; \ + while (!__ac_isempty (new_flags, i)) \ + i = (i + (++step)) & new_mask; \ + __ac_set_isempty_false (new_flags, i); \ + if (i < h->n_buckets && __ac_iseither (h->flags, i) == 0) { /* kick out the existing element */ \ + { \ + khkey_t tmp = h->keys[i]; \ + h->keys[i] = key; \ + key = tmp; \ + } \ + if (kh_is_map) { \ + khval_t tmp = h->vals[i]; \ + h->vals[i] = val; \ + val = tmp; \ + } \ + __ac_set_isdel_true (h->flags, i); /* mark it as deleted in the old hash table */ \ + } else { /* write the element and jump out of the loop */ \ + h->keys[i] = key; \ + if (kh_is_map) \ + h->vals[i] = val; \ + break; \ + } \ + } \ + } \ + } \ + if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ + h->keys = (khkey_t *) krealloc ((void *) h->keys, new_n_buckets * sizeof (khkey_t)); \ + if (kh_is_map) \ + h->vals = (khval_t *) krealloc ((void *) h->vals, new_n_buckets * sizeof (khval_t)); \ + } \ + kfree (h->flags); /* free the working space */ \ + h->flags = new_flags; \ + h->n_buckets = new_n_buckets; \ + h->n_occupied = h->size; \ + h->upper_bound = (khint_t) (h->n_buckets * __ac_HASH_UPPER + 0.5); \ + } \ + return 0; \ + } \ + SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ + { \ + khint_t x; \ + if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ + if (h->n_buckets > (h->size << 1)) { \ + if (kh_resize_##name (h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ + *ret = -1; \ + return h->n_buckets; \ + } \ + } else if (kh_resize_##name (h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ + *ret = -1; \ + return h->n_buckets; \ + } \ + } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ + { \ + khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ + x = site = h->n_buckets; \ + k = __hash_func (key); \ + i = k & mask; \ + if (__ac_isempty (h->flags, i)) \ + x = i; /* for speed up */ \ + else { \ + last = i; \ + while (!__ac_isempty (h->flags, i) && (__ac_isdel (h->flags, i) || !__hash_equal (h->keys[i], key))) { \ + if (__ac_isdel (h->flags, i)) \ + site = i; \ + i = (i + (++step)) & mask; \ + if (i == last) { \ + x = site; \ + break; \ + } \ + } \ + if (x == h->n_buckets) { \ + if (__ac_isempty (h->flags, i) && site != h->n_buckets) \ + x = site; \ + else \ + x = i; \ + } \ + } \ + } \ + if (__ac_isempty (h->flags, x)) { /* not present at all */ \ + h->keys[x] = key; \ + __ac_set_isboth_false (h->flags, x); \ + ++h->size; \ + ++h->n_occupied; \ + *ret = 1; \ + } else if (__ac_isdel (h->flags, x)) { /* deleted */ \ + h->keys[x] = key; \ + __ac_set_isboth_false (h->flags, x); \ + ++h->size; \ + *ret = 2; \ + } else \ + *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ + return x; \ + } \ + SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ + { \ + if (x != h->n_buckets && !__ac_iseither (h->flags, x)) { \ + __ac_set_isdel_true (h->flags, x); \ + --h->size; \ + } \ + } \ + +#define KHASH_DECLARE(name, khkey_t, khval_t) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_PROTOTYPES(name, khkey_t, khval_t) + +#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) + +#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + +/* --- BEGIN OF HASH FUNCTIONS --- */ + +/*! @function + @abstract Integer hash function + @param key The integer [khint32_t] + @return The hash value [khint_t] + */ +#define kh_int_hash_func(key) (khint32_t)(key) +/*! @function + @abstract Integer comparison function + */ +#define kh_int_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract 64-bit integer hash function + @param key The integer [khint64_t] + @return The hash value [khint_t] + */ +#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) +/*! @function + @abstract 64-bit integer comparison function + */ +#define kh_int64_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract const char* hash function + @param s Pointer to a null terminated string + @return The hash value + */ +static kh_inline khint_t +__ac_X31_hash_string (const char *s) +{ + khint_t h = (khint_t) * s; + if (h) + for (++s; *s; ++s) + h = (h << 5) - h + (khint_t) * s; + return h; +} + +/*! @function + @abstract Another interface to const char* hash function + @param key Pointer to a null terminated string [const char*] + @return The hash value [khint_t] + */ +#define kh_str_hash_func(key) __ac_X31_hash_string(key) +/*! @function + @abstract Const char* comparison function + */ +#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) + +static kh_inline khint_t +__ac_Wang_hash (khint_t key) +{ + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; +} + +#define kh_int_hash_func2(k) __ac_Wang_hash((khint_t)key) + +/* --- END OF HASH FUNCTIONS --- */ + +/* Other convenient macros... */ + +/*! + @abstract Type of the hash table. + @param name Name of the hash table [symbol] + */ +#define khash_t(name) kh_##name##_t + +/*! @function + @abstract Initiate a hash table. + @param name Name of the hash table [symbol] + @return Pointer to the hash table [khash_t(name)*] + */ +#define kh_init(name) kh_init_##name() + +/*! @function + @abstract Destroy a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_destroy(name, h) kh_destroy_##name(h) + +/*! @function + @abstract Reset a hash table without deallocating memory. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_clear(name, h) kh_clear_##name(h) + +/*! @function + @abstract Resize a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param s New size [khint_t] + */ +#define kh_resize(name, h, s) kh_resize_##name(h, s) + +/*! @function + @abstract Insert a key to the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @param r Extra return code: -1 if the operation failed; + 0 if the key is present in the hash table; + 1 if the bucket is empty (never used); 2 if the element in + the bucket has been deleted [int*] + @return Iterator to the inserted element [khint_t] + */ +#define kh_put(name, h, k, r) kh_put_##name(h, k, r) + +/*! @function + @abstract Retrieve a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] + */ +#define kh_get(name, h, k) kh_get_##name(h, k) + +/*! @function + @abstract Remove a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Iterator to the element to be deleted [khint_t] + */ +#define kh_del(name, h, k) kh_del_##name(h, k) + +/*! @function + @abstract Test whether a bucket contains data. + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return 1 if containing data; 0 otherwise [int] + */ +#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) + +/*! @function + @abstract Get key given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Key [type of keys] + */ +#define kh_key(h, x) ((h)->keys[x]) + +/*! @function + @abstract Get value given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Value [type of values] + @discussion For hash sets, calling this results in segfault. + */ +#define kh_val(h, x) ((h)->vals[x]) + +/*! @function + @abstract Alias of kh_val() + */ +#define kh_value(h, x) ((h)->vals[x]) + +/*! @function + @abstract Get the start iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The start iterator [khint_t] + */ +#define kh_begin(h) (khint_t)(0) + +/*! @function + @abstract Get the end iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The end iterator [khint_t] + */ +#define kh_end(h) ((h)->n_buckets) + +/*! @function + @abstract Get the number of elements in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of elements in the hash table [khint_t] + */ +#define kh_size(h) ((h)->size) + +/*! @function + @abstract Get the number of buckets in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of buckets in the hash table [khint_t] + */ +#define kh_n_buckets(h) ((h)->n_buckets) + +/*! @function + @abstract Iterate over the entries in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param kvar Variable to which key will be assigned + @param vvar Variable to which value will be assigned + @param code Block of code to execute + */ +#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h,__i)) continue; \ + (kvar) = kh_key(h,__i); \ + (vvar) = kh_val(h,__i); \ + code; \ + } } + +/*! @function + @abstract Iterate over the values in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param vvar Variable to which value will be assigned + @param code Block of code to execute + */ +#define kh_foreach_value(h, vvar, code) { khint_t __i; \ + for (__i = kh_begin (h); __i != kh_end (h); ++__i) { \ + if (!kh_exist (h, __i)) \ + continue; \ + (vvar) = kh_val (h, __i); \ + code; \ + } } + +/* More conenient interfaces */ + +/*! @function + @abstract Instantiate a hash set containing integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT(name) \ + KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT(name, khval_t) \ + KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT64(name) \ + KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT64(name, khval_t) \ + KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) + +typedef const char *kh_cstr_t; +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_STR(name) \ + KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_STR(name, khval_t) \ + KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) + +#endif /* __AC_KHASH_H */ diff --git a/goaccess++/src/labels.h b/goaccess++/src/labels.h new file mode 100644 index 0000000..1022d83 --- /dev/null +++ b/goaccess++/src/labels.h @@ -0,0 +1,497 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef LABELS_H_INCLUDED +#define LABELS_H_INCLUDED + +#include <libintl.h> + +#define _(String) dgettext (PACKAGE , String) +#define gettext_noop(String) String +#define N_(String) gettext_noop (String) + +/* global lang attribute */ +#define DOC_LANG _( "en") + +/* General */ +#define GEN_EXPAND_PANEL _( "Exp. Panel") +#define GEN_HELP _( "Help") +#define GEN_QUIT _( "Quit") +#define GEN_TOTAL _( "Total") + +/* Sort Labels */ +#define SORT_ASC_SEL _( "[x] ASC [ ] DESC") +#define SORT_DESC_SEL _( "[ ] ASC [x] DESC") + +/* Overall Stats Labels */ +#define T_ACTIVE_PANEL _("[Active Panel: %1$s]") +#define T_QUIT _("[q]uit GoAccess") +#define T_HELP_ENTER _("[?] Help [Enter] Exp. Panel") +#define T_DASH _( "Dashboard") +#define T_DASH_HEAD _( "Dashboard - Overall Analyzed Requests") +#define T_HEAD N_( "Overall Analyzed Requests") + +#define T_BW _( "Tx. Amount") +#define T_DATETIME _( "Date/Time") +#define T_EXCLUDE_IP _( "Excl. IP Hits") +#define T_FAILED _( "Failed Requests") +#define T_GEN_TIME _( "Init. Proc. Time") +#define T_LOG _( "Log Size") +#define T_LOG_PATH _( "Log Source") +#define T_REFERRER _( "Referrers") +#define T_REQUESTS _( "Total Requests") +#define T_STATIC_FILES _( "Static Files") +#define T_UNIQUE404 _( "Not Found") +#define T_UNIQUE_FILES _( "Requested Files") +#define T_UNIQUE_VISITORS _( "Unique Visitors") +#define T_VALID _( "Valid Requests") + +/* Metric Labels */ +#define MTRC_HITS_LBL _( "Hits") +#define MTRC_HITS_PERC_LBL _( "h%") +#define MTRC_VISITORS_LBL _( "Visitors") +#define MTRC_VISITORS_SHORT_LBL _( "Vis.") +#define MTRC_VISITORS_PERC_LBL _( "v%") +#define MTRC_BW_LBL _( "Tx. Amount") +#define MTRC_AVGTS_LBL _( "Avg. T.S.") +#define MTRC_CUMTS_LBL _( "Cum. T.S.") +#define MTRC_MAXTS_LBL _( "Max. T.S.") +#define MTRC_METHODS_LBL _( "Method") +#define MTRC_METHODS_SHORT_LBL _( "Mtd") +#define MTRC_PROTOCOLS_LBL _( "Protocol") +#define MTRC_PROTOCOLS_SHORT_LBL _( "Proto") +#define MTRC_CITY_LBL _( "City") +#define MTRC_COUNTRY_LBL _( "Country") +#define MTRC_HOSTNAME_LBL _( "Hostname") +#define MTRC_DATA_LBL _( "Data") + +#define HTML_PLOT_HITS_VIS _( "Hits/Visitors") + +/* Panel Labels and Descriptions */ +#define VISITORS_HEAD \ + N_("Unique visitors per day") +#define VISITORS_HEAD_BOTS \ + N_("Unique visitors per day - Including spiders") +#define VISITORS_DESC \ + N_("Hits having the same IP, date and agent are a unique visit.") +#define VISITORS_LABEL \ + N_("Visitors") + +#define REQUESTS_HEAD \ + N_("Requested Files (URLs)") +#define REQUESTS_DESC \ + N_("Top requests sorted by hits [, avgts, cumts, maxts, mthd, proto]") +#define REQUESTS_LABEL \ + N_("Requests") + +#define REQUESTS_STATIC_HEAD \ + N_("Static Requests") +#define REQUESTS_STATIC_DESC \ + N_("Top static requests sorted by hits [, avgts, cumts, maxts, mthd, proto]") +#define REQUESTS_STATIC_LABEL \ + N_("Static Requests") + +#define VISIT_TIMES_HEAD \ + N_("Time Distribution") +#define VISIT_TIMES_DESC \ + N_("Data sorted by hour [, avgts, cumts, maxts]") +#define VISIT_TIMES_LABEL \ + N_("Time") + +#define VIRTUAL_HOSTS_HEAD \ + N_("Virtual Hosts") +#define VIRTUAL_HOSTS_DESC \ + N_("Data sorted by hits [, avgts, cumts, maxts]") +#define VIRTUAL_HOSTS_LABEL \ + N_("Virtual Hosts") + +#define REMOTE_USER_HEAD \ + N_("Remote User (HTTP authentication)") +#define REMOTE_USER_DESC \ + N_("Data sorted by hits [, avgts, cumts, maxts]") +#define REMOTE_USER_LABEL \ + N_("Remote User") + +#define NOT_FOUND_HEAD \ + N_("Not Found URLs (404s)") +#define NOT_FOUND_DESC \ + N_("Top not found URLs sorted by hits [, avgts, cumts, maxts, mthd, proto]") +#define NOT_FOUND_LABEL \ + N_("Not Found") + +#define HOSTS_HEAD \ + N_("Visitor Hostnames and IPs") +#define HOSTS_DESC \ + N_("Top visitor hosts sorted by hits [, avgts, cumts, maxts]") +#define HOSTS_LABEL \ + N_("Hosts") + +#define OS_HEAD \ + N_("Operating Systems") +#define OS_DESC \ + N_("Top Operating Systems sorted by hits [, avgts, cumts, maxts]") +#define OS_LABEL \ + N_("OS") + +#define BROWSERS_HEAD \ + N_("Browsers") +#define BROWSERS_DESC \ + N_("Top Browsers sorted by hits [, avgts, cumts, maxts]") +#define BROWSERS_LABEL \ + N_("Browsers") + +#define REFERRERS_HEAD \ + N_("Referrers URLs") +#define REFERRERS_DESC \ + N_("Top Requested Referrers sorted by hits [, avgts, cumts, maxts]") +#define REFERRERS_LABEL \ + N_("Referrers") + +#define REFERRING_SITES_HEAD \ + N_("Referring Sites") +#define REFERRING_SITES_DESC \ + N_("Top Referring Sites sorted by hits [, avgts, cumts, maxts]") +#define REFERRING_SITES_LABEL \ + N_("Referring Sites") + +#define KEYPHRASES_HEAD \ + N_("Keyphrases from Google's search engine") +#define KEYPHRASES_DESC \ + N_("Top Keyphrases sorted by hits [, avgts, cumts, maxts]") +#define KEYPHRASES_LABEL \ + N_("Keyphrases") + +#define GEO_LOCATION_HEAD \ + N_("Geo Location") +#define GEO_LOCATION_DESC \ + N_("Continent > Country sorted by unique hits [, avgts, cumts, maxts]") +#define GEO_LOCATION_LABEL \ + N_("Geo Location") + +#define STATUS_CODES_HEAD \ + N_("HTTP Status Codes") +#define STATUS_CODES_DESC \ + N_("Top HTTP Status Codes sorted by hits [, avgts, cumts, maxts]") +#define STATUS_CODES_LABEL \ + N_("Status Codes") + +/* Find Labels */ +#define CISENSITIVE \ + _("[ ] case sensitive") +#define CSENSITIVE \ + _("[x] case sensitive") +#define FIND_DESC \ + _("Regex allowed - ^g to cancel - TAB switch case") +#define FIND_HEAD \ + _("Find pattern in all views") + +/* Config Dialog */ +#define CONFDLG_HEAD \ + _("Log Format Configuration") +#define CONFDLG_KEY_HINTS \ + _("[SPACE] to toggle - [ENTER] to proceed - [q] to quit") +#define CONFDLG_LOG_FORMAT \ + _("Log Format - [c] to add/edit format") +#define CONFDLG_DATE_FORMAT \ + _("Date Format - [d] to add/edit format") +#define CONFDLG_TIME_FORMAT \ + _("Time Format - [t] to add/edit format") +#define CONFDLG_DESC \ + _("[UP/DOWN] to scroll - [q] to close window") + +/* Agents Dialog */ +#define AGENTSDLG_DESC \ + _("[UP/DOWN] to scroll - [q] to close window") +#define AGENTSDLG_HEAD \ + _("User Agents for %1$s") + +/* Color Scheme Dialog */ +#define SCHEMEDLG_HEAD \ + _("Scheme Configuration") +#define SCHEMEDLG_DESC \ + _("[ENTER] to use scheme - [q]uit") + +/* Sort Dialog */ +#define SORTDLG_HEAD \ + _("Sort active module by") +#define SORTDLG_DESC \ + _("[ENTER] select - [TAB] sort - [q]uit") + +/* Help TUI Dialog */ +#define HELPDLG_HEAD \ + _("GoAccess Quick Help") +#define HELPDLG_DESC \ + _("[UP/DOWN] to scroll - [q] to quit") + +/* Storage Built-in Option */ +#define BUILT_WITH_TCBTREE \ + _("Built using Tokyo Cabinet on-disk B+ Tree.") +#define BUILT_WITH_TCMEMHASH \ + _("Built using Tokyo Cabinet in-memory hash database.") +#define BUILT_WITH_DEFHASH \ + _("Built using the default in-memory hash database.") + +/* Common UI Errors */ +#define ERR_FORMAT_HEADER \ + _("Format Errors - Verify your log/date/time format") +#define ERR_FORMAT_NO_DATE_FMT \ + _("No date format was found on your conf file.") +#define ERR_FORMAT_NO_LOG_FMT \ + _("No log format was found on your conf file.") +#define ERR_FORMAT_NO_TIME_FMT \ + _("No time format was found on your conf file.") +#define ERR_NODEF_CONF_FILE \ + _("No default config file found.") +#define ERR_NODEF_CONF_FILE_DESC \ + _("You may specify one with") +#define ERR_PARSED_NLINES_DESC \ + _("producing the following errors") +#define ERR_PARSED_NLINES \ + _("Parsed %1$d lines") +#define ERR_PLEASE_REPORT \ + _("Please report it by opening an issue on GitHub") +#define ERR_FORMAT_NO_TIME_FMT_DLG \ + _("Select a time format.") +#define ERR_FORMAT_NO_DATE_FMT_DLG \ + _("Select a date format.") +#define ERR_FORMAT_NO_LOG_FMT_DLG \ + _("Select a log format.") +#define ERR_PANEL_DISABLED \ + _("'%1$s' panel is disabled") + +/* Other */ +#define INFO_MORE_INFO \ + _("For more details visit") +#define INFO_LAST_UPDATED \ + _("Last Updated") +#define INFO_WS_READY_FOR_CONN \ + _("WebSocket server ready to accept new client connections") + +#define INFO_HELP_FOLLOWING_OPTS \ + _("The following options can also be supplied to the command") +#define INFO_HELP_EXAMPLES \ + _("Examples can be found by running") + +#define HTML_REPORT_TITLE \ + _( "Server Statistics") +#define HTML_REPORT_NAV_THEME \ + N_("Theme") +#define HTML_REPORT_NAV_DARK_GRAY \ + N_("Dark Gray") +#define HTML_REPORT_NAV_BRIGHT \ + N_("Bright") +#define HTML_REPORT_NAV_DARK_BLUE \ + N_("Dark Blue") +#define HTML_REPORT_NAV_DARK_PURPLE \ + N_("Dark Purple") +#define HTML_REPORT_NAV_PANELS \ + N_("Panels") +#define HTML_REPORT_NAV_ITEMS_PER_PAGE \ + N_("Items per Page") +#define HTML_REPORT_NAV_TABLES \ + N_("Tables") +#define HTML_REPORT_NAV_DISPLAY_TABLES \ + N_("Display Tables") +#define HTML_REPORT_NAV_AH_SMALL \ + N_("Auto-Hide on Small Devices") +#define HTML_REPORT_NAV_AH_SMALL_TITLE \ + N_("Automatically hide tables on small screen devices") +#define HTML_REPORT_NAV_LAYOUT \ + N_("Layout") +#define HTML_REPORT_NAV_HOR \ + N_("Horizontal") +#define HTML_REPORT_NAV_VER \ + N_("Vertical") +#define HTML_REPORT_NAV_FILE_OPTS \ + N_("File Options") +#define HTML_REPORT_NAV_EXPORT_JSON \ + N_("Export as JSON") +#define HTML_REPORT_PANEL_PANEL_OPTS \ + N_("Panel Options") +#define HTML_REPORT_PANEL_PREVIOUS \ + N_("Previous") +#define HTML_REPORT_PANEL_NEXT \ + N_("Next") +#define HTML_REPORT_PANEL_FIRST \ + N_("First") +#define HTML_REPORT_PANEL_LAST \ + N_("Last") +#define HTML_REPORT_PANEL_CHART_OPTS \ + N_("Chart Options") +#define HTML_REPORT_PANEL_CHART \ + N_("Chart") +#define HTML_REPORT_PANEL_TYPE \ + N_("Type") +#define HTML_REPORT_PANEL_AREA_SPLINE \ + N_("Area Spline") +#define HTML_REPORT_PANEL_BAR \ + N_("Bar") +#define HTML_REPORT_PANEL_PLOT_METRIC \ + N_("Plot Metric") +#define HTML_REPORT_PANEL_TABLE_COLS \ + N_("Table Columns") + +/* Status Codes */ +#define STATUS_CODE_1XX \ + N_("1xx Informational") +#define STATUS_CODE_2XX \ + N_("2xx Success") +#define STATUS_CODE_3XX \ + N_("3xx Redirection") +#define STATUS_CODE_4XX \ + N_("4xx Client Errors") +#define STATUS_CODE_5XX \ + N_("5xx Server Errors") + +#define STATUS_CODE_100 \ + N_("100 - Continue: Server received the initial part of the request") +#define STATUS_CODE_101 \ + N_("101 - Switching Protocols: Client asked to switch protocols") +#define STATUS_CODE_200 \ + N_("200 - OK: The request sent by the client was successful") +#define STATUS_CODE_201 \ + N_("201 - Created: The request has been fulfilled and created") +#define STATUS_CODE_202 \ + N_("202 - Accepted: The request has been accepted for processing") +#define STATUS_CODE_203 \ + N_("203 - Non-authoritative Information: Response from a third party") +#define STATUS_CODE_204 \ + N_("204 - No Content: Request did not return any content") +#define STATUS_CODE_205 \ + N_("205 - Reset Content: Server asked the client to reset the document") +#define STATUS_CODE_206 \ + N_("206 - Partial Content: The partial GET has been successful") +#define STATUS_CODE_207 \ + N_("207 - Multi-Status: WebDAV; RFC 4918") +#define STATUS_CODE_208 \ + N_("208 - Already Reported: WebDAV; RFC 5842") +#define STATUS_CODE_300 \ + N_("300 - Multiple Choices: Multiple options for the resource") +#define STATUS_CODE_301 \ + N_("301 - Moved Permanently: Resource has permanently moved") +#define STATUS_CODE_302 \ + N_("302 - Moved Temporarily (redirect)") +#define STATUS_CODE_303 \ + N_("303 - See Other Document: The response is at a different URI") +#define STATUS_CODE_304 \ + N_("304 - Not Modified: Resource has not been modified") +#define STATUS_CODE_305 \ + N_("305 - Use Proxy: Can only be accessed through the proxy") +#define STATUS_CODE_307 \ + N_("307 - Temporary Redirect: Resource temporarily moved") +#define STATUS_CODE_400 \ + N_("400 - Bad Request: The syntax of the request is invalid") +#define STATUS_CODE_401 \ + N_("401 - Unauthorized: Request needs user authentication") +#define STATUS_CODE_402 \ + N_("402 - Payment Required") +#define STATUS_CODE_403 \ + N_("403 - Forbidden: Server is refusing to respond to it") +#define STATUS_CODE_404 \ + N_("404 - Not Found: Requested resource could not be found") +#define STATUS_CODE_405 \ + N_("405 - Method Not Allowed: Request method not supported") +#define STATUS_CODE_406 \ + N_("406 - Not Acceptable") +#define STATUS_CODE_407 \ + N_("407 - Proxy Authentication Required") +#define STATUS_CODE_408 \ + N_("408 - Request Timeout: Server timed out waiting for the request") +#define STATUS_CODE_409 \ + N_("409 - Conflict: Conflict in the request") +#define STATUS_CODE_410 \ + N_("410 - Gone: Resource requested is no longer available") +#define STATUS_CODE_411 \ + N_("411 - Length Required: Invalid Content-Length") +#define STATUS_CODE_412 \ + N_("412 - Precondition Failed: Server does not meet preconditions") +#define STATUS_CODE_413 \ + N_("413 - Payload Too Large") +#define STATUS_CODE_414 \ + N_("414 - Request-URI Too Long") +#define STATUS_CODE_415 \ + N_("415 - Unsupported Media Type: Media type is not supported") +#define STATUS_CODE_416 \ + N_("416 - Requested Range Not Satisfiable: Cannot supply that portion") +#define STATUS_CODE_417 \ + N_("417 - Expectation Failed") +#define STATUS_CODE_421 \ + N_("421 - Misdirected Request") +#define STATUS_CODE_422 \ + N_("422 - Unprocessable Entity due to semantic errors: WebDAV") +#define STATUS_CODE_423 \ + N_("423 - The resource that is being accessed is locked") +#define STATUS_CODE_424 \ + N_("424 - Failed Dependency: WebDAV") +#define STATUS_CODE_426 \ + N_("426 - Upgrade Required: Client should switch to a different protocol") +#define STATUS_CODE_428 \ + N_("428 - Precondition Required") +#define STATUS_CODE_429 \ + N_("429 - Too Many Requests: The user has sent too many requests") +#define STATUS_CODE_431 \ + N_("431 - Request Header Fields Too Large") +#define STATUS_CODE_451 \ + N_("451 - Unavailable For Legal Reasons") +#define STATUS_CODE_444 \ + N_("444 - (Nginx) Connection closed without sending any headers") +#define STATUS_CODE_494 \ + N_("494 - (Nginx) Request Header Too Large") +#define STATUS_CODE_495 \ + N_("495 - (Nginx) SSL client certificate error") +#define STATUS_CODE_496 \ + N_("496 - (Nginx) Client didn't provide certificate") +#define STATUS_CODE_497 \ + N_("497 - (Nginx) HTTP request sent to HTTPS port") +#define STATUS_CODE_499 \ + N_("499 - (Nginx) Connection closed by client while processing request") +#define STATUS_CODE_500 \ + N_("500 - Internal Server Error") +#define STATUS_CODE_501 \ + N_("501 - Not Implemented") +#define STATUS_CODE_502 \ + N_("502 - Bad Gateway: Received an invalid response from the upstream") +#define STATUS_CODE_503 \ + N_("503 - Service Unavailable: The server is currently unavailable") +#define STATUS_CODE_504 \ + N_("504 - Gateway Timeout: The upstream server failed to send request") +#define STATUS_CODE_505 \ + N_("505 - HTTP Version Not Supported") +#define STATUS_CODE_520 \ + N_("520 - CloudFlare - Web server is returning an unknown error") +#define STATUS_CODE_521 \ + N_("521 - CloudFlare - Web server is down") +#define STATUS_CODE_522 \ + N_("522 - CloudFlare - Connection timed out") +#define STATUS_CODE_523 \ + N_("523 - CloudFlare - Origin is unreachable") +#define STATUS_CODE_524 \ + N_("524 - CloudFlare - A timeout occurred") + +#endif // for #ifndef LABELS_H diff --git a/goaccess++/src/opesys.c b/goaccess++/src/opesys.c new file mode 100644 index 0000000..98c6c02 --- /dev/null +++ b/goaccess++/src/opesys.c @@ -0,0 +1,398 @@ +/** + * opesys.c -- functions for dealing with operating systems + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include <ctype.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stddef.h> + +#include "opesys.h" + +#include "settings.h" +#include "util.h" +#include "xmalloc.h" + +/* ###NOTE: The size of the list is proportional to the run time, + * which makes this pretty slow */ + +/* {"search string", "belongs to"} */ +static const char *os[][2] = { + {"Android", "Android"}, + {"Windows NT 10.0", "Windows"}, + {"Windows NT 6.3; ARM", "Windows"}, + {"Windows NT 6.3", "Windows"}, + {"Windows NT 6.2; ARM", "Windows"}, + {"Windows NT 6.2", "Windows"}, + {"Windows NT 6.1", "Windows"}, + {"Windows NT 6.0", "Windows"}, + {"Windows NT 5.2", "Windows"}, + {"Windows NT 5.1", "Windows"}, + {"Windows NT 5.01", "Windows"}, + {"Windows NT 5.0", "Windows"}, + {"Windows NT 4.0", "Windows"}, + {"Windows NT", "Windows"}, + {"Win 9x 4.90", "Windows"}, + {"Windows 98", "Windows"}, + {"Windows 95", "Windows"}, + {"Windows CE", "Windows"}, + {"Windows Phone 8.1", "Windows"}, + {"Windows Phone 8.0", "Windows"}, + + {"Googlebot", "Unix-like"}, + {"Mastodon", "Unix-like"}, + {"bingbot", "Windows"}, + + {"iPad", "iOS"}, + {"iPod", "iOS"}, + {"iPhone", "iOS"}, + {"AppleTV", "iOS"}, + {"iTunes", "Macintosh"}, + {"OS X", "Macintosh"}, + {"Darwin", "Darwin"}, + + {"Debian", "Linux"}, + {"Ubuntu", "Linux"}, + {"Fedora", "Linux"}, + {"Mint", "Linux"}, + {"SUSE", "Linux"}, + {"Mandriva", "Linux"}, + {"Red Hat", "Linux"}, + {"Gentoo", "Linux"}, + {"CentOS", "Linux"}, + {"PCLinuxOS", "Linux"}, + {"Linux", "Linux"}, + + {"FreeBSD", "BSD"}, + {"NetBSD", "BSD"}, + {"OpenBSD", "BSD"}, + {"DragonFly", "BSD"}, + {"PlayStation", "BSD"}, + + {"CrOS", "Chrome OS"}, + {"SunOS", "Unix-like"}, + {"QNX", "Unix-like"}, + {"BB10", "Unix-like"}, + + {"BlackBerry", "Others"}, + {"Sony", "Others"}, + {"AmigaOS", "Others"}, + {"SymbianOS", "Others"}, + {"Nokia", "Others"}, + {"Nintendo", "Others"}, + {"Apache", "Others"}, + {"Xbox One", "Windows"}, + {"Xbox", "Windows"}, +}; + +/* Get the Android code name (if applicable). + * + * On error, the given name is allocated and returned. + * On success, the matching Android codename is allocated and + * returned. */ +static char * +get_real_android (const char *droid) +{ + if (strstr (droid, "9")) + return alloc_string ("Pie 9"); + else if (strstr (droid, "8.1")) + return alloc_string ("Oreo 8.1"); + else if (strstr (droid, "8.0")) + return alloc_string ("Oreo 8.0"); + else if (strstr (droid, "7.1")) + return alloc_string ("Nougat 7.1"); + else if (strstr (droid, "7.0")) + return alloc_string ("Nougat 7.0"); + else if (strstr (droid, "6.0.1")) + return alloc_string ("Marshmallow 6.0.1"); + else if (strstr (droid, "6.0")) + return alloc_string ("Marshmallow 6.0"); + else if (strstr (droid, "5.1")) + return alloc_string ("Lollipop 5.1"); + else if (strstr (droid, "5.0")) + return alloc_string ("Lollipop 5.0"); + else if (strstr (droid, "4.4")) + return alloc_string ("KitKat 4.4"); + else if (strstr (droid, "4.3")) + return alloc_string ("Jelly Bean 4.3"); + else if (strstr (droid, "4.2")) + return alloc_string ("Jelly Bean 4.2"); + else if (strstr (droid, "4.1")) + return alloc_string ("Jelly Bean 4.1"); + else if (strstr (droid, "4.0")) + return alloc_string ("Ice Cream Sandwich 4.0"); + else if (strstr (droid, "3.")) + return alloc_string ("Honeycomb 3"); + else if (strstr (droid, "2.3")) + return alloc_string ("Gingerbread 2.3"); + else if (strstr (droid, "2.2")) + return alloc_string ("Froyo 2.2"); + else if (strstr (droid, "2.0") || strstr (droid, "2.1")) + return alloc_string ("Eclair 2"); + else if (strstr (droid, "1.6")) + return alloc_string ("Donut 1.6"); + else if (strstr (droid, "1.5")) + return alloc_string ("Cupcake 1.5"); + return alloc_string (droid); +} + +/* Get the Windows marketing name (if applicable). + * + * On error, the given name is allocated and returned. + * On success, the matching Windows marketing name is allocated and + * returned. */ +static char * +get_real_win (const char *win) +{ + if (strstr (win, "10.0")) + return alloc_string ("Windows 10"); + else if (strstr (win, "6.3")) + return alloc_string ("Windows 8.1"); + else if (strstr (win, "6.3; ARM")) + return alloc_string ("Windows RT"); + else if (strstr (win, "6.2; ARM")) + return alloc_string ("Windows RT"); + else if (strstr (win, "6.2")) + return alloc_string ("Windows 8"); + else if (strstr (win, "6.1")) + return alloc_string ("Windows 7"); + else if (strstr (win, "6.0")) + return alloc_string ("Windows Vista"); + else if (strstr (win, "5.2")) + return alloc_string ("Windows XP x64"); + else if (strstr (win, "5.1")) + return alloc_string ("Windows XP"); + else if (strstr (win, "5.0")) + return alloc_string ("Windows 2000"); + return NULL; +} + +/* Get the Mac OS X code name (if applicable). + * + * On error, the given name is allocated and returned. + * On success, the matching Mac OS X codename is allocated and + * returned. */ +static char * +get_real_mac_osx (const char *osx) +{ + if (strstr (osx, "10.14")) + return alloc_string ("macOS 10.14 Mojave"); + else if (strstr (osx, "10.13")) + return alloc_string ("macOS 10.13 High Sierra"); + else if (strstr (osx, "10.12")) + return alloc_string ("macOS 10.12 Sierra"); + else if (strstr (osx, "10.11")) + return alloc_string ("OS X 10.11 El Capitan"); + else if (strstr (osx, "10.10")) + return alloc_string ("OS X 10.10 Yosemite"); + else if (strstr (osx, "10.9")) + return alloc_string ("OS X 10.9 Mavericks"); + else if (strstr (osx, "10.8")) + return alloc_string ("OS X 10.8 Mountain Lion"); + else if (strstr (osx, "10.7")) + return alloc_string ("OS X 10.7 Lion"); + else if (strstr (osx, "10.6")) + return alloc_string ("OS X 10.6 Snow Leopard"); + else if (strstr (osx, "10.5")) + return alloc_string ("OS X 10.5 Leopard"); + else if (strstr (osx, "10.4")) + return alloc_string ("OS X 10.4 Tiger"); + else if (strstr (osx, "10.3")) + return alloc_string ("OS X 10.3 Panther"); + else if (strstr (osx, "10.2")) + return alloc_string ("OS X 10.2 Jaguar"); + else if (strstr (osx, "10.1")) + return alloc_string ("OS X 10.1 Puma"); + else if (strstr (osx, "10.0")) + return alloc_string ("OS X 10.0 Cheetah"); + return alloc_string (osx); +} + +/* Parse all other operating systems. + * + * On error, the given name is returned. + * On success, the parsed OS is returned. */ +static char * +parse_others (char *agent, int spaces) +{ + char *p; + int space = 0; + p = agent; + /* assume the following chars are within the given agent */ + while (*p != ';' && *p != ')' && *p != '(' && *p != '\0') { + if (*p == ' ') + space++; + if (space > spaces) + break; + p++; + } + *p = 0; + + return agent; +} + +/* Parse iOS string including version number. + * + * On error, the matching token is returned (no version). + * On success, the parsed iOS is returned. */ +static char * +parse_ios (char *agent, int tlen) +{ + char *p = NULL, *q = NULL; + ptrdiff_t offset; + + p = agent; + if ((p = strstr (agent, " OS ")) == NULL) + goto out; + + if ((offset = p - agent) <= 0) + goto out; + + if ((q = strstr (p, " like Mac")) == NULL) + goto out; + + *q = 0; + memmove (agent + tlen, agent + offset, offset); + return char_replace (agent, '_', '.'); + +out: + agent[tlen] = 0; + return agent; +} + +/* Parse a Mac OS X string. + * + * On error, the given name is returned. + * On success, the parsed Mac OS X is returned. */ +static char * +parse_osx (char *agent) +{ + int space = 0; + char *p; + + p = agent; + /* assume the following chars are within the given agent */ + while (*p != ';' && *p != ')' && *p != '(' && *p != '\0') { + if (*p == '_') + *p = '.'; + if (*p == ' ') + space++; + if (space > 3) + break; + p++; + } + *p = 0; + + return agent; +} + +/* Parse an Android string. + * + * On error, the given name is returned. + * On success, the parsed Android is returned. */ +static char * +parse_android (char *agent) +{ + char *p; + p = agent; + /* assume the following chars are within the given agent */ + while (*p != ';' && *p != ')' && *p != '(' && *p != '\0') + p++; + *p = 0; + + return agent; +} + +/* Attempt to parse specific OS. + * + * On success, a malloc'd string containing the OS is returned. */ +static char * +parse_os (const char *str, char *tkn, char *os_type, int idx) +{ + char *b; + int spaces = 0; + + xstrncpy (os_type, os[idx][1], OPESYS_TYPE_LEN); + /* Windows */ + if ((strstr (str, "Windows")) != NULL) + return conf.real_os && (b = get_real_win (tkn)) ? b : xstrdup (os[idx][0]); + /* Android */ + if ((strstr (tkn, "Android")) != NULL) { + tkn = parse_android (tkn); + return conf.real_os ? get_real_android (tkn) : xstrdup (tkn); + } + /* iOS */ + if (strstr (tkn, "iPad") || strstr (tkn, "iPod")) + return xstrdup (parse_ios (tkn, 4)); + if (strstr (tkn, "iPhone")) + return xstrdup (parse_ios (tkn, 6)); + /* Mac OS X */ + if ((strstr (tkn, "OS X")) != NULL) { + tkn = parse_osx (tkn); + return conf.real_os ? get_real_mac_osx (tkn) : xstrdup (tkn); + } + /* Darwin - capture the first part of agents such as: + * Slack/248000 CFNetwork/808.0.2 Darwin/16.0.0 */ + if ((strstr (tkn, "Darwin")) != NULL) { + if ((b = strchr (str, ' '))) + *b = 0; + return xstrdup (str); + } + /* all others */ + spaces = count_matches (os[idx][0], ' '); + + return alloc_string (parse_others (tkn, spaces)); +} + +/* Given a user agent, determine the operating system used. + * + * ###NOTE: The size of the list is proportional to the run time, + * which makes this pretty slow + * + * On error, NULL is returned. + * On success, a malloc'd string containing the OS is returned. */ +char * +verify_os (const char *str, char *os_type) +{ + char *a; + size_t i; + + if (str == NULL || *str == '\0') + return NULL; + + for (i = 0; i < ARRAY_SIZE (os); i++) { + if ((a = strstr (str, os[i][0])) != NULL) + return parse_os (str, a, os_type, i); + } + xstrncpy (os_type, "Unknown", OPESYS_TYPE_LEN); + + return alloc_string ("Unknown"); +} diff --git a/goaccess++/src/opesys.h b/goaccess++/src/opesys.h new file mode 100644 index 0000000..15f8fd7 --- /dev/null +++ b/goaccess++/src/opesys.h @@ -0,0 +1,44 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef OPESYS_H_INCLUDED +#define OPESYS_H_INCLUDED + +#define OPESYS_TYPE_LEN 10 + +/* Each OS contains the number of hits and the OS's type */ +typedef struct GOpeSys_ +{ + char os_type[OPESYS_TYPE_LEN]; + int hits; +} GOpeSys; + +char *verify_os (const char *str, char *os_type); + +#endif diff --git a/goaccess++/src/opesys.o b/goaccess++/src/opesys.o new file mode 100644 index 0000000..c16473f Binary files /dev/null and b/goaccess++/src/opesys.o differ diff --git a/goaccess++/src/options.c b/goaccess++/src/options.c new file mode 100644 index 0000000..f1ea1ff --- /dev/null +++ b/goaccess++/src/options.c @@ -0,0 +1,839 @@ +/** + * options.c -- functions related to parsing program options + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <getopt.h> +#include <errno.h> + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#include "tcbtdb.h" +#endif + +#ifdef HAVE_LIBGEOIP +#include <GeoIP.h> +#endif + +#include "options.h" + +#include "error.h" +#include "labels.h" +#include "util.h" +#include "xmalloc.h" + +static char short_options[] = "f:e:p:o:l:H:M:S:b:" +#ifdef HAVE_LIBGEOIP + "g" +#endif + "acirmMhHqdsV"; + +/* *INDENT-OFF* */ +struct option long_opts[] = { + {"agent-list" , no_argument , 0 , 'a' } , + {"browsers-file" , required_argument , 0 , 'b' } , + {"config-dialog" , no_argument , 0 , 'c' } , + {"config-file" , required_argument , 0 , 'p' } , + {"debug-file" , required_argument , 0 , 'l' } , + {"exclude-ip" , required_argument , 0 , 'e' } , +#ifdef HAVE_LIBGEOIP + {"std-geoip" , no_argument , 0 , 'g' } , +#endif + {"help" , no_argument , 0 , 'h' } , + {"hl-header" , no_argument , 0 , 'i' } , + {"http-method" , required_argument , 0 , 'M' } , + {"http-protocol" , required_argument , 0 , 'H' } , + {"log-file" , required_argument , 0 , 'f' } , + {"log-size" , required_argument , 0 , 'S' } , + {"no-query-string" , no_argument , 0 , 'q' } , + {"no-term-resolver" , no_argument , 0 , 'r' } , + {"output-format" , required_argument , 0 , 'o' } , + {"storage" , no_argument , 0 , 's' } , + {"version" , no_argument , 0 , 'V' } , + {"with-mouse" , no_argument , 0 , 'm' } , + {"with-output-resolver" , no_argument , 0 , 'd' } , + {"444-as-404" , no_argument , 0 , 0 } , + {"4xx-to-unique-count" , no_argument , 0 , 0 } , + {"anonymize-ip" , no_argument , 0 , 0 } , + {"addr" , required_argument , 0 , 0 } , + {"all-static-files" , no_argument , 0 , 0 } , + {"color" , required_argument , 0 , 0 } , + {"color-scheme" , required_argument , 0 , 0 } , + {"crawlers-only" , no_argument , 0 , 0 } , + {"daemonize" , no_argument , 0 , 0 } , + {"date-format" , required_argument , 0 , 0 } , + {"date-spec" , required_argument , 0 , 0 } , + {"dcf" , no_argument , 0 , 0 } , + {"double-decode" , no_argument , 0 , 0 } , + {"enable-panel" , required_argument , 0 , 0 } , + {"fifo-in" , required_argument , 0 , 0 } , + {"fifo-out" , required_argument , 0 , 0 } , + {"hide-referer" , required_argument , 0 , 0 } , + {"hour-spec" , required_argument , 0 , 0 } , + {"html-custom-css" , required_argument , 0 , 0 } , + {"html-custom-js" , required_argument , 0 , 0 } , + {"html-prefs" , required_argument , 0 , 0 } , + {"html-report-title" , required_argument , 0 , 0 } , + {"ignore-crawlers" , no_argument , 0 , 0 } , + {"ignore-statics" , required_argument , 0 , 0 } , + {"ignore-panel" , required_argument , 0 , 0 } , + {"ignore-referer" , required_argument , 0 , 0 } , + {"ignore-status" , required_argument , 0 , 0 } , + {"invalid-requests" , required_argument , 0 , 0 } , + {"json-pretty-print" , no_argument , 0 , 0 } , + {"log-format" , required_argument , 0 , 0 } , + {"max-items" , required_argument , 0 , 0 } , + {"no-color" , no_argument , 0 , 0 } , + {"no-column-names" , no_argument , 0 , 0 } , + {"no-csv-summary" , no_argument , 0 , 0 } , + {"no-global-config" , no_argument , 0 , 0 } , + {"no-html-last-updated" , no_argument , 0 , 0 } , + {"no-parsing-spinner" , no_argument , 0 , 0 } , + {"no-progress" , no_argument , 0 , 0 } , + {"no-tab-scroll" , no_argument , 0 , 0 } , + {"num-tests" , required_argument , 0 , 0 } , + {"origin" , required_argument , 0 , 0 } , + {"output" , required_argument , 0 , 0 } , + {"pid-file" , required_argument , 0 , 0 } , + {"port" , required_argument , 0 , 0 } , + {"process-and-exit" , no_argument , 0 , 0 } , + {"real-os" , no_argument , 0 , 0 } , + {"real-time-html" , no_argument , 0 , 0 } , + {"sort-panel" , required_argument , 0 , 0 } , + {"static-file" , required_argument , 0 , 0 } , +#ifdef HAVE_LIBSSL + {"ssl-cert" , required_argument , 0 , 0 } , + {"ssl-key" , required_argument , 0 , 0 } , +#endif + {"time-format" , required_argument , 0 , 0 } , + {"ws-url" , required_argument , 0 , 0 } , +#ifdef HAVE_GEOLOCATION + {"geoip-database" , required_argument , 0 , 0 } , +#endif +#ifdef HAVE_LIBGEOIP + {"geoip-city-data" , required_argument , 0 , 0 } , +#endif +#ifdef TCB_BTREE + {"accumulated-time" , no_argument , 0 , 0 } , + {"cache-lcnum" , required_argument , 0 , 0 } , + {"cache-ncnum" , required_argument , 0 , 0 } , + {"compression" , required_argument , 0 , 0 } , + {"db-path" , required_argument , 0 , 0 } , + {"keep-db-files" , no_argument , 0 , 0 } , + {"load-from-disk" , no_argument , 0 , 0 } , + {"tune-bnum" , required_argument , 0 , 0 } , + {"tune-lmemb" , required_argument , 0 , 0 } , + {"tune-nmemb" , required_argument , 0 , 0 } , + {"xmmap" , required_argument , 0 , 0 } , +#endif + {0, 0, 0, 0} +}; + +/* Command line help. */ +void +cmd_help (void) +{ + printf ("\nGoAccess - %s\n\n", GO_VERSION); + printf ( + "Usage: " + "goaccess [filename] [ options ... ] [-c][-M][-H][-S][-q][-d][...]\n" + "%s:\n\n", INFO_HELP_FOLLOWING_OPTS); + + printf ( + /* Log & Date Format Options */ + "Log & Date Format Options\n\n" + " --date-format=<dateformat> - Specify log date format. e.g., %%d/%%b/%%Y\n" + " --log-format=<logformat> - Specify log format. Inner quotes need to be\n" + " escaped, or use single quotes.\n" + " --time-format=<timeformat> - Specify log time format. e.g., %%H:%%M:%%S\n\n" + + /* User Interface Options */ + "User Interface Options\n\n" + " -c --config-dialog - Prompt log/date/time configuration window.\n" + " -i --hl-header - Color highlight active panel.\n" + " -m --with-mouse - Enable mouse support on main dashboard.\n" + " --color=<fg:bg[attrs, PANEL]> - Specify custom colors. See manpage for more\n" + " details and options.\n" + " --color-scheme=<1|2|3> - Schemes: 1 => Grey, 2 => Green, 3 => Monokai.\n" + " --html-custom-css=<path.css> - Specify a custom CSS file in the HTML report.\n" + " --html-custom-js=<path.js> - Specify a custom JS file in the HTML report.\n" + " --html-prefs=<json_obj> - Set default HTML report preferences.\n" + " --html-report-title=<title> - Set HTML report page title and header.\n" + " --json-pretty-print - Format JSON output w/ tabs & newlines.\n" + " --max-items - Maximum number of items to show per panel.\n" + " See man page for limits.\n" + " --no-color - Disable colored output.\n" + " --no-column-names - Don't write column names in term output.\n" + " --no-csv-summary - Disable summary metrics on the CSV output.\n" + " --no-html-last-updated - Hide HTML last updated field.\n" + " --no-parsing-spinner - Disable progress metrics and parsing spinner.\n" + " --no-progress - Disable progress metrics.\n" + " --no-tab-scroll - Disable scrolling through panels on TAB.\n" + "\n" + + /* Server Options */ + "Server Options\n\n" + " --addr=<addr> - Specify IP address to bind server to.\n" + " --daemonize - Run as daemon (if --real-time-html enabled).\n" + " --fifo-in=<path> - Path to read named pipe (FIFO).\n" + " --fifo-out=<path> - Path to write named pipe (FIFO).\n" + " --origin=<addr> - Ensure clients send the specified origin header\n" + " upon the WebSocket handshake.\n" + " --pid-file=<path> - Write PID to a file when --daemonize is used.\n" + " --port=<port> - Specify the port to use.\n" + " --real-time-html - Enable real-time HTML output.\n" + " --ssl-cert=<cert.crt> - Path to TLS/SSL certificate.\n" + " --ssl-key=<priv.key> - Path to TLS/SSL private key.\n" + " --ws-url=<url> - URL to which the WebSocket server responds.\n" + "\n" + + /* File Options */ + "File Options\n\n" + " - - The log file to parse is read from stdin.\n" + " -f --log-file=<filename> - Path to input log file.\n" + " -S --log-size=<number> - Specify the log size, useful when piping in logs.\n" + " -l --debug-file=<filename> - Send all debug messages to the specified\n" + " file.\n" + " -p --config-file=<filename> - Custom configuration file.\n" + " --invalid-requests=<filename> - Log invalid requests to the specified file.\n" + " --no-global-config - Don't load global configuration file.\n" + "\n" + + /* Parse Options */ + "Parse Options\n\n" + " -a --agent-list - Enable a list of user-agents by host.\n" + " -b --browsers-file=<path> - Use additional custom list of browsers.\n" + " -d --with-output-resolver - Enable IP resolver on HTML|JSON output.\n" + " -e --exclude-ip=<IP> - Exclude one or multiple IPv4/6. Allows IP\n" + " ranges e.g. 192.168.0.1-192.168.0.10\n" + " -H --http-protocol=<yes|no> - Set/unset HTTP request protocol if found.\n" + " -M --http-method=<yes|no> - Set/unset HTTP request method if found.\n" + " -o --output=file.html|json|csv - Output either an HTML, JSON or a CSV file.\n" + " -q --no-query-string - Ignore request's query string. Removing the\n" + " query string can greatly decrease memory\n" + " consumption.\n" + " -r --no-term-resolver - Disable IP resolver on terminal output.\n" + " --444-as-404 - Treat non-standard status code 444 as 404.\n" + " --4xx-to-unique-count - Add 4xx client errors to the unique visitors\n" + " count.\n" +#ifdef TCB_BTREE + " --accumulated-time - Store accumulated time from parsing day-by-day logs.\n" +#endif + " --anonymize-ip - Anonymize IP addresses before outputting to report.\n" + " --all-static-files - Include static files with a query string.\n" + " --crawlers-only - Parse and display only crawlers.\n" + " --date-spec=<date|hr> - Date specificity. Possible values: `date`\n" + " (default), or `hr`.\n" + " --double-decode - Decode double-encoded values.\n" + " --enable-panel=<PANEL> - Enable parsing/displaying the given panel.\n" + " --hide-referer=<NEEDLE> - Hide a referer but still count it. Wild cards\n" + " are allowed. i.e., *.bing.com\n" + " --hour-spec=<hr|min> - Hour specificity. Possible values: `hr`\n" + " (default), or `min` (tenth of a min).\n" + " --ignore-crawlers - Ignore crawlers.\n" + " --ignore-panel=<PANEL> - Ignore parsing/displaying the given panel.\n" + " --ignore-referer=<NEEDLE> - Ignore a referer from being counted. Wild cards\n" + " are allowed. i.e., *.bing.com\n" + " --ignore-statics=<req|panel> - Ignore static requests.\n" + " req => Ignore from valid requests.\n" + " panel => Ignore from valid requests and panels.\n" + " --ignore-status=<CODE> - Ignore parsing the given status code.\n" + " --num-tests=<number> - Number of lines to test. >= 0 (10 default)\n" + " --process-and-exit - Parse log and exit without outputting data.\n" + " --real-os - Display real OS names. e.g, Windows XP, Snow\n" + " Leopard.\n" + " --sort-panel=PANEL,METRIC,ORDER - Sort panel on initial load. For example:\n" + " --sort-panel=VISITORS,BY_HITS,ASC. See\n" + " manpage for a list of panels/fields.\n" + " --static-file=<extension> - Add static file extension. e.g.: .mp3.\n" + " Extensions are case sensitive.\n" + "\n" + +/* GeoIP Options */ +#ifdef HAVE_GEOLOCATION + "GeoIP Options\n\n" +#ifdef HAVE_LIBGEOIP + " -g --std-geoip - Standard GeoIP database for less memory\n" + " consumption.\n" +#endif + " --geoip-database=<path> - Specify path to GeoIP database file. i.e.,\n" + " GeoLiteCity.dat, GeoIPv6.dat ...\n" + "\n" +#endif + +/* On-Disk Database Options */ +#ifdef TCB_BTREE + "On-Disk Database Options\n\n" + " --keep-db-files - Persist parsed data into disk.\n" + " --load-from-disk - Load previously stored data from disk.\n" + " --db-path=<path> - Path of the database file. Default [%s]\n" + " --cache-lcnum=<number> - Max number of leaf nodes to be cached. Default\n" + " [%d]\n" + " --cache-ncnum=<number> - Max number of non-leaf nodes to be cached.\n" + " Default [%d]\n" + " --tune-bnum=<number> - Number of elements of the bucket array. Default\n" + " [%d]\n" + " --tune-lmemb=<number> - Number of members in each leaf page. Default\n" + " [%d]\n" + " --tune-nmemb=<number> - Number of members in each non-leaf page.\n" + " Default [%d]\n" + " --xmmap=<number> - Set the size in bytes of the extra mapped\n" + " memory. Default [%d]\n" +#if defined(HAVE_ZLIB) || defined(HAVE_BZ2) + " --compression=<zlib|bz2> - Specifies that each page is compressed with\n" + " ZLIB|BZ2 encoding.\n" + "\n" +#endif +#endif + +/* Other Options */ + "Other Options\n\n" + " -h --help - This help.\n" + " -V --version - Display version information and exit.\n" + " -s --storage - Display current storage method. e.g., B+\n" + " Tree, Hash.\n" + " --dcf - Display the path of the default config\n" + " file when `-p` is not used.\n" + "\n" + + "%s `man goaccess`.\n\n" + "%s: http://goaccess.io\n" + "GoAccess Copyright (C) 2009-2017 by Gerardo Orellana" + "\n\n" +#ifdef TCB_BTREE + , TC_DBPATH, TC_MMAP, TC_LCNUM, TC_NCNUM, TC_LMEMB, TC_NMEMB, TC_BNUM +#endif + , INFO_HELP_EXAMPLES, INFO_MORE_INFO + ); + exit (EXIT_FAILURE); +} +/* *INDENT-ON* */ + +/* Push a command line option to the given array if within bounds and if it's + * not in the array. */ +static void +set_array_opt (const char *oarg, const char *arr[], int *size, int max) +{ + if (str_inarray (oarg, arr, *size) < 0 && *size < max) + arr[(*size)++] = oarg; +} + +/* Parse command line long options. */ +static void +parse_long_opt (const char *name, const char *oarg) +{ + if (!strcmp ("no-global-config", name)) + return; + + /* LOG & DATE FORMAT OPTIONS + * ========================= */ + /* log format */ + if (!strcmp ("log-format", name)) + set_log_format_str (oarg); + + /* time format */ + if (!strcmp ("time-format", name)) + set_time_format_str (oarg); + + /* date format */ + if (!strcmp ("date-format", name)) + set_date_format_str (oarg); + + /* USER INTERFACE OPTIONS + * ========================= */ + /* colors */ + if (!strcmp ("color", name)) + set_array_opt (oarg, conf.colors, &conf.color_idx, MAX_CUSTOM_COLORS); + + /* color scheme */ + if (!strcmp ("color-scheme", name)) + conf.color_scheme = atoi (oarg); + + /* html custom CSS */ + if (!strcmp ("html-custom-css", name)) + conf.html_custom_css = oarg; + + /* html custom JS */ + if (!strcmp ("html-custom-js", name)) + conf.html_custom_js = oarg; + + /* html JSON object containing default preferences */ + if (!strcmp ("html-prefs", name)) + conf.html_prefs = oarg; + + /* html report title */ + if (!strcmp ("html-report-title", name)) + conf.html_report_title = oarg; + + /* json pretty print */ + if (!strcmp ("json-pretty-print", name)) + conf.json_pretty_print = 1; + + /* max items */ + if (!strcmp ("max-items", name)) { + char *sEnd; + int max = strtol (oarg, &sEnd, 10); + if (oarg == sEnd || *sEnd != '\0' || errno == ERANGE) + conf.max_items = 1; + else + conf.max_items = max; + } + + /* no color */ + if (!strcmp ("no-color", name)) + conf.no_color = 1; + + /* no columns */ + if (!strcmp ("no-column-names", name)) + conf.no_column_names = 1; + + /* no csv summary */ + if (!strcmp ("no-csv-summary", name)) + conf.no_csv_summary = 1; + + /* no parsing spinner */ + if (!strcmp ("no-parsing-spinner", name)) + conf.no_parsing_spinner = 1; + + /* no progress */ + if (!strcmp ("no-progress", name)) + conf.no_progress = 1; + + /* no tab scroll */ + if (!strcmp ("no-tab-scroll", name)) + conf.no_tab_scroll = 1; + + /* no html last updated field */ + if (!strcmp ("no-html-last-updated", name)) + conf.no_html_last_updated = 1; + + /* SERVER OPTIONS + * ========================= */ + /* address to bind to */ + if (!strcmp ("addr", name)) + conf.addr = oarg; + + /* FIFO in (read) */ + if (!strcmp ("fifo-in", name)) + conf.fifo_in = oarg; + + /* FIFO out (write) */ + if (!strcmp ("fifo-out", name)) + conf.fifo_out = oarg; + + /* run program as a Unix daemon */ + if (!strcmp ("daemonize", name)) + conf.daemonize = 1; + + /* WebSocket origin */ + if (!strcmp ("origin", name)) + conf.origin = oarg; + + /* PID file to write */ + if (!strcmp ("pid-file", name)) + conf.pidfile = oarg; + + /* port to use */ + if (!strcmp ("port", name)) { + int port = strtol (oarg, NULL, 10); + if (port < 0 || port > 65535) + LOG_DEBUG (("Invalid port.")); + else + conf.port = oarg; + } + + /* real time HTML */ + if (!strcmp ("real-time-html", name)) + conf.real_time_html = 1; + + /* TLS/SSL certificate */ + if (!strcmp ("ssl-cert", name)) + conf.sslcert = oarg; + + /* TLS/SSL private key */ + if (!strcmp ("ssl-key", name)) + conf.sslkey = oarg; + + /* URL to which the WebSocket server responds. */ + if (!strcmp ("ws-url", name)) + conf.ws_url = oarg; + + /* FILE OPTIONS + * ========================= */ + /* invalid requests */ + if (!strcmp ("invalid-requests", name)) { + conf.invalid_requests_log = oarg; + invalid_log_open (conf.invalid_requests_log); + } + + /* output file */ + if (!strcmp ("output", name)) + set_array_opt (oarg, conf.output_formats, &conf.output_format_idx, + MAX_OUTFORMATS); + + /* PARSE OPTIONS + * ========================= */ + /* 444 as 404 */ + if (!strcmp ("444-as-404", name)) + conf.code444_as_404 = 1; + + /* 4xx to unique count */ + if (!strcmp ("4xx-to-unique-count", name)) + conf.client_err_to_unique_count = 1; + + /* anonymize ip */ + if (!strcmp ("anonymize-ip", name)) + conf.anonymize_ip = 1; + + /* store accumulated time in tcb */ + if (!strcmp ("accumulated-time", name)) + conf.store_accumulated_time = 1; + + /* all static files */ + if (!strcmp ("all-static-files", name)) + conf.all_static_files = 1; + + /* crawlers only */ + if (!strcmp ("crawlers-only", name)) + conf.crawlers_only = 1; + + /* date specificity */ + if (!strcmp ("date-spec", name) && !strcmp (oarg, "hr")) + conf.date_spec_hr = 1; + + /* double decode */ + if (!strcmp ("double-decode", name)) + conf.double_decode = 1; + + /* enable panel */ + if (!strcmp ("enable-panel", name)) + set_array_opt (oarg, conf.enable_panels, &conf.enable_panel_idx, + TOTAL_MODULES); + + /* hour specificity */ + if (!strcmp ("hour-spec", name) && !strcmp (oarg, "min")) + conf.hour_spec_min = 1; + + /* ignore crawlers */ + if (!strcmp ("ignore-crawlers", name)) + conf.ignore_crawlers = 1; + + /* ignore panel */ + if (!strcmp ("ignore-panel", name)) + set_array_opt (oarg, conf.ignore_panels, &conf.ignore_panel_idx, + TOTAL_MODULES); + + /* ignore referer */ + if (!strcmp ("ignore-referer", name)) + set_array_opt (oarg, conf.ignore_referers, &conf.ignore_referer_idx, + MAX_IGNORE_REF); + + /* hide referer from report (e.g. within same site) */ + if (!strcmp ("hide-referer", name)) + set_array_opt (oarg, conf.hide_referers, &conf.hide_referer_idx, + MAX_IGNORE_REF); + + /* ignore status code */ + if (!strcmp ("ignore-status", name)) + set_array_opt (oarg, conf.ignore_status, &conf.ignore_status_idx, + MAX_IGNORE_STATUS); + + /* ignore static requests */ + if (!strcmp ("ignore-statics", name)) { + if (!strcmp ("req", oarg)) + conf.ignore_statics = IGNORE_LEVEL_REQ; + else if (!strcmp ("panel", oarg)) + conf.ignore_statics = IGNORE_LEVEL_PANEL; + else + LOG_DEBUG (("Invalid statics ignore option.")); + } + + /* number of line tests */ + if (!strcmp ("num-tests", name)) { + char *sEnd; + int tests = strtol (oarg, &sEnd, 10); + if (oarg == sEnd || *sEnd != '\0' || errno == ERANGE) + return; + conf.num_tests = tests >= 0 ? tests : 0; + } + + /* process and exit */ + if (!strcmp ("process-and-exit", name)) + conf.process_and_exit = 1; + + /* real os */ + if (!strcmp ("real-os", name)) + conf.real_os = 1; + + /* sort view */ + if (!strcmp ("sort-panel", name)) + set_array_opt (oarg, conf.sort_panels, &conf.sort_panel_idx, TOTAL_MODULES); + + /* static file */ + if (!strcmp ("static-file", name) && conf.static_file_idx < MAX_EXTENSIONS) { + if (conf.static_file_max_len < strlen (oarg)) + conf.static_file_max_len = strlen (oarg); + set_array_opt (oarg, conf.static_files, &conf.static_file_idx, + MAX_EXTENSIONS); + } + + /* GEOIP OPTIONS + * ========================= */ + /* specifies the path of the GeoIP City database file */ + if (!strcmp ("geoip-city-data", name) || !strcmp ("geoip-database", name)) + conf.geoip_database = oarg; + + /* BTREE OPTIONS + * ========================= */ + /* keep database files */ + if (!strcmp ("keep-db-files", name)) + conf.keep_db_files = 1; + + /* load data from disk */ + if (!strcmp ("load-from-disk", name)) + conf.load_from_disk = 1; + + /* specifies the path of the database file */ + if (!strcmp ("db-path", name)) + conf.db_path = oarg; + + /* specifies the maximum number of leaf nodes to be cached */ + if (!strcmp ("cache-lcnum", name)) + conf.cache_lcnum = atoi (oarg); + + /* specifies the maximum number of non-leaf nodes to be cached */ + if (!strcmp ("cache-ncnum", name)) + conf.cache_ncnum = atoi (oarg); + + /* number of elements of the bucket array */ + if (!strcmp ("tune-bnum", name)) + conf.tune_bnum = atoi (oarg); + + /* number of members in each non-leaf page */ + if (!strcmp ("tune-nmemb", name)) + conf.tune_nmemb = atoi (oarg); + + /* number of members in each leaf page */ + if (!strcmp ("tune-lmemb", name)) + conf.tune_lmemb = atoi (oarg); + + /* set the size in bytes of the extra mapped memory */ + if (!strcmp ("xmmap", name)) + conf.xmmap = atoi (oarg); + + /* specifies that each page is compressed with X encoding */ + if (!strcmp ("compression", name)) { +#ifdef HAVE_ZLIB + if (!strcmp ("zlib", oarg)) + conf.compression = TC_ZLIB; +#endif +#ifdef HAVE_BZ2 + if (!strcmp ("bz2", oarg)) + conf.compression = TC_BZ2; +#endif + } + + /* default config file --dwf */ + if (!strcmp ("dcf", name)) { + display_default_config_file (); + exit (EXIT_SUCCESS); + } +} + +/* Determine if the '--no-global-config' command line option needs to be + * enabled or not. */ +void +verify_global_config (int argc, char **argv) +{ + int o, idx = 0; + + conf.load_global_config = 1; + while ((o = getopt_long (argc, argv, short_options, long_opts, &idx)) >= 0) { + if (-1 == o || EOF == o) + break; + + switch (o) { + case 'p': + conf.iconfigfile = xstrdup (optarg); + break; + case 0: + if (!strcmp ("no-global-config", long_opts[idx].name)) + conf.load_global_config = 0; + break; + case '?': + exit (EXIT_FAILURE); + } + } + + /* reset it to 1 */ + optind = 1; +} + +/* Attempt to add - to the array of filenames if it hasn't been added it yet. */ +void +add_dash_filename (void) +{ + int i; + // pre-scan for '-' and don't add if already exists: github.com/allinurl/goaccess/issues/907 + for (i = 0; i < conf.filenames_idx; ++i) { + if (conf.filenames[i][0] == '-' && conf.filenames[i][1] == '\0') + return; + } + + if (conf.filenames_idx < MAX_FILENAMES && !conf.read_stdin) { + conf.read_stdin = 1; + conf.filenames[conf.filenames_idx++] = "-"; + } +} + +/* Read the user's supplied command line options. */ +void +read_option_args (int argc, char **argv) +{ + int o, idx = 0; + +#ifdef HAVE_LIBGEOIP + conf.geo_db = GEOIP_MEMORY_CACHE; +#endif + + while ((o = getopt_long (argc, argv, short_options, long_opts, &idx)) >= 0) { + if (-1 == o || EOF == o) + break; + switch (o) { + case 'f': + if (conf.filenames_idx < MAX_FILENAMES) + conf.filenames[conf.filenames_idx++] = optarg; + break; + case 'S': + if (strchr (optarg, '-')) { + printf ("[ERROR] log-size must be a positive integer\n"); + exit (EXIT_FAILURE); + } + conf.log_size = (uint64_t) atoll (optarg); + break; + case 'p': + /* ignore it */ + break; +#ifdef HAVE_LIBGEOIP + case 'g': + conf.geo_db = GEOIP_STANDARD; + break; +#endif + case 'e': + if (conf.ignore_ip_idx < MAX_IGNORE_IPS) + conf.ignore_ips[conf.ignore_ip_idx++] = optarg; + else + LOG_DEBUG (("Max num of (%d) IPs to ignore reached.", MAX_IGNORE_IPS)); + break; + case 'a': + conf.list_agents = 1; + break; + case 'b': + conf.browsers_file = optarg; + break; + case 'c': + conf.load_conf_dlg = 1; + break; + case 'i': + conf.hl_header = 1; + break; + case 'q': + conf.ignore_qstr = 1; + break; + case 'o': + if (!valid_output_type (optarg)) { + printf + ("[ERROR] Invalid filename extension used, must be any of .csv, .json, or .html\n"); + exit (EXIT_FAILURE); + } + if (conf.output_format_idx < MAX_OUTFORMATS) + conf.output_formats[conf.output_format_idx++] = optarg; + break; + case 'l': + conf.debug_log = optarg; + dbg_log_open (conf.debug_log); + break; + case 'r': + conf.skip_term_resolver = 1; + break; + case 'd': + conf.enable_html_resolver = 1; + break; + case 'm': + conf.mouse_support = 1; + break; + case 'M': + if (strcmp ("no", optarg) == 0) + conf.append_method = 0; + else + conf.append_method = 1; + break; + case 'h': + cmd_help (); + break; + case 'H': + if (strcmp ("no", optarg) == 0) + conf.append_protocol = 0; + else + conf.append_protocol = 1; + break; + case 'V': + display_version (); + exit (EXIT_SUCCESS); + break; + case 0: + parse_long_opt (long_opts[idx].name, optarg); + break; + case 's': + display_storage (); + exit (EXIT_SUCCESS); + case '?': + exit (EXIT_FAILURE); + default: + exit (EXIT_FAILURE); + } + } + + for (idx = optind; idx < argc; ++idx) { + /* read from standard input */ + if (!conf.read_stdin && strcmp ("-", argv[idx]) == 0) + add_dash_filename (); + /* read filenames */ + else { + if (conf.filenames_idx < MAX_FILENAMES) + conf.filenames[conf.filenames_idx++] = argv[idx]; + } + } +} diff --git a/goaccess++/src/options.h b/goaccess++/src/options.h new file mode 100644 index 0000000..fad12b4 --- /dev/null +++ b/goaccess++/src/options.h @@ -0,0 +1,38 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef OPTIONS_H_INCLUDED +#define OPTIONS_H_INCLUDED + +void add_dash_filename (void); +void cmd_help (void); +void read_option_args (int argc, char **argv); +void verify_global_config (int argc, char **argv); + +#endif diff --git a/goaccess++/src/options.o b/goaccess++/src/options.o new file mode 100644 index 0000000..1b22a3e Binary files /dev/null and b/goaccess++/src/options.o differ diff --git a/goaccess++/src/output.c b/goaccess++/src/output.c new file mode 100644 index 0000000..b57786b --- /dev/null +++ b/goaccess++/src/output.c @@ -0,0 +1,1240 @@ +/** + * output.c -- output to the standard output stream + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana <hello @ goaccess.io> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#include <errno.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "output.h" + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#include "error.h" +#include "gwsocket.h" +#include "json.h" +#include "settings.h" +#include "ui.h" +#include "util.h" +#include "xmalloc.h" + +#include "tpls.h" +#include "bootstrapcss.h" +#include "facss.h" +#include "appcss.h" +#include "d3js.h" +#include "hoganjs.h" +#include "chartsjs.h" +#include "appjs.h" + +static void hits_bw_plot (FILE * fp, GHTMLPlot plot, int sp); +static void hits_bw_req_plot (FILE * fp, GHTMLPlot plot, int sp); +static void hits_visitors_plot (FILE * fp, GHTMLPlot plot, int sp); +static void hits_visitors_req_plot (FILE * fp, GHTMLPlot plot, int sp); + +static void print_metrics (FILE * fp, const GHTML * def, int sp); +static void print_host_metrics (FILE * fp, const GHTML * def, int sp); + +/* *INDENT-OFF* */ +static GHTML htmldef[] = { + {VISITORS, 1, print_metrics, { + {CHART_AREASPLINE, hits_visitors_plot, 1, 1} , + {CHART_AREASPLINE, hits_bw_plot, 1, 1} , + }}, + {REQUESTS, 1, print_metrics, { + {CHART_VBAR, hits_visitors_req_plot, 0, 0}, + {CHART_VBAR, hits_bw_req_plot, 0, 0}, + }}, + {REQUESTS_STATIC, 1, print_metrics, { + {CHART_VBAR, hits_visitors_req_plot, 0, 0}, + {CHART_VBAR, hits_bw_req_plot, 0, 0}, + }}, + {NOT_FOUND, 1, print_metrics, { + {CHART_VBAR, hits_visitors_req_plot, 0, 0}, + {CHART_VBAR, hits_bw_req_plot, 0, 0}, + }}, + {HOSTS, 1, print_host_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 0}, + {CHART_VBAR, hits_bw_plot, 0, 0}, + }}, + {OS, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 1}, + {CHART_VBAR, hits_bw_plot, 0, 1}, + }}, + {BROWSERS, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 1}, + {CHART_VBAR, hits_bw_plot, 0, 1}, + }}, + {VISIT_TIMES, 1, print_metrics, { + {CHART_AREASPLINE, hits_visitors_plot, 0, 1}, + {CHART_AREASPLINE, hits_bw_plot, 0, 1}, + }}, + {VIRTUAL_HOSTS, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 0}, + {CHART_VBAR, hits_bw_plot, 0, 0}, + }}, + {REFERRERS, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 0}, + {CHART_VBAR, hits_bw_plot, 0, 0}, + }}, + {REFERRING_SITES, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 0}, + {CHART_VBAR, hits_bw_plot, 0, 0}, + }}, + {KEYPHRASES, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 0}, + {CHART_VBAR, hits_bw_plot, 0, 0}, + }}, + {STATUS_CODES, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 1}, + {CHART_VBAR, hits_bw_plot, 0, 1}, + }}, + {REMOTE_USER, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 0}, + {CHART_VBAR, hits_bw_plot, 0, 0}, + }}, +#ifdef HAVE_GEOLOCATION + {GEO_LOCATION, 1, print_metrics, { + {CHART_VBAR, hits_visitors_plot, 0, 1}, + {CHART_VBAR, hits_bw_plot, 0, 1}, + }}, +#endif +}; +/* *INDENT-ON* */ + +/* number of new lines (applicable fields) */ +static int nlines = 0; + +/* Get the chart type for the JSON definition. + * + * On success, the chart type string is returned. */ +static const char * +chart2str (GChartType type) +{ + static const char *strings[] = { "null", "bar", "area-spline" }; + return strings[type]; +} + +/* Get panel output data for the given module. + * + * If not found, NULL is returned. + * On success, panel data is returned . */ +static GHTML * +panel_lookup (GModule module) +{ + int i, num_panels = ARRAY_SIZE (htmldef); + + for (i = 0; i < num_panels; i++) { + if (htmldef[i].module == module) + return &htmldef[i]; + } + return NULL; +} + +/* Sanitize output with html entities for special chars */ +static void +clean_output (FILE * fp, char *s) +{ + if (!s) { + LOG_DEBUG (("NULL data on clean_output.\n")); + return; + } + + while (*s) { + switch (*s) { + case '\'': + fprintf (fp, "'"); + break; + case '"': + fprintf (fp, """); + break; + case '&': + fprintf (fp, "&"); + break; + case '<': + fprintf (fp, "<"); + break; + case '>': + fprintf (fp, ">"); + break; + case ' ': + fprintf (fp, " "); + break; + default: + fputc (*s, fp); + break; + } + s++; + } +} + +/* Set the HTML document title and the generated date/time */ +static void +print_html_title (FILE * fp) +{ + const char *title = + conf.html_report_title ? conf.html_report_title : HTML_REPORT_TITLE; + + fprintf (fp, "<title>"); + clean_output (fp, (char *) title); + fprintf (fp, ""); +} + +/* *INDENT-OFF* */ +/* Output all the document head elements. */ +static void +print_html_header (FILE * fp) +{ + fprintf (fp, + "" + "" + "" + "" + "" + "" + "" + "" + "", _(DOC_LANG)); + + print_html_title (fp); + + fprintf (fp, "", fa_css); + fprintf (fp, "", bootstrap_css); + fprintf (fp, "", app_css); + /* load custom CSS file, if any */ + if (conf.html_custom_css) + fprintf (fp, "", conf.html_custom_css); + + fprintf (fp, + "" + ""); +} + +/* Output all structural elements of the HTML document. */ +static void +print_html_body (FILE * fp, const char *now) +{ + fprintf (fp, + "" + + "" + "
    " + "
    " + "
    " + "
    " + "" + "
    " + "
    " + "
    " + "
    " + "
    " + "
    ", conf.html_report_title ? conf.html_report_title : ""); + + fprintf (fp, "%s", tpls); +} + +/* Output all the document footer elements such as script and closing + * tags. */ +static void +print_html_footer (FILE * fp) +{ + fprintf (fp, "", d3_js); + fprintf (fp, "", hogan_js); + fprintf (fp, "", app_js); + fprintf (fp, "", charts_js); + + /* load custom JS file, if any */ + if (conf.html_custom_js) + fprintf (fp, "", conf.html_custom_js); + + fprintf (fp, ""); + fprintf (fp, ""); +} +/* *INDENT-ON* */ + +static const GChartDef ChartDefStopper = { NULL, NULL }; + +/* Get the number of chart definitions per panel. + * + * The number of chart definitions is returned . */ +static int +get_chartdef_cnt (GChart * chart) +{ + GChartDef *def = chart->def; + + while (memcmp (def, &ChartDefStopper, sizeof ChartDefStopper)) + ++def; + + return def - chart->def; +} + +/* Output the given JSON chart axis definition for the given panel. */ +static void +print_d3_chart_def_axis (FILE * fp, GChart * chart, size_t cnt, int isp) +{ + GChartDef *def = chart->def; + size_t j = 0; + + for (j = 0; j < cnt; ++j) { + if (strchr (def[j].value, '[') != NULL) + fpskeyaval (fp, def[j].key, def[j].value, isp, j == cnt - 1); + else + fpskeysval (fp, def[j].key, def[j].value, isp, j == cnt - 1); + } +} + +/* Output the given JSON chart definition for the given panel. */ +static void +print_d3_chart_def (FILE * fp, GChart * chart, size_t n, int sp) +{ + size_t i = 0, cnt = 0; + int isp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + for (i = 0; i < n; ++i) { + cnt = get_chartdef_cnt (chart + i); + + fpopen_obj_attr (fp, chart[i].key, sp); + print_d3_chart_def_axis (fp, chart + i, cnt, isp); + fpclose_obj (fp, sp, (i == n - 1)); + } +} + +static void +print_plot_def (FILE * fp, const GHTMLPlot plot, GChart * chart, int n, int sp) +{ + int isp = 0, iisp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1, iisp = sp + 2; + + fpskeysval (fp, "className", plot.chart_key, isp, 0); + fpskeysval (fp, "label", plot.chart_lbl, isp, 0); + fpskeysval (fp, "chartType", chart2str (plot.chart_type), isp, 0); + fpskeyival (fp, "chartReverse", plot.chart_reverse, isp, 0); + fpskeyival (fp, "redrawOnExpand", plot.redraw_expand, isp, 0); + + /* D3.js data */ + fpopen_obj_attr (fp, "d3", isp); + /* print chart definitions */ + print_d3_chart_def (fp, chart, n, iisp); + /* close D3 */ + fpclose_obj (fp, isp, 1); +} + +/* Output D3.js hits/visitors plot definitions. */ +static void +hits_visitors_plot (FILE * fp, GHTMLPlot plot, int sp) +{ + /* *INDENT-OFF* */ + GChart def[] = { + {"y0", (GChartDef[]) { + {"key", "hits"}, {"label", MTRC_HITS_LBL}, ChartDefStopper + }}, + {"y1", (GChartDef[]) { + {"key", "visitors"}, {"label", MTRC_VISITORS_LBL}, ChartDefStopper + }}, + }; + + plot.chart_key = (char[]) {"hits-visitors"}; + plot.chart_lbl = (char *) {HTML_PLOT_HITS_VIS}; + /* *INDENT-ON* */ + print_plot_def (fp, plot, def, ARRAY_SIZE (def), sp); +} + +/* Output D3.js hits/visitors plot definitions. */ +static void +hits_visitors_req_plot (FILE * fp, GHTMLPlot plot, int sp) +{ + /* *INDENT-OFF* */ + GChart def[] = { + {"x", (GChartDef[]) { + {"key", "[\"method\", \"data\", \"protocol\"]"}, ChartDefStopper + }}, + {"y0", (GChartDef[]) { + {"key", "hits"}, {"label", MTRC_HITS_LBL}, ChartDefStopper + }}, + {"y1", (GChartDef[]) { + {"key", "visitors"}, {"label", MTRC_VISITORS_LBL}, ChartDefStopper + }}, + }; + + plot.chart_key = (char[]) {"hits-visitors"}; + plot.chart_lbl = (char *) {HTML_PLOT_HITS_VIS}; + /* *INDENT-ON* */ + print_plot_def (fp, plot, def, ARRAY_SIZE (def), sp); +} + +/* Output C3.js bandwidth plot definitions. */ +static void +hits_bw_plot (FILE * fp, GHTMLPlot plot, int sp) +{ + /* *INDENT-OFF* */ + GChart def[] = { + {"y0", (GChartDef[]) { + {"key", "bytes"}, {"label", MTRC_BW_LBL}, {"format", "bytes"}, ChartDefStopper + }}, + }; + + if (!conf.bandwidth) + return; + + plot.chart_key = (char[]) {"bandwidth"}; + plot.chart_lbl = (char *) {MTRC_BW_LBL}; + /* *INDENT-ON* */ + print_plot_def (fp, plot, def, ARRAY_SIZE (def), sp); +} + +/* Output C3.js bandwidth plot definitions. */ +static void +hits_bw_req_plot (FILE * fp, GHTMLPlot plot, int sp) +{ + /* *INDENT-OFF* */ + GChart def[] = { + {"x", (GChartDef[]) { + {"key", "[\"method\", \"protocol\", \"data\"]"}, ChartDefStopper + }}, + {"y0", (GChartDef[]) { + {"key", "bytes"}, {"label", MTRC_BW_LBL}, {"format", "bytes"}, ChartDefStopper + }}, + }; + + if (!conf.bandwidth) + return; + + plot.chart_key = (char[]) {"bandwidth"}; + plot.chart_lbl = (char *) {MTRC_BW_LBL}; + /* *INDENT-ON* */ + print_plot_def (fp, plot, def, ARRAY_SIZE (def), sp); +} + +/* Output JSON data definitions. */ +static void +print_json_data (FILE * fp, GLog * glog, GHolder * holder) +{ + char *json = NULL; + + if ((json = get_json (glog, holder, 1)) == NULL) + return; + + fprintf (fp, ""); + + free (json); +} + +/* Output WebSocket connection definition. */ +static void +print_conn_def (FILE * fp) +{ + int sp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + sp += 1; + + if (!conf.real_time_html) + return; + + fprintf (fp, ""); +} + +/* Output JSON per panel metric definitions. */ +static void +print_def_metric (FILE * fp, const GDefMetric def, int sp) +{ + int isp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + if (def.cname) + fpskeysval (fp, "className", def.cname, isp, 0); + if (def.cwidth) + fpskeysval (fp, "colWidth", def.cwidth, isp, 0); + if (def.metakey) + fpskeysval (fp, "meta", def.metakey, isp, 0); + if (def.metatype) + fpskeysval (fp, "metaType", def.metatype, isp, 0); + if (def.metalbl) + fpskeysval (fp, "metaLabel", def.metalbl, isp, 0); + if (def.datatype) + fpskeysval (fp, "dataType", def.datatype, isp, 0); + if (def.datakey) + fpskeysval (fp, "key", def.datakey, isp, 0); + if (def.lbl) + fpskeysval (fp, "label", def.lbl, isp, 1); +} + +/* Output JSON metric definition block. */ +static void +print_def_block (FILE * fp, const GDefMetric def, int sp, int last) +{ + fpopen_obj (fp, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, last); +} + +/* Output JSON overall requests definition block. */ +static void +print_def_overall_requests (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_REQUESTS, + .datatype = "numeric", + .cname = "black" + }; + fpopen_obj_attr (fp, OVERALL_REQ, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall valid requests definition block. */ +static void +print_def_overall_valid_reqs (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_VALID, + .datatype = "numeric", + .cname = "green" + }; + fpopen_obj_attr (fp, OVERALL_VALID, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall invalid requests definition block. */ +static void +print_def_overall_invalid_reqs (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_FAILED, + .datatype = "numeric", + .cname = "red" + }; + fpopen_obj_attr (fp, OVERALL_FAILED, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON process time definition block. */ +static void +print_def_overall_processed_time (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_GEN_TIME, + .datatype = "secs", + .cname = "gray" + }; + fpopen_obj_attr (fp, OVERALL_GENTIME, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall visitors definition block. */ +static void +print_def_overall_visitors (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_UNIQUE_VISITORS, + .datatype = "numeric", + .cname = "blue" + }; + fpopen_obj_attr (fp, OVERALL_VISITORS, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall files definition block. */ +static void +print_def_overall_files (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_UNIQUE_FILES, + .datatype = "numeric", + }; + fpopen_obj_attr (fp, OVERALL_FILES, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall excluded requests definition block. */ +static void +print_def_overall_excluded (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_EXCLUDE_IP, + .datatype = "numeric", + }; + fpopen_obj_attr (fp, OVERALL_EXCL_HITS, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall referrers definition block. */ +static void +print_def_overall_refs (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_REFERRER, + .datatype = "numeric", + }; + fpopen_obj_attr (fp, OVERALL_REF, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall not found definition block. */ +static void +print_def_overall_notfound (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_UNIQUE404, + .datatype = "numeric", + }; + fpopen_obj_attr (fp, OVERALL_NOTFOUND, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall static files definition block. */ +static void +print_def_overall_static_files (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_STATIC_FILES, + .datatype = "numeric", + }; + fpopen_obj_attr (fp, OVERALL_STATIC, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON log size definition block. */ +static void +print_def_overall_log_size (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_LOG, + .datatype = "bytes", + }; + fpopen_obj_attr (fp, OVERALL_LOGSIZE, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 0); +} + +/* Output JSON overall bandwidth definition block. */ +static void +print_def_overall_bandwidth (FILE * fp, int sp) +{ + GDefMetric def = { + .lbl = T_BW, + .datatype = "bytes", + }; + fpopen_obj_attr (fp, OVERALL_BANDWIDTH, sp); + print_def_metric (fp, def, sp); + fpclose_obj (fp, sp, 1); +} + +/* Output JSON hits definition block. */ +static void +print_def_hits (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "hits", + .lbl = MTRC_HITS_LBL, + .datatype = "numeric", + .metakey = "count", + .cwidth = "12%", + }; + print_def_block (fp, def, sp, 0); +} + +/* Output JSON visitors definition block. */ +static void +print_def_visitors (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "visitors", + .lbl = MTRC_VISITORS_LBL, + .datatype = "numeric", + .metakey = "count", + .cwidth = "12%", + }; + print_def_block (fp, def, sp, 0); +} + +/* Output JSON bandwidth definition block. */ +static void +print_def_bw (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "bytes", + .lbl = MTRC_BW_LBL, + .datatype = "bytes", + .metakey = "count", + .cwidth = "12%", + }; + + if (!conf.bandwidth) + return; + + print_def_block (fp, def, sp, 0); +} + +/* Output JSON Avg. T.S. definition block. */ +static void +print_def_avgts (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "avgts", + .lbl = MTRC_AVGTS_LBL, + .datatype = "utime", + .metakey = "avg", + .cwidth = "8%", + }; + + if (!conf.serve_usecs) + return; + + print_def_block (fp, def, sp, 0); +} + +/* Output JSON Cum. T.S. definition block. */ +static void +print_def_cumts (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "cumts", + .lbl = MTRC_CUMTS_LBL, + .datatype = "utime", + .metakey = "count", + .cwidth = "8%", + }; + + if (!conf.serve_usecs) + return; + + print_def_block (fp, def, sp, 0); +} + +/* Output JSON Max. T.S. definition block. */ +static void +print_def_maxts (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "maxts", + .lbl = MTRC_MAXTS_LBL, + .datatype = "utime", + .metakey = "count", + .cwidth = "8%", + }; + + if (!conf.serve_usecs) + return; + print_def_block (fp, def, sp, 0); +} + +/* Output JSON method definition block. */ +static void +print_def_method (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "method", + .lbl = MTRC_METHODS_LBL, + .datatype = "string", + .cwidth = "6%", + }; + + if (!conf.append_method) + return; + + print_def_block (fp, def, sp, 0); +} + +/* Output JSON protocol definition block. */ +static void +print_def_protocol (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "protocol", + .lbl = MTRC_PROTOCOLS_LBL, + .datatype = "string", + .cwidth = "7%", + }; + + if (!conf.append_protocol) + return; + + print_def_block (fp, def, sp, 0); +} + +/* Output JSON city definition block. */ +static void +print_def_city (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "city", + .lbl = MTRC_CITY_LBL, + .datatype = "string", + }; + + if (!conf.has_geocity) + return; + + print_def_block (fp, def, sp, 0); +} + +/* Output JSON country definition block. */ +static void +print_def_country (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "country", + .lbl = MTRC_COUNTRY_LBL, + .datatype = "string", + }; + + if (!conf.has_geocountry) + return; + + print_def_block (fp, def, sp, 0); +} + +/* Output JSON hostname definition block. */ +static void +print_def_hostname (FILE * fp, int sp) +{ + GDefMetric def = { + .datakey = "hostname", + .lbl = MTRC_HOSTNAME_LBL, + .datatype = "string", + .cname = "light", + }; + + if (!conf.enable_html_resolver) + return; + + print_def_block (fp, def, sp, 0); +} + +/* Output JSON data definition block. */ +static void +print_def_data (FILE * fp, GModule module, int sp) +{ + GDefMetric def = { + .cname = "trunc", + .cwidth = "100%", + .datakey = "data", + .datatype = module == VISITORS ? "date" : "string", + .lbl = MTRC_DATA_LBL, + .metakey = "unique", + .metalbl = "Total", + .metatype = "numeric", + }; + + print_def_block (fp, def, sp, 1); +} + +/* Get the number of plots for the given panel definition. + * + * The number of plots for the given panel is returned. */ +static int +count_plot_fp (const GHTML * def) +{ + int i = 0; + for (i = 0; def->chart[i].plot != 0; ++i); + return i; +} + +/* Entry function to output JSON plot definition block. */ +static void +print_def_plot (FILE * fp, const GHTML * def, int sp) +{ + int i, isp = 0, n = count_plot_fp (def); + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + fpopen_arr_attr (fp, "plot", sp); + + for (i = 0; i < n; ++i) { + fpopen_obj (fp, isp); + def->chart[i].plot (fp, def->chart[i], isp); + fpclose_obj (fp, isp, (i == n - 1)); + } + + fpclose_arr (fp, sp, 0); +} + +/* Output JSON host panel definitions. */ +static void +print_host_metrics (FILE * fp, const GHTML * def, int sp) +{ + const GOutput *output = output_lookup (def->module); + + print_def_hits (fp, sp); + print_def_visitors (fp, sp); + print_def_bw (fp, sp); + print_def_avgts (fp, sp); + print_def_cumts (fp, sp); + print_def_maxts (fp, sp); + + if (output->method) + print_def_method (fp, sp); + if (output->protocol) + print_def_protocol (fp, sp); + + print_def_city (fp, sp); + print_def_country (fp, sp); + print_def_hostname (fp, sp); + + print_def_data (fp, def->module, sp); +} + +/* Output JSON panel definitions. */ +static void +print_metrics (FILE * fp, const GHTML * def, int sp) +{ + const GOutput *output = output_lookup (def->module); + + print_def_hits (fp, sp); + print_def_visitors (fp, sp); + print_def_bw (fp, sp); + print_def_avgts (fp, sp); + print_def_cumts (fp, sp); + print_def_maxts (fp, sp); + + if (output->method) + print_def_method (fp, sp); + if (output->protocol) + print_def_protocol (fp, sp); + + print_def_data (fp, def->module, sp); +} + +/* Entry point to output JSON metric definitions. */ +static void +print_def_metrics (FILE * fp, const GHTML * def, int sp) +{ + int isp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + /* open data metric data */ + fpopen_arr_attr (fp, "items", sp); + /* definition metrics */ + def->metrics (fp, def, isp); + /* close metrics block */ + fpclose_arr (fp, sp, 1); +} + +/* Output panel header and description metadata definitions. */ +static void +print_def_meta (FILE * fp, const char *head, const char *desc, int sp) +{ + int isp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + fpskeysval (fp, "head", head, isp, 0); + fpskeysval (fp, "desc", desc, isp, 0); +} + +/* Output panel sort metadata definitions. */ +static void +print_def_sort (FILE * fp, const GHTML * def, int sp) +{ + GSort sort = module_sort[def->module]; + int isp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + /* output open sort attribute */ + fpopen_obj_attr (fp, "sort", sp); + fpskeysval (fp, "field", get_sort_field_key (sort.field), isp, 0); + fpskeysval (fp, "order", get_sort_order_str (sort.sort), isp, 1); + /* output close sort attribute */ + fpclose_obj (fp, sp, 0); +} + +/* Output panel metadata definitions. */ +static void +print_panel_def_meta (FILE * fp, const GHTML * def, int sp) +{ + const char *desc = module_to_desc (def->module); + const char *head = module_to_head (def->module); + const char *id = module_to_id (def->module); + + int isp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1; + + print_def_meta (fp, head, desc, sp); + + fpskeysval (fp, "id", id, isp, 0); + fpskeyival (fp, "table", def->table, isp, 0); + + print_def_sort (fp, def, isp); + print_def_plot (fp, def, isp); + print_def_metrics (fp, def, isp); +} + +/* Output definitions for the given panel. */ +static void +print_json_def (FILE * fp, const GHTML * def) +{ + int sp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + sp = 1; + + /* output open panel attribute */ + fpopen_obj_attr (fp, module_to_id (def->module), sp); + /* output panel data definitions */ + print_panel_def_meta (fp, def, sp); + /* output close panel attribute */ + fpclose_obj (fp, sp, 1); + + fpjson (fp, (def->module != TOTAL_MODULES - 1) ? ",%.*s" : "%.*s", nlines, + NL); +} + +/* Output overall definitions. */ +static void +print_def_summary (FILE * fp, int sp) +{ + int isp = 0, iisp = 0; + /* use tabs to prettify output */ + if (conf.json_pretty_print) + isp = sp + 1, iisp = sp + 2; + + /* open metrics block */ + fpopen_obj_attr (fp, "items", isp); + + print_def_overall_requests (fp, iisp); + print_def_overall_valid_reqs (fp, iisp); + print_def_overall_invalid_reqs (fp, iisp); + print_def_overall_processed_time (fp, iisp); + print_def_overall_visitors (fp, iisp); + print_def_overall_files (fp, iisp); + print_def_overall_excluded (fp, iisp); + print_def_overall_refs (fp, iisp); + print_def_overall_notfound (fp, iisp); + print_def_overall_static_files (fp, iisp); + print_def_overall_log_size (fp, iisp); + print_def_overall_bandwidth (fp, iisp); + + /* close metrics block */ + fpclose_obj (fp, isp, 1); +} + +/* Cheap JSON internationalisation (i18n) - report labels */ +static void +print_json_i18n_def (FILE * fp) +{ + int sp = 0; + size_t i = 0; + + /* *INDENT-OFF* */ + static const char *json_i18n[][2] = { + {"theme" , HTML_REPORT_NAV_THEME} , + {"dark_gray" , HTML_REPORT_NAV_DARK_GRAY} , + {"bright" , HTML_REPORT_NAV_BRIGHT} , + {"dark_blue" , HTML_REPORT_NAV_DARK_BLUE} , + {"dark_purple" , HTML_REPORT_NAV_DARK_PURPLE} , + {"panels" , HTML_REPORT_NAV_PANELS} , + {"items_per_page" , HTML_REPORT_NAV_ITEMS_PER_PAGE} , + {"tables" , HTML_REPORT_NAV_TABLES} , + {"display_tables" , HTML_REPORT_NAV_DISPLAY_TABLES} , + {"ah_small" , HTML_REPORT_NAV_AH_SMALL} , + {"ah_small_title" , HTML_REPORT_NAV_AH_SMALL_TITLE} , + {"layout" , HTML_REPORT_NAV_LAYOUT} , + {"horizontal" , HTML_REPORT_NAV_HOR} , + {"vertical" , HTML_REPORT_NAV_VER} , + {"file_opts" , HTML_REPORT_NAV_FILE_OPTS} , + {"export_json" , HTML_REPORT_NAV_EXPORT_JSON} , + {"panel_opts" , HTML_REPORT_PANEL_PANEL_OPTS} , + {"previous" , HTML_REPORT_PANEL_PREVIOUS} , + {"next" , HTML_REPORT_PANEL_NEXT} , + {"first" , HTML_REPORT_PANEL_FIRST} , + {"last" , HTML_REPORT_PANEL_LAST} , + {"chart_opts" , HTML_REPORT_PANEL_CHART_OPTS} , + {"chart" , HTML_REPORT_PANEL_CHART} , + {"type" , HTML_REPORT_PANEL_TYPE} , + {"area_spline" , HTML_REPORT_PANEL_AREA_SPLINE} , + {"bar" , HTML_REPORT_PANEL_BAR} , + {"plot_metric" , HTML_REPORT_PANEL_PLOT_METRIC} , + {"table_columns" , HTML_REPORT_PANEL_TABLE_COLS} , + {"thead" , T_HEAD} , + {"version" , GO_VERSION} , + }; + /* *INDENT-ON* */ + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + sp = 1; + + fpopen_obj (fp, 0); + for (i = 0; i < ARRAY_SIZE (json_i18n); ++i) { + fpskeysval (fp, json_i18n[i][0], _(json_i18n[i][1]), sp, 0); + } + fpclose_obj (fp, 0, 1); +} + +/* Output definitions for the given panel. */ +static void +print_json_def_summary (FILE * fp) +{ + int sp = 0; + + /* use tabs to prettify output */ + if (conf.json_pretty_print) + sp = 1; + + /* output open panel attribute */ + fpopen_obj_attr (fp, GENER_ID, sp); + print_def_meta (fp, _(T_HEAD), "", sp); + print_def_summary (fp, sp); + /* output close panel attribute */ + fpclose_obj (fp, sp, 0); +} + +/* Entry point to output definitions for all panels. */ +static void +print_json_defs (FILE * fp) +{ + const GHTML *def; + size_t idx = 0; + + fprintf (fp, ""); +} + +/* entry point to generate a report writing it to the fp */ +void +output_html (GLog * glog, GHolder * holder, const char *filename) +{ + FILE *fp; + char now[DATE_TIME]; + + if (filename != NULL) + fp = fopen (filename, "w"); + else + fp = stdout; + + if (!fp) + FATAL ("Unable to open HTML file: %s.", strerror (errno)); + + /* use new lines to prettify output */ + if (conf.json_pretty_print) + nlines = 1; + set_json_nlines (nlines); + + generate_time (); + strftime (now, DATE_TIME, "%Y-%m-%d %H:%M:%S %z", now_tm); + + print_html_header (fp); + + print_html_body (fp, now); + print_json_defs (fp); + print_json_data (fp, glog, holder); + print_conn_def (fp); + + print_html_footer (fp); + + fclose (fp); +} diff --git a/goaccess++/src/output.h b/goaccess++/src/output.h new file mode 100644 index 0000000..35468f0 --- /dev/null +++ b/goaccess++/src/output.h @@ -0,0 +1,99 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include +#endif + +#ifndef OUTPUT_H_INCLUDED +#define OUTPUT_H_INCLUDED + +#define MAX_PLOTS 5 /* number of metrics we can plot */ + +#include "commons.h" +#include "parser.h" + +/* Enumerated chart types */ +typedef enum GChartType_ +{ + CHART_NONE, + CHART_VBAR, + CHART_AREASPLINE, +} GChartType; + +/* Chart axis structure */ +typedef struct GChartDef_ +{ + const char *key; + const char *value; +} GChartDef; + +/* Chart axis structure */ +typedef struct GChart_ +{ + const char *key; + GChartDef *def; +} GChart; + +/* Chart behavior */ +typedef struct GHTMLPlot_ +{ + GChartType chart_type; + void (*plot) (FILE * fp, struct GHTMLPlot_ plot, int sp); + int8_t chart_reverse; + int8_t redraw_expand; + char *chart_key; + char *chart_lbl; +} GHTMLPlot; + +/* Controls HTML panel output. */ +typedef struct GHTML_ +{ + GModule module; + int8_t table; + void (*metrics) (FILE * fp, const struct GHTML_ * def, int sp); + GHTMLPlot chart[MAX_PLOTS]; +} GHTML; + +/* Metric definition . */ +typedef struct GDefMetric_ +{ + const char *cname; /* metric class name */ + const char *cwidth; /* metric column width */ + const char *datakey; /* metric JSON data key */ + const char *datatype; /* metric data value type */ + const char *lbl; /* metric label (column name) */ + const char *metakey; /* metric JSON meta key */ + const char *metatype; /* metric meta value type */ + const char *metalbl; /* metric meta value label */ +} GDefMetric; + +void output_html (GLog * glog, GHolder * holder, const char *filename); + +#endif diff --git a/goaccess++/src/output.o b/goaccess++/src/output.o new file mode 100644 index 0000000..016c740 Binary files /dev/null and b/goaccess++/src/output.o differ diff --git a/goaccess++/src/parser.c b/goaccess++/src/parser.c new file mode 100644 index 0000000..0af8345 --- /dev/null +++ b/goaccess++/src/parser.c @@ -0,0 +1,2804 @@ +/** + * parser.c -- web log parsing + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * "_XOPEN_SOURCE" is required for the GNU libc to export "strptime(3)" + * correctly. + */ +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#define _XOPEN_SOURCE 700 + +#include +#include + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#include "tcbtdb.h" +#else +#include "gkhash.h" +#endif + +#ifdef HAVE_GEOLOCATION +#include "geoip1.h" +#endif + +#include "parser.h" + +#include "browsers.h" +#include "goaccess.h" +#include "error.h" +#include "opesys.h" +#include "util.h" +#include "xmalloc.h" + +/* private prototypes */ +/* key/data generators for each module */ +static int gen_visitor_key (GKeyData * kdata, GLogItem * logitem); +static int gen_404_key (GKeyData * kdata, GLogItem * logitem); +static int gen_browser_key (GKeyData * kdata, GLogItem * logitem); +static int gen_host_key (GKeyData * kdata, GLogItem * logitem); +static int gen_keyphrase_key (GKeyData * kdata, GLogItem * logitem); +static int gen_os_key (GKeyData * kdata, GLogItem * logitem); +static int gen_vhost_key (GKeyData * kdata, GLogItem * logitem); +static int gen_remote_user_key (GKeyData * kdata, GLogItem * logitem); +static int gen_referer_key (GKeyData * kdata, GLogItem * logitem); +static int gen_ref_site_key (GKeyData * kdata, GLogItem * logitem); +static int gen_request_key (GKeyData * kdata, GLogItem * logitem); +static int gen_static_request_key (GKeyData * kdata, GLogItem * logitem); +static int gen_status_code_key (GKeyData * kdata, GLogItem * logitem); +static int gen_visit_time_key (GKeyData * kdata, GLogItem * logitem); +#ifdef HAVE_GEOLOCATION +static int gen_geolocation_key (GKeyData * kdata, GLogItem * logitem); +#endif + +/* insertion routines */ +static void insert_data (int data_nkey, const char *data, GModule module); +static void insert_rootmap (int root_nkey, const char *root, GModule module); + +/* insertion metric routines */ +static void insert_hit (int data_nkey, GModule module); +static void insert_visitor (int uniq_nkey, GModule module); +static void insert_bw (int data_nkey, uint64_t size, GModule module); +static void insert_cumts (int data_nkey, uint64_t ts, GModule module); +static void insert_maxts (int data_nkey, uint64_t ts, GModule module); +static void insert_method (int data_nkey, const char *method, GModule module); +static void insert_protocol (int data_nkey, const char *proto, GModule module); +static void insert_agent (int data_nkey, int agent_nkey, GModule module); + +/* *INDENT-OFF* */ +static GParse paneling[] = { + { + VISITORS, + gen_visitor_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, { + REQUESTS, + gen_request_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + insert_method, + insert_protocol, + NULL, + }, { + REQUESTS_STATIC, + gen_static_request_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + insert_method, + insert_protocol, + NULL, + }, { + NOT_FOUND, + gen_404_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + insert_method, + insert_protocol, + NULL, + }, { + HOSTS, + gen_host_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + insert_agent, + }, { + OS, + gen_os_key, + insert_data, + insert_rootmap, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + insert_method, + insert_protocol, + NULL, + }, { + BROWSERS, + gen_browser_key, + insert_data, + insert_rootmap, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, { + REFERRERS, + gen_referer_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, { + REFERRING_SITES, + gen_ref_site_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, { + KEYPHRASES, + gen_keyphrase_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, +#ifdef HAVE_GEOLOCATION + { + GEO_LOCATION, + gen_geolocation_key, + insert_data, + insert_rootmap, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, +#endif + { + STATUS_CODES, + gen_status_code_key, + insert_data, + insert_rootmap, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, { + VISIT_TIMES, + gen_visit_time_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, { + VIRTUAL_HOSTS, + gen_vhost_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, { + REMOTE_USER, + gen_remote_user_key, + insert_data, + NULL, + insert_hit, + insert_visitor, + insert_bw, + insert_cumts, + insert_maxts, + NULL, + NULL, + NULL, + }, +}; +/* *INDENT-ON* */ + +/* Initialize a new GKeyData instance */ +static void +new_modulekey (GKeyData * kdata) +{ + GKeyData key = { + .data = NULL, + .data_key = NULL, + .data_nkey = 0, + .root = NULL, + .root_key = NULL, + .root_nkey = 0, + .uniq_key = NULL, + .uniq_nkey = 0, + }; + *kdata = key; +} + +/* Get a panel from the GParse structure given a module. + * + * On error, or if not found, NULL is returned. + * On success, the panel value is returned. */ +static GParse * +panel_lookup (GModule module) +{ + int i, num_panels = ARRAY_SIZE (paneling); + + for (i = 0; i < num_panels; i++) { + if (paneling[i].module == module) + return &paneling[i]; + } + return NULL; +} + +/* Allocate memory for a new GRawData instance. + * + * On success, the newly allocated GRawData is returned . */ +GRawData * +new_grawdata (void) +{ + GRawData *raw_data = xmalloc (sizeof (*raw_data)); + memset (raw_data, 0, sizeof *raw_data); + + return raw_data; +} + +/* Allocate memory for a new GRawDataItem instance. + * + * On success, the newly allocated GRawDataItem is returned . */ +GRawDataItem * +new_grawdata_item (unsigned int size) +{ + GRawDataItem *item = xcalloc (size, sizeof (*item)); + return item; +} + +#ifdef HAVE_LIBTOKYOCABINET +/* This is due to an additional allocation on tokyo's value + * retrieval :( on tcadbget() */ +static void +free_raw_data_str_value (GRawData * raw_data) +{ + int i = 0; + char *str = NULL; + + for (i = 0; i < raw_data->size; ++i) { + str = raw_data->items[i].value.svalue; + if (str) + free (str); + } +} +#endif + +/* Free memory allocated for a GRawData and GRawDataItem instance. */ +void +free_raw_data (GRawData * raw_data) +{ +#ifdef HAVE_LIBTOKYOCABINET + if (raw_data->type == STRING) + free_raw_data_str_value (raw_data); +#endif + free (raw_data->items); + free (raw_data); +} + +/* Reset an instance of GLog structure. */ +void +reset_struct (GLog * glog) +{ + glog->invalid = 0; + glog->processed = 0; + glog->resp_size = 0LL; + glog->valid = 0; +} + +/* Allocate memory for a new GLog instance. + * + * On success, the newly allocated GLog is returned . */ +GLog * +init_log (void) +{ + GLog *glog = xmalloc (sizeof (GLog)); + memset (glog, 0, sizeof *glog); + + return glog; +} + +/* Initialize a new GLogItem instance. + * + * On success, the new GLogItem instance is returned. */ +GLogItem * +init_log_item (GLog * glog) +{ + GLogItem *logitem; + glog->items = xmalloc (sizeof (GLogItem)); + logitem = glog->items; + memset (logitem, 0, sizeof *logitem); + + logitem->agent = NULL; + logitem->browser = NULL; + logitem->browser_type = NULL; + logitem->continent = NULL; + logitem->country = NULL; + logitem->date = NULL; + logitem->errstr = NULL; + logitem->host = NULL; + logitem->keyphrase = NULL; + logitem->method = NULL; + logitem->os = NULL; + logitem->os_type = NULL; + logitem->protocol = NULL; + logitem->qstr = NULL; + logitem->ref = NULL; + logitem->req_key = NULL; + logitem->req = NULL; + logitem->resp_size = 0LL; + logitem->serve_time = 0; + logitem->status = NULL; + logitem->time = NULL; + logitem->uniq_key = NULL; + logitem->vhost = NULL; + logitem->userid = NULL; + + memset (logitem->site, 0, sizeof (logitem->site)); + + return logitem; +} + +/* Free all members of a GLogItem */ +static void +free_glog (GLogItem * logitem) +{ + if (logitem->agent != NULL) + free (logitem->agent); + if (logitem->browser != NULL) + free (logitem->browser); + if (logitem->browser_type != NULL) + free (logitem->browser_type); + if (logitem->continent != NULL) + free (logitem->continent); + if (logitem->country != NULL) + free (logitem->country); + if (logitem->date != NULL) + free (logitem->date); + if (logitem->errstr != NULL) + free (logitem->errstr); + if (logitem->host != NULL) + free (logitem->host); + if (logitem->keyphrase != NULL) + free (logitem->keyphrase); + if (logitem->method != NULL) + free (logitem->method); + if (logitem->os != NULL) + free (logitem->os); + if (logitem->os_type != NULL) + free (logitem->os_type); + if (logitem->protocol != NULL) + free (logitem->protocol); + if (logitem->qstr != NULL) + free (logitem->qstr); + if (logitem->ref != NULL) + free (logitem->ref); + if (logitem->req_key != NULL) + free (logitem->req_key); + if (logitem->req != NULL) + free (logitem->req); + if (logitem->status != NULL) + free (logitem->status); + if (logitem->time != NULL) + free (logitem->time); + if (logitem->uniq_key != NULL) + free (logitem->uniq_key); + if (logitem->userid != NULL) + free (logitem->userid); + if (logitem->vhost != NULL) + free (logitem->vhost); + + free (logitem); +} + +/* Decodes the given URL-encoded string. + * + * On success, the decoded string is assigned to the output buffer. */ +#define B16210(x) (((x) >= '0' && (x) <= '9') ? ((x) - '0') : (toupper((x)) - 'A' + 10)) +static void +decode_hex (char *url, char *out) +{ + char *ptr; + const char *c; + + for (c = url, ptr = out; *c; c++) { + if (*c != '%' || !isxdigit (c[1]) || !isxdigit (c[2])) { + *ptr++ = *c; + } else { + *ptr++ = (B16210 (c[1]) * 16) + (B16210 (c[2])); + c += 2; + } + } + *ptr = 0; +} + +/* Entry point to decode the given URL-encoded string. + * + * On success, the decoded trimmed string is assigned to the output + * buffer. */ +static char * +decode_url (char *url) +{ + char *out, *decoded; + + if ((url == NULL) || (*url == '\0')) + return NULL; + + out = decoded = xstrdup (url); + decode_hex (url, out); + /* double encoded URL? */ + if (conf.double_decode) + decode_hex (decoded, out); + strip_newlines (out); + + return trim_str (out); +} + +/* Process keyphrases from Google search, cache, and translate. + * Note that the referer hasn't been decoded at the entry point + * since there could be '&' within the search query. + * + * On error, 1 is returned. + * On success, the extracted keyphrase is assigned and 0 is returned. */ +static int +extract_keyphrase (char *ref, char **keyphrase) +{ + char *r, *ptr, *pch, *referer; + int encoded = 0; + + if (!(strstr (ref, "http://www.google.")) && + !(strstr (ref, "http://webcache.googleusercontent.com/")) && + !(strstr (ref, "http://translate.googleusercontent.com/")) && + !(strstr (ref, "https://www.google.")) && + !(strstr (ref, "https://webcache.googleusercontent.com/")) && + !(strstr (ref, "https://translate.googleusercontent.com/"))) + return 1; + + /* webcache.googleusercontent */ + if ((r = strstr (ref, "/+&")) != NULL) + return 1; + /* webcache.googleusercontent */ + else if ((r = strstr (ref, "/+")) != NULL) + r += 2; + /* webcache.googleusercontent */ + else if ((r = strstr (ref, "q=cache:")) != NULL) { + pch = strchr (r, '+'); + if (pch) + r += pch - r + 1; + } + /* www.google.* or translate.googleusercontent */ + else if ((r = strstr (ref, "&q=")) != NULL || + (r = strstr (ref, "?q=")) != NULL) + r += 3; + else if ((r = strstr (ref, "%26q%3D")) != NULL || + (r = strstr (ref, "%3Fq%3D")) != NULL) + encoded = 1, r += 7; + else + return 1; + + if (!encoded && (ptr = strchr (r, '&')) != NULL) + *ptr = '\0'; + else if (encoded && (ptr = strstr (r, "%26")) != NULL) + *ptr = '\0'; + + referer = decode_url (r); + if (referer == NULL || *referer == '\0') + return 1; + + referer = char_replace (referer, '+', ' '); + *keyphrase = trim_str (referer); + + return 0; +} + +#ifdef HAVE_GEOLOCATION +/* Extract geolocation for the given host. + * + * On error, 1 is returned. + * On success, the extracted continent and country are set and 0 is + * returned. */ +static int +extract_geolocation (GLogItem * logitem, char *continent, char *country) +{ + if (!is_geoip_resource ()) + return 1; + + geoip_get_country (logitem->host, country, logitem->type_ip); + geoip_get_continent (logitem->host, continent, logitem->type_ip); + + return 0; +} +#endif + + +/* Parse a URI and extracts the *host* part from it + * i.e., //www.example.com/path?googleguy > www.example.com + * + * On error, 1 is returned. + * On success, the extracted referer is set and 0 is returned. */ +static int +extract_referer_site (const char *referer, char *host) +{ + char *url, *begin, *end; + int len = 0; + + if ((referer == NULL) || (*referer == '\0')) + return 1; + + url = strdup (referer); + if ((begin = strstr (url, "//")) == NULL) + goto clean; + + begin += 2; + if ((len = strlen (begin)) == 0) + goto clean; + + if ((end = strchr (begin, '/')) != NULL) + len = end - begin; + + if (len == 0) + goto clean; + + if (len >= REF_SITE_LEN) + len = REF_SITE_LEN; + + memcpy (host, begin, len); + host[len] = '\0'; + free (url); + return 0; +clean: + free (url); + + return 1; +} + +/* Determine if the given request is static (e.g., jpg, css, js, etc). + * + * On error, or if not static, 0 is returned. + * On success, the 1 is returned. */ +static int +verify_static_content (const char *req) +{ + const char *nul = req + strlen (req); + const char *ext = NULL, *pch = NULL; + int elen = 0, i; + + if (strlen (req) < conf.static_file_max_len) + return 0; + + for (i = 0; i < conf.static_file_idx; ++i) { + ext = conf.static_files[i]; + if (ext == NULL || *ext == '\0') + continue; + + elen = strlen (ext); + if (conf.all_static_files && (pch = strchr (req, '?')) != NULL && + pch - req > elen) { + pch -= elen; + if (0 == strncasecmp (ext, pch, elen)) + return 1; + continue; + } + + if (!strncasecmp (nul - elen, ext, elen)) + return 1; + } + + return 0; +} + +/* Extract the HTTP method. + * + * On error, or if not found, NULL is returned. + * On success, the HTTP method is returned. */ +static const char * +extract_method (const char *token) +{ + const char *methods[] = { + "OPTIONS", "GET", "HEAD", "POST", "PUT", + "DELETE", "TRACE", "CONNECT", "PATCH", "options", + "get", "head", "post", "put", "delete", + "trace", "connect", "patch", + /* WebDAV */ + "PROPFIND", "PROPPATCH", "MKCOL", "COPY", "MOVE", + "LOCK", "UNLOCK", "VERSION-CONTROL", "REPORT", "CHECKOUT", + "CHECKIN", "UNCHECKOUT", "MKWORKSPACE", "UPDATE", "LABEL", + "MERGE", "BASELINE-CONTROL", "MKACTIVITY", "ORDERPATCH", "propfind", + "propwatch", "mkcol", "copy", "move", "lock", + "unlock", "version-control", "report", "checkout", "checkin", + "uncheckout", "mkworkspace", "update", "label", "merge", + "baseline-control", "mkactivity", "orderpatch" + }; + + const int methods_count = sizeof (methods) / sizeof (*methods); + + int i; + /* Length of every string in list */ + static int list_length[sizeof (methods) / sizeof (*methods)] = { -1 }; + /* Only calculate length on first time */ + if (list_length[0] == -1) { + for (i = 0; i < methods_count; i++) { + list_length[i] = strlen (methods[i]); + } + } + + for (i = 0; i < methods_count; i++) { + if (strncmp (token, methods[i], list_length[i]) == 0) { + return methods[i]; + } + } + return NULL; +} + +/* Determine if time-served data was stored on-disk. */ +static void +contains_usecs (void) +{ + if (conf.serve_usecs) + return; + +#ifdef TCB_BTREE + ht_insert_genstats ("serve_usecs", 1); +#endif + conf.serve_usecs = 1; /* flag */ +} + +/* Determine if the given token is a valid HTTP protocol. + * + * If not valid, 1 is returned. + * If valid, 0 is returned. */ +static const char * +extract_protocol (const char *token) +{ + const char *lookfor; + + if ((lookfor = "HTTP/1.0", !strncmp (token, lookfor, 8)) || + (lookfor = "HTTP/1.1", !strncmp (token, lookfor, 8)) || + (lookfor = "HTTP/2", !strncmp (token, lookfor, 6))) + return lookfor; + return NULL; +} + +/* Parse a request containing the method and protocol. + * + * On error, or unable to parse, NULL is returned. + * On success, the HTTP request is returned and the method and + * protocol are assigned to the corresponding buffers. */ +static char * +parse_req (char *line, char **method, char **protocol) +{ + char *req = NULL, *request = NULL, *dreq = NULL, *ptr = NULL; + const char *meth, *proto; + ptrdiff_t rlen; + + meth = extract_method (line); + + /* couldn't find a method, so use the whole request line */ + if (meth == NULL) { + request = xstrdup (line); + } + /* method found, attempt to parse request */ + else { + req = line + strlen (meth); + if (!(ptr = strrchr (req, ' ')) || !(proto = extract_protocol (++ptr))) + return alloc_string ("-"); + + req++; + if ((rlen = ptr - req) <= 0) + return alloc_string ("-"); + + request = xmalloc (rlen + 1); + strncpy (request, req, rlen); + request[rlen] = 0; + + if (conf.append_method) + (*method) = strtoupper (xstrdup (meth)); + + if (conf.append_protocol) + (*protocol) = strtoupper (xstrdup (proto)); + } + + if (!(dreq = decode_url (request))) + return request; + else if (*dreq == '\0') { + free (dreq); + return request; + } + + free (request); + return dreq; +} + +/* Extract the next delimiter given a log format and copy the + * delimiter(s) to the destination buffer. + * Note that it's possible to store up to two delimiters. + * + * On error, the function returns. + * On success, the delimiter(s) are stored in the dest buffer and the + * number of extra delimiters is returned. */ +static int +get_delim (char *dest, const char *p) +{ + /* done, nothing to do */ + if (p[0] == '\0' || p[1] == '\0') { + dest[0] = '\0'; + return 0; + } + /* add the first delim */ + dest[0] = *(p + 1); + /* check if there's another possible delim */ + if (p[2] == '|' && p[3] != '%' && p[3] != '\0') { + dest[1] = *(p + 3); + return 1; + } + return 0; +} + +/* Extract and malloc a token given the parsed rule. + * + * On success, the malloc'd token is returned. */ +static char * +parsed_string (const char *pch, char **str, int move_ptr) +{ + char *p; + size_t len = (pch - *str + 1); + + p = xmalloc (len); + memcpy (p, *str, (len - 1)); + p[len - 1] = '\0'; + if (move_ptr) + *str += len - 1; + + return trim_str (p); +} + +/* Find and extract a token given a log format rule. + * + * On error, or unable to parse it, NULL is returned. + * On success, the malloc'd token is returned. */ +static char * +parse_string (char **str, const char *delims, int cnt) +{ + int idx = 0; + char *pch = *str, *p = NULL; + char end; + + if ((*delims != 0x0) && (p = strpbrk (*str, delims)) == NULL) + return NULL; + + end = !*delims ? 0x0 : *p; + do { + /* match number of delims */ + if (*pch == end) + idx++; + /* delim found, parse string then */ + if ((*pch == end && cnt == idx) || *pch == '\0') + return parsed_string (pch, str, 1); + /* advance to the first unescaped delim */ + if (*pch == '\\') + pch++; + } while (*pch++); + + return NULL; +} + +/* Move forward through the log string until a non-space (!isspace) + * char is found. */ +static void +find_alpha (char **str) +{ + char *s = *str; + while (*s) { + if (isspace (*s)) + s++; + else + break; + } + *str += s - *str; +} + +/* Format the broken-down time tm to a numeric date format. + * + * On error, or unable to format the given tm, 1 is returned. + * On success, a malloc'd format is returned. */ +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +static int +set_date (char **fdate, struct tm tm) +{ + char buf[DATE_LEN] = ""; /* Ymd */ + + memset (buf, 0, sizeof (buf)); + if (strftime (buf, DATE_LEN, conf.date_num_format, &tm) <= 0) + return 1; + *fdate = xstrdup (buf); + + return 0; +} + +/* Format the broken-down time tm to a numeric time format. + * + * On error, or unable to format the given tm, 1 is returned. + * On success, a malloc'd format is returned. */ +static int +set_time (char **ftime, struct tm tm) +{ + char buf[TIME_LEN] = ""; + + memset (buf, 0, sizeof (buf)); + if (strftime (buf, TIME_LEN, "%H:%M:%S", &tm) <= 0) + return 1; + *ftime = xstrdup (buf); + + return 0; +} + +/* Determine the parsing specifier error and construct a message out + * of it. + * + * On success, a malloc'd error message is assigned to the log + * structure and 1 is returned. */ +static int +spec_err (GLogItem * logitem, int code, const char spec, const char *tkn) +{ + char *err = NULL; + const char *fmt = NULL; + + switch (code) { + case SPEC_TOKN_INV: + fmt = "Token '%s' doesn't match specifier '%%%c'"; + err = xmalloc (snprintf (NULL, 0, fmt, (tkn ? tkn : "-"), spec) + 1); + sprintf (err, fmt, (tkn ? tkn : "-"), spec); + break; + case SPEC_TOKN_SET: + fmt = "Token already set for '%%%c' specifier."; + err = xmalloc (snprintf (NULL, 0, fmt, spec) + 1); + sprintf (err, fmt, spec); + break; + case SPEC_TOKN_NUL: + fmt = "Token for '%%%c' specifier is NULL."; + err = xmalloc (snprintf (NULL, 0, fmt, spec) + 1); + sprintf (err, fmt, spec); + break; + case SPEC_SFMT_MIS: + fmt = "Missing braces '%s' and ignore chars for specifier '%%%c'"; + err = xmalloc (snprintf (NULL, 0, fmt, (tkn ? tkn : "-"), spec) + 1); + sprintf (err, fmt, (tkn ? tkn : "-"), spec); + break; + } + logitem->errstr = err; + + return 1; +} + +#pragma GCC diagnostic warning "-Wformat-nonliteral" + +/* Parse the log string given log format rule. + * + * On error, or unable to parse it, 1 is returned. + * On success, the malloc'd token is assigned to a GLogItem member. */ +static int +parse_specifier (GLogItem * logitem, char **str, const char *p, const char *end) +{ + struct tm tm; + const char *dfmt = conf.date_format; + const char *tfmt = conf.time_format; + + char *pch, *sEnd, *bEnd, *tkn = NULL; + double serve_secs = 0.0; + uint64_t bandw = 0, serve_time = 0; + long status = 0L; + + errno = 0; + memset (&tm, 0, sizeof (tm)); + + switch (*p) { + /* date */ + case 'd': + if (logitem->date) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + /* parse date format including dates containing spaces, + * i.e., syslog date format (Jul 15 20:10:56) */ + if (!(tkn = parse_string (&(*str), end, count_matches (dfmt, ' ') + 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + if (str_to_time (tkn, dfmt, &tm) != 0 || set_date (&logitem->date, tm) != 0) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + free (tkn); + break; + /* time */ + case 't': + if (logitem->time) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + if (str_to_time (tkn, tfmt, &tm) != 0 || set_time (&logitem->time, tm) != 0) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + free (tkn); + break; + /* date/time as decimal, i.e., timestamps, ms/us */ + case 'x': + if (logitem->time && logitem->date) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + if (str_to_time (tkn, tfmt, &tm) != 0 || set_date (&logitem->date, tm) != 0 + || set_time (&logitem->time, tm) != 0) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + break; + /* Virtual Host */ + case 'v': + if (logitem->vhost) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + tkn = parse_string (&(*str), end, 1); + if (tkn == NULL) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + logitem->vhost = tkn; + break; + /* remote user */ + case 'e': + if (logitem->userid) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + tkn = parse_string (&(*str), end, 1); + if (tkn == NULL) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + logitem->userid = tkn; + break; + /* remote hostname (IP only) */ + case 'h': + if (logitem->host) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + if (invalid_ipaddr (tkn, &logitem->type_ip)) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + logitem->host = tkn; + break; + /* request method */ + case 'm': + if (logitem->method) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + if (!extract_method (tkn)) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + logitem->method = tkn; + break; + /* request not including method or protocol */ + case 'U': + if (logitem->req) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + tkn = parse_string (&(*str), end, 1); + if (tkn == NULL || *tkn == '\0') + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + if ((logitem->req = decode_url (tkn)) == NULL) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + free (tkn); + break; + /* query string alone, e.g., ?param=goaccess&tbm=shop */ + case 'q': + if (logitem->qstr) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + tkn = parse_string (&(*str), end, 1); + if (tkn == NULL || *tkn == '\0') + return 0; + + if ((logitem->qstr = decode_url (tkn)) == NULL) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + free (tkn); + break; + /* request protocol */ + case 'H': + if (logitem->protocol) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + if (!extract_protocol (tkn)) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + logitem->protocol = tkn; + break; + /* request, including method + protocol */ + case 'r': + if (logitem->req) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + logitem->req = parse_req (tkn, &logitem->method, &logitem->protocol); + free (tkn); + break; + /* Status Code */ + case 's': + if (logitem->status) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + status = strtol (tkn, &sEnd, 10); + if (tkn == sEnd || *sEnd != '\0' || errno == ERANGE || status < 100 || + status > 599) { + spec_err (logitem, SPEC_TOKN_INV, *p, tkn); + free (tkn); + return 1; + } + logitem->status = tkn; + break; + /* size of response in bytes - excluding HTTP headers */ + case 'b': + if (logitem->resp_size) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + bandw = strtoull (tkn, &bEnd, 10); + if (tkn == bEnd || *bEnd != '\0' || errno == ERANGE) + bandw = 0; + logitem->resp_size = bandw; + conf.bandwidth = 1; + free (tkn); + break; + /* referrer */ + case 'R': + if (logitem->ref) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + + if (!(tkn = parse_string (&(*str), end, 1))) + tkn = alloc_string ("-"); + if (*tkn == '\0') { + free (tkn); + tkn = alloc_string ("-"); + } + if (strcmp (tkn, "-") != 0) { + extract_keyphrase (tkn, &logitem->keyphrase); + extract_referer_site (tkn, logitem->site); + + /* hide referrers from report */ + if (hide_referer (logitem->site)) { + logitem->site[0] = '\0'; + free (tkn); + } else + logitem->ref = tkn; + break; + } + logitem->ref = tkn; + + break; + /* user agent */ + case 'u': + if (logitem->agent) + return spec_err (logitem, SPEC_TOKN_SET, *p, NULL); + + tkn = parse_string (&(*str), end, 1); + if (tkn != NULL && *tkn != '\0') { + /* Make sure the user agent is decoded (i.e.: CloudFront) + * and replace all '+' with ' ' (i.e.: w3c) */ + logitem->agent = decode_url (tkn); + free (tkn); + break; + } else if (tkn != NULL && *tkn == '\0') { + free (tkn); + tkn = alloc_string ("-"); + } + /* must be null */ + else { + tkn = alloc_string ("-"); + } + logitem->agent = tkn; + break; + /* time taken to serve the request, in milliseconds as a decimal number */ + case 'L': + /* ignore it if we already have served time */ + if (logitem->serve_time) + return 0; + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + serve_secs = strtoull (tkn, &bEnd, 10); + if (tkn == bEnd || *bEnd != '\0' || errno == ERANGE) + serve_secs = 0; + /* convert it to microseconds */ + logitem->serve_time = (serve_secs > 0) ? serve_secs * MILS : 0; + + contains_usecs (); /* set flag */ + free (tkn); + break; + /* time taken to serve the request, in seconds with a milliseconds + * resolution */ + case 'T': + /* ignore it if we already have served time */ + if (logitem->serve_time) + return 0; + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + if (strchr (tkn, '.') != NULL) + serve_secs = strtod (tkn, &bEnd); + else + serve_secs = strtoull (tkn, &bEnd, 10); + + if (tkn == bEnd || *bEnd != '\0' || errno == ERANGE) + serve_secs = 0; + /* convert it to microseconds */ + logitem->serve_time = (serve_secs > 0) ? serve_secs * SECS : 0; + + contains_usecs (); /* set flag */ + free (tkn); + break; + /* time taken to serve the request, in microseconds */ + case 'D': + /* ignore it if we already have served time */ + if (logitem->serve_time) + return 0; + if (!(tkn = parse_string (&(*str), end, 1))) + return spec_err (logitem, SPEC_TOKN_NUL, *p, NULL); + + serve_time = strtoull (tkn, &bEnd, 10); + if (tkn == bEnd || *bEnd != '\0' || errno == ERANGE) + serve_time = 0; + logitem->serve_time = serve_time; + + contains_usecs (); /* set flag */ + free (tkn); + break; + /* move forward through str until not a space */ + case '~': + find_alpha (&(*str)); + break; + /* everything else skip it */ + default: + if ((pch = strchr (*str, p[1])) != NULL) + *str += pch - *str; + } + + return 0; +} + +/* Parse the special host specifier and extract the characters that + * need to be rejected when attempting to parse the XFF field. + * + * If no unable to find both curly braces (boundaries), NULL is returned. + * On success, the malloc'd reject set is returned. */ +static char * +extract_braces (char **p) +{ + char *b1 = NULL, *b2 = NULL, *ret = NULL, *s = *p; + int esc = 0; + ptrdiff_t len = 0; + + /* iterate over the log format */ + for (; *s; s++) { + if (*s == '\\') { + esc = 1; + } else if (*s == '{' && !esc) { + b1 = s; + } else if (*s == '}' && !esc) { + b2 = s; + break; + } else { + esc = 0; + } + } + + if ((!b1) || (!b2)) + return NULL; + if ((len = b2 - (b1 + 1)) <= 0) + return NULL; + + /* Found braces, extract 'reject' character set. */ + ret = xmalloc (len + 1); + memcpy (ret, b1 + 1, len); + ret[len] = '\0'; + (*p) = b2 + 1; + + return ret; +} + +/* Attempt to extract the client IP from an X-Forwarded-For (XFF) field. + * + * If no IP is found, 1 is returned. + * On success, the malloc'd token is assigned to a GLogItem->host and + * 0 is returned. */ +static int +find_xff_host (GLogItem * logitem, char **str, char **p) +{ + char *ptr = NULL, *tkn = NULL, *skips = NULL; + int invalid_ip = 1, len = 0, type_ip = TYPE_IPINV; + + if (!(skips = extract_braces (p))) + return spec_err (logitem, SPEC_SFMT_MIS, **p, "{}"); + + ptr = *str; + while (*ptr != '\0') { + if ((len = strcspn (ptr, skips)) == 0) { + len++, ptr++; + goto move; + } + + ptr += len; + /* extract possible IP */ + if (!(tkn = parsed_string (ptr, str, 0))) + break; + + invalid_ip = invalid_ipaddr (tkn, &type_ip); + /* done, already have IP and current token is not a host */ + if (logitem->host && invalid_ip) { + free (tkn); + break; + } + if (!logitem->host && !invalid_ip) { + logitem->host = xstrdup (tkn); + logitem->type_ip = type_ip; + } + free (tkn); + + move: + *str += len; + } + + free (skips); + + return logitem->host == NULL; +} + +/* Handle special specifiers. + * + * On error, or unable to parse it, 1 is returned. + * On success, the malloc'd token is assigned to a GLogItem member and + * 0 is returned. */ +static int +special_specifier (GLogItem * logitem, char **str, char **p) +{ + switch (**p) { + /* XFF remote hostname (IP only) */ + case 'h': + if (logitem->host) + return spec_err (logitem, SPEC_TOKN_SET, **p, NULL); + if (find_xff_host (logitem, str, p)) + return spec_err (logitem, SPEC_TOKN_NUL, 'h', NULL); + break; + } + + return 0; +} + +/* Iterate over the given log format. + * + * On error, or unable to parse it, 1 is returned. + * On success, the malloc'd token is assigned to a GLogItem member and + * 0 is returned. */ +static int +parse_format (GLogItem * logitem, char *str) +{ + char end[2 + 1] = { 0 }; + char *lfmt = conf.log_format, *p = NULL; + int perc = 0, tilde = 0, optdelim = 0; + + if (str == NULL || *str == '\0') + return 1; + + /* iterate over the log format */ + for (p = lfmt; *p; p++) { + /* advance to the first unescaped delim */ + if (*p == '\\') + continue; + if (*p == '%') { + perc++; + continue; + } + if (*p == '~' && perc == 0) { + tilde++; + continue; + } + + if (tilde && *p != '\0') { + if ((str == NULL) || (*str == '\0')) + return 0; + if (special_specifier (logitem, &str, &p) == 1) + return 1; + tilde = 0; + } + /* %h */ + else if (perc && *p != '\0') { + if ((str == NULL) || (*str == '\0')) + return 0; + + memset (end, 0, sizeof end); + optdelim = get_delim (end, p); + /* attempt to parse format specifiers */ + if (parse_specifier (logitem, &str, p, end) == 1) + return 1; + /* account for the extra delimiter */ + if (optdelim) + p++; + perc = 0; + } else if (perc && isspace (p[0])) { + return 1; + } else { + str++; + } + } + + return 0; +} + +/* Determine if the log string is valid and if it's not a comment. + * + * On error, or invalid, 1 is returned. + * On success, or valid line, 0 is returned. */ +static int +valid_line (char *line) +{ + /* invalid line */ + if ((line == NULL) || (*line == '\0')) + return 1; + /* ignore comments */ + if (*line == '#' || *line == '\n') + return 1; + + return 0; +} + +/* Determine if we need to lock the mutex. */ +static void +lock_spinner (void) +{ + if (parsing_spinner != NULL && parsing_spinner->state == SPN_RUN) + pthread_mutex_lock (&parsing_spinner->mutex); +} + +/* Determine if we need to unlock the mutex. */ +static void +unlock_spinner (void) +{ + if (parsing_spinner != NULL && parsing_spinner->state == SPN_RUN) + pthread_mutex_unlock (&parsing_spinner->mutex); +} + +/* Ignore request's query string. e.g., + * /index.php?timestamp=1454385289 */ +static void +strip_qstring (char *req) +{ + char *qmark; + if ((qmark = strchr (req, '?')) != NULL) { + if ((qmark - req) > 0) + *qmark = '\0'; + } +} + +/* Increment the overall bandwidth. */ +static void +inc_resp_size (GLog * glog, uint64_t resp_size) +{ + glog->resp_size += resp_size; +#ifdef TCB_BTREE + ht_insert_genstats_bw ("bandwidth", resp_size); +#endif +} + +/* Output all log errors stored during parsing. */ +void +output_logerrors (GLog * glog) +{ + int i; + + if (!glog->log_erridx) + return; + + fprintf (stderr, ERR_PARSED_NLINES, glog->log_erridx); + fprintf (stderr, "%s:\n\n", ERR_PARSED_NLINES_DESC); + + for (i = 0; i < glog->log_erridx; ++i) + fprintf (stderr, "%s\n", glog->errors[i]); + fprintf (stderr, "\n%s\n", ERR_FORMAT_HEADER); +} + +/* Free all log errors stored during parsing. */ +void +free_logerrors (GLog * glog) +{ + int i; + + if (!glog->log_erridx) + return; + + for (i = 0; i < glog->log_erridx; ++i) + free (glog->errors[i]); + free (glog->errors); + + glog->errors = NULL; + glog->log_erridx = 0; +} + +/* Ensure we have the following fields. */ +static int +verify_missing_fields (GLogItem * logitem) +{ + /* must have the following fields */ + if (logitem->host == NULL) + logitem->errstr = xstrdup ("IPv4/6 is required."); + else if (logitem->date == NULL) + logitem->errstr = xstrdup ("A valid date is required."); + else if (logitem->req == NULL) + logitem->errstr = xstrdup ("A request is required."); + + return logitem->errstr != NULL; +} + +/* Keep track of all invalid log strings. */ +static void +count_invalid (GLog * glog, const char *line) +{ + glog->invalid++; +#ifdef TCB_BTREE + ht_insert_genstats ("failed_requests", 1); +#endif + if (conf.invalid_requests_log) { + LOG_INVALID (("%s", line)); + } + + if (glog->items->errstr && glog->invalid < MAX_LOG_ERRORS) { + if (glog->errors == NULL) + glog->errors = xcalloc (MAX_LOG_ERRORS, sizeof (char *)); + glog->errors[glog->log_erridx++] = xstrdup (glog->items->errstr); + } +} + +/* Count down the number of invalids hits. + * Note: Upon performing a log test, invalid hits are counted, since + * no valid records were found, then we count down by the number of + * tests ran. +*/ +static void +uncount_invalid (GLog * glog) +{ + glog->invalid -= conf.num_tests; +#ifdef TCB_BTREE + ht_replace_genstats ("failed_requests", glog->invalid); +#endif +} + +/* Count down the number of processed hits. + * Note: Upon performing a log test, processed hits are counted, since + * no valid records were found, then we count down by the number of + * tests ran. +*/ +static void +uncount_processed (GLog * glog) +{ + glog->processed -= conf.num_tests; +#ifdef TCB_BTREE + ht_replace_genstats ("total_requests", glog->processed); +#endif +} + +/* Keep track of all valid log strings. */ +static void +count_valid (GLog * glog) +{ + lock_spinner (); + glog->valid++; +#ifdef TCB_BTREE + ht_insert_genstats ("valid_requests", 1); +#endif + unlock_spinner (); +} + +/* Keep track of all valid and processed log strings. */ +static void +count_process (GLog * glog) +{ + lock_spinner (); + glog->processed++; +#ifdef TCB_BTREE + ht_insert_genstats ("total_requests", 1); +#endif + unlock_spinner (); +} + +/* Keep track of all excluded log strings (IPs). + * + * If IP not range, 1 is returned. + * If IP is excluded, 0 is returned. */ +static int +excluded_ip (GLog * glog, GLogItem * logitem) +{ + if (conf.ignore_ip_idx && ip_in_range (logitem->host)) { + glog->excluded_ip++; +#ifdef TCB_BTREE + ht_insert_genstats ("excluded_ip", 1); +#endif + return 0; + } + return 1; +} + +/* Determine if the request is from a robot or spider and check if we + * need to ignore or show crawlers only. + * + * If the request line is not ignored, 0 is returned. + * If the request line is ignored, 1 is returned. */ +static int +handle_crawler (const char *agent) +{ + int bot = 0; + + if (!conf.ignore_crawlers && !conf.crawlers_only) + return 1; + + bot = is_crawler (agent); + return (conf.ignore_crawlers && bot) || (conf.crawlers_only && !bot) ? 0 : 1; +} + +/* A wrapper function to determine if the request is static. + * + * If the request is not static, 0 is returned. + * If the request is static, 1 is returned. */ +static int +is_static (const char *req) +{ + return verify_static_content (req); +} + +/* Determine if the request of the given status code needs to be + * ignored. + * + * If the status code is not within the ignore-array, 0 is returned. + * If the status code is within the ignore-array, 1 is returned. */ +static int +ignore_status_code (const char *status) +{ + if (conf.ignore_status_idx == 0) + return 0; + + if (str_inarray (status, conf.ignore_status, conf.ignore_status_idx) != -1) + return 1; + return 0; +} + +/* Determine if static file request should be ignored + * + * If the request line is not ignored, 0 is returned. + * If the request line is ignored, 1 is returned. */ +static int +ignore_static (const char *req) +{ + if (conf.ignore_statics && is_static (req)) + return 1; + return 0; +} + +/* Determine if the request status code is a 404. + * + * If the request is not a 404, 0 is returned. + * If the request is a 404, 1 is returned. */ +static int +is_404 (GLogItem * logitem) +{ + /* is this a 404? */ + if (logitem->status && !memcmp (logitem->status, "404", 3)) + return 1; + /* treat 444 as 404? */ + else if (logitem->status && !memcmp (logitem->status, "444", 3) && + conf.code444_as_404) + return 1; + return 0; +} + +/* A wrapper function to determine if a log line needs to be ignored. + * + * If the request line is not ignored, 0 is returned. + * If the request line is ignored, IGNORE_LEVEL_PANEL is returned. + * If the request line is only not counted as valid, IGNORE_LEVEL_REQ is returned. */ +static int +ignore_line (GLog * glog, GLogItem * logitem) +{ + if (excluded_ip (glog, logitem) == 0) + return IGNORE_LEVEL_PANEL; + if (handle_crawler (logitem->agent) == 0) + return IGNORE_LEVEL_PANEL; + if (ignore_referer (logitem->site)) + return IGNORE_LEVEL_PANEL; + if (ignore_status_code (logitem->status)) + return IGNORE_LEVEL_PANEL; + if (ignore_static (logitem->req)) + return conf.ignore_statics; // IGNORE_LEVEL_PANEL or IGNORE_LEVEL_REQ + + /* check if we need to remove the request's query string */ + if (conf.ignore_qstr) + strip_qstring (logitem->req); + + return 0; +} + +/* A wrapper function to insert a keymap string key. + * + * If the given key exists, its value is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +static int +insert_keymap (char *key, GModule module) +{ + return ht_insert_keymap (module, key); +} + +/* A wrapper function to insert a datamap int key and string value. */ +static void +insert_data (int nkey, const char *data, GModule module) +{ + ht_insert_datamap (module, nkey, data); +} + +/* A wrapper function to insert a uniqmap string key. + * + * If the given key exists, 0 is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +static int +insert_uniqmap (char *uniq_key, GModule module) +{ + return ht_insert_uniqmap (module, uniq_key); +} + +/* A wrapper function to insert a rootmap int key from the keymap + * store mapped to its string value. */ +static void +insert_rootmap (int root_nkey, const char *root, GModule module) +{ + ht_insert_rootmap (module, root_nkey, root); +} + +/* A wrapper function to insert a data int key mapped to the + * corresponding int root key. */ +static void +insert_root (int data_nkey, int root_nkey, GModule module) +{ + ht_insert_root (module, data_nkey, root_nkey); +} + +/* A wrapper function to increase hits counter from an int key. */ +static void +insert_hit (int data_nkey, GModule module) +{ + ht_insert_hits (module, data_nkey, 1); + ht_insert_meta_data (module, "hits", 1); +} + +/* A wrapper function to increase visitors counter from an int + * key. */ +static void +insert_visitor (int uniq_nkey, GModule module) +{ + ht_insert_visitor (module, uniq_nkey, 1); + ht_insert_meta_data (module, "visitors", 1); +} + +/* A wrapper function to increases bandwidth counter from an int + * key. */ +static void +insert_bw (int data_nkey, uint64_t size, GModule module) +{ + ht_insert_bw (module, data_nkey, size); + ht_insert_meta_data (module, "bytes", size); +} + +/* A wrapper call to increases cumulative time served counter + * from an int key. */ +static void +insert_cumts (int data_nkey, uint64_t ts, GModule module) +{ + ht_insert_cumts (module, data_nkey, ts); + ht_insert_meta_data (module, "cumts", ts); +} + +/* A wrapper call to insert the maximum time served counter from + * an int key. */ +static void +insert_maxts (int data_nkey, uint64_t ts, GModule module) +{ + ht_insert_maxts (module, data_nkey, ts); + ht_insert_meta_data (module, "maxts", ts); +} + +static void +insert_method (int nkey, const char *data, GModule module) +{ + ht_insert_method (module, nkey, data ? data : "---"); +} + +/* A wrapper call to insert a method given an int key and string + * value. */ +static void +insert_protocol (int nkey, const char *data, GModule module) +{ + ht_insert_protocol (module, nkey, data ? data : "---"); +} + +/* A wrapper call to insert an agent for a hostname given an int + * key and int value. */ +static void +insert_agent (int data_nkey, int agent_nkey, GModule module) +{ + ht_insert_agent (module, data_nkey, agent_nkey); +} + +/* The following generates a unique key to identity unique visitors. + * The key is made out of the IP, date, and user agent. + * Note that for readability, doing a simple snprintf/sprintf should + * suffice, however, memcpy is the fastest solution + * + * On success the new unique visitor key is returned */ +static char * +get_uniq_visitor_key (GLogItem * logitem) +{ + char *ua = NULL, *key = NULL; + size_t s1, s2, s3; + + ua = deblank (xstrdup (logitem->agent)); + + s1 = strlen (logitem->host); + s2 = strlen (logitem->date); + s3 = strlen (ua); + + /* includes terminating null */ + key = xcalloc (s1 + s2 + s3 + 3, sizeof (char)); + + memcpy (key, logitem->host, s1); + + key[s1] = '|'; + memcpy (key + s1 + 1, logitem->date, s2 + 1); + + key[s1 + s2 + 1] = '|'; + memcpy (key + s1 + s2 + 2, ua, s3 + 1); + + free (ua); + return key; +} + +/* The following generates a unique key to identity unique requests. + * The key is made out of the actual request, and if available, the + * method and the protocol. Note that for readability, doing a simple + * snprintf/sprintf should suffice, however, memcpy is the fastest + * solution + * + * On success the new unique request key is returned */ +static char * +gen_unique_req_key (GLogItem * logitem) +{ + char *key = NULL; + size_t s1 = 0, s2 = 0, s3 = 0, nul = 1, sep = 0; + + /* nothing to do */ + if (!conf.append_method && !conf.append_protocol) + return xstrdup (logitem->req); + /* still nothing to do */ + if (!logitem->method && !logitem->protocol) + return xstrdup (logitem->req); + + s1 = strlen (logitem->req); + if (logitem->method && conf.append_method) { + s2 = strlen (logitem->method); + nul++; + } + if (logitem->protocol && conf.append_protocol) { + s3 = strlen (logitem->protocol); + nul++; + } + + /* includes terminating null */ + key = xcalloc (s1 + s2 + s3 + nul, sizeof (char)); + /* append request */ + memcpy (key, logitem->req, s1); + + if (logitem->method && conf.append_method) { + key[s1] = '|'; + sep++; + memcpy (key + s1 + sep, logitem->method, s2 + 1); + } + if (logitem->protocol && conf.append_protocol) { + key[s1 + s2 + sep] = '|'; + sep++; + memcpy (key + s1 + s2 + sep, logitem->protocol, s3 + 1); + } + + return key; +} + +/* Append the query string to the request, and therefore, it modifies + * the original logitem->req */ +static void +append_query_string (char **req, const char *qstr) +{ + char *r; + size_t s1, s2, qm = 0; + + s1 = strlen (*req); + s2 = strlen (qstr); + + /* add '?' between the URL and the query string */ + if (*qstr != '?') + qm = 1; + + r = xmalloc (s1 + s2 + qm + 1); + memcpy (r, *req, s1); + if (qm) + r[s1] = '?'; + memcpy (r + s1 + qm, qstr, s2 + 1); + + free (*req); + *req = r; +} + +/* A wrapper to assign the given data key and the data item to the key + * data structure */ +static void +get_kdata (GKeyData * kdata, char *data_key, char *data) +{ + /* inserted in keymap */ + kdata->data_key = data_key; + /* inserted in datamap */ + kdata->data = data; +} + +/* Generate a visitor's key given the date specificity. For instance, + * if the specificity if set to hours, then a generated key would + * look like: 03/Jan/2016:09 */ +static void +set_spec_visitor_key (char **fdate, const char *ftime) +{ + size_t dlen = 0, tlen = 0; + char *key = NULL, *tkey = NULL, *pch = NULL; + + tkey = xstrdup (ftime); + if (conf.date_spec_hr && (pch = strchr (tkey, ':')) && (pch - tkey) > 0) + *pch = '\0'; + + dlen = strlen (*fdate); + tlen = strlen (tkey); + + key = xmalloc (dlen + tlen + 1); + memcpy (key, *fdate, dlen); + memcpy (key + dlen, tkey, tlen + 1); + + free (*fdate); + free (tkey); + *fdate = key; +} + +/* Generate a unique key for the visitors panel from the given logitem + * structure and assign it to the output key data structure. + * + * On error, or if no date is found, 1 is returned. + * On success, the date key is assigned to our key data structure. + */ +static int +gen_visitor_key (GKeyData * kdata, GLogItem * logitem) +{ + if (!logitem->date || !logitem->time) + return 1; + + /* Append time specificity to date */ + if (conf.date_spec_hr) + set_spec_visitor_key (&logitem->date, logitem->time); + + get_kdata (kdata, logitem->date, logitem->date); + + return 0; +} + +/* Generate a unique key for the requests panel from the given logitem + * structure and assign it to out key data structure. + * + * On success, the generated request key is assigned to our key data + * structure. + */ +static int +gen_req_key (GKeyData * kdata, GLogItem * logitem) +{ + if (logitem->req && logitem->qstr) + append_query_string (&logitem->req, logitem->qstr); + logitem->req_key = gen_unique_req_key (logitem); + + get_kdata (kdata, logitem->req_key, logitem->req); + + return 0; +} + +/* A wrapper to generate a unique key for the request panel. + * + * On error, or if the request is static or a 404, 1 is returned. + * On success, the generated request key is assigned to our key data + * structure. + */ +static int +gen_request_key (GKeyData * kdata, GLogItem * logitem) +{ + if (!logitem->req || logitem->is_404 || logitem->is_static) + return 1; + + return gen_req_key (kdata, logitem); +} + +/* A wrapper to generate a unique key for the request panel. + * + * On error, or if the request is not a 404, 1 is returned. + * On success, the generated request key is assigned to our key data + * structure. */ +static int +gen_404_key (GKeyData * kdata, GLogItem * logitem) +{ + if (logitem->req && logitem->is_404) + return gen_req_key (kdata, logitem); + return 1; +} + +/* A wrapper to generate a unique key for the request panel. + * + * On error, or if the request is not a static request, 1 is returned. + * On success, the generated request key is assigned to our key data + * structure. */ +static int +gen_static_request_key (GKeyData * kdata, GLogItem * logitem) +{ + if (logitem->req && logitem->is_static) + return gen_req_key (kdata, logitem); + return 1; +} + +/* A wrapper to generate a unique key for the virtual host panel. + * + * On error, 1 is returned. + * On success, the generated vhost key is assigned to our key data + * structure. */ +static int +gen_vhost_key (GKeyData * kdata, GLogItem * logitem) +{ + if (!logitem->vhost) + return 1; + + get_kdata (kdata, logitem->vhost, logitem->vhost); + + return 0; +} + +/* A wrapper to generate a unique key for the virtual host panel. + * + * On error, 1 is returned. + * On success, the generated userid key is assigned to our key data + * structure. */ +static int +gen_remote_user_key (GKeyData * kdata, GLogItem * logitem) +{ + if (!logitem->userid) + return 1; + + get_kdata (kdata, logitem->userid, logitem->userid); + + return 0; +} + +/* A wrapper to generate a unique key for the hosts panel. + * + * On error, 1 is returned. + * On success, the generated host key is assigned to our key data + * structure. */ +static int +gen_host_key (GKeyData * kdata, GLogItem * logitem) +{ + if (!logitem->host) + return 1; + + get_kdata (kdata, logitem->host, logitem->host); + + return 0; +} + +/* Generate a browser unique key for the browser's panel given a user + * agent and assign the browser type/category as a root element. + * + * On error, 1 is returned. + * On success, the generated browser key is assigned to our key data + * structure. */ +static int +gen_browser_key (GKeyData * kdata, GLogItem * logitem) +{ + char *agent = NULL; + char browser_type[BROWSER_TYPE_LEN] = ""; + + if (logitem->agent == NULL || *logitem->agent == '\0') + return 1; + + agent = xstrdup (logitem->agent); + logitem->browser = verify_browser (agent, browser_type); + logitem->browser_type = xstrdup (browser_type); + + /* e.g., Firefox 11.12 */ + kdata->data = logitem->browser; + kdata->data_key = logitem->browser; + + /* Firefox */ + kdata->root = logitem->browser_type; + kdata->root_key = logitem->browser_type; + + free (agent); + + return 0; +} + +/* Generate an operating system unique key for the OS' panel given a + * user agent and assign the OS type/category as a root element. + * + * On error, 1 is returned. + * On success, the generated OS key is assigned to our key data + * structure. */ +static int +gen_os_key (GKeyData * kdata, GLogItem * logitem) +{ + char *agent = NULL; + char os_type[OPESYS_TYPE_LEN] = ""; + + if (logitem->agent == NULL || *logitem->agent == '\0') + return 1; + + agent = xstrdup (logitem->agent); + logitem->os = verify_os (agent, os_type); + logitem->os_type = xstrdup (os_type); + + /* e.g., Linux,Ubuntu 10.12 */ + kdata->data = logitem->os; + kdata->data_key = logitem->os; + + /* Linux */ + kdata->root = logitem->os_type; + kdata->root_key = logitem->os_type; + + free (agent); + + return 0; +} + +/* A wrapper to generate a unique key for the referrers panel. + * + * On error, 1 is returned. + * On success, the generated referrer key is assigned to our key data + * structure. */ +static int +gen_referer_key (GKeyData * kdata, GLogItem * logitem) +{ + if (!logitem->ref) + return 1; + + get_kdata (kdata, logitem->ref, logitem->ref); + + return 0; +} + +/* A wrapper to generate a unique key for the referring sites panel. + * + * On error, 1 is returned. + * On success, the generated referring site key is assigned to our key data + * structure. */ +static int +gen_ref_site_key (GKeyData * kdata, GLogItem * logitem) +{ + if (logitem->site[0] == '\0') + return 1; + + get_kdata (kdata, logitem->site, logitem->site); + + return 0; +} + +/* A wrapper to generate a unique key for the keyphrases panel. + * + * On error, 1 is returned. + * On success, the generated keyphrase key is assigned to our key data + * structure. */ +static int +gen_keyphrase_key (GKeyData * kdata, GLogItem * logitem) +{ + if (!logitem->keyphrase) + return 1; + + get_kdata (kdata, logitem->keyphrase, logitem->keyphrase); + + return 0; +} + +/* A wrapper to generate a unique key for the geolocation panel. + * + * On error, 1 is returned. + * On success, the generated geolocation key is assigned to our key + * data structure. */ +#ifdef HAVE_GEOLOCATION +static int +gen_geolocation_key (GKeyData * kdata, GLogItem * logitem) +{ + char continent[CONTINENT_LEN] = ""; + char country[COUNTRY_LEN] = ""; + + if (extract_geolocation (logitem, continent, country) == 1) + return 1; + + if (country[0] != '\0') + logitem->country = xstrdup (country); + + if (continent[0] != '\0') + logitem->continent = xstrdup (continent); + + kdata->data_key = logitem->country; + kdata->data = logitem->country; + + kdata->root = logitem->continent; + kdata->root_key = logitem->continent; + + return 0; +} +#endif + +/* A wrapper to generate a unique key for the status code panel. + * + * On error, 1 is returned. + * On success, the generated status code key is assigned to our key + * data structure. */ +static int +gen_status_code_key (GKeyData * kdata, GLogItem * logitem) +{ + const char *status = NULL, *type = NULL; + + if (!logitem->status) + return 1; + + type = verify_status_code_type (logitem->status); + status = verify_status_code (logitem->status); + + kdata->data = (char *) status; + kdata->data_key = (char *) status; + + kdata->root = (char *) type; + kdata->root_key = (char *) type; + + return 0; +} + +/* Given a time string containing at least %H:%M, extract either the + * tenth of a minute or an hour. + * + * On error, the given string is not modified. + * On success, the conf specificity is extracted. */ +static void +parse_time_specificity_string (char *hmark, char *ftime) +{ + /* tenth of a minute specificity - e.g., 18:2 */ + if (conf.hour_spec_min && hmark[1] != '\0') { + hmark[2] = '\0'; + return; + } + + /* hour specificity (default) */ + if ((hmark - ftime) > 0) + *hmark = '\0'; +} + +/* A wrapper to generate a unique key for the time distribution panel. + * + * On error, 1 is returned. + * On success, the generated time key is assigned to our key data + * structure. */ +static int +gen_visit_time_key (GKeyData * kdata, GLogItem * logitem) +{ + char *hmark = NULL; + char hour[HRMI_LEN] = ""; /* %H:%M */ + if (!logitem->time) + return 1; + + /* if not a timestamp, then it must be a string containing the hour. + * this is faster than actual date conversion */ + if (!has_timestamp (conf.time_format) && + (hmark = strchr (logitem->time, ':'))) { + parse_time_specificity_string (hmark, logitem->time); + get_kdata (kdata, logitem->time, logitem->time); + return 0; + } + + /* otherwise it attempts to convert the date given a time format, + * though this is slower */ + memset (hour, 0, sizeof *hour); + if (convert_date (hour, logitem->time, conf.time_format, "%H:%M", HRMI_LEN) != + 0) + return 1; + + if (*hour == '\0') + return 1; + + if ((hmark = strchr (hour, ':'))) + parse_time_specificity_string (hmark, hour); + + free (logitem->time); + logitem->time = xstrdup (hour); + get_kdata (kdata, logitem->time, logitem->time); + + return 0; +} + +/* Determine if 404s need to be added to the unique visitors count. + * + * If it needs to be added, 0 is returned else 1 is returned. */ +static int +include_uniq (GLogItem * logitem) +{ + int u = conf.client_err_to_unique_count; + + if (!logitem->status || logitem->status[0] != '4' || + (u && logitem->status[0] == '4')) + return 1; + return 0; +} + +/* Convert two integers keys to to a string (concatenated). + * + * On success, the given numbers as a string are returned. */ +static char * +intkeys2str (int a, int b) +{ + char *s = xmalloc (snprintf (NULL, 0, "%d|%d", a, b) + 1); + sprintf (s, "%d|%d", a, b); + + return s; +} + +/* Determine which data metrics need to be set and set them. */ +static void +set_datamap (GLogItem * logitem, GKeyData * kdata, const GParse * parse) +{ + GModule module; + module = parse->module; + + /* insert data */ + parse->datamap (kdata->data_nkey, kdata->data, module); + + /* insert rootmap and root-data map */ + if (parse->rootmap) { + parse->rootmap (kdata->root_nkey, kdata->root, module); + insert_root (kdata->data_nkey, kdata->root_nkey, module); + } + /* insert hits */ + if (parse->hits) + parse->hits (kdata->data_nkey, module); + /* insert visitors */ + if (parse->visitor && kdata->uniq_nkey != 0) + parse->visitor (kdata->data_nkey, module); + /* insert bandwidth */ + if (parse->bw) + parse->bw (kdata->data_nkey, logitem->resp_size, module); + /* insert averages time served */ + if (parse->cumts) + parse->cumts (kdata->data_nkey, logitem->serve_time, module); + /* insert averages time served */ + if (parse->maxts) + parse->maxts (kdata->data_nkey, logitem->serve_time, module); + /* insert method */ + if (parse->method && conf.append_method) + parse->method (kdata->data_nkey, logitem->method, module); + /* insert protocol */ + if (parse->protocol && conf.append_protocol) + parse->protocol (kdata->data_nkey, logitem->protocol, module); + /* insert agent */ + if (parse->agent && conf.list_agents) + parse->agent (kdata->data_nkey, logitem->agent_nkey, module); +} + +/* Set data mapping and metrics. */ +static void +map_log (GLogItem * logitem, const GParse * parse, GModule module) +{ + GKeyData kdata; + char *uniq_key = NULL; + + new_modulekey (&kdata); + if (parse->key_data (&kdata, logitem) == 1) + return; + + /* each module requires a data key/value */ + if (parse->datamap && kdata.data_key) + kdata.data_nkey = insert_keymap (kdata.data_key, module); + + /* each module contains a uniq visitor key/value */ + if (parse->visitor && logitem->uniq_key && include_uniq (logitem)) { + uniq_key = intkeys2str (logitem->uniq_nkey, kdata.data_nkey); + /* unique key already exists? */ + kdata.uniq_nkey = insert_uniqmap (uniq_key, module); + free (uniq_key); + } + + /* root keys are optional */ + if (parse->rootmap && kdata.root_key) + kdata.root_nkey = insert_keymap (kdata.root_key, module); + + /* each module requires a root key/value */ + if (parse->datamap && kdata.data_key) + set_datamap (logitem, &kdata, parse); +} + +/* Process a log line and set the data into the corresponding data + * structure. */ +static void +process_log (GLogItem * logitem) +{ + GModule module; + const GParse *parse = NULL; + size_t idx = 0; + + /* Insert one unique visitor key per request to avoid the + * overhead of storing one key per module */ + logitem->uniq_nkey = ht_insert_unique_key (logitem->uniq_key); + + /* If we need to store user agents per IP, then we store them and retrieve + * its numeric key. + * It maintains two maps, one for key -> value, and another + * map for value -> key*/ + if (conf.list_agents) { + /* insert UA key and get a numeric value */ + logitem->agent_nkey = ht_insert_agent_key (logitem->agent); + /* insert a numeric key and map it to a UA string */ + ht_insert_agent_value (logitem->agent_nkey, logitem->agent); + } + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + if (!(parse = panel_lookup (module))) + continue; + map_log (logitem, parse, module); + } +} + +/* Process a line from the log and store it accordingly taking into + * account multiple parsing options prior to setting data into the + * corresponding data structure. + * + * On success, 0 is returned */ +static int +pre_process_log (GLog * glog, char *line, int dry_run) +{ + GLogItem *logitem; + int ret = 0; + int ignorelevel = 0; + + /* soft ignore these lines */ + if (valid_line (line)) + return -1; + + count_process (glog); + logitem = init_log_item (glog); + /* Parse a line of log, and fill structure with appropriate values */ + if (parse_format (logitem, line) || verify_missing_fields (logitem)) { + ret = 1; + count_invalid (glog, line); + goto cleanup; + } + + /* agent will be null in cases where %u is not specified */ + if (logitem->agent == NULL) + logitem->agent = alloc_string ("-"); + + /* testing log only */ + if (dry_run) + goto cleanup; + + ignorelevel = ignore_line (glog, logitem); + /* ignore line */ + if (ignorelevel == IGNORE_LEVEL_PANEL) + goto cleanup; + + if (is_404 (logitem)) + logitem->is_404 = 1; + else if (is_static (logitem->req)) + logitem->is_static = 1; + + logitem->uniq_key = get_uniq_visitor_key (logitem); + + inc_resp_size (glog, logitem->resp_size); + process_log (logitem); + + /* don't ignore line but neither count as valid */ + if (ignorelevel != IGNORE_LEVEL_REQ) + count_valid (glog); + +cleanup: + free_glog (logitem); + + return ret; +} + +/* Entry point to process the given live from the log. + * + * On error, 1 is returned. + * On success or soft ignores, 0 is returned. */ +static int +read_line (GLog * glog, char *line, int *test, int *cnt, int dry_run) +{ + int ret = 0; + int tests = conf.num_tests; + + /* start processing log line */ + if ((ret = pre_process_log (glog, line, dry_run)) == 0 && *test) + *test = 0; + + /* soft ignores */ + if (ret == -1) + return 0; + + /* glog->processed can actually be less than conf.num_tests, so we make sure + * (cnt) compares to the right number */ + tests = MIN (conf.num_tests, glog->processed); + + /* reached num of lines to test and no valid records were found, log + * format is likely not matching */ + if (conf.num_tests && ++(*cnt) == tests && *test) { + uncount_processed (glog); + uncount_invalid (glog); + return 1; + } + + return 0; +} + +/* A replacement for GNU getline() to dynamically expand fgets buffer. + * + * On error, NULL is returned. + * On success, the malloc'd line is returned. */ +char * +fgetline (FILE * fp) +{ + char buf[LINE_BUFFER] = { 0 }; + char *line = NULL, *tmp = NULL; + size_t linelen = 0, len = 0; + + while (1) { + if (!fgets (buf, sizeof (buf), fp)) { + if (conf.process_and_exit && errno == EAGAIN) { + nanosleep ((const struct timespec[]) { { + 0, 100000000L}}, NULL); + continue; + } else + break; + } + + len = strlen (buf); + + /* overflow check */ + if (SIZE_MAX - len - 1 < linelen) + break; + + if ((tmp = realloc (line, linelen + len + 1)) == NULL) + break; + + line = tmp; + /* append */ + strcpy (line + linelen, buf); + linelen += len; + + if (feof (fp) || buf[len - 1] == '\n') + return line; + } + free (line); + + return NULL; +} + +/* Iterate over the log and read line by line (use GNU get_line to parse the + * whole line). + * + * On error, 1 is returned. + * On success, 0 is returned. */ +#ifdef WITH_GETLINE +static int +read_lines (FILE * fp, GLog ** glog, int dry_run) +{ + char *line = NULL; + int ret = 0, cnt = 0, test = conf.num_tests > 0 ? 1 : 0; + + while ((line = fgetline (fp)) != NULL) { + /* handle SIGINT */ + if (conf.stop_processing) + goto out; + if ((ret = read_line ((*glog), line, &test, &cnt, dry_run))) + goto out; + if (dry_run && NUM_TESTS == cnt) + goto out; + free (line); + } + + /* if no data was available to read from (probably from a pipe) and + * still in test mode, we simply return until data becomes available */ + if (!line && (errno == EAGAIN || errno == EWOULDBLOCK) && test) + return 0; + + return (line && test) || ret; + +out: + free (line); + return test || ret; +} +#endif + +/* Iterate over the log and read line by line (uses a buffer of fixed size). + * + * On error, 1 is returned. + * On success, 0 is returned. */ +#ifndef WITH_GETLINE +static int +read_lines (FILE * fp, GLog ** glog, int dry_run) +{ + char *s = NULL; + char line[LINE_BUFFER] = { 0 }; + int ret = 0, cnt = 0, test = conf.num_tests > 0 ? 1 : 0; + + while ((s = fgets (line, LINE_BUFFER, fp)) != NULL) { + /* handle SIGINT */ + if (conf.stop_processing) + break; + if ((ret = read_line ((*glog), line, &test, &cnt, dry_run))) + break; + if (dry_run && NUM_TESTS == cnt) + break; + } + + /* if no data was available to read from (probably from a pipe) and + * still in test mode, we simply return until data becomes available */ + if (!s && (errno == EAGAIN || errno == EWOULDBLOCK) && test) + return 0; + + return (s && test) || ret; +} +#endif + +/* Read the given log line by line and process its data. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +static int +read_log (GLog ** glog, const char *fn, int dry_run) +{ + FILE *fp = NULL; + int piping = 0; + + /* Ensure we have a valid pipe to read from stdin. Only checking for + * conf.read_stdin without verifying for a valid FILE pointer would certainly + * lead to issues. */ + if (fn[0] == '-' && fn[1] == '\0' && (*glog)->pipe) { + fp = (*glog)->pipe; + (*glog)->piping = piping = 1; + } + + /* make sure we can open the log (if not reading from stdin) */ + if (!piping && (fp = fopen (fn, "r")) == NULL) + FATAL ("Unable to open the specified log file. %s", strerror (errno)); + + /* read line by line */ + if (read_lines (fp, glog, dry_run)) { + if (!piping) + fclose (fp); + return 1; + } + + /* close log file if not a pipe */ + if (!piping) + fclose (fp); + + return 0; +} + +/* Entry point to parse the log line by line. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +int +parse_log (GLog ** glog, char *tail, int dry_run) +{ + const char *err_log = NULL; + int i; + + /* process tail data and return */ + if (tail != NULL) { + /* no line testing on tail */ + if (pre_process_log ((*glog), tail, dry_run)) + return 1; + return 0; + } + + /* verify that we have the required formats */ + if ((err_log = verify_formats ())) + FATAL ("%s", err_log); + + /* no data piped, no logs passed, load from disk only then */ + if (conf.load_from_disk && !conf.filenames_idx && !conf.read_stdin) { + (*glog)->load_from_disk_only = 1; + return 0; + } + + for (i = 0; i < conf.filenames_idx; ++i) { + if (read_log (glog, conf.filenames[i], dry_run)) { + fprintf (stderr, "%s\n", conf.filenames[i]); + return 1; + } + } + + return 0; +} + +/* Ensure we have valid hits + * + * On error, an array of pointers containing the error strings. + * On success, NULL is returned. */ +char ** +test_format (GLog * glog, int *len) +{ + char **errors = NULL; + int i; + + if (parse_log (&glog, NULL, 1) == 0) + goto clean; + + errors = xcalloc (glog->log_erridx, sizeof (char *)); + for (i = 0; i < glog->log_erridx; ++i) + errors[i] = xstrdup (glog->errors[i]); + *len = glog->log_erridx; + +clean: + free_logerrors (glog); + + return errors; +} diff --git a/goaccess++/src/parser.h b/goaccess++/src/parser.h new file mode 100644 index 0000000..e2b89c3 --- /dev/null +++ b/goaccess++/src/parser.h @@ -0,0 +1,185 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef PARSER_H_INCLUDED +#define PARSER_H_INCLUDED + +#define KEY_FOUND 1 +#define KEY_NOT_FOUND -1 +#define LINE_BUFFER 4096 /* read at most this num of chars */ +#define NUM_TESTS 20 /* test this many lines from the log */ +#define MAX_LOG_ERRORS 20 + +#define LINE_LEN 23 +#define ERROR_LEN 255 +#define REF_SITE_LEN 511 /* maximum length of a referring site */ + +#define SPEC_TOKN_SET 0x1 +#define SPEC_TOKN_NUL 0x2 +#define SPEC_TOKN_INV 0x3 +#define SPEC_SFMT_MIS 0x4 + +#include "commons.h" + +/* Log properties. Note: This is per line parsed */ +typedef struct GLogItem_ +{ + char *agent; + char *browser; + char *browser_type; + char *continent; + char *country; + char *date; + char *host; + char *keyphrase; + char *method; + char *os; + char *os_type; + char *protocol; + char *qstr; + char *ref; + char *req; + char *req_key; + char *status; + char *time; + char *uniq_key; + char *vhost; + char *userid; + + char site[REF_SITE_LEN + 1]; + + uint64_t resp_size; + uint64_t serve_time; + + int type_ip; + int is_404; + int is_static; + int uniq_nkey; + int agent_nkey; + + char *errstr; +} GLogItem; + +/* Overall parsed log properties */ +typedef struct GLog_ +{ + unsigned int excluded_ip; + unsigned int invalid; + unsigned int offset; + unsigned int processed; + unsigned int valid; + unsigned long long resp_size; + unsigned short load_from_disk_only; + unsigned short piping; + GLogItem *items; + + unsigned short log_erridx; + char **errors; + + FILE *pipe; +} GLog; + +/* Raw data field type */ +typedef enum +{ + INTEGER, + STRING +} GRawDataType; + +/* Raw Data extracted from table stores */ +typedef struct GRawDataItem_ +{ + int key; + union + { + char *svalue; + int ivalue; + } value; +} GRawDataItem; + +/* Raw Data per module */ +typedef struct GRawData_ +{ + GRawDataItem *items; /* data */ + GModule module; /* current module */ + GRawDataType type; /* raw data items type */ + int idx; /* first level index */ + int size; /* total num of items on ht */ +} GRawData; + +/* Each record contains a data value, i.e., Windows XP, and it may contain a + * root value, i.e., Windows, and a unique key which is the combination of + * date, IP and user agent */ +typedef struct GKeyData_ +{ + void *data; + void *data_key; + int data_nkey; + + void *root; + void *root_key; + int root_nkey; + + void *uniq_key; + int uniq_nkey; +} GKeyData; + +typedef struct GParse_ +{ + GModule module; + int (*key_data) (GKeyData * kdata, GLogItem * logitem); + + /* data field */ + void (*datamap) (int data_nkey, const char *data, GModule module); + void (*rootmap) (int root_nkey, const char *root, GModule module); + + /* metrics */ + void (*hits) (int data_nkey, GModule module); + void (*visitor) (int uniq_nkey, GModule module); + void (*bw) (int data_nkey, uint64_t size, GModule module); + void (*cumts) (int data_nkey, uint64_t ts, GModule module); + void (*maxts) (int data_nkey, uint64_t ts, GModule module); + void (*method) (int data_nkey, const char *method, GModule module); + void (*protocol) (int data_nkey, const char *proto, GModule module); + void (*agent) (int data_nkey, int agent_nkey, GModule module); +} GParse; + +char *fgetline (FILE * fp); +char **test_format (GLog * glog, int *len); +GLog *init_log (void); +GLogItem *init_log_item (GLog * glog); +GRawDataItem *new_grawdata_item (unsigned int size); +GRawData *new_grawdata (void); +int parse_log (GLog ** glog, char *tail, int dry_run); +void free_logerrors (GLog * glog); +void free_raw_data (GRawData * raw_data); +void output_logerrors (GLog * glog); +void reset_struct (GLog * glog); + +#endif diff --git a/goaccess++/src/parser.o b/goaccess++/src/parser.o new file mode 100644 index 0000000..4c733e2 Binary files /dev/null and b/goaccess++/src/parser.o differ diff --git a/goaccess++/src/settings.c b/goaccess++/src/settings.c new file mode 100644 index 0000000..02043d1 --- /dev/null +++ b/goaccess++/src/settings.c @@ -0,0 +1,787 @@ +/** + * settings.c -- goaccess configuration + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#include +#include +#include +#include +#include +#include + +#include "settings.h" + +#include "error.h" +#include "labels.h" +#include "util.h" +#include "xmalloc.h" + +static char **nargv; +static int nargc = 0; + +/* *INDENT-OFF* */ +static GEnum LOGTYPE[] = { + {"COMBINED" , COMBINED} , + {"VCOMBINED" , VCOMBINED} , + {"COMMON" , COMMON} , + {"VCOMMON" , VCOMMON} , + {"W3C" , W3C} , + {"SQUID" , SQUID} , + {"CLOUDFRONT" , CLOUDFRONT} , + {"CLOUDSTORAGE" , CLOUDSTORAGE} , + {"AWSELB" , AWSELB} , + {"AWSS3" , AWSS3} , +}; + +static const GPreConfLog logs = { + "%h %^[%d:%t %^] \"%r\" %s %b \"%R\" \"%u\"", /* NCSA */ + "%v:%^ %h %^[%d:%t %^] \"%r\" %s %b \"%R\" \"%u\"", /* NCSA + VHost */ + "%h %^[%d:%t %^] \"%r\" %s %b", /* CLF */ + "%v:%^ %h %^[%d:%t %^] \"%r\" %s %b", /* CLF+VHost */ + "%d %t %^ %m %U %q %^ %^ %h %u %R %s %^ %^ %L", /* W3C */ + "%d\\t%t\\t%^\\t%b\\t%h\\t%m\\t%^\\t%r\\t%s\\t%R\\t%u\\t%^", /* CloudFront */ + "\"%x\",\"%h\",%^,%^,\"%m\",\"%U\",\"%s\",%^,\"%b\",\"%D\",%^,\"%R\",\"%u\"", /* Cloud Storage */ + "%dT%t.%^ %^ %h:%^ %^ %T %^ %^ %^ %s %^ %b \"%r\" \"%u\"", /* AWS Elastic Load Balancing */ + "%^ %^ %^ %v %^: %x.%^ %~%L %h %^/%s %b %m %U", /* Squid Native */ + "%^ %v [%d:%t %^] %h %^\"%r\" %s %^ %b %^ %L %^ \"%R\" \"%u\"", /* Amazon S3 */ +}; + +static const GPreConfTime times = { + "%H:%M:%S", + "%f", /* Cloud Storage (usec) */ + "%s", /* Squid (sec) */ +}; + +static const GPreConfDate dates = { + "%d/%b/%Y", /* Apache */ + "%Y-%m-%d", /* W3C */ + "%f", /* Cloud Storage (usec) */ + "%s", /* Squid (sec) */ +}; +/* *INDENT-ON* */ + +/* Ignore the following options */ +static const char *ignore_cmd_opts[] = { + "help", + "storage", + "version", +}; + +/* Determine if the given command line option needs to be ignored. + * + * If needs to be ignored, 1 is returned. + * If not within the list of ignored command line options, 0 is returned. */ +static int +in_ignore_cmd_opts (const char *val) +{ + size_t i; + for (i = 0; i < ARRAY_SIZE (ignore_cmd_opts); i++) { + if (strstr (val, ignore_cmd_opts[i]) != NULL) + return 1; + } + return 0; +} + +/* Get the location of the configuration file. + * + * By default, it attempts to read it from the user supplied path, else it will + * try to open the global config file path (sysconfdir) or from the HOME + * environment variable (~/.goaccessrc). + * + * On success, the path to the configuration file is returned. */ +char * +get_config_file_path (void) +{ + char *upath = NULL, *rpath = NULL; + + /* determine which config file to open, default or custom */ + if (conf.iconfigfile != NULL) { + rpath = realpath (conf.iconfigfile, NULL); + if (rpath == NULL) + FATAL ("Unable to open the specified config file. %s", strerror (errno)); + return rpath; + } + + /* attempt to use the user's config file */ + upath = get_home (); + rpath = realpath (upath, NULL); + if (upath) { + free (upath); + } + + /* otherwise, fallback to global config file */ + if (rpath == NULL && conf.load_global_config) { + upath = get_global_config (); + rpath = realpath (upath, NULL); + if (upath) { + free (upath); + } + } + + return rpath; +} + +/* Use predefined static files when no config file is used. Note that + * the order in which are listed is from the most to the least common + * (most cases). */ +void +set_default_static_files (void) +{ + size_t i; + const char *exts[] = { + ".css", + ".js ", + ".jpg", + ".png", + ".gif", + ".ico", + ".jpeg", + ".pdf", + ".txt", + ".csv", + ".mpeg", + ".mpg", + ".swf", + ".woff", + ".woff2", + ".xls", + ".xlsx", + ".doc ", + ".docx", + ".ppt ", + ".pptx", + ".zip", + ".mp3", + ".mp4", + ".exe", + ".iso ", + ".gz ", + ".rar ", + ".svg ", + ".bmp ", + ".tar ", + ".tgz ", + ".tiff", + ".tif ", + ".ttf ", + ".flv ", + }; + + if (conf.static_file_idx > 0) + return; + + for (i = 0; i < ARRAY_SIZE (exts); i++) { + if (conf.static_file_max_len < strlen (exts[i])) + conf.static_file_max_len = strlen (exts[i]); + conf.static_files[conf.static_file_idx++] = exts[i]; + } +} + +/* Clean malloc'd log/date/time escaped formats. */ +void +free_formats (void) +{ + free (conf.log_format); + free (conf.date_format); + free (conf.date_num_format); + free (conf.spec_date_time_format); + free (conf.spec_date_time_num_format); + free (conf.time_format); +} + +/* Clean malloc'd command line arguments. */ +void +free_cmd_args (void) +{ + int i; + if (nargc == 0) + return; + for (i = 0; i < nargc; i++) + free (nargv[i]); + free (nargv); + free (conf.iconfigfile); +} + +/* Append extra value to argv */ +static void +append_to_argv (int *argc, char ***argv, char *val) +{ + char **_argv = xrealloc (*argv, (*argc + 2) * sizeof (*_argv)); + _argv[*argc] = val; + _argv[*argc + 1] = (char *) '\0'; + (*argc)++; + *argv = _argv; +} + +/* Parses the configuration file to feed getopt_long. + * + * On error, ENOENT error code is returned. + * On success, 0 is returned and config file enabled options are appended to + * argv. */ +int +parse_conf_file (int *argc, char ***argv) +{ + char line[MAX_LINE_CONF + 1]; + char *path = NULL, *val, *opt, *p; + FILE *file; + int i, n = 0; + size_t idx; + + /* assumes program name is on argv[0], though, it is not guaranteed */ + append_to_argv (&nargc, &nargv, xstrdup ((char *) *argv[0])); + + /* determine which config file to open, default or custom */ + path = get_config_file_path (); + if (path == NULL) + return ENOENT; + + /* could not open conf file, if so prompt conf dialog */ + if ((file = fopen (path, "r")) == NULL) { + free (path); + return ENOENT; + } + + while (fgets (line, sizeof line, file) != NULL) { + while (line[0] == ' ' || line[0] == '\t') + memmove (line, line + 1, strlen (line)); + n++; + if (line[0] == '\n' || line[0] == '\r' || line[0] == '#') + continue; + + /* key */ + idx = strcspn (line, " \t"); + if (strlen (line) == idx) + FATAL ("Malformed config key at line: %d", n); + + line[idx] = '\0'; + + /* make old config options backwards compatible by + * substituting underscores with dashes */ + while ((p = strpbrk (line, "_")) != NULL) + *p = '-'; + + /* Ignore the following options when reading the config file */ + if (in_ignore_cmd_opts (line)) + continue; + + /* value */ + val = line + (idx + 1); + idx = strspn (val, " \t"); + if (strlen (line) == idx) + FATAL ("Malformed config value at line: %d", n); + val = val + idx; + val = trim_str (val); + + if (strcmp ("false", val) == 0) + continue; + + /* set it as command line options */ + opt = xmalloc (snprintf (NULL, 0, "--%s", line) + 1); + sprintf (opt, "--%s", line); + + append_to_argv (&nargc, &nargv, opt); + if (strcmp ("true", val) != 0) + append_to_argv (&nargc, &nargv, xstrdup (val)); + } + + /* give priority to command line arguments */ + for (i = 1; i < *argc; i++) + append_to_argv (&nargc, &nargv, xstrdup ((char *) (*argv)[i])); + + *argc = nargc; + *argv = (char **) nargv; + + fclose (file); + + if (conf.iconfigfile == NULL) + conf.iconfigfile = xstrdup (path); + + free (path); + return 0; +} + +/* Get the enumerated log format given its equivalent format string. + * + * On error, -1 is returned. + * On success, the enumerated format is returned. */ +static int +get_log_format_item_enum (const char *str) +{ + return str2enum (LOGTYPE, ARRAY_SIZE (LOGTYPE), str); +} + +/* Determine the selected log format from the config file or command line + * option. + * + * On error, -1 is returned. + * On success, the index of the matched item is returned. */ +size_t +get_selected_format_idx (void) +{ + if (conf.log_format == NULL) + return -1; + if (strcmp (conf.log_format, logs.common) == 0) + return COMMON; + else if (strcmp (conf.log_format, logs.vcommon) == 0) + return VCOMMON; + else if (strcmp (conf.log_format, logs.combined) == 0) + return COMBINED; + else if (strcmp (conf.log_format, logs.vcombined) == 0) + return VCOMBINED; + else if (strcmp (conf.log_format, logs.w3c) == 0) + return W3C; + else if (strcmp (conf.log_format, logs.cloudfront) == 0) + return CLOUDFRONT; + else if (strcmp (conf.log_format, logs.cloudstorage) == 0) + return CLOUDSTORAGE; + else if (strcmp (conf.log_format, logs.awselb) == 0) + return AWSELB; + else if (strcmp (conf.log_format, logs.squid) == 0) + return SQUID; + else if (strcmp (conf.log_format, logs.awss3) == 0) + return AWSS3; + else + return -1; +} + +/* Determine the selected log format from the config file or command line + * option. + * + * On error, NULL is returned. + * On success, an allocated string containing the log format is returned. */ +char * +get_selected_format_str (size_t idx) +{ + char *fmt = NULL; + switch (idx) { + case COMMON: + fmt = alloc_string (logs.common); + break; + case VCOMMON: + fmt = alloc_string (logs.vcommon); + break; + case COMBINED: + fmt = alloc_string (logs.combined); + break; + case VCOMBINED: + fmt = alloc_string (logs.vcombined); + break; + case W3C: + fmt = alloc_string (logs.w3c); + break; + case CLOUDFRONT: + fmt = alloc_string (logs.cloudfront); + break; + case CLOUDSTORAGE: + fmt = alloc_string (logs.cloudstorage); + break; + case AWSELB: + fmt = alloc_string (logs.awselb); + break; + case SQUID: + fmt = alloc_string (logs.squid); + break; + case AWSS3: + fmt = alloc_string (logs.awss3); + break; + } + + return fmt; +} + +/* Determine the selected date format from the config file or command line + * option. + * + * On error, NULL is returned. + * On success, an allocated string containing the date format is returned. */ +char * +get_selected_date_str (size_t idx) +{ + char *fmt = NULL; + switch (idx) { + case COMMON: + case VCOMMON: + case COMBINED: + case VCOMBINED: + case AWSS3: + fmt = alloc_string (dates.apache); + break; + case AWSELB: + case CLOUDFRONT: + case W3C: + fmt = alloc_string (dates.w3c); + break; + case CLOUDSTORAGE: + fmt = alloc_string (dates.usec); + break; + case SQUID: + fmt = alloc_string (dates.sec); + break; + } + + return fmt; +} + +/* Determine the selected time format from the config file or command line + * option. + * + * On error, NULL is returned. + * On success, an allocated string containing the time format is returned. */ +char * +get_selected_time_str (size_t idx) +{ + char *fmt = NULL; + switch (idx) { + case AWSELB: + case CLOUDFRONT: + case COMBINED: + case COMMON: + case VCOMBINED: + case VCOMMON: + case W3C: + case AWSS3: + fmt = alloc_string (times.fmt24); + break; + case CLOUDSTORAGE: + fmt = alloc_string (times.usec); + break; + case SQUID: + fmt = alloc_string (times.sec); + break; + } + + return fmt; +} + +/* Determine if the log/date/time were set, otherwise exit the program + * execution. */ +const char * +verify_formats (void) +{ + if (conf.time_format == NULL || *conf.time_format == '\0') + return ERR_FORMAT_NO_TIME_FMT; + + if (conf.date_format == NULL || *conf.date_format == '\0') + return ERR_FORMAT_NO_DATE_FMT; + + if (conf.log_format == NULL || *conf.log_format == '\0') + return ERR_FORMAT_NO_LOG_FMT; + + return NULL; +} + +/* A wrapper function to concat the given specificity to the date + * format. */ +static char * +append_spec_date_format (const char *date_format, const char *spec_format) +{ + char *s = xmalloc (snprintf (NULL, 0, "%s%s", date_format, spec_format) + 1); + sprintf (s, "%s%s", date_format, spec_format); + + return s; +} + +/* Iterate over the given format and clean unwanted chars and keep all + * date/time specifiers such as %b%Y%d%M%S. + * + * On error NULL is returned. + * On success, a clean format containing only date/time specifiers is + * returned. */ +static char * +clean_date_time_format (const char *format) +{ + char *fmt = NULL, *pr = NULL, *pw = NULL; + int special = 0; + + if (format == NULL || *format == '\0') + return NULL; + + fmt = xstrdup (format); + pr = fmt; + pw = fmt; + while (*pr) { + *pw = *pr++; + if (*pw == '%' || special) { + special = !special; + pw++; + } + } + *pw = '\0'; + + return fmt; +} + +/* Determine if the given specifier character is an abbreviated type + * of date. + * + * If it is, 1 is returned, otherwise, 0 is returned. */ +static int +is_date_abbreviated (const char *fdate) +{ + if (strpbrk (fdate, "cDF")) + return 1; + + return 0; +} + +/* A wrapper to extract time specifiers from a time format. + * + * On error NULL is returned. + * On success, a clean format containing only time specifiers is + * returned. */ +static char * +set_format_time (void) +{ + char *ftime = NULL; + + if (has_timestamp (conf.date_format) || !strcmp ("%T", conf.time_format)) + ftime = xstrdup ("%H%M%S"); + else + ftime = clean_date_time_format (conf.time_format); + + return ftime; +} + +/* A wrapper to extract date specifiers from a date format. + * + * On error NULL is returned. + * On success, a clean format containing only date specifiers is + * returned. */ +static char * +set_format_date (void) +{ + char *fdate = NULL; + + if (has_timestamp (conf.date_format)) + fdate = xstrdup ("%Y%m%d"); + else + fdate = clean_date_time_format (conf.date_format); + + return fdate; +} + +/* Once we have a numeric date format, we attempt to read the time + * format and construct a date_time numeric specificity format (if any + * specificity is given). The result may look like Ymd[HM]. + * + * On success, the numeric date time specificity format is set. */ +static void +set_spec_date_time_num_format (void) +{ + char *buf = NULL, *tf = set_format_time (); + const char *df = conf.date_num_format; + + if (!df || !tf) + return; + + if (conf.date_spec_hr && strchr (tf, 'H')) + buf = append_spec_date_format (df, "%H"); + else + buf = xstrdup (df); + + conf.spec_date_time_num_format = buf; + free (tf); +} + +/* Set a human readable specificity date and time format. + * + * On success, the human readable date time specificity format is set. */ +static void +set_spec_date_time_format (void) +{ + char *buf = NULL; + const char *fmt = conf.spec_date_time_num_format; + int buflen = 0, flen = 0; + + if (!fmt) + return; + + flen = (strlen (fmt) * 2) + 1; + buf = xcalloc (flen, sizeof (char)); + + if (strchr (fmt, 'd')) + buflen += snprintf (buf + buflen, flen - buflen, "%%d/"); + if (strchr (fmt, 'm')) + buflen += snprintf (buf + buflen, flen - buflen, "%%b/"); + if (strchr (fmt, 'Y')) + buflen += snprintf (buf + buflen, flen - buflen, "%%Y"); + if (strchr (fmt, 'H')) + buflen += snprintf (buf + buflen, flen - buflen, ":%%H"); + + conf.spec_date_time_format = buf; +} + +/* Normalize the date format from the date format given by the user to + * Ymd so it can be sorted out properly afterwards. + * + * On error or unable to determine the format, 1 is returned. + * On success, the numeric date format as Ymd is set and 0 is + * returned. */ +static int +set_date_num_format (void) +{ + char *fdate = NULL, *buf = NULL; + int buflen = 0, flen = 0; + + fdate = set_format_date (); + if (!fdate) + return 1; + + if (is_date_abbreviated (fdate)) { + free (fdate); + conf.date_num_format = xstrdup ("%Y%m%d"); + return 0; + } + + flen = strlen (fdate) + 1; + buf = xcalloc (flen, sizeof (char)); + + if (strpbrk (fdate, "Yy")) + buflen += snprintf (buf + buflen, flen - buflen, "%%Y"); + if (strpbrk (fdate, "hbmB")) + buflen += snprintf (buf + buflen, flen - buflen, "%%m"); + if (strpbrk (fdate, "de")) + buflen += snprintf (buf + buflen, flen - buflen, "%%d"); + + conf.date_num_format = buf; + free (fdate); + + return buflen == 0 ? 1 : 0; +} + +/* If specificity is supplied, then determine which value we need to + * append to the date format. */ +void +set_spec_date_format (void) +{ + if (verify_formats ()) + return; + + if (conf.date_num_format) + free (conf.date_num_format); + if (conf.spec_date_time_format) + free (conf.spec_date_time_format); + if (conf.spec_date_time_num_format) + free (conf.spec_date_time_num_format); + + if (set_date_num_format () == 0) { + set_spec_date_time_num_format (); + set_spec_date_time_format (); + } +} + +/* Attempt to set the date format given a command line option + * argument. The supplied optarg can be either an actual format string + * or the enumerated value such as VCOMBINED */ +void +set_date_format_str (const char *oarg) +{ + char *fmt = NULL; + int type = get_log_format_item_enum (oarg); + + /* free date format if it was previously set by set_log_format_str() */ + if (conf.date_format) + free (conf.date_format); + + /* type not found, use whatever was given by the user then */ + if (type == -1) { + conf.date_format = unescape_str (oarg); + return; + } + + /* attempt to get the format string by the enum value */ + if ((fmt = get_selected_date_str (type)) == NULL) { + LOG_DEBUG (("Unable to set date format from enum: %s\n", oarg)); + return; + } + + conf.date_format = fmt; +} + +/* Attempt to set the time format given a command line option + * argument. The supplied optarg can be either an actual format string + * or the enumerated value such as VCOMBINED */ +void +set_time_format_str (const char *oarg) +{ + char *fmt = NULL; + int type = get_log_format_item_enum (oarg); + + /* free time format if it was previously set by set_log_format_str() */ + if (conf.time_format) + free (conf.time_format); + + /* type not found, use whatever was given by the user then */ + if (type == -1) { + conf.time_format = unescape_str (oarg); + return; + } + + /* attempt to get the format string by the enum value */ + if ((fmt = get_selected_time_str (type)) == NULL) { + LOG_DEBUG (("Unable to set time format from enum: %s\n", oarg)); + return; + } + + conf.time_format = fmt; +} + +/* Attempt to set the log format given a command line option argument. + * The supplied optarg can be either an actual format string or the + * enumerated value such as VCOMBINED */ +void +set_log_format_str (const char *oarg) +{ + char *fmt = NULL; + int type = get_log_format_item_enum (oarg); + + /* free log format if it was previously set */ + if (conf.log_format) + free (conf.log_format); + + /* type not found, use whatever was given by the user then */ + if (type == -1) { + conf.log_format = unescape_str (oarg); + return; + } + + /* attempt to get the format string by the enum value */ + if ((fmt = get_selected_format_str (type)) == NULL) { + LOG_DEBUG (("Unable to set log format from enum: %s\n", oarg)); + return; + } + + conf.log_format = unescape_str (fmt); + /* assume we are using the default date/time formats */ + set_time_format_str (oarg); + set_date_format_str (oarg); + free (fmt); +} diff --git a/goaccess++/src/settings.h b/goaccess++/src/settings.h new file mode 100644 index 0000000..8faf66c --- /dev/null +++ b/goaccess++/src/settings.h @@ -0,0 +1,237 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef SETTINGS_H_INCLUDED +#define SETTINGS_H_INCLUDED + +#include +#include "commons.h" + +#define MAX_LINE_CONF 512 +#define MAX_EXTENSIONS 128 +#define MAX_IGNORE_IPS 1024 + 128 +#define MAX_IGNORE_REF 64 +#define MAX_CUSTOM_COLORS 64 +#define MAX_IGNORE_STATUS 64 +#define MAX_OUTFORMATS 3 +#define MAX_FILENAMES 512 +#define NO_CONFIG_FILE "No config file used" + +typedef enum LOGTYPE +{ + COMBINED, + VCOMBINED, + COMMON, + VCOMMON, + W3C, + SQUID, + CLOUDFRONT, + CLOUDSTORAGE, + AWSELB, + AWSS3, +} GLogType; + +/* predefined log times */ +typedef struct GPreConfTime_ +{ + const char *fmt24; + const char *usec; + const char *sec; +} GPreConfTime; + +/* predefined log dates */ +typedef struct GPreConfDate_ +{ + const char *apache; + const char *w3c; + const char *usec; + const char *sec; +} GPreConfDate; + +/* predefined log formats */ +typedef struct GPreConfLog_ +{ + const char *combined; + const char *vcombined; + const char *common; + const char *vcommon; + const char *w3c; + const char *cloudfront; + const char *cloudstorage; + const char *awselb; + const char *squid; + const char *awss3; +} GPreConfLog; + +/* *INDENT-OFF* */ +/* All configuration properties */ +typedef struct GConf_ +{ + /* Array options */ + const char *colors[MAX_CUSTOM_COLORS]; /* colors */ + const char *enable_panels[TOTAL_MODULES]; /* array of panels to enable */ + const char *filenames[MAX_FILENAMES]; /* log files */ + const char *hide_referers[MAX_IGNORE_REF]; /* hide referrers from report */ + const char *ignore_ips[MAX_IGNORE_IPS]; /* array of ips to ignore */ + const char *ignore_panels[TOTAL_MODULES]; /* array of panels to ignore */ + const char *ignore_referers[MAX_IGNORE_REF]; /* referrers to ignore */ + const char *ignore_status[MAX_IGNORE_STATUS]; /* status to ignore */ + const char *output_formats[MAX_OUTFORMATS]; /* output format, e.g. , HTML */ + const char *sort_panels[TOTAL_MODULES]; /* sorting options for each panel */ + const char *static_files[MAX_EXTENSIONS]; /* static extensions */ + + /* Log/date/time formats */ + char *date_format; /* date format */ + char *date_num_format; /* numeric date format %Y%m%d */ + char *time_format; /* time format as given by the user */ + char *spec_date_time_format; /* date format w/ specificity */ + char *spec_date_time_num_format; /* numeric date format w/ specificity */ + char *log_format; /* log format */ + char *iconfigfile; /* config file path */ + char ***user_browsers_hash; /* custom list of browsers */ + + const char *debug_log; /* debug log path */ + const char *geoip_database; /* geoip db path */ + const char *html_custom_css; /* custom CSS */ + const char *html_custom_js; /* custom JS */ + const char *html_prefs; /* default HTML JSON preferences */ + const char *html_report_title; /* report title */ + const char *invalid_requests_log; /* invalid lines log path */ + const char *pidfile; /* daemonize pid file path */ + const char *browsers_file; /* browser's file path */ + + /* HTML real-time */ + const char *addr; /* IP address to bind to */ + const char *fifo_in; /* path FIFO in (reader) */ + const char *fifo_out; /* path FIFO out (writer) */ + const char *origin; /* WebSocket origin */ + const char *port; /* port to use */ + const char *sslcert; /* TLS/SSL path to certificate */ + const char *sslkey; /* TLS/SSL path to private key */ + const char *ws_url; /* WebSocket URL */ + + /* User flags */ + int store_accumulated_time; /* store accumulated processing time in tcb */ + int all_static_files; /* parse all static files */ + int anonymize_ip; /* anonymize ip addresses */ + int append_method; /* append method to the req key */ + int append_protocol; /* append protocol to the req key */ + int client_err_to_unique_count; /* count 400s as visitors */ + int code444_as_404; /* 444 as 404s? */ + int color_scheme; /* color scheme */ + int crawlers_only ; /* crawlers only */ + int daemonize; /* run program as a Unix daemon */ + int double_decode; /* need to double decode */ + int enable_html_resolver; /* html/json/csv resolver */ + int geo_db; /* legacy geoip db */ + int hl_header; /* highlight header on term */ + int ignore_crawlers; /* ignore crawlers */ + int ignore_qstr; /* ignore query string */ + int ignore_statics; /* ignore static files */ + int json_pretty_print; /* pretty print JSON data */ + int list_agents; /* show list of agents per host */ + int load_conf_dlg; /* load curses config dialog */ + int load_global_config; /* use global config file */ + int max_items; /* max number of items to output */ + int mouse_support; /* add curses mouse support */ + int no_color; /* no terminal colors */ + int no_column_names; /* don't show col names on termnal */ + int no_csv_summary; /* don't show overall metrics */ + int no_html_last_updated; /* don't show HTML last updated field */ + int no_parsing_spinner; /* disable parsing spinner */ + int no_progress; /* disable progress metrics */ + int no_tab_scroll; /* don't scroll dashboard on tab */ + int output_stdout; /* outputting to stdout */ + int process_and_exit; /* parse and exit without outputting */ + int real_os; /* show real OSs */ + int real_time_html; /* enable real-time HTML output */ + int skip_term_resolver; /* no terminal resolver */ + uint32_t num_tests; /* number of lines to test */ + uint64_t log_size; /* log size override */ + + /* Internal flags */ + int bandwidth; /* is there bandwidth within the req line */ + int date_spec_hr; /* date specificity - hour */ + int has_geocity; + int has_geocountry; + int hour_spec_min; /* hour specificity - min */ + int read_stdin; /* read from stdin */ + int serve_usecs; /* is there time served within req line */ + int stop_processing; /* stop all processing */ + int tailing_mode; /* in tailing-mode? */ + + /* Array indices */ + int color_idx; /* colors index */ + int enable_panel_idx; /* enable panels index */ + int filenames_idx; /* filenames index */ + int hide_referer_idx; /* hide referrers index */ + int ignore_ip_idx; /* ignored ips index */ + int ignore_panel_idx; /* ignored panels index */ + int ignore_referer_idx; /* ignored referrers index */ + int ignore_status_idx; /* ignore status index */ + int output_format_idx; /* output format index */ + int sort_panel_idx; /* sort panel index */ + int static_file_idx; /* static extensions index */ + int browsers_hash_idx; /* browsers hash index */ + + size_t static_file_max_len; + + /* TokyoCabinet */ + const char *db_path; /* db path to files */ + int64_t xmmap; /* size of the extra mapped memory */ + int cache_lcnum; /* max num of leaf nodes to cache */ + int cache_ncnum; /* max num of non-leaf nodes to cache */ + int compression; /* deflate or BZIP2 */ + int keep_db_files; /* persist parsed data into disk */ + int load_from_disk; /* load stored data */ + int tune_bnum; /* num of elems of the bucket array */ + int tune_lmemb; /* num of memb in each leaf page */ + int tune_nmemb; /* num of memb in each non-leaf page */ +} GConf; +/* *INDENT-ON* */ + +char *get_selected_date_str (size_t idx); +char *get_selected_format_str (size_t idx); +char *get_selected_time_str (size_t idx); +const char *verify_formats (void); +size_t get_selected_format_idx (void); +void set_date_format_str (const char *optarg); +void set_log_format_str (const char *optarg); +void set_spec_date_format (void); +void set_time_format_str (const char *optarg); + +extern GConf conf; + +char *get_config_file_path (void); +int parse_conf_file (int *argc, char ***argv); +void free_cmd_args (void); +void free_formats (void); +void set_default_static_files (void); + +#endif diff --git a/goaccess++/src/settings.o b/goaccess++/src/settings.o new file mode 100644 index 0000000..040d79c Binary files /dev/null and b/goaccess++/src/settings.o differ diff --git a/goaccess++/src/sha1.c b/goaccess++/src/sha1.c new file mode 100644 index 0000000..5bc4fec --- /dev/null +++ b/goaccess++/src/sha1.c @@ -0,0 +1,235 @@ +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* #define LITTLE_ENDIAN * This should be #define'd if true. */ +#if __LITTLE_ENDIAN__ +#define LITTLE_ENDIAN +#endif +/* #define SHA1HANDSOFF * Copies data before messing with it. */ + +#include +#include + +#include "sha1.h" + +void SHA1Transform (uint32_t state[5], uint8_t buffer[64]); + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#ifdef LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void +SHA1Transform (uint32_t state[5], uint8_t buffer[64]) +{ + uint32_t a, b, c, d, e; + typedef union + { + uint8_t c[64]; + uint32_t l[16]; + } CHAR64LONG16; + CHAR64LONG16 *block; +#ifdef SHA1HANDSOFF + static uint8_t workspace[64]; + block = (CHAR64LONG16 *) workspace; + memcpy (block, buffer, 64); +#else + block = (CHAR64LONG16 *) buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0 (a, b, c, d, e, 0); + R0 (e, a, b, c, d, 1); + R0 (d, e, a, b, c, 2); + R0 (c, d, e, a, b, 3); + R0 (b, c, d, e, a, 4); + R0 (a, b, c, d, e, 5); + R0 (e, a, b, c, d, 6); + R0 (d, e, a, b, c, 7); + R0 (c, d, e, a, b, 8); + R0 (b, c, d, e, a, 9); + R0 (a, b, c, d, e, 10); + R0 (e, a, b, c, d, 11); + R0 (d, e, a, b, c, 12); + R0 (c, d, e, a, b, 13); + R0 (b, c, d, e, a, 14); + R0 (a, b, c, d, e, 15); + R1 (e, a, b, c, d, 16); + R1 (d, e, a, b, c, 17); + R1 (c, d, e, a, b, 18); + R1 (b, c, d, e, a, 19); + R2 (a, b, c, d, e, 20); + R2 (e, a, b, c, d, 21); + R2 (d, e, a, b, c, 22); + R2 (c, d, e, a, b, 23); + R2 (b, c, d, e, a, 24); + R2 (a, b, c, d, e, 25); + R2 (e, a, b, c, d, 26); + R2 (d, e, a, b, c, 27); + R2 (c, d, e, a, b, 28); + R2 (b, c, d, e, a, 29); + R2 (a, b, c, d, e, 30); + R2 (e, a, b, c, d, 31); + R2 (d, e, a, b, c, 32); + R2 (c, d, e, a, b, 33); + R2 (b, c, d, e, a, 34); + R2 (a, b, c, d, e, 35); + R2 (e, a, b, c, d, 36); + R2 (d, e, a, b, c, 37); + R2 (c, d, e, a, b, 38); + R2 (b, c, d, e, a, 39); + R3 (a, b, c, d, e, 40); + R3 (e, a, b, c, d, 41); + R3 (d, e, a, b, c, 42); + R3 (c, d, e, a, b, 43); + R3 (b, c, d, e, a, 44); + R3 (a, b, c, d, e, 45); + R3 (e, a, b, c, d, 46); + R3 (d, e, a, b, c, 47); + R3 (c, d, e, a, b, 48); + R3 (b, c, d, e, a, 49); + R3 (a, b, c, d, e, 50); + R3 (e, a, b, c, d, 51); + R3 (d, e, a, b, c, 52); + R3 (c, d, e, a, b, 53); + R3 (b, c, d, e, a, 54); + R3 (a, b, c, d, e, 55); + R3 (e, a, b, c, d, 56); + R3 (d, e, a, b, c, 57); + R3 (c, d, e, a, b, 58); + R3 (b, c, d, e, a, 59); + R4 (a, b, c, d, e, 60); + R4 (e, a, b, c, d, 61); + R4 (d, e, a, b, c, 62); + R4 (c, d, e, a, b, 63); + R4 (b, c, d, e, a, 64); + R4 (a, b, c, d, e, 65); + R4 (e, a, b, c, d, 66); + R4 (d, e, a, b, c, 67); + R4 (c, d, e, a, b, 68); + R4 (b, c, d, e, a, 69); + R4 (a, b, c, d, e, 70); + R4 (e, a, b, c, d, 71); + R4 (d, e, a, b, c, 72); + R4 (c, d, e, a, b, 73); + R4 (b, c, d, e, a, 74); + R4 (a, b, c, d, e, 75); + R4 (e, a, b, c, d, 76); + R4 (d, e, a, b, c, 77); + R4 (c, d, e, a, b, 78); + R4 (b, c, d, e, a, 79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void +SHA1Init (SHA1_CTX * context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void +SHA1Update (SHA1_CTX * context, uint8_t * data, unsigned int len) +{ + unsigned int i, j; + + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) + context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + memcpy (&context->buffer[j], data, (i = 64 - j)); + SHA1Transform (context->state, context->buffer); + for (; i + 63 < len; i += 64) { + SHA1Transform (context->state, &data[i]); + } + j = 0; + } else + i = 0; + memcpy (&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void +SHA1Final (uint8_t digest[20], SHA1_CTX * context) +{ + uint32_t i, j; + uint8_t finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (uint8_t) ((context->count[(i >= 4 ? 0 : 1)] + >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ + } + SHA1Update (context, (uint8_t *) "\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1Update (context, (uint8_t *) "\0", 1); + } + SHA1Update (context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (uint8_t) + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); + } + /* Wipe variables */ + i = j = 0; + memset (context->buffer, 0, 64); + memset (context->state, 0, 20); + memset (context->count, 0, 8); + memset (&finalcount, 0, 8); +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ + SHA1Transform (context->state, context->buffer); +#endif +} diff --git a/goaccess++/src/sha1.h b/goaccess++/src/sha1.h new file mode 100644 index 0000000..cc07482 --- /dev/null +++ b/goaccess++/src/sha1.h @@ -0,0 +1,20 @@ +#ifndef SHA1_H_INCLUDED +#define SHA1_H_INCLUDED + +#include +#include + +// From http://www.mirrors.wiretapped.net/security/cryptography/hashes/sha1/sha1.c + +typedef struct +{ + uint32_t state[5]; + uint32_t count[2]; + uint8_t buffer[64]; +} SHA1_CTX; + +extern void SHA1Init (SHA1_CTX * context); +extern void SHA1Update (SHA1_CTX * context, uint8_t * data, uint32_t len); +extern void SHA1Final (uint8_t digest[20], SHA1_CTX * context); + +#endif // for #ifndef SHA1_H diff --git a/goaccess++/src/sha1.o b/goaccess++/src/sha1.o new file mode 100644 index 0000000..5830f2c Binary files /dev/null and b/goaccess++/src/sha1.o differ diff --git a/goaccess++/src/sort.c b/goaccess++/src/sort.c new file mode 100644 index 0000000..f07e347 --- /dev/null +++ b/goaccess++/src/sort.c @@ -0,0 +1,572 @@ +/** + * sort.c -- functions related to sort functionality + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "error.h" +#include "settings.h" +#include "util.h" + +#include "sort.h" + +/* *INDENT-OFF* */ +const int sort_choices[][SORT_MAX_OPTS] = { + /* VISITORS */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* REQUESTS */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, SORT_BY_PROT, SORT_BY_MTHD, -1}, + /* REQUESTS_STATIC */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, SORT_BY_PROT, SORT_BY_MTHD, -1}, + /* NOT_FOUND */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, SORT_BY_PROT, SORT_BY_MTHD, -1}, + /* HOSTS */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* OS */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* BROWSERS */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* VISIT_TIMES */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* VIRTUAL_HOSTS */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* REFERRERS */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* REFERRING_SITES */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* KEYPHRASES */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* STATUS_CODES */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, + /* REMOTE_USER */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, +#ifdef HAVE_GEOLOCATION + /* GEO_LOCATION */ + {SORT_BY_HITS, SORT_BY_VISITORS, SORT_BY_DATA, SORT_BY_BW, SORT_BY_AVGTS, SORT_BY_CUMTS, SORT_BY_MAXTS, -1}, +#endif +}; + +static GEnum FIELD[] = { + {"BY_HITS" , SORT_BY_HITS } , + {"BY_VISITORS" , SORT_BY_VISITORS } , + {"BY_DATA" , SORT_BY_DATA } , + {"BY_BW" , SORT_BY_BW } , + {"BY_AVGTS" , SORT_BY_AVGTS } , + {"BY_CUMTS" , SORT_BY_CUMTS } , + {"BY_MAXTS" , SORT_BY_MAXTS } , + {"BY_PROT" , SORT_BY_PROT } , + {"BY_MTHD" , SORT_BY_MTHD } , +}; + +static GEnum ORDER[] = { + {"ASC" , SORT_ASC } , + {"DESC" , SORT_DESC } , +}; + +GSort module_sort[TOTAL_MODULES] = { + {VISITORS , SORT_BY_DATA , SORT_DESC } , + {REQUESTS , SORT_BY_HITS , SORT_DESC } , + {REQUESTS_STATIC , SORT_BY_HITS , SORT_DESC } , + {NOT_FOUND , SORT_BY_HITS , SORT_DESC } , + {HOSTS , SORT_BY_HITS , SORT_DESC } , + {OS , SORT_BY_HITS , SORT_DESC } , + {BROWSERS , SORT_BY_HITS , SORT_DESC } , + {VISIT_TIMES , SORT_BY_DATA , SORT_ASC } , + {VIRTUAL_HOSTS , SORT_BY_HITS , SORT_DESC } , + {REFERRERS , SORT_BY_HITS , SORT_DESC } , + {REFERRING_SITES , SORT_BY_HITS , SORT_DESC } , + {KEYPHRASES , SORT_BY_HITS , SORT_DESC } , + {STATUS_CODES , SORT_BY_HITS , SORT_DESC } , + {REMOTE_USER , SORT_BY_HITS , SORT_DESC } , +#ifdef HAVE_GEOLOCATION + {GEO_LOCATION , SORT_BY_HITS , SORT_DESC } , +#endif +}; +/* *INDENT-ON* */ + +/* Sort an array of strings ascending */ +int +strcmp_asc (const void *a, const void *b) +{ + return strcmp (*((char **) a), *((char **) b)); +} + +/* Sort 'data' metric ascending */ +static int +cmp_data_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + return strcmp (ia->metrics->data, ib->metrics->data); +} + +/* Sort 'data' metric descending */ +static int +cmp_data_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + return strcmp (ib->metrics->data, ia->metrics->data); +} + +/* Sort 'hits' metric descending */ +static int +cmp_num_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + int va = ia->metrics->hits; + int vb = ib->metrics->hits; + + return (va < vb) - (va > vb); +} + +/* Sort 'hits' metric ascending */ +static int +cmp_num_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + int va = ia->metrics->hits; + int vb = ib->metrics->hits; + + return (va > vb) - (va < vb); +} + +/* Sort 'visitors' metric descending */ +static int +cmp_vis_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + int va = ia->metrics->visitors; + int vb = ib->metrics->visitors; + + return (va < vb) - (va > vb); +} + +/* Sort 'visitors' metric ascending */ +static int +cmp_vis_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + int va = ia->metrics->visitors; + int vb = ib->metrics->visitors; + + return (va > vb) - (va < vb); +} + +/* Sort GRawDataItem value descending */ +static int +cmp_raw_num_desc (const void *a, const void *b) +{ + const GRawDataItem *ia = a; + const GRawDataItem *ib = b; + + int va = ia->value.ivalue; + int vb = ib->value.ivalue; + + return (va < vb) - (va > vb); +} + +/* Sort GRawDataItem value descending */ +static int +cmp_raw_str_desc (const void *a, const void *b) +{ + const GRawDataItem *ia = a; + const GRawDataItem *ib = b; + + return strcmp (ib->value.svalue, ia->value.svalue); +} + +/* Sort 'bandwidth' metric descending */ +static int +cmp_bw_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + uint64_t va = ia->metrics->bw.nbw; + uint64_t vb = ib->metrics->bw.nbw; + + return (va < vb) - (va > vb); +} + +/* Sort 'bandwidth' metric ascending */ +static int +cmp_bw_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + uint64_t va = ia->metrics->bw.nbw; + uint64_t vb = ib->metrics->bw.nbw; + + return (va > vb) - (va < vb); +} + +/* Sort 'avgts' metric descending */ +static int +cmp_avgts_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + uint64_t va = ia->metrics->avgts.nts; + uint64_t vb = ib->metrics->avgts.nts; + + return (va < vb) - (va > vb); +} + +/* Sort 'avgts' metric ascending */ +static int +cmp_avgts_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + uint64_t va = ia->metrics->avgts.nts; + uint64_t vb = ib->metrics->avgts.nts; + + return (va > vb) - (va < vb); +} + +/* Sort 'cumts' metric descending */ +static int +cmp_cumts_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + uint64_t va = ia->metrics->cumts.nts; + uint64_t vb = ib->metrics->cumts.nts; + + return (va < vb) - (va > vb); +} + +/* Sort 'cumts' metric ascending */ +static int +cmp_cumts_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + uint64_t va = ia->metrics->cumts.nts; + uint64_t vb = ib->metrics->cumts.nts; + + return (va > vb) - (va < vb); +} + +/* Sort 'maxts' metric descending */ +static int +cmp_maxts_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + uint64_t va = ia->metrics->maxts.nts; + uint64_t vb = ib->metrics->maxts.nts; + + return (va < vb) - (va > vb); +} + +/* Sort 'maxts' metric ascending */ +static int +cmp_maxts_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + + uint64_t va = ia->metrics->maxts.nts; + uint64_t vb = ib->metrics->maxts.nts; + + return (va > vb) - (va < vb); +} + +/* Sort 'protocol' metric ascending */ +static int +cmp_proto_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + return strcmp (ia->metrics->protocol, ib->metrics->protocol); +} + +/* Sort 'protocol' metric descending */ +static int +cmp_proto_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + return strcmp (ib->metrics->protocol, ia->metrics->protocol); +} + +/* Sort 'method' metric ascending */ +static int +cmp_mthd_asc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + return strcmp (ia->metrics->method, ib->metrics->method); +} + +/* Sort 'method' metric descending */ +static int +cmp_mthd_desc (const void *a, const void *b) +{ + const GHolderItem *ia = a; + const GHolderItem *ib = b; + return strcmp (ib->metrics->method, ia->metrics->method); +} + +/* Given a string sort field, get the enum field value. + * + * On error, -1 is returned. + * On success, the enumerated field value is returned. */ +int +get_sort_field_enum (const char *str) +{ + return str2enum (FIELD, ARRAY_SIZE (FIELD), str); +} + +/* Given a string sort order, get the enum order value. + * + * On error, -1 is returned. + * On success, the enumerated order value is returned. */ +int +get_sort_order_enum (const char *str) +{ + return str2enum (ORDER, ARRAY_SIZE (ORDER), str); +} + +/* Given a GSortOrder enum value, return the corresponding string. + * + * The string corresponding to the enumerated order value is returned. */ +const char * +get_sort_order_str (GSortOrder order) +{ + return ORDER[order].str; +} + +/* Given a GSortField enum value, return the corresponding string. + * + * The string corresponding to the enumerated field value is returned. */ +const char * +get_sort_field_str (GSortField field) +{ + return FIELD[field].str; +} + +/* Given a GSortField enum value, return the corresponding key. + * + * The key corresponding to the enumerated field value is returned. */ +const char * +get_sort_field_key (GSortField field) +{ + static const char *field2key[][2] = { + {"BY_HITS", "hits"}, + {"BY_VISITORS", "visitors"}, + {"BY_DATA", "data"}, + {"BY_BW", "bytes"}, + {"BY_AVGTS", "avgts"}, + {"BY_CUMTS", "cumts"}, + {"BY_MAXTS", "maxts"}, + {"BY_PROT", "protocol"}, + {"BY_MTHD", "method"}, + }; + + return field2key[field][1]; +} + +/* Set the initial metric sort per module/panel. + * + * On error, function returns. + * On success, panel metrics are sorted. */ +void +set_initial_sort (const char *smod, const char *sfield, const char *ssort) +{ + int module, field, order; + if ((module = get_module_enum (smod)) == -1) + return; + + if ((field = get_sort_field_enum (sfield)) == -1) + return; + if ((order = get_sort_order_enum (ssort)) == -1) + return; + if (!can_sort_module (module, field)) + return; + + module_sort[module].field = field; + module_sort[module].sort = order; +} + +/* Determine if module/panel metric can be sorted. + * + * On error or if metric can't be sorted, 0 is returned. + * On success, 1 is returned. */ +int +can_sort_module (GModule module, int field) +{ + int i, can_sort = 0; + for (i = 0; -1 != sort_choices[module][i]; i++) { + if (sort_choices[module][i] != field) + continue; + if (SORT_BY_AVGTS == field && !conf.serve_usecs) + continue; + if (SORT_BY_CUMTS == field && !conf.serve_usecs) + continue; + if (SORT_BY_MAXTS == field && !conf.serve_usecs) + continue; + else if (SORT_BY_BW == field && !conf.bandwidth) + continue; + else if (SORT_BY_PROT == field && !conf.append_protocol) + continue; + else if (SORT_BY_MTHD == field && !conf.append_method) + continue; + + can_sort = 1; + break; + } + + return can_sort; +} + +/* Parse all initial sort options from the config file. + * + * On error, function returns. + * On success, panel metrics are sorted. */ +void +parse_initial_sort (void) +{ + int i; + char module[SORT_MODULE_LEN], field[SORT_FIELD_LEN], order[SORT_ORDER_LEN]; + for (i = 0; i < conf.sort_panel_idx; ++i) { + if (sscanf + (conf.sort_panels[i], "%15[^','],%11[^','],%4s", module, field, + order) != 3) + continue; + set_initial_sort (module, field, order); + } +} + +/* Apply user defined sort */ +void +sort_holder_items (GHolderItem * items, int size, GSort sort) +{ + switch (sort.field) { + case SORT_BY_HITS: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_num_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_num_asc); + break; + case SORT_BY_VISITORS: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_vis_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_vis_asc); + break; + case SORT_BY_DATA: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_data_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_data_asc); + break; + case SORT_BY_BW: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_bw_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_bw_asc); + break; + case SORT_BY_AVGTS: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_avgts_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_avgts_asc); + break; + case SORT_BY_CUMTS: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_cumts_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_cumts_asc); + break; + case SORT_BY_MAXTS: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_maxts_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_maxts_asc); + break; + case SORT_BY_PROT: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_proto_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_proto_asc); + break; + case SORT_BY_MTHD: + if (sort.sort == SORT_DESC) + qsort (items, size, sizeof (GHolderItem), cmp_mthd_desc); + else + qsort (items, size, sizeof (GHolderItem), cmp_mthd_asc); + break; + } +} + +/* Sort raw numeric data in a descending order for the first run + * (default sort) + * + * On success, raw data sorted in a descending order. */ +GRawData * +sort_raw_num_data (GRawData * raw_data, int ht_size) +{ + qsort (raw_data->items, ht_size, sizeof *(raw_data->items), cmp_raw_num_desc); + return raw_data; +} + +/* Sort raw string data in a descending order for the first run. + * + * On success, raw data sorted in a descending order. */ +GRawData * +sort_raw_str_data (GRawData * raw_data, int ht_size) +{ + qsort (raw_data->items, ht_size, sizeof *(raw_data->items), cmp_raw_str_desc); + return raw_data; +} diff --git a/goaccess++/src/sort.h b/goaccess++/src/sort.h new file mode 100644 index 0000000..8b63071 --- /dev/null +++ b/goaccess++/src/sort.h @@ -0,0 +1,92 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include +#endif + +#ifndef SORT_H_INCLUDED +#define SORT_H_INCLUDED + +#include "commons.h" +#include "parser.h" + +#define SORT_MAX_OPTS 11 + +/* See GEnum for mapping */ +#define SORT_FIELD_LEN 11 + 1 /* longest metric name */ +#define SORT_MODULE_LEN 15 + 1 /* longest module name */ +#define SORT_ORDER_LEN 4 + 1 /* length of ASC or DESC */ + +/* Enumerated sorting metrics */ +typedef enum GSortField_ +{ + SORT_BY_HITS, + SORT_BY_VISITORS, + SORT_BY_DATA, + SORT_BY_BW, + SORT_BY_AVGTS, + SORT_BY_CUMTS, + SORT_BY_MAXTS, + SORT_BY_PROT, + SORT_BY_MTHD, +} GSortField; + +/* Enumerated sorting order */ +typedef enum GSortOrder_ +{ + SORT_ASC, + SORT_DESC +} GSortOrder; + +/* Sorting of each panel, metric and order */ +typedef struct GSort_ +{ + GModule module; + GSortField field; + GSortOrder sort; +} GSort; + +extern GSort module_sort[TOTAL_MODULES]; +extern const int sort_choices[][SORT_MAX_OPTS];; + +GRawData *sort_raw_num_data (GRawData * raw_data, int ht_size); +GRawData *sort_raw_str_data (GRawData * raw_data, int ht_size); +const char *get_sort_field_key (GSortField field); +const char *get_sort_field_str (GSortField field); +const char *get_sort_order_str (GSortOrder order); +int can_sort_module (GModule module, int field); +int get_sort_field_enum (const char *str); +int get_sort_order_enum (const char *str); +int strcmp_asc (const void *a, const void *b); +void parse_initial_sort (void); +void set_initial_sort (const char *smod, const char *sfield, const char *ssort); +void sort_holder_items (GHolderItem * items, int size, GSort sort); + +#endif diff --git a/goaccess++/src/sort.o b/goaccess++/src/sort.o new file mode 100644 index 0000000..fcdf46b Binary files /dev/null and b/goaccess++/src/sort.o differ diff --git a/goaccess++/src/stamp-h1 b/goaccess++/src/stamp-h1 new file mode 100644 index 0000000..57ea58e --- /dev/null +++ b/goaccess++/src/stamp-h1 @@ -0,0 +1 @@ +timestamp for src/config.h diff --git a/goaccess++/src/tcabdb.c b/goaccess++/src/tcabdb.c new file mode 100644 index 0000000..e3914dc --- /dev/null +++ b/goaccess++/src/tcabdb.c @@ -0,0 +1,1716 @@ +/** + * tcabdb.c -- Tokyo Cabinet database functions + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "tcabdb.h" +#include "tcbtdb.h" + +#ifdef HAVE_GEOLOCATION +#include "geoip1.h" +#endif + +#include "error.h" +#include "sort.h" +#include "util.h" +#include "xmalloc.h" + +/* Hash tables storage */ +static GTCStorage *tc_storage; + +/* tables for the whole app */ +static TCADB *ht_agent_keys = NULL; +static TCADB *ht_agent_vals = NULL; +static TCADB *ht_general_stats = NULL; +static TCADB *ht_hostnames = NULL; +static TCADB *ht_unique_keys = NULL; + +/* db paths for whole app hashes */ +static char *dbpath_agent_keys = NULL; +static char *dbpath_agent_vals = NULL; +static char *dbpath_general_stats = NULL; +static char *dbpath_hostnames = NULL; +static char *dbpath_unique_keys = NULL; + +/* Instantiate a new store */ +static GTCStorage * +new_tcstorage (uint32_t size) +{ + GTCStorage *storage = xcalloc (size, sizeof (GTCStorage)); + return storage; +} + +/* Open a concrete database */ +static int +tc_adb_open (TCADB * adb, const char *params) +{ + /* attempt to open the database */ + if (!tcadbopen (adb, params)) + return 1; + return 0; +} + +/* Close the database handle */ +static int +tc_db_close (TCADB * adb, char *dbname) +{ + if (adb == NULL) + return 1; + + /* close the database */ + if (!tcadbclose (adb)) + FATAL ("Unable to close DB: %s", dbname); + + /* delete the object */ + tcadbdel (adb); + +#ifdef TCB_BTREE + /* remove database file */ + if (!conf.keep_db_files && !tcremovelink (dbname)) + LOG_DEBUG (("Unable to remove DB: %s\n", dbname)); +#endif + free (dbname); + + return 0; +} + +/* Setup a database given the file path and open it up */ +static TCADB * +tc_adb_create (char *path) +{ + char params[DB_PARAMS] = ""; + TCADB *adb = tcadbnew (); + +#ifdef TCB_MEMHASH + xstrncpy (params, path, DB_PARAMS); +#endif +#ifdef TCB_BTREE + tc_db_get_params (params, path); +#endif + + if (tc_adb_open (adb, params)) { + free (path); + LOG_DEBUG (("params: %s", params)); + FATAL ("Unable to open an abstract database: %s", params); + } + + return adb; +} + +/* Get the file path for the given a database name */ +static char * +get_dbname (const char *dbname, int module) +{ + char *path = NULL; +#ifdef TCB_MEMHASH + (void) dbname; + (void) module; + path = alloc_string ("*"); +#endif + +#ifdef TCB_BTREE + path = tc_db_set_path (dbname, module); +#endif + + return path; +} + +/* Create hashes used across the whole app (not per module) */ +static void +create_prog_tables (void) +{ + ht_agent_keys = tc_adb_create (dbpath_agent_keys); + ht_agent_vals = tc_adb_create (dbpath_agent_vals); + ht_general_stats = tc_adb_create (dbpath_general_stats); + ht_hostnames = tc_adb_create (dbpath_hostnames); + ht_unique_keys = tc_adb_create (dbpath_unique_keys); +} + +/* Set db paths for hashes used across the whole app (not per module) */ +static void +set_prog_tables_dbpaths (void) +{ + dbpath_agent_keys = get_dbname (DB_AGENT_KEYS, -1); + dbpath_agent_vals = get_dbname (DB_AGENT_VALS, -1); + dbpath_general_stats = get_dbname (DB_GEN_STATS, -1); + dbpath_hostnames = get_dbname (DB_HOSTNAMES, -1); + dbpath_unique_keys = get_dbname (DB_UNIQUE_KEYS, -1); +} + +/* Free hashes used across the whole app (not per module) */ +static void +free_prog_tables (void) +{ + tc_db_close (ht_agent_keys, dbpath_agent_keys); + tc_db_close (ht_agent_vals, dbpath_agent_vals); + tc_db_close (ht_general_stats, dbpath_general_stats); + tc_db_close (ht_hostnames, dbpath_hostnames); + tc_db_close (ht_unique_keys, dbpath_unique_keys); +} + +/* Initialize map & metric hashes */ +static void +init_tables (GModule module) +{ + GTCStorageMetric mtrc; + int n = 0, i; + + /* *INDENT-OFF* */ + GTCStorageMetric metrics[] = { + {MTRC_KEYMAP , DB_KEYMAP , NULL, NULL} , + {MTRC_ROOTMAP , DB_ROOTMAP , NULL, NULL} , + {MTRC_DATAMAP , DB_DATAMAP , NULL, NULL} , + {MTRC_UNIQMAP , DB_UNIQMAP , NULL, NULL} , + {MTRC_ROOT , DB_ROOT , NULL, NULL} , + {MTRC_HITS , DB_HITS , NULL, NULL} , + {MTRC_VISITORS , DB_VISITORS , NULL, NULL} , + {MTRC_BW , DB_BW , NULL, NULL} , + {MTRC_CUMTS , DB_CUMTS , NULL, NULL} , + {MTRC_MAXTS , DB_MAXTS , NULL, NULL} , + {MTRC_METHODS , DB_METHODS , NULL, NULL} , + {MTRC_PROTOCOLS , DB_PROTOCOLS , NULL, NULL} , + {MTRC_AGENTS , DB_AGENTS , NULL, NULL} , + {MTRC_METADATA , DB_METADATA , NULL, NULL} , + }; + /* *INDENT-ON* */ + + n = ARRAY_SIZE (metrics); + for (i = 0; i < n; i++) { + mtrc = metrics[i]; +#ifdef TCB_MEMHASH + mtrc.dbpath = get_dbname (mtrc.dbname, module); + mtrc.store = tc_adb_create (mtrc.dbpath); +#endif +#ifdef TCB_BTREE + /* allow for duplicate keys */ + if (mtrc.metric == MTRC_AGENTS) { + mtrc.dbpath = tc_db_set_path (DB_AGENTS, module); + mtrc.store = tc_bdb_create (mtrc.dbpath); + } else { + mtrc.dbpath = get_dbname (mtrc.dbname, module); + mtrc.store = tc_adb_create (mtrc.dbpath); + } +#endif + tc_storage[module].metrics[i] = mtrc; + } +} + +/* Initialize hash tables */ +void +init_storage (void) +{ + GModule module; + size_t idx = 0; + + set_prog_tables_dbpaths (); + create_prog_tables (); + + tc_storage = new_tcstorage (TOTAL_MODULES); + + FOREACH_MODULE (idx, module_list) { + module = module_list[idx]; + + tc_storage[module].module = module; + init_tables (module); + } +} + +/* Destroys the hash structure allocated metrics */ +static void +free_metrics (GModule module) +{ + int i; + GTCStorageMetric mtrc; + + for (i = 0; i < GSMTRC_TOTAL; i++) { + mtrc = tc_storage[module].metrics[i]; +#ifdef TCB_MEMHASH + tc_db_close (mtrc.store, mtrc.dbpath); +#endif +#ifdef TCB_BTREE + if (mtrc.metric == MTRC_AGENTS) + tc_bdb_close (mtrc.store, mtrc.dbpath); + else + tc_db_close (mtrc.store, mtrc.dbpath); +#endif + } +} + +/* Destroys the hash structure and its content */ +void +free_storage (void) +{ + size_t idx = 0; + + if (!tc_storage) + return; + + free_prog_tables (); + FOREACH_MODULE (idx, module_list) { + free_metrics (module_list[idx]); + } + free (tc_storage); + +#ifdef TCB_BTREE + tc_db_rmdir (); +#endif + +} + +static uint32_t +ht_get_size (TCADB * adb) +{ + return tcadbrnum (adb); +} + +/* Given a module and a metric, get the hash table + * + * On error, or if table is not found, NULL is returned. + * On success the hash structure pointer is returned. */ +static void * +get_hash (GModule module, GSMetric metric) +{ + void *hash = NULL; + int i; + GTCStorageMetric mtrc; + + if (!tc_storage) + return NULL; + + for (i = 0; i < GSMTRC_TOTAL; i++) { + mtrc = tc_storage[module].metrics[i]; + if (mtrc.metric != metric) + continue; + hash = mtrc.store; + break; + } + + return hash; +} + +/* Insert a string key and the corresponding int value. + * Note: If the key exists, the value is not replaced. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +static int +ins_si32 (void *hash, const char *key, int value) +{ + if (!hash) + return -1; + + /* if key exists in the database, it is overwritten */ + if (!tcadbput (hash, key, strlen (key), &value, sizeof (int))) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Insert an int key and the corresponding string value. + * Note: If the key exists, the value is not replaced. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +static int +ins_is32 (void *hash, int key, const char *value) +{ + if (!hash) + return -1; + + /* if key exists in the database, it is overwritten */ + if (!tcadbput (hash, &key, sizeof (int), value, strlen (value))) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Insert a string key and the corresponding string value. + * Note: If the key exists, the value is not replaced. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +static int +ins_ss32 (void *hash, const char *key, const char *value) +{ + if (!hash) + return -1; + + /* if key exists in the database, it is overwritten */ + if (!tcadbput2 (hash, key, value)) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Insert an int key and an int value + * Note: If the key exists, its value is replaced by the given value. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +ins_ii32 (void *hash, int key, int value) +{ + if (!hash) + return -1; + + /* if key exists in the database, it is overwritten */ + if (!tcadbput (hash, &key, sizeof (int), &value, sizeof (int))) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Insert an int key and a uint64_t value + * Note: If the key exists, its value is replaced by the given value. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +ins_iu64 (void *hash, int key, uint64_t value) +{ + if (!hash) + return -1; + + /* if key exists in the database, it is overwritten */ + if (!tcadbput (hash, &key, sizeof (int), &value, sizeof (uint64_t))) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Increase an int value given an int key. + * Note: If the key exists, its value is increased by the given inc. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +inc_ii32 (void *hash, int key, int inc) +{ + if (!hash) + return -1; + + /* if key exists in the database, it is incremented */ + if (tcadbaddint (hash, &key, sizeof (int), inc) == INT_MIN) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Increase a uint64_t value given an int key. + * Note: If the key exists, its value is increased by the given inc. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +inc_iu64 (void *hash, int key, uint64_t inc) +{ + int sp; + uint64_t value = inc; + void *ptr; + + if (!hash) + return -1; + + if ((ptr = tcadbget (hash, &key, sizeof (int), &sp)) != NULL) { + value = (*(uint64_t *) ptr) + inc; + free (ptr); + } + + /* if key exists in the database, it is overwritten */ + if (!tcadbput (hash, &key, sizeof (int), &value, sizeof (uint64_t))) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Insert a string key and auto increment its value. + * + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +static int +inc_si32 (void *hash, const char *key, int inc) +{ + int value = inc, sp; + void *ptr; + + if (!hash) + return -1; + + if ((ptr = tcadbget (hash, key, strlen (key), &sp)) != NULL) { + value = (*(int *) ptr) + inc; + free (ptr); + } + + /* if key exists in the database, it is overwritten */ + if (!tcadbput (hash, key, strlen (key), &value, sizeof (int))) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Insert a string key and auto increment by uint64_t value. + * + * On error, -1 is returned. + * On success the value of the key is inserted and 0 is returned */ +static int +inc_su64 (void *hash, const char *key, uint64_t inc) +{ + int sp; + uint64_t value = inc; + void *ptr; + + if (!hash) + return -1; + + if ((ptr = tcadbget (hash, key, strlen (key), &sp)) != NULL) { + value = (*(uint64_t *) ptr) + inc; + free (ptr); + } + + /* if key exists in the database, it is overwritten */ + if (!tcadbput (hash, key, strlen (key), &value, sizeof (uint64_t))) + LOG_DEBUG (("Unable to tcadbput\n")); + + return 0; +} + +/* Insert a string key and auto increment int value. + * + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +static int +ins_si32_ai (void *hash, const char *key) +{ + int size = 0, value = 0; + + if (!hash) + return -1; + + size = ht_get_size (hash); + /* the auto increment value starts at SIZE (hash table) + 1 */ + value = size > 0 ? size + 1 : 1; + + if (ins_si32 (hash, key, value) == -1) + return -1; + + return value; +} + +#ifdef TCB_MEMHASH + +/* Compare if the given needle is in the haystack + * + * if equal, 1 is returned, else 0 */ +static int +find_int_key_in_list (void *data, void *needle) +{ + return (*(int *) data) == (*(int *) needle) ? 1 : 0; +} + +/* Insert an int key and the corresponding GSLList (Single linked-list) value. + * Note: If the key exists within the list, the value is not appended. + * + * On error, -1 is returned. + * On success 0 is returned */ +static int +ins_igsl (void *hash, int key, int value) +{ + GSLList *list, *match; + int sp; + + if (!hash) + return -1; + + /* key found, check if key exists within the list */ + if ((list = tcadbget (hash, &key, sizeof (int), &sp)) != NULL) { + if ((match = list_find (list, find_int_key_in_list, &value))) + goto out; + list = list_insert_prepend (list, int2ptr (value)); + } else { + list = list_create (int2ptr (value)); + } + + if (!tcadbput (hash, &key, sizeof (int), list, sizeof (GSLList))) + LOG_DEBUG (("Unable to tcadbput\n")); +out: + free (list); + + return 0; +} + +#endif + +/* Get the int value of a given string key. + * + * On error, or if key is not found, -1 is returned. + * On success the int value for the given key is returned */ +static int +get_si32 (void *hash, const char *key) +{ + int ret = 0, sp; + void *ptr; + + if (!hash) + return -1; + + /* key found, return current value */ + if ((ptr = tcadbget (hash, key, strlen (key), &sp)) != NULL) { + ret = (*(int *) ptr); + free (ptr); + return ret; + } + + return -1; +} + +/* Get the unsigned int value of a given string key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint32_t value for the given key is returned */ +static uint32_t +get_sui32 (void *hash, const char *key) +{ + int ret = 0, sp; + void *ptr; + if (!hash) + return 0; + + /* key found, return current value */ + if ((ptr = tcadbget (hash, key, strlen (key), &sp)) != NULL) { + ret = (*(uint32_t *) ptr); + free (ptr); + return ret; + } + + return 0; +} + +/* Get the uint64_t value of a given string key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +static uint64_t +get_su64 (void *hash, const char *key) +{ + int sp; + uint64_t ret = 0; + void *ptr; + if (!hash) + return 0; + + /* key found, return current value */ + if ((ptr = tcadbget (hash, key, strlen (key), &sp)) != NULL) { + ret = (*(uint64_t *) ptr); + free (ptr); + return ret; + } + + return 0; +} + +/* Iterate over all the key/value pairs for the given hash structure + * and set the maximum and minimum values found on an integer key and + * integer value. + * + * Note: This are expensive calls since it has to iterate over all + * key-value pairs + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +static void +get_ii32_min_max (void *hash, int *min, int *max) +{ + int curvalue = 0, i = 0, ksize = 0, sp = 0; + void *key, *ptr; + + tcadbiterinit (hash); + while ((key = tcadbiternext (hash, &ksize)) != NULL) { + if ((ptr = tcadbget (hash, key, ksize, &sp)) == NULL) { + free (key); + continue; + } + + curvalue = (*(int *) ptr); + if (i++ == 0) + *min = curvalue; + if (curvalue > *max) + *max = curvalue; + if (curvalue < *min) + *min = curvalue; + free (key); + free (ptr); + } +} + +/* Iterate over all the key/value pairs for the given hash structure + * and set the maximum and minimum values found on an integer key and + * a uint64_t value. + * + * Note: This are expensive calls since it has to iterate over all + * key-value pairs + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +static void +get_iu64_min_max (void *hash, uint64_t * min, uint64_t * max) +{ + int i = 0, ksize = 0, sp = 0; + uint64_t curvalue = 0; + void *key, *ptr; + + tcadbiterinit (hash); + while ((key = tcadbiternext (hash, &ksize)) != NULL) { + if ((ptr = tcadbget (hash, key, ksize, &sp)) == NULL) { + free (key); + continue; + } + + curvalue = (*(uint64_t *) ptr); + if (i++ == 0) + *min = curvalue; + if (curvalue > *max) + *max = curvalue; + if (curvalue < *min) + *min = curvalue; + free (key); + free (ptr); + } +} + +/* Get the string value of a given int key. + * + * On error, or if key is not found, NULL is returned. + * On success the string value for the given key is returned */ +static char * +get_is32 (void *hash, int key) +{ + int sp; + char *value = NULL; + + if (!hash) + return NULL; + + if ((value = tcadbget (hash, &key, sizeof (int), &sp)) != NULL) + return value; + + return NULL; +} + +/* Get the string value of a given string key. + * + * On error, or if key is not found, NULL is returned. + * On success the string value for the given key is returned */ +static char * +get_ss32 (void *hash, const char *key) +{ + char *value = NULL; + + if (!hash) + return NULL; + + if ((value = tcadbget2 (hash, key)) != NULL) + return value; + + return NULL; +} + +/* Get the int value of a given int key. + * + * If key is not found, 0 is returned. + * On error, -1 is returned. + * On success the int value for the given key is returned */ +static int +get_ii32 (void *hash, int key) +{ + int sp, ret = 0; + void *ptr = 0; + + if (!hash) + return -1; + + /* key found, return current value */ + if ((ptr = tcadbget (hash, &key, sizeof (int), &sp)) != NULL) { + ret = (*(int *) ptr); + free (ptr); + return ret; + } + + return 0; +} + +/* Get the uint64_t value of a given int key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +static uint64_t +get_iu64 (void *hash, int key) +{ + int sp; + uint64_t ret = 0; + void *ptr = 0; + + if (!hash) + return 0; + + /* key found, return current value */ + if ((ptr = tcadbget (hash, &key, sizeof (int), &sp)) != NULL) { + ret = (*(uint64_t *) ptr); + free (ptr); + return ret; + } + + return 0; +} + +/* Get the GSLList value of a given int key. + * + * On error, or if key is not found, NULL is returned. + * On success the GSLList value for the given key is returned */ +static GSLList * +get_igsl (void *hash, int key) +{ + int sp; + GSLList *list = NULL; + + if (!hash) + return NULL; + + /* key found, return current value */ + if ((list = tcadbget (hash, &key, sizeof (int), &sp)) != NULL) + return list; + + return NULL; +} + +/* Get the TCLIST value of a given int key. + * + * On error, or if key is not found, NULL is returned. + * On success the GSLList value for the given key is returned */ +static TCLIST * +get_itcli (void *hash, int key) +{ + TCLIST *list = NULL; + + if (!hash) + return NULL; + + /* key found, return current value */ + if ((list = tcbdbget4 (hash, &key, sizeof (int))) != NULL) + return list; + + return NULL; +} + +/* Insert a unique visitor key string (IP/DATE/UA), mapped to an auto + * incremented value. + * + * If the given key exists, its value is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_unique_key (const char *key) +{ + int value = -1; + void *hash = ht_unique_keys; + + if (!hash) + return -1; + + if ((value = get_si32 (hash, key)) != -1) + return value; + + return ins_si32_ai (hash, key); +} + +/* Set the maximum and minimum values found on an integer key and + * integer value found on the MTRC_VISITORS hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_hits_min_max (GModule module, int *min, int *max) +{ + void *hash = get_hash (module, MTRC_HITS); + + if (!hash) + return; + + get_ii32_min_max (hash, min, max); +} + +/* Set the maximum and minimum values found on an integer key and + * integer value found on the MTRC_VISITORS hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_visitors_min_max (GModule module, int *min, int *max) +{ + void *hash = get_hash (module, MTRC_VISITORS); + + if (!hash) + return; + + get_ii32_min_max (hash, min, max); +} + +/* Set the maximum and minimum values found on an integer key and + * a uint64_t value found on the MTRC_BW hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_bw_min_max (GModule module, uint64_t * min, uint64_t * max) +{ + void *hash = get_hash (module, MTRC_BW); + + if (!hash) + return; + + get_iu64_min_max (hash, min, max); +} + +/* Set the maximum and minimum values found on an integer key and + * a uint64_t value found on the MTRC_CUMTS hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_cumts_min_max (GModule module, uint64_t * min, uint64_t * max) +{ + void *hash = get_hash (module, MTRC_CUMTS); + + if (!hash) + return; + + get_iu64_min_max (hash, min, max); +} + +/* Set the maximum and minimum values found on an integer key and + * a uint64_t value found on the MTRC_MAXTS hash structure. + * + * If the hash structure is empty, no values are set. + * On success the minimum and maximum values are set. */ +void +ht_get_maxts_min_max (GModule module, uint64_t * min, uint64_t * max) +{ + void *hash = get_hash (module, MTRC_MAXTS); + + if (!hash) + return; + + get_iu64_min_max (hash, min, max); +} + +/* Insert a user agent key string, mapped to an auto incremented value. + * + * If the given key exists, its value is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_agent_key (const char *key) +{ + int value = -1; + void *hash = ht_agent_keys; + + if (!hash) + return -1; + + if ((value = get_si32 (hash, key)) != -1) + return value; + + return ins_si32_ai (hash, key); +} + +/* Insert a user agent int key, mapped to a user agent string value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_agent_value (int key, const char *value) +{ + void *hash = ht_agent_vals; + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert a keymap string key. + * + * If the given key exists, its value is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_keymap (GModule module, const char *key) +{ + int value = -1; + void *hash = get_hash (module, MTRC_KEYMAP); + + if (!hash) + return -1; + + if ((value = get_si32 (hash, key)) != -1) + return value; + + return ins_si32_ai (hash, key); +} + +/* Insert a datamap int key and string value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_datamap (GModule module, int key, const char *value) +{ + void *hash = get_hash (module, MTRC_DATAMAP); + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert a rootmap int key from the keymap store mapped to its string value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_rootmap (GModule module, int key, const char *value) +{ + void *hash = get_hash (module, MTRC_ROOTMAP); + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert a uniqmap string key. + * + * If the given key exists, 0 is returned. + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_uniqmap (GModule module, const char *key) +{ + int value = -1; + void *hash = get_hash (module, MTRC_UNIQMAP); + + if (!hash) + return -1; + + if ((value = get_si32 (hash, key)) != -1) + return 0; + + return ins_si32_ai (hash, key); +} + +/* Insert a data int key mapped to the corresponding int root key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_root (GModule module, int key, int value) +{ + void *hash = get_hash (module, MTRC_ROOT); + + if (!hash) + return -1; + + return ins_ii32 (hash, key, value); +} + +/* Increases hits counter from an int key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_hits (GModule module, int key, int inc) +{ + void *hash = get_hash (module, MTRC_HITS); + + if (!hash) + return -1; + + return inc_ii32 (hash, key, inc); +} + +/* Increases visitors counter from an int key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_visitor (GModule module, int key, int inc) +{ + void *hash = get_hash (module, MTRC_VISITORS); + + if (!hash) + return -1; + + return inc_ii32 (hash, key, inc); +} + +/* Increases bandwidth counter from an int key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_bw (GModule module, int key, uint64_t inc) +{ + void *hash = get_hash (module, MTRC_BW); + + if (!hash) + return -1; + + return inc_iu64 (hash, key, inc); +} + +/* Increases cumulative time served counter from an int key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_cumts (GModule module, int key, uint64_t inc) +{ + void *hash = get_hash (module, MTRC_CUMTS); + + if (!hash) + return -1; + + return inc_iu64 (hash, key, inc); +} + +/* Insert the maximum time served counter from an int key. + * Note: it compares the current value with the given value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_maxts (GModule module, int key, uint64_t value) +{ + uint64_t curvalue = 0; + void *hash = get_hash (module, MTRC_MAXTS); + + if (!hash) + return -1; + + if ((curvalue = get_iu64 (hash, key)) < value) + ins_iu64 (hash, key, value); + + return 0; +} + +/* Insert a method given an int key and string value. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +int +ht_insert_method (GModule module, int key, const char *value) +{ + void *hash = get_hash (module, MTRC_METHODS); + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert a protocol given an int key and string value. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +int +ht_insert_protocol (GModule module, int key, const char *value) +{ + void *hash = get_hash (module, MTRC_PROTOCOLS); + + if (!hash) + return -1; + + return ins_is32 (hash, key, value); +} + +/* Insert an agent for a hostname given an int key and int value. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_agent (GModule module, int key, int value) +{ + void *hash = get_hash (module, MTRC_AGENTS); + + if (!hash) + return -1; + + return ins_igsl (hash, key, value); +} + +/* Insert an IP hostname mapped to the corresponding hostname. + * + * On error, or if key exists, -1 is returned. + * On success 0 is returned */ +int +ht_insert_hostname (const char *ip, const char *host) +{ + void *hash = ht_hostnames; + + if (!hash) + return -1; + + return ins_ss32 (hash, ip, host); +} + +/* Increases a general stats counter int from a string key. + * + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_genstats (const char *key, int inc) +{ + void *hash = ht_general_stats; + + if (!hash) + return -1; + + return inc_si32 (hash, key, inc); +} + +/* Replaces a general stats counter int from a string key. + * + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_replace_genstats (const char *key, int value) +{ + void *hash = ht_general_stats; + + if (!hash) + return -1; + + return ins_si32 (hash, key, value); +} + +/* Increases the general stats counter accumulated_time. + * + * On error, 0 is returned + * On success 1 is returned */ +int +ht_insert_genstats_accumulated_time (time_t elapsed) +{ + void *hash = ht_general_stats; + + if (!hash) + return 0; + + return inc_si32 (hash, "accumulated_time", (int) elapsed) != -1; +} + +/* Increases a general stats counter uint64_t from a string key. + * + * On error, -1 is returned. + * On success the value of the key inserted is returned */ +int +ht_insert_genstats_bw (const char *key, uint64_t inc) +{ + void *hash = ht_general_stats; + + if (!hash) + return -1; + + return inc_su64 (hash, key, inc); +} + +/* Insert meta data counters from a string key. + * + * On error, -1 is returned. + * On success 0 is returned */ +int +ht_insert_meta_data (GModule module, const char *key, uint64_t value) +{ + void *hash = get_hash (module, MTRC_METADATA); + + if (!hash) + return -1; + + return inc_su64 (hash, key, value); +} + + +/* Get the number of elements in a datamap. + * + * Return -1 if the operation fails, else number of elements. */ +uint32_t +ht_get_size_datamap (GModule module) +{ + void *hash = get_hash (module, MTRC_DATAMAP); + + if (!hash) + return 0; + + return ht_get_size (hash); +} + +/* Get the number of elements in a uniqmap. + * + * On error, 0 is returned. + * On success the number of elements in MTRC_UNIQMAP is returned */ +uint32_t +ht_get_size_uniqmap (GModule module) +{ + void *hash = get_hash (module, MTRC_UNIQMAP); + + if (!hash) + return 0; + + return ht_get_size (hash); +} + +/* Get the string data value of a given int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_datamap (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_DATAMAP); + + if (!hash) + return NULL; + + return get_is32 (hash, key); +} + +/* Get the int value from MTRC_KEYMAP given a string key. + * + * On error, -1 is returned. + * On success the int value for the given key is returned */ +int +ht_get_keymap (GModule module, const char *key) +{ + void *hash = get_hash (module, MTRC_KEYMAP); + + if (!hash) + return -1; + + return get_si32 (hash, key); +} + +/* Get the int value from MTRC_UNIQMAP given a string key. + * + * On error, -1 is returned. + * On success the int value for the given key is returned */ +int +ht_get_uniqmap (GModule module, const char *key) +{ + void *hash = get_hash (module, MTRC_UNIQMAP); + + if (!hash) + return -1; + + return get_si32 (hash, key); +} + +/* Get the uint32_t value from ht_general_stats given a string key. + * + * On error, 0 is returned. + * On success the uint32_t value for the given key is returned */ +uint32_t +ht_get_genstats (const char *key) +{ + void *hash = ht_general_stats; + + if (!hash) + return 0; + + return get_sui32 (hash, key); +} + +/* Get the uint64_t value from ht_general_stats given a string key. + * + * On error, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_genstats_bw (const char *key) +{ + void *hash = ht_general_stats; + + if (!hash) + return 0; + + return get_su64 (hash, key); +} + +/* Get the string root from MTRC_ROOTMAP given an int data key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_root (GModule module, int key) +{ + int root_key = 0; + void *hashroot = get_hash (module, MTRC_ROOT); + void *hashrootmap = get_hash (module, MTRC_ROOTMAP); + + if (!hashroot || !hashrootmap) + return NULL; + + /* not found */ + if ((root_key = get_ii32 (hashroot, key)) == 0) + return NULL; + + return get_is32 (hashrootmap, root_key); +} + +/* Get the int visitors value from MTRC_HITS given an int key. + * + * If key is not found, 0 is returned. + * On error, -1 is returned. + * On success the int value for the given key is returned */ +int +ht_get_hits (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_HITS); + + if (!hash) + return -1; + + return get_ii32 (hash, key); +} + +/* Get the int visitors value from MTRC_VISITORS given an int key. + * + * If key is not found, 0 is returned. + * On error, -1 is returned. + * On success the int value for the given key is returned */ +int +ht_get_visitors (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_VISITORS); + + if (!hash) + return -1; + + return get_ii32 (hash, key); +} + +/* Get the uint64_t value from MTRC_BW given an int key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_bw (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_BW); + + if (!hash) + return 0; + + return get_iu64 (hash, key); +} + +/* Get the uint64_t value from MTRC_CUMTS given an int key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_cumts (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_CUMTS); + + if (!hash) + return 0; + + return get_iu64 (hash, key); +} + +/* Get the uint64_t value from MTRC_MAXTS given an int key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_maxts (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_MAXTS); + + if (!hash) + return 0; + + return get_iu64 (hash, key); +} + +/* Get the string value from MTRC_METHODS given an int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_method (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_METHODS); + + if (!hash) + return NULL; + + return get_is32 (hash, key); +} + +char * +ht_get_protocol (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_PROTOCOLS); + + if (!hash) + return NULL; + + return get_is32 (hash, key); +} + +/* Get the string value from MTRC_PROTOCOLS given an int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_hostname (const char *host) +{ + void *hash = ht_hostnames; + + if (!hash) + return NULL; + + return get_ss32 (hash, host); +} + +/* Get the string value from ht_agent_vals (user agent) given an int key. + * + * On error, NULL is returned. + * On success the string value for the given key is returned */ +char * +ht_get_host_agent_val (int key) +{ + void *hash = ht_agent_vals; + + if (!hash) + return NULL; + + return get_is32 (hash, key); +} + +/* Get the list value from MTRC_AGENTS given an int key. + * + * On error, or if key is not found, NULL is returned. + * On success the GSLList value for the given key is returned */ +GSLList * +ht_get_host_agent_list (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_AGENTS); + GSLList *list; + + if ((list = get_igsl (hash, key))) + return list; + return NULL; +} + +/* Get the meta data uint64_t from MTRC_METADATA given a string key. + * + * On error, or if key is not found, 0 is returned. + * On success the uint64_t value for the given key is returned */ +uint64_t +ht_get_meta_data (GModule module, const char *key) +{ + void *hash = get_hash (module, MTRC_METADATA); + if (!hash) + return 0; + + return get_su64 (hash, key); +} + +/* Get the list value from MTRC_AGENTS given an int key. + * + * On error, or if key is not found, NULL is returned. + * On success the TCLIST value for the given key is returned */ +TCLIST * +ht_get_host_agent_tclist (GModule module, int key) +{ + void *hash = get_hash (module, MTRC_AGENTS); + TCLIST *list; + + if ((list = get_itcli (hash, key))) + return list; + return NULL; +} + +/* Insert the values from a TCLIST into a GSLList. + * + * On success the GSLList is returned */ +GSLList * +tclist_to_gsllist (TCLIST * tclist) +{ + GSLList *list = NULL; + int i, sz; + int *val; + + for (i = 0; i < tclistnum (tclist); ++i) { + val = (int *) tclistval (tclist, i, &sz); + if (list == NULL) + list = list_create (int2ptr (*val)); + else + list = list_insert_prepend (list, int2ptr (*val)); + } + + return list; +} + +/* Calls the given function for each of the key/value pairs */ +static void +tc_db_foreach (void *db, void (*fp) (TCADB * m, void *k, int s, void *u), + void *user_data) +{ + TCADB *adb = db; + int ksize = 0; + void *key; + + tcadbiterinit (adb); + while ((key = tcadbiternext (adb, &ksize)) != NULL) { + (*fp) (adb, key, ksize, user_data); + free (key); + } +} + +/* Free the key/value pair */ +static void +free_agent_values (TCADB * adb, void *key, int ksize, GO_UNUSED void *user_data) +{ + void *list; + int sp = 0; + + list = tcadbget (adb, key, ksize, &sp); + if (list) + list_remove_nodes (list); +} + +/* Iterate over the each key/value pair under MTRC_AGENTS and free the and the + * list of values */ +void +free_agent_list (void) +{ + void *hash = get_hash (HOSTS, MTRC_AGENTS); + if (!hash) + return; + + tc_db_foreach (hash, free_agent_values, NULL); +} + +/* A wrapper to initialize a raw data structure. + * + * On success a GRawData structure is returned. */ +static GRawData * +init_new_raw_data (GModule module, uint32_t ht_size) +{ + GRawData *raw_data; + + raw_data = new_grawdata (); + raw_data->idx = 0; + raw_data->module = module; + raw_data->size = ht_size; + raw_data->items = new_grawdata_item (ht_size); + + return raw_data; +} + +/* For each key/value pair stored in MTRC_HITS/MTRC_DATAMAP, assign the + * key/value to a GRawDataItem */ +static void +set_raw_data (void *key, void *value, GRawData * raw_data) +{ + raw_data->items[raw_data->idx].key = (*(int *) key); + if (raw_data->type == STRING) + raw_data->items[raw_data->idx].value.svalue = (char *) value; + else + raw_data->items[raw_data->idx].value.ivalue = (*(int *) value); + raw_data->idx++; +} + +/* Get the value stored in MTRC_HITS */ +static void +data_iter_generic (TCADB * adb, void *key, int ksize, void *user_data) +{ + GRawData *raw_data = user_data; + void *value; + int sp = 0; + + value = tcadbget (adb, key, ksize, &sp); + if (value) { + set_raw_data (key, value, raw_data); + if (raw_data->type != STRING) + free (value); + } +} + +/* Entry point to load the raw data from the data store into our + * GRawData structure. + * + * On error, NULL is returned. + * On success the GRawData sorted is returned */ +GRawData * +parse_raw_data (GModule module) +{ + GRawData *raw_data; + GRawDataType type; + uint32_t ht_size = 0; + void *hash = NULL; + + switch (module) { + case VISITORS: + hash = get_hash (module, MTRC_DATAMAP); + type = STRING; + break; + default: + hash = get_hash (module, MTRC_HITS); + type = INTEGER; + } + + if (!hash) + return NULL; + + ht_size = ht_get_size (hash); + raw_data = init_new_raw_data (module, ht_size); + raw_data->type = type; + + tc_db_foreach (hash, data_iter_generic, raw_data); + sort_raw_num_data (raw_data, raw_data->idx); + + return raw_data; +} diff --git a/goaccess++/src/tcabdb.h b/goaccess++/src/tcabdb.h new file mode 100644 index 0000000..caa9ee8 --- /dev/null +++ b/goaccess++/src/tcabdb.h @@ -0,0 +1,226 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include +#endif + +#ifndef TCABDB_H_INCLUDED +#define TCABDB_H_INCLUDED + +#include + +#include "gslist.h" +#include "gstorage.h" +#include "parser.h" + +#define DB_PARAMS 256 + +/* Metrics Storage */ + +/* Maps keys (string) to numeric values (integer). + * This mitigates the issue of having multiple stores + * with the same string key, and therefore, avoids unnecessary + * memory usage (in most cases). + * + * HEAD|/index.php -> 1 + * POST|/index.php -> 2 + * Windows XP -> 3 + * Ubuntu 10.10 -> 4 + * GET|Ubuntu 10.10 -> 5 + * Linux -> 6 + * 26/Dec/2014 -> 7 + * Windows -> 8 + */ +/* MTRC_KEYMAP */ + +/* Maps integer keys of root elements from the keymap hash + * to actual string values. + * + * 6 -> Linux + * 8 -> Windows + */ +/* MTRC_ROOTMAP */ + +/* Maps integer keys of data elements from the keymap hash + * to actual string values. + * + * 1 -> /index.php + * 2 -> /index.php + * 3 -> Windows XP + * 4 -> Ubuntu 10.10 + * 5 -> Ubuntu 10.10 + * 7 -> 26/Dec/2014 + */ +/* MTRC_DATAMAP */ + +/* Maps a string key made from the integer key of the + * IP/date/UA and the integer key from the data field of + * each module to numeric autoincremented values. e.g., "1|4" + * => 1 -> unique visitor key (concatenated) with 4 -> data + * key. + * + * "1|4" -> 1 + * "1|5" -> 2 + */ +/* MTRC_UNIQMAP */ + +/* Maps integer key from the keymap hash to the number of + * hits. + * + * 1 -> 10934 + * 2 -> 3231 + * 3 -> 500 + * 4 -> 201 + * 5 -> 206 + */ +/* MTRC_HITS */ + +/* Maps numeric keys made from the uniqmap store to autoincremented values + * (counter). + * 10 -> 100 + * 40 -> 56 + */ +/* MTRC_VISITORS */ + +/* Maps numeric data keys to bandwidth (in bytes). + * 1 -> 1024 + * 2 -> 2048 + */ +/* MTRC_BW */ + +/* Maps numeric data keys to cumulative time served (in usecs/msecs). + * 1 -> 187 + * 2 -> 208 + */ +/* MTRC_CUMTS */ + +/* Maps numeric data keys to max time served (in usecs/msecs). + * 1 -> 1287 + * 2 -> 2308 + */ +/* MTRC_MAXTS */ + +/* Maps numeric data keys to string values. + * 1 -> GET + * 2 -> POST + */ +/* MTRC_METHODS */ + +/* Maps numeric data keys to string values. + * 1 -> HTTP/1.1 + * 2 -> HTTP/1.0 + */ +/* MTRC_PROTOCOLS */ + +/* Maps numeric unique user-agent keys to the + * corresponding numeric value. + * 1 -> 3 + * 2 -> 4 + */ +/* MTRC_AGENTS */ + +/* Enumerated Storage Metrics */ +typedef struct GTCStorageMetric_ +{ + GSMetric metric; + const char *dbname; + char *dbpath; + void *store; +} GTCStorageMetric; + +/* Data Storage per module */ +typedef struct GTCStorage_ +{ + GModule module; + GTCStorageMetric metrics[GSMTRC_TOTAL]; +} GTCStorage; + +void free_agent_list (void); +void free_storage (void); +void init_storage (void); + +int ht_insert_agent_key (const char *key); +int ht_insert_agent_value (int key, const char *value); +int ht_insert_unique_key (const char *key); + +int ht_insert_agent (GModule module, int key, int value); +int ht_insert_bw (GModule module, int key, uint64_t inc); +int ht_insert_cumts (GModule module, int key, uint64_t inc); +int ht_insert_datamap (GModule module, int key, const char *value); +int ht_insert_genstats_accumulated_time (time_t elapsed); +int ht_insert_genstats_bw (const char *key, uint64_t inc); +int ht_insert_genstats (const char *key, int inc); +int ht_insert_hits (GModule module, int key, int inc); +int ht_insert_hostname (const char *ip, const char *host); +int ht_insert_keymap (GModule module, const char *key); +int ht_insert_maxts (GModule module, int key, uint64_t value); +int ht_insert_meta_data (GModule module, const char *key, uint64_t value); +int ht_insert_method (GModule module, int key, const char *value); +int ht_insert_protocol (GModule module, int key, const char *value); +int ht_insert_root (GModule module, int key, int value); +int ht_insert_rootmap (GModule module, int key, const char *value); +int ht_insert_uniqmap (GModule module, const char *key); +int ht_insert_visitor (GModule module, int key, int inc); +int ht_replace_genstats (const char *key, int value); + +uint32_t ht_get_size_datamap (GModule module); +uint32_t ht_get_size_uniqmap (GModule module); + +char *ht_get_datamap (GModule module, int key); +char *ht_get_host_agent_val (int key); +char *ht_get_hostname (const char *host); +char *ht_get_method (GModule module, int key); +char *ht_get_protocol (GModule module, int key); +char *ht_get_root (GModule module, int key); +int ht_get_hits (GModule module, int key); +int ht_get_keymap (GModule module, const char *key); +int ht_get_uniqmap (GModule module, const char *key); +int ht_get_visitors (GModule module, int key); +uint32_t ht_get_genstats (const char *key); +uint64_t ht_get_bw (GModule module, int key); +uint64_t ht_get_cumts (GModule module, int key); +uint64_t ht_get_genstats_bw (const char *key); +uint64_t ht_get_maxts (GModule module, int key); +uint64_t ht_get_meta_data (GModule module, const char *key); +void ht_get_bw_min_max (GModule module, uint64_t * min, uint64_t * max); +void ht_get_cumts_min_max (GModule module, uint64_t * min, uint64_t * max); +void ht_get_hits_min_max (GModule module, int *min, int *max); +void ht_get_maxts_min_max (GModule module, uint64_t * min, uint64_t * max); +void ht_get_visitors_min_max (GModule module, int *min, int *max); + +GSLList *tclist_to_gsllist (TCLIST * tclist); +GSLList *ht_get_host_agent_list (GModule module, int key); +TCLIST *ht_get_host_agent_tclist (GModule module, int key); + +GRawData *parse_raw_data (GModule module); + +/* *INDENT-ON* */ + +#endif diff --git a/goaccess++/src/tcbtdb.c b/goaccess++/src/tcbtdb.c new file mode 100644 index 0000000..a509038 --- /dev/null +++ b/goaccess++/src/tcbtdb.c @@ -0,0 +1,333 @@ +/** + * tcbtdb.c -- Tokyo Cabinet database functions + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tcbtdb.h" +#include "tcabdb.h" + +#ifdef HAVE_GEOLOCATION +#include "geoip1.h" +#endif + +#include "error.h" +#include "util.h" +#include "xmalloc.h" + +#ifdef TCB_BTREE + +/* Get the on-disk databases path. + * + * On success, the databases path string is returned. */ +char * +tc_db_set_path (const char *dbname, int module) +{ + struct stat info; + static char default_path[sizeof (TC_DBPATH "01234567890/")]; + static char *db_path; + char *path; + char fname[RAND_FN]; + int cx; + + /* db_path is either specified explicitly, or gets the default (pid appended) */ + if (conf.db_path != NULL) + db_path = (char *) conf.db_path; + else { + sprintf (default_path, "%s%d", TC_DBPATH, getpid ()); + db_path = default_path; + mkdir (db_path, TC_DBPMODE); + } + + /* sanity check: Is db_path accessible and a directory? */ + if (stat (db_path, &info) != 0) + FATAL ("Unable to access database path: %s", strerror (errno)); + if (!(info.st_mode & S_IFDIR)) + FATAL ("Database path is not a directory."); + + /* for tc_db_rmdir(), return the pure folder path (or NULL to keep) */ + if (dbname == NULL) + return conf.db_path == NULL ? db_path : NULL; + + memset (fname, 0, sizeof (fname)); + /* tcadbopen requires the db name suffix to be ".tcb" and thus we + * don't use mkstemp(3) */ + genstr (fname, RAND_FN - 1); + + cx = snprintf (NULL, 0, "%s/%dm%s%s", db_path, module, fname, dbname) + 1; + path = xmalloc (cx); + sprintf (path, "%s/%dm%s%s", db_path, module, fname, dbname); + + return path; +} + +/* delete db folder if we used the customized (pid appended) default */ +void +tc_db_rmdir () +{ + const char *db_path = NULL; + + db_path = tc_db_set_path (NULL, 0); + if (db_path != NULL) + if (rmdir (db_path)) + LOG_DEBUG (("Unable to remove custom db folder: %s\n", db_path)); +} + + +/* Set the given database parameter into the parameters buffer. + * + * On error, a negative number is returned. + * On success, the number of characters that would have been written is + * returned. */ +static int +set_dbparam (char *params, int len, const char *fmt, ...) +{ + int n; + va_list args; + + va_start (args, fmt); + n = vsnprintf (params + len, DB_PARAMS - len, fmt, args); + va_end (args); + + if (n < 0) { + n = 0; + LOG_DEBUG (("Output error is encountered on set_dbparam\n")); + } else if (n >= DB_PARAMS - len) { + LOG_DEBUG (("Output truncated on set_dbparam\n")); + n = DB_PARAMS - len; + } + + return n; +} + +/* Set the on-disk database parameters from enabled options in the config file. */ +void +tc_db_get_params (char *params, const char *path) +{ + int len = 0; + long xmmap = conf.xmmap; + uint32_t lcnum, ncnum, lmemb, nmemb, bnum; + + /* copy path name to buffer */ + len += set_dbparam (params, len, "%s", path); + + /* caching parameters of a B+ tree database object */ + lcnum = conf.cache_lcnum > 0 ? conf.cache_lcnum : TC_LCNUM; + len += set_dbparam (params, len, "#%s=%d", "lcnum", lcnum); + + ncnum = conf.cache_ncnum > 0 ? conf.cache_ncnum : TC_NCNUM; + len += set_dbparam (params, len, "#%s=%d", "ncnum", ncnum); + + /* set the size of the extra mapped memory */ + if (xmmap > 0) + len += set_dbparam (params, len, "#%s=%ld", "xmsiz", xmmap); + + lmemb = conf.tune_lmemb > 0 ? conf.tune_lmemb : TC_LMEMB; + len += set_dbparam (params, len, "#%s=%d", "lmemb", lmemb); + + nmemb = conf.tune_nmemb > 0 ? conf.tune_nmemb : TC_NMEMB; + len += set_dbparam (params, len, "#%s=%d", "nmemb", nmemb); + + bnum = conf.tune_bnum > 0 ? conf.tune_bnum : TC_BNUM; + len += set_dbparam (params, len, "#%s=%d", "bnum", bnum); + + /* compression */ + len += set_dbparam (params, len, "#%s=%c", "opts", 'l'); + + if (conf.compression == TC_BZ2) { + len += set_dbparam (params, len, "%c", 'b'); + } else if (conf.compression == TC_ZLIB) { + len += set_dbparam (params, len, "%c", 'd'); + } + + /* open flags. create a new database if not exist, otherwise read it */ + len += set_dbparam (params, len, "#%s=%s", "mode", "wc"); + /* if not loading from disk, truncate regardless if a db file exists */ + if (!conf.load_from_disk) + len += set_dbparam (params, len, "%c", 't'); + + LOG_DEBUG (("%s\n", path)); + LOG_DEBUG (("params: %s\n", params)); +} + +/* Open the database handle. + * + * On error, the program will exit. + * On success, the opened on-disk database is returned. */ +TCBDB * +tc_bdb_create (char *dbpath) +{ + TCBDB *bdb; + int ecode; + uint32_t lcnum, ncnum, lmemb, nmemb, bnum, flags; + + bdb = tcbdbnew (); + + lcnum = conf.cache_lcnum > 0 ? conf.cache_lcnum : TC_LCNUM; + ncnum = conf.cache_ncnum > 0 ? conf.cache_ncnum : TC_NCNUM; + + /* set the caching parameters of a B+ tree database object */ + if (!tcbdbsetcache (bdb, lcnum, ncnum)) { + free (dbpath); + FATAL ("Unable to set TCB cache"); + } + + /* set the size of the extra mapped memory */ + if (conf.xmmap > 0 && !tcbdbsetxmsiz (bdb, conf.xmmap)) { + free (dbpath); + FATAL ("Unable to set TCB xmmap."); + } + + lmemb = conf.tune_lmemb > 0 ? conf.tune_lmemb : TC_LMEMB; + nmemb = conf.tune_nmemb > 0 ? conf.tune_nmemb : TC_NMEMB; + bnum = conf.tune_bnum > 0 ? conf.tune_bnum : TC_BNUM; + + /* compression */ + flags = BDBTLARGE; + if (conf.compression == TC_BZ2) { + flags |= BDBTBZIP; + } else if (conf.compression == TC_ZLIB) { + flags |= BDBTDEFLATE; + } + + /* set the tuning parameters */ + tcbdbtune (bdb, lmemb, nmemb, bnum, 8, 10, flags); + + /* open flags */ + flags = BDBOWRITER | BDBOCREAT; + if (!conf.load_from_disk) + flags |= BDBOTRUNC; + + /* attempt to open the database */ + if (!tcbdbopen (bdb, dbpath, flags)) { + free (dbpath); + ecode = tcbdbecode (bdb); + + FATAL ("%s", tcbdberrmsg (ecode)); + } + + return bdb; +} + +/* Close the database handle. + * + * On error, 1 is returned. + * On success or the database is closed, 0 is returned. */ +int +tc_bdb_close (void *db, char *dbname) +{ + TCBDB *bdb = db; + int ecode; + + if (bdb == NULL) + return 1; + + /* close the database */ + if (!tcbdbclose (bdb)) { + ecode = tcbdbecode (bdb); + FATAL ("%s", tcbdberrmsg (ecode)); + } + /* delete the object */ + tcbdbdel (bdb); + + /* remove database file */ + if (!conf.keep_db_files && !tcremovelink (dbname)) + LOG_DEBUG (("Unable to remove DB: %s\n", dbname)); + free (dbname); + + return 0; +} + +/* Compare the given integer value with one in the list object. + * + * If values are the equal, 1 is returned else 0 is returned. */ +static int +find_int_key_in_list (void *data, void *needle) +{ + return (*(int *) data) == (*(int *) needle) ? 1 : 0; +} + +/* Iterate over the list object and compare the current value with the given + * value. + * + * If the value exists, 1 is returned else 0 is returned. */ +static int +is_value_in_tclist (TCLIST * tclist, void *value) +{ + int i, sz; + int *val; + + if (!tclist) + return 0; + + for (i = 0; i < tclistnum (tclist); ++i) { + val = (int *) tclistval (tclist, i, &sz); + if (find_int_key_in_list (value, val)) + return 1; + } + + return 0; +} + +/* Insert a string key and the corresponding string value. + * Note: If the key exists, the value is not replaced. + * + * On error, or if found, 1 is returned. + * On success, or if not in the list, 0 is returned. */ +int +ins_igsl (void *hash, int key, int value) +{ + TCLIST *list; + int in_list = 0; + + if (!hash) + return -1; + + /* key found, check if key exists within the list */ + if ((list = tcbdbget4 (hash, &key, sizeof (int))) != NULL) { + if (is_value_in_tclist (list, &value)) + in_list = 1; + tclistdel (list); + } + /* if not on the list, add it */ + if (!in_list && tcbdbputdup (hash, &key, sizeof (int), &value, sizeof (int))) + return 0; + + return -1; +} +#endif diff --git a/goaccess++/src/tcbtdb.h b/goaccess++/src/tcbtdb.h new file mode 100644 index 0000000..01a2bf2 --- /dev/null +++ b/goaccess++/src/tcbtdb.h @@ -0,0 +1,91 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#if HAVE_CONFIG_H +#include +#endif + +#ifndef TCBTDB_H_INCLUDED +#define TCBTDB_H_INCLUDED + +#include + +#include "commons.h" +#include "gstorage.h" +#include "parser.h" + +#define TC_MMAP 0 +#define TC_LCNUM 1024 +#define TC_NCNUM 512 +#define TC_LMEMB 128 +#define TC_NMEMB 256 +#define TC_BNUM 32749 +#define TC_DBPATH "/tmp/goaccess" +#define TC_DBPMODE 0755 +#define TC_ZLIB 1 +#define TC_BZ2 2 + +#define RAND_FN 7 + 1 + +/* B+ Tree - on-disk databases */ +#define DB_AGENT_KEYS "db_agent_keys.tcb" +#define DB_AGENT_VALS "db_agent_vals.tcb" +#define DB_GEN_STATS "db_gen_stats.tcb" +#define DB_HOSTNAMES "db_hostnames.tcb" +#define DB_UNIQUE_KEYS "db_unique_keys.tcb" + +#define DB_KEYMAP "db_keymap.tcb" +#define DB_DATAMAP "db_datamap.tcb" +#define DB_ROOTMAP "db_rootmap.tcb" +#define DB_UNIQMAP "db_uniqmap.tcb" +#define DB_VISITORS "db_visitors.tcb" +#define DB_ROOT "db_root.tcb" +#define DB_HITS "db_hits.tcb" +#define DB_BW "db_bw.tcb" +#define DB_CUMTS "db_cumts.tcb" +#define DB_MAXTS "db_maxts.tcb" +#define DB_METHODS "db_methods.tcb" +#define DB_PROTOCOLS "db_protocols.tcb" +#define DB_AGENTS "db_agents.tcb" +#define DB_METADATA "db_metadata.tcb" + +/* *INDENT-OFF* */ +TCBDB *tc_bdb_create (char *dbpath); + +char *tc_db_set_path (const char *dbname, int module); +void tc_db_rmdir(void); +int tc_bdb_close (void *db, char *dbname); +void tc_db_get_params (char *params, const char *path); + +#ifdef TCB_BTREE +int ins_igsl (void *hash, int key, int value); +#endif +/* *INDENT-ON* */ + +#endif diff --git a/goaccess++/src/tpls.h b/goaccess++/src/tpls.h new file mode 100644 index 0000000..e6d723b --- /dev/null +++ b/goaccess++/src/tpls.h @@ -0,0 +1,941 @@ +const char tpls[10299] = { + 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x54, 0x50, 0x4c, 0x20, 0x47, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, + 0x74, 0x70, 0x6c, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, + 0x74, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, + 0x3e, 0x3c, 0x68, 0x34, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, 0x78, 0x73, 0x20, + 0x67, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x7b, 0x7b, + 0x68, 0x65, 0x61, 0x64, 0x7d, 0x7d, 0x3c, 0x73, 0x70, 0x61, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, 0x75, 0x6c, + 0x6c, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x7b, 0x7b, + 0x23, 0x66, 0x72, 0x6f, 0x6d, 0x7d, 0x7d, 0x3c, 0x73, 0x70, 0x61, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x72, + 0x6f, 0x6d, 0x22, 0x3e, 0x7b, 0x7b, 0x66, 0x72, 0x6f, 0x6d, 0x7d, + 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x7b, 0x7b, 0x2f, + 0x66, 0x72, 0x6f, 0x6d, 0x7d, 0x7d, 0x7b, 0x7b, 0x23, 0x74, 0x6f, + 0x7d, 0x7d, 0x20, 0x26, 0x23, 0x38, 0x32, 0x31, 0x32, 0x3b, 0x20, + 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x74, 0x6f, 0x22, 0x3e, 0x7b, 0x7b, 0x74, 0x6f, 0x7d, + 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x7b, 0x7b, 0x2f, + 0x74, 0x6f, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x3c, 0x2f, 0x68, 0x34, 0x3e, 0x3c, 0x68, 0x35, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, + 0x65, 0x2d, 0x78, 0x73, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, + 0x2d, 0x73, 0x6d, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, + 0x6d, 0x64, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, 0x6c, + 0x67, 0x20, 0x67, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, + 0x7b, 0x7b, 0x68, 0x65, 0x61, 0x64, 0x7d, 0x7d, 0x26, 0x6e, 0x62, + 0x73, 0x70, 0x3b, 0x26, 0x6e, 0x62, 0x73, 0x70, 0x3b, 0x7b, 0x7b, + 0x23, 0x66, 0x72, 0x6f, 0x6d, 0x7d, 0x7d, 0x3c, 0x73, 0x70, 0x61, + 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x72, + 0x6f, 0x6d, 0x22, 0x3e, 0x7b, 0x7b, 0x66, 0x72, 0x6f, 0x6d, 0x7d, + 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x7b, 0x7b, 0x2f, + 0x66, 0x72, 0x6f, 0x6d, 0x7d, 0x7d, 0x7b, 0x7b, 0x23, 0x74, 0x6f, + 0x7d, 0x7d, 0x20, 0x26, 0x23, 0x38, 0x32, 0x31, 0x32, 0x3b, 0x20, + 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x74, 0x6f, 0x22, 0x3e, 0x7b, 0x7b, 0x74, 0x6f, 0x7d, + 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x7b, 0x7b, 0x2f, + 0x74, 0x6f, 0x7d, 0x7d, 0x3c, 0x2f, 0x68, 0x35, 0x3e, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x77, + 0x72, 0x61, 0x70, 0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, + 0x2d, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x54, 0x50, 0x4c, 0x20, 0x47, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x70, 0x6c, 0x2d, 0x67, + 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x2d, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, + 0x78, 0x74, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x32, + 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x67, 0x72, 0x69, 0x64, 0x2d, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x20, 0x7b, 0x7b, 0x23, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x7d, 0x7b, 0x7b, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x7d, 0x7b, 0x7b, + 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x7d, + 0x7d, 0x7b, 0x7b, 0x5e, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, + 0x6d, 0x65, 0x7d, 0x7d, 0x67, 0x72, 0x61, 0x79, 0x7b, 0x7b, 0x2f, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x7d, + 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6c, 0x2d, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x62, 0x61, 0x72, + 0x2d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x69, + 0x3e, 0x20, 0x7b, 0x7b, 0x23, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7d, + 0x7d, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7d, 0x7d, 0x7b, + 0x7b, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7d, 0x7d, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x68, 0x33, 0x20, 0x69, 0x64, 0x3d, + 0x22, 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x30, 0x3b, 0x22, 0x3e, + 0x7b, 0x7b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x7d, 0x3c, 0x2f, + 0x68, 0x33, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x54, 0x50, 0x4c, 0x20, + 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x70, 0x6c, 0x2d, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x2d, 0x72, 0x6f, 0x77, 0x22, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x7b, 0x7b, 0x23, + 0x72, 0x6f, 0x77, 0x73, 0x7d, 0x7d, 0x3c, 0x74, 0x72, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x7b, 0x7b, 0x23, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x7d, 0x7b, 0x7b, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x7d, + 0x7b, 0x7b, 0x2f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, + 0x65, 0x7d, 0x7d, 0x20, 0x7b, 0x7b, 0x23, 0x68, 0x61, 0x73, 0x53, + 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x7b, 0x7b, + 0x23, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x65, 0x78, 0x70, + 0x61, 0x6e, 0x64, 0x61, 0x62, 0x6c, 0x65, 0x7b, 0x7b, 0x2f, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x7b, 0x7b, 0x2f, 0x68, 0x61, + 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, + 0x22, 0x20, 0x7b, 0x7b, 0x23, 0x69, 0x64, 0x78, 0x7d, 0x7d, 0x64, + 0x61, 0x74, 0x61, 0x2d, 0x70, 0x69, 0x64, 0x3d, 0x22, 0x7b, 0x7b, + 0x69, 0x64, 0x78, 0x7d, 0x7d, 0x22, 0x7b, 0x7b, 0x2f, 0x69, 0x64, + 0x78, 0x7d, 0x7d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x7d, 0x7d, 0x22, 0x20, 0x7b, 0x7b, 0x23, 0x6b, 0x65, 0x79, + 0x7d, 0x7d, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6b, 0x65, 0x79, 0x3d, + 0x22, 0x7b, 0x7b, 0x6b, 0x65, 0x79, 0x7d, 0x7d, 0x22, 0x7b, 0x7b, + 0x2f, 0x6b, 0x65, 0x79, 0x7d, 0x7d, 0x3e, 0x7b, 0x7b, 0x23, 0x68, + 0x61, 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x7d, + 0x7d, 0x3c, 0x74, 0x64, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x72, 0x6f, 0x77, 0x2d, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x63, + 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x7b, 0x7b, 0x23, 0x69, 0x74, + 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x61, + 0x62, 0x6c, 0x65, 0x7b, 0x7b, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x7d, 0x7d, 0x22, 0x3e, 0x7b, 0x7b, 0x23, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x7d, 0x7d, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x66, 0x61, 0x20, 0x7b, 0x7b, 0x23, 0x65, 0x78, 0x70, + 0x61, 0x6e, 0x64, 0x65, 0x64, 0x7d, 0x7d, 0x66, 0x61, 0x2d, 0x63, + 0x61, 0x72, 0x65, 0x74, 0x2d, 0x64, 0x6f, 0x77, 0x6e, 0x7b, 0x7b, + 0x2f, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x7d, 0x7d, + 0x7b, 0x7b, 0x5e, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, + 0x7d, 0x7d, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x61, 0x72, + 0x65, 0x74, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x7b, 0x7b, 0x2f, + 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x7d, 0x7d, 0x22, + 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x7b, 0x7b, 0x2f, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x7d, 0x7d, 0x7b, 0x7b, 0x5e, 0x69, 0x74, 0x65, 0x6d, + 0x73, 0x7d, 0x7d, 0x3c, 0x69, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x7b, + 0x7b, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x7b, 0x7b, 0x2f, 0x68, 0x61, 0x73, 0x53, 0x75, + 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x74, 0x64, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x72, 0x6f, 0x77, + 0x2d, 0x69, 0x64, 0x78, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x7b, 0x7b, 0x23, 0x69, 0x64, + 0x78, 0x7d, 0x7d, 0x7b, 0x7b, 0x69, 0x64, 0x78, 0x7d, 0x7d, 0x7b, + 0x7b, 0x2f, 0x69, 0x64, 0x78, 0x7d, 0x7d, 0x3c, 0x2f, 0x74, 0x64, + 0x3e, 0x7b, 0x7b, 0x23, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x7d, 0x7d, + 0x3c, 0x74, 0x64, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x7b, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, + 0x7d, 0x7d, 0x22, 0x20, 0x7b, 0x7b, 0x23, 0x63, 0x6f, 0x6c, 0x73, + 0x70, 0x61, 0x6e, 0x7d, 0x7d, 0x63, 0x6f, 0x6c, 0x73, 0x70, 0x61, + 0x6e, 0x3d, 0x22, 0x7b, 0x7b, 0x63, 0x6f, 0x6c, 0x73, 0x70, 0x61, + 0x6e, 0x7d, 0x7d, 0x22, 0x7b, 0x7b, 0x2f, 0x63, 0x6f, 0x6c, 0x73, + 0x70, 0x61, 0x6e, 0x7d, 0x7d, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x3e, 0x7b, 0x7b, 0x7b, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x7d, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x7b, 0x7b, 0x23, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x7d, + 0x7d, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x22, + 0x3e, 0x20, 0x28, 0x7b, 0x7b, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, + 0x74, 0x7d, 0x7d, 0x29, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x7b, 0x7b, 0x2f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x7d, + 0x7d, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x7b, 0x7b, 0x2f, 0x63, 0x65, + 0x6c, 0x6c, 0x73, 0x7d, 0x7d, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x7b, + 0x7b, 0x2f, 0x72, 0x6f, 0x77, 0x73, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, + 0x54, 0x50, 0x4c, 0x20, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x20, 0x2d, + 0x2d, 0x3e, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x69, + 0x64, 0x3d, 0x22, 0x74, 0x70, 0x6c, 0x2d, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x72, 0x6f, 0x77, 0x2d, 0x6d, 0x65, 0x74, 0x61, 0x22, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, + 0x7b, 0x7b, 0x23, 0x72, 0x6f, 0x77, 0x7d, 0x7d, 0x3c, 0x74, 0x72, + 0x3e, 0x7b, 0x7b, 0x23, 0x68, 0x61, 0x73, 0x53, 0x75, 0x62, 0x49, + 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x74, 0x64, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x2f, 0x74, + 0x64, 0x3e, 0x7b, 0x7b, 0x2f, 0x68, 0x61, 0x73, 0x53, 0x75, 0x62, + 0x49, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x74, 0x64, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x22, 0x3e, 0x3c, 0x2f, + 0x74, 0x64, 0x3e, 0x7b, 0x7b, 0x23, 0x63, 0x65, 0x6c, 0x6c, 0x73, + 0x7d, 0x7d, 0x3c, 0x74, 0x64, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x7b, 0x7b, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, + 0x6d, 0x65, 0x7d, 0x7d, 0x22, 0x20, 0x7b, 0x7b, 0x23, 0x63, 0x6f, + 0x6c, 0x73, 0x70, 0x61, 0x6e, 0x7d, 0x7d, 0x63, 0x6f, 0x6c, 0x73, + 0x70, 0x61, 0x6e, 0x3d, 0x22, 0x7b, 0x7b, 0x63, 0x6f, 0x6c, 0x73, + 0x70, 0x61, 0x6e, 0x7d, 0x7d, 0x22, 0x7b, 0x7b, 0x2f, 0x63, 0x6f, + 0x6c, 0x73, 0x70, 0x61, 0x6e, 0x7d, 0x7d, 0x3e, 0x7b, 0x7b, 0x23, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x7d, 0x3c, 0x68, 0x34, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x74, 0x69, + 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x7b, 0x7b, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x7d, 0x7d, 0x22, 0x3e, 0x7b, 0x7b, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x7b, + 0x7b, 0x23, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7d, 0x7d, 0x3c, 0x73, + 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x3e, 0x7b, 0x7b, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7d, 0x7d, + 0x7b, 0x7b, 0x23, 0x6d, 0x61, 0x78, 0x7d, 0x7d, 0x3c, 0x62, 0x72, + 0x3e, 0x3c, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x4d, 0x61, 0x78, + 0x3a, 0x20, 0x7b, 0x7b, 0x6d, 0x61, 0x78, 0x7d, 0x7d, 0x3c, 0x2f, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x7b, 0x7b, 0x2f, 0x6d, 0x61, + 0x78, 0x7d, 0x7d, 0x7b, 0x7b, 0x23, 0x6d, 0x69, 0x6e, 0x7d, 0x7d, + 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, + 0x4d, 0x69, 0x6e, 0x3a, 0x20, 0x7b, 0x7b, 0x6d, 0x69, 0x6e, 0x7d, + 0x7d, 0x3c, 0x2f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x7b, 0x7b, + 0x2f, 0x6d, 0x69, 0x6e, 0x7d, 0x7d, 0x3c, 0x2f, 0x68, 0x34, 0x3e, + 0x7b, 0x7b, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x7d, 0x3c, + 0x2f, 0x74, 0x64, 0x3e, 0x7b, 0x7b, 0x2f, 0x63, 0x65, 0x6c, 0x6c, + 0x73, 0x7d, 0x7d, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x7b, 0x7b, 0x2f, + 0x72, 0x6f, 0x77, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x54, 0x50, 0x4c, + 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, 0x61, + 0x64, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x70, 0x6c, 0x2d, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x74, 0x68, 0x65, 0x61, 0x64, 0x22, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, + 0x3c, 0x74, 0x72, 0x3e, 0x7b, 0x7b, 0x23, 0x68, 0x61, 0x73, 0x53, + 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x74, + 0x68, 0x3e, 0x3c, 0x2f, 0x74, 0x68, 0x3e, 0x7b, 0x7b, 0x2f, 0x68, + 0x61, 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x7d, + 0x7d, 0x3c, 0x74, 0x68, 0x3e, 0x23, 0x3c, 0x2f, 0x74, 0x68, 0x3e, + 0x7b, 0x7b, 0x23, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x3c, + 0x74, 0x68, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x7b, + 0x7b, 0x64, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x7d, 0x7d, + 0x20, 0x7b, 0x7b, 0x23, 0x6b, 0x65, 0x79, 0x7d, 0x7d, 0x73, 0x6f, + 0x72, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x7b, 0x7b, 0x2f, 0x6b, 0x65, + 0x79, 0x7d, 0x7d, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6b, + 0x65, 0x79, 0x3d, 0x22, 0x7b, 0x7b, 0x6b, 0x65, 0x79, 0x7d, 0x7d, + 0x22, 0x20, 0x7b, 0x7b, 0x23, 0x73, 0x6f, 0x72, 0x74, 0x7d, 0x7d, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x3d, + 0x22, 0x7b, 0x7b, 0x23, 0x61, 0x73, 0x63, 0x7d, 0x7d, 0x61, 0x73, + 0x63, 0x7b, 0x7b, 0x2f, 0x61, 0x73, 0x63, 0x7d, 0x7d, 0x7b, 0x7b, + 0x5e, 0x61, 0x73, 0x63, 0x7d, 0x7d, 0x64, 0x65, 0x73, 0x63, 0x7b, + 0x7b, 0x2f, 0x61, 0x73, 0x63, 0x7d, 0x7d, 0x22, 0x7b, 0x7b, 0x2f, + 0x73, 0x6f, 0x72, 0x74, 0x7d, 0x7d, 0x3e, 0x7b, 0x7b, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x7d, 0x7d, 0x20, 0x3c, 0x69, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, + 0x7b, 0x7b, 0x5e, 0x73, 0x6f, 0x72, 0x74, 0x7d, 0x7d, 0x73, 0x6f, + 0x72, 0x74, 0x7b, 0x7b, 0x2f, 0x73, 0x6f, 0x72, 0x74, 0x7d, 0x7d, + 0x7b, 0x7b, 0x23, 0x73, 0x6f, 0x72, 0x74, 0x7d, 0x7d, 0x7b, 0x7b, + 0x23, 0x61, 0x73, 0x63, 0x7d, 0x7d, 0x63, 0x61, 0x72, 0x65, 0x74, + 0x2d, 0x75, 0x70, 0x7b, 0x7b, 0x2f, 0x61, 0x73, 0x63, 0x7d, 0x7d, + 0x7b, 0x7b, 0x5e, 0x61, 0x73, 0x63, 0x7d, 0x7d, 0x63, 0x61, 0x72, + 0x65, 0x74, 0x2d, 0x64, 0x6f, 0x77, 0x6e, 0x7b, 0x7b, 0x2f, 0x61, + 0x73, 0x63, 0x7d, 0x7d, 0x7b, 0x7b, 0x2f, 0x73, 0x6f, 0x72, 0x74, + 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x3c, 0x2f, 0x74, + 0x68, 0x3e, 0x7b, 0x7b, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x7d, + 0x7d, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x54, 0x50, + 0x4c, 0x20, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x44, 0x72, 0x6f, 0x70, 0x44, 0x6f, + 0x77, 0x6e, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x70, 0x6c, 0x2d, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x6f, 0x70, 0x74, 0x73, 0x22, + 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, + 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, + 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x7b, 0x7b, 0x20, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x5f, + 0x6f, 0x70, 0x74, 0x73, 0x20, 0x7d, 0x7d, 0x3c, 0x2f, 0x6c, 0x69, + 0x3e, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, + 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x3d, 0x22, 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x3d, + 0x22, 0x7b, 0x7b, 0x73, 0x68, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x72, + 0x74, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x7b, + 0x7b, 0x23, 0x73, 0x68, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x72, 0x74, + 0x7d, 0x7d, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x2d, 0x7b, 0x7b, 0x2f, + 0x73, 0x68, 0x6f, 0x77, 0x43, 0x68, 0x61, 0x72, 0x74, 0x7d, 0x7d, + 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x2d, 0x6f, 0x22, 0x3e, 0x3c, + 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x2e, 0x63, 0x68, 0x61, 0x72, 0x74, 0x7d, 0x7d, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x7b, 0x7b, 0x23, 0x70, + 0x6c, 0x6f, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7d, + 0x7d, 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x7b, 0x7b, 0x20, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x20, + 0x7d, 0x7d, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, + 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, + 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, + 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, + 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x3d, + 0x22, 0x61, 0x72, 0x65, 0x61, 0x2d, 0x73, 0x70, 0x6c, 0x69, 0x6e, + 0x65, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, + 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x61, 0x72, 0x65, 0x61, 0x2d, + 0x73, 0x70, 0x6c, 0x69, 0x6e, 0x65, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, + 0x7b, 0x2f, 0x61, 0x72, 0x65, 0x61, 0x2d, 0x73, 0x70, 0x6c, 0x69, + 0x6e, 0x65, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, + 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x61, 0x72, + 0x65, 0x61, 0x5f, 0x73, 0x70, 0x6c, 0x69, 0x6e, 0x65, 0x7d, 0x7d, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, + 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, + 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x3d, 0x22, + 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x62, 0x61, 0x72, 0x22, 0x3e, 0x3c, 0x69, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, + 0x61, 0x2d, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, + 0x62, 0x61, 0x72, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, 0x2f, 0x62, + 0x61, 0x72, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, + 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x62, 0x61, + 0x72, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, + 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x7b, 0x7b, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x70, 0x6c, 0x6f, 0x74, 0x5f, 0x6d, + 0x65, 0x74, 0x72, 0x69, 0x63, 0x7d, 0x7d, 0x3c, 0x2f, 0x6c, 0x69, + 0x3e, 0x7b, 0x7b, 0x23, 0x70, 0x6c, 0x6f, 0x74, 0x7d, 0x7d, 0x3c, + 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x3d, + 0x22, 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x2d, 0x70, 0x6c, 0x6f, 0x74, 0x3d, 0x22, 0x7b, 0x7b, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x7d, + 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x2d, 0x70, 0x6c, 0x6f, 0x74, 0x2d, 0x7b, 0x7b, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x7d, 0x7d, + 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, 0x63, + 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, 0x2f, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, + 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, + 0x7b, 0x7b, 0x2f, 0x70, 0x6c, 0x6f, 0x74, 0x7d, 0x7d, 0x7b, 0x7b, + 0x2f, 0x70, 0x6c, 0x6f, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x7d, 0x7d, 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, + 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x7b, 0x7b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x7d, 0x7d, + 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x7b, 0x7b, 0x23, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, + 0x30, 0x29, 0x3b, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, 0x69, 0x64, 0x7d, + 0x7d, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x6d, 0x65, 0x74, + 0x72, 0x69, 0x63, 0x3d, 0x22, 0x7b, 0x7b, 0x6b, 0x65, 0x79, 0x7d, + 0x7d, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x7b, 0x7b, 0x5e, + 0x68, 0x69, 0x64, 0x65, 0x7d, 0x7d, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x2d, 0x7b, 0x7b, 0x2f, 0x68, 0x69, 0x64, 0x65, 0x7d, 0x7d, 0x73, + 0x71, 0x75, 0x61, 0x72, 0x65, 0x2d, 0x6f, 0x22, 0x3e, 0x3c, 0x2f, + 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x7d, + 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x7b, + 0x7b, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x2f, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, + 0x20, 0x54, 0x50, 0x4c, 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x20, + 0x63, 0x6f, 0x6c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x20, 0x2d, 0x2d, + 0x3e, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x69, 0x64, + 0x3d, 0x22, 0x74, 0x70, 0x6c, 0x2d, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x2d, 0x63, 0x6f, 0x6c, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x7b, + 0x7b, 0x23, 0x68, 0x61, 0x73, 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, + 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x63, 0x6f, 0x6c, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x20, 0x32, 0x25, 0x3b, 0x22, 0x3e, 0x20, 0x3c, 0x21, 0x2d, 0x2d, + 0x20, 0x72, 0x69, 0x67, 0x68, 0x74, 0x2d, 0x63, 0x61, 0x72, 0x65, + 0x74, 0x20, 0x2d, 0x2d, 0x3e, 0x7b, 0x7b, 0x2f, 0x68, 0x61, 0x73, + 0x53, 0x75, 0x62, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x7d, 0x7d, 0x3c, + 0x63, 0x6f, 0x6c, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x33, 0x25, 0x3b, 0x22, + 0x3e, 0x20, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x72, 0x6f, 0x77, 0x20, + 0x23, 0x20, 0x2d, 0x2d, 0x3e, 0x7b, 0x7b, 0x23, 0x69, 0x74, 0x65, + 0x6d, 0x73, 0x7d, 0x7d, 0x3c, 0x63, 0x6f, 0x6c, 0x20, 0x73, 0x74, + 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x7b, 0x7b, 0x63, 0x6f, 0x6c, 0x57, 0x69, 0x64, 0x74, 0x68, 0x7d, + 0x7d, 0x22, 0x3e, 0x7b, 0x7b, 0x2f, 0x69, 0x74, 0x65, 0x6d, 0x73, + 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, + 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x54, 0x50, 0x4c, 0x20, 0x50, 0x61, + 0x6e, 0x65, 0x6c, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x70, 0x6c, + 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x22, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x72, 0x6f, 0x77, + 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x31, + 0x32, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x66, 0x6f, 0x72, 0x6d, 0x2d, 0x67, 0x72, + 0x6f, 0x75, 0x70, 0x20, 0x63, 0x6c, 0x65, 0x61, 0x72, 0x66, 0x69, + 0x78, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x68, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x68, 0x34, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, 0x75, 0x6c, 0x6c, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x2d, + 0x78, 0x73, 0x20, 0x67, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, + 0x20, 0x69, 0x64, 0x3d, 0x22, 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, + 0x22, 0x3e, 0x7b, 0x7b, 0x68, 0x65, 0x61, 0x64, 0x7d, 0x7d, 0x3c, + 0x62, 0x72, 0x3e, 0x3c, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x7b, + 0x7b, 0x64, 0x65, 0x73, 0x63, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x6d, + 0x61, 0x6c, 0x6c, 0x3e, 0x3c, 0x2f, 0x68, 0x34, 0x3e, 0x3c, 0x68, + 0x35, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, 0x75, + 0x6c, 0x6c, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x20, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x6c, 0x65, 0x2d, 0x78, 0x73, 0x20, 0x68, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x2d, 0x73, 0x6d, 0x20, 0x68, 0x69, 0x64, 0x64, + 0x65, 0x6e, 0x2d, 0x6d, 0x64, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, + 0x6e, 0x2d, 0x6c, 0x67, 0x20, 0x67, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x7b, 0x7b, 0x69, 0x64, + 0x7d, 0x7d, 0x22, 0x3e, 0x7b, 0x7b, 0x68, 0x65, 0x61, 0x64, 0x7d, + 0x7d, 0x3c, 0x62, 0x72, 0x3e, 0x3c, 0x73, 0x6d, 0x61, 0x6c, 0x6c, + 0x3e, 0x7b, 0x7b, 0x64, 0x65, 0x73, 0x63, 0x7d, 0x7d, 0x3c, 0x2f, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x3e, 0x3c, 0x2f, 0x68, 0x35, 0x3e, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x70, 0x6c, 0x6f, 0x74, + 0x2d, 0x77, 0x72, 0x61, 0x70, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x64, 0x72, 0x6f, + 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x22, 0x3e, 0x3c, 0x62, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x62, 0x74, 0x6e, 0x20, 0x62, 0x74, 0x6e, 0x2d, 0x64, 0x65, 0x66, + 0x61, 0x75, 0x6c, 0x74, 0x20, 0x62, 0x74, 0x6e, 0x2d, 0x73, 0x6d, + 0x20, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x74, + 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 0x64, + 0x61, 0x74, 0x61, 0x2d, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x3d, + 0x22, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x22, 0x20, + 0x61, 0x72, 0x69, 0x61, 0x2d, 0x68, 0x61, 0x73, 0x70, 0x6f, 0x70, + 0x75, 0x70, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x20, 0x61, + 0x72, 0x69, 0x61, 0x2d, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, + 0x64, 0x3d, 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x20, 0x64, 0x61, + 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x3d, 0x22, 0x7b, + 0x7b, 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, + 0x2d, 0x67, 0x65, 0x61, 0x72, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, + 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x73, 0x7d, 0x7d, + 0x20, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x61, + 0x72, 0x65, 0x74, 0x2d, 0x64, 0x6f, 0x77, 0x6e, 0x22, 0x3e, 0x3c, + 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x3c, 0x2f, 0x62, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x3e, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, + 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x20, 0x64, 0x72, 0x6f, 0x70, + 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x6d, 0x65, 0x6e, 0x75, 0x2d, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x20, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, + 0x6f, 0x70, 0x74, 0x73, 0x2d, 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, + 0x22, 0x3e, 0x3c, 0x2f, 0x75, 0x6c, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x7b, 0x7b, 0x23, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x7d, 0x7d, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x72, 0x6f, 0x77, 0x22, 0x3e, 0x3c, 0x64, + 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, + 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x31, 0x32, 0x22, 0x3e, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x63, 0x68, 0x61, + 0x72, 0x74, 0x2d, 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x22, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x7b, 0x7b, 0x2f, 0x63, 0x68, 0x61, 0x72, + 0x74, 0x7d, 0x7d, 0x7b, 0x7b, 0x23, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x7d, 0x7d, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x72, 0x6f, 0x77, 0x20, 0x63, 0x6c, 0x65, 0x61, + 0x72, 0x66, 0x69, 0x78, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, + 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x20, 0x7b, 0x7b, 0x23, + 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x73, 0x7d, 0x7d, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, + 0x2d, 0x78, 0x73, 0x7b, 0x7b, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x48, + 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x7d, 0x7d, + 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x63, 0x6f, 0x6c, 0x2d, 0x6d, 0x64, 0x2d, 0x31, + 0x32, 0x22, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x22, 0x3e, + 0x3c, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, 0x69, + 0x64, 0x7d, 0x7d, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x2d, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, + 0x73, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x68, 0x6f, 0x76, + 0x65, 0x72, 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x2d, 0x7b, 0x7b, + 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x63, 0x6f, 0x6c, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x3e, 0x3c, 0x2f, 0x63, 0x6f, 0x6c, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x3e, 0x3c, 0x74, 0x68, 0x65, 0x61, 0x64, + 0x3e, 0x3c, 0x2f, 0x74, 0x68, 0x65, 0x61, 0x64, 0x3e, 0x3c, 0x74, + 0x62, 0x6f, 0x64, 0x79, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x6d, 0x65, 0x74, 0x61, + 0x22, 0x3e, 0x3c, 0x2f, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, + 0x74, 0x62, 0x6f, 0x64, 0x79, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x2d, 0x64, 0x61, 0x74, + 0x61, 0x22, 0x3e, 0x3c, 0x2f, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0x3c, 0x2f, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x3e, 0x3c, 0x2f, 0x64, + 0x69, 0x76, 0x3e, 0x3c, 0x75, 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x2d, 0x73, 0x6d, 0x20, 0x70, 0x75, 0x6c, 0x6c, 0x2d, + 0x6c, 0x65, 0x66, 0x74, 0x22, 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x22, 0x3e, 0x3c, 0x61, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, + 0x61, 0x72, 0x69, 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3d, + 0x22, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x7d, 0x7d, 0x22, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, + 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x3d, 0x22, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, + 0x66, 0x69, 0x72, 0x73, 0x74, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x69, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, + 0x66, 0x61, 0x2d, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2d, 0x64, 0x6f, + 0x75, 0x62, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x22, 0x3e, + 0x3c, 0x2f, 0x69, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, + 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, + 0x3e, 0x3c, 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x70, 0x72, 0x65, 0x76, 0x22, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, + 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x61, 0x72, 0x69, 0x61, 0x2d, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, + 0x75, 0x73, 0x7d, 0x7d, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, 0x69, 0x64, + 0x7d, 0x7d, 0x22, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, + 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x70, 0x72, + 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, + 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, + 0x20, 0x66, 0x61, 0x2d, 0x61, 0x6e, 0x67, 0x6c, 0x65, 0x2d, 0x6c, + 0x65, 0x66, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x3c, 0x2f, + 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x3e, + 0x3c, 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, + 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x6e, 0x65, 0x78, 0x74, 0x22, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, + 0x30, 0x29, 0x3b, 0x22, 0x20, 0x61, 0x72, 0x69, 0x61, 0x2d, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x7d, 0x7d, 0x22, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, 0x6e, 0x65, 0x6c, + 0x3d, 0x22, 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, 0x22, 0x20, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x7b, 0x7b, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x2e, 0x6e, 0x65, 0x78, 0x74, 0x7d, 0x7d, 0x22, + 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x61, 0x6e, 0x67, 0x6c, 0x65, + 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x69, + 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, + 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x2d, 0x6c, 0x61, 0x73, + 0x74, 0x22, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, + 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, + 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x61, 0x72, 0x69, + 0x61, 0x2d, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x6c, 0x61, 0x73, 0x74, + 0x7d, 0x7d, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x61, + 0x6e, 0x65, 0x6c, 0x3d, 0x22, 0x7b, 0x7b, 0x69, 0x64, 0x7d, 0x7d, + 0x22, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x7b, 0x7b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x6c, 0x61, 0x73, 0x74, + 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x61, 0x6e, + 0x67, 0x6c, 0x65, 0x2d, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x2d, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, + 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x2f, + 0x75, 0x6c, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x64, 0x69, 0x76, 0x3e, 0x7b, 0x7b, 0x2f, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x54, 0x50, 0x4c, 0x20, 0x4e, + 0x61, 0x76, 0x20, 0x42, 0x61, 0x72, 0x20, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x72, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x70, 0x6c, + 0x2d, 0x6e, 0x61, 0x76, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x22, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x3c, + 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x6e, 0x61, 0x76, 0x2d, 0x62, 0x61, 0x72, 0x73, 0x20, 0x66, 0x61, + 0x20, 0x66, 0x61, 0x2d, 0x62, 0x61, 0x72, 0x73, 0x22, 0x3e, 0x3c, + 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6e, 0x61, 0x76, 0x2d, 0x67, + 0x65, 0x61, 0x72, 0x73, 0x20, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, + 0x63, 0x6f, 0x67, 0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, + 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x6e, 0x61, 0x76, 0x2d, 0x77, 0x73, 0x2d, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x20, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, + 0x69, 0x72, 0x63, 0x6c, 0x65, 0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, + 0x76, 0x3e, 0x3c, 0x64, 0x69, 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x6e, 0x61, 0x76, 0x2d, 0x6c, 0x69, 0x73, 0x74, + 0x22, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x64, 0x69, + 0x76, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, 0x6f, + 0x77, 0x65, 0x72, 0x65, 0x64, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, + 0x6e, 0x2d, 0x78, 0x73, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, + 0x2d, 0x73, 0x6d, 0x22, 0x3e, 0x62, 0x79, 0x20, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x73, + 0x3a, 0x2f, 0x2f, 0x67, 0x6f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2e, 0x69, 0x6f, 0x2f, 0x22, 0x3e, 0x47, 0x6f, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x3c, 0x2f, 0x61, 0x3e, 0x20, 0x3c, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x76, 0x7b, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x7d, 0x7d, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, + 0x20, 0x61, 0x6e, 0x64, 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x67, + 0x77, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x69, 0x6f, 0x2f, + 0x22, 0x3e, 0x47, 0x57, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x3c, 0x2f, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, + 0x20, 0x54, 0x50, 0x4c, 0x20, 0x4e, 0x61, 0x76, 0x20, 0x42, 0x61, + 0x72, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x20, 0x2d, 0x2d, 0x3e, + 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x69, 0x64, 0x3d, + 0x22, 0x74, 0x70, 0x6c, 0x2d, 0x6e, 0x61, 0x76, 0x2d, 0x6d, 0x65, + 0x6e, 0x75, 0x22, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, + 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x22, 0x3e, 0x3c, 0x68, 0x33, 0x3e, 0x7b, 0x7b, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x73, + 0x7d, 0x7d, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x3c, 0x75, 0x6c, 0x3e, + 0x3c, 0x6c, 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x6f, 0x76, 0x65, 0x72, + 0x61, 0x6c, 0x6c, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, + 0x6f, 0x76, 0x65, 0x72, 0x61, 0x6c, 0x6c, 0x7d, 0x7d, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x23, 0x22, 0x3e, + 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, + 0x61, 0x20, 0x66, 0x61, 0x2d, 0x62, 0x61, 0x72, 0x2d, 0x63, 0x68, + 0x61, 0x72, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, + 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x74, 0x68, 0x65, + 0x61, 0x64, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, + 0x69, 0x3e, 0x7b, 0x7b, 0x23, 0x6e, 0x61, 0x76, 0x7d, 0x7d, 0x3c, + 0x6c, 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x63, 0x75, 0x72, 0x72, 0x65, + 0x6e, 0x74, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x63, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x7d, 0x7d, 0x3e, 0x3c, 0x61, + 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x23, 0x7b, 0x7b, 0x6b, + 0x65, 0x79, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, + 0x7b, 0x7b, 0x69, 0x63, 0x6f, 0x6e, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, + 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x68, 0x65, 0x61, 0x64, 0x7d, + 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x7b, + 0x7b, 0x2f, 0x6e, 0x61, 0x76, 0x7d, 0x7d, 0x3c, 0x2f, 0x75, 0x6c, + 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, + 0x21, 0x2d, 0x2d, 0x20, 0x54, 0x50, 0x4c, 0x20, 0x4e, 0x61, 0x76, + 0x20, 0x42, 0x61, 0x72, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x74, 0x70, 0x6c, 0x2d, 0x6e, + 0x61, 0x76, 0x2d, 0x6f, 0x70, 0x74, 0x73, 0x22, 0x20, 0x74, 0x79, + 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x3c, 0x68, 0x33, + 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x68, 0x61, 0x73, 0x68, 0x74, + 0x61, 0x67, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x74, 0x68, 0x65, 0x6d, + 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x3c, 0x75, 0x6c, + 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x64, 0x61, 0x72, + 0x6b, 0x47, 0x72, 0x61, 0x79, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, + 0x7b, 0x2f, 0x64, 0x61, 0x72, 0x6b, 0x47, 0x72, 0x61, 0x79, 0x7d, + 0x7d, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, + 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, 0x68, 0x65, 0x6d, 0x65, + 0x2d, 0x64, 0x61, 0x72, 0x6b, 0x2d, 0x67, 0x72, 0x61, 0x79, 0x22, + 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, 0x63, 0x6c, + 0x65, 0x7b, 0x7b, 0x5e, 0x64, 0x61, 0x72, 0x6b, 0x47, 0x72, 0x61, + 0x79, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, 0x2f, 0x64, 0x61, 0x72, + 0x6b, 0x47, 0x72, 0x61, 0x79, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x2f, + 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, + 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x5f, 0x67, 0x72, 0x61, 0x79, 0x7d, + 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, + 0x6c, 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x62, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x62, 0x72, + 0x69, 0x67, 0x68, 0x74, 0x7d, 0x7d, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, + 0x29, 0x3b, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x74, 0x68, 0x65, 0x6d, 0x65, 0x2d, 0x62, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, + 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x62, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, 0x2f, 0x62, 0x72, 0x69, + 0x67, 0x68, 0x74, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, + 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x62, + 0x72, 0x69, 0x67, 0x68, 0x74, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, + 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x7b, 0x7b, + 0x23, 0x64, 0x61, 0x72, 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x7d, 0x7d, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x64, 0x61, 0x72, 0x6b, 0x42, + 0x6c, 0x75, 0x65, 0x7d, 0x7d, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, + 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, + 0x3b, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x74, + 0x68, 0x65, 0x6d, 0x65, 0x2d, 0x64, 0x61, 0x72, 0x6b, 0x2d, 0x62, + 0x6c, 0x75, 0x65, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, + 0x69, 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x64, 0x61, 0x72, + 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, + 0x2f, 0x64, 0x61, 0x72, 0x6b, 0x42, 0x6c, 0x75, 0x65, 0x7d, 0x7d, + 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x5f, 0x62, + 0x6c, 0x75, 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x64, + 0x61, 0x72, 0x6b, 0x50, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x7d, 0x7d, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x64, 0x61, 0x72, 0x6b, 0x50, + 0x75, 0x72, 0x70, 0x6c, 0x65, 0x7d, 0x7d, 0x3e, 0x3c, 0x61, 0x20, + 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, + 0x30, 0x29, 0x3b, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x74, 0x68, 0x65, 0x6d, 0x65, 0x2d, 0x64, 0x61, 0x72, 0x6b, + 0x2d, 0x70, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x22, 0x3e, 0x3c, 0x69, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, + 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x7b, + 0x5e, 0x64, 0x61, 0x72, 0x6b, 0x50, 0x75, 0x72, 0x70, 0x6c, 0x65, + 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, 0x2f, 0x64, 0x61, 0x72, 0x6b, + 0x50, 0x75, 0x72, 0x70, 0x6c, 0x65, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, + 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x2e, 0x64, 0x61, 0x72, 0x6b, 0x5f, 0x70, 0x75, 0x72, 0x70, + 0x6c, 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, + 0x69, 0x3e, 0x3c, 0x2f, 0x75, 0x6c, 0x3e, 0x3c, 0x68, 0x33, 0x3e, + 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, + 0x61, 0x20, 0x66, 0x61, 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x2d, 0x61, + 0x6c, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x70, 0x61, 0x6e, 0x65, + 0x6c, 0x73, 0x7d, 0x7d, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x3c, 0x75, + 0x6c, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x70, 0x65, + 0x72, 0x70, 0x61, 0x67, 0x65, 0x2d, 0x77, 0x72, 0x61, 0x70, 0x22, + 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x64, 0x72, 0x6f, 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, + 0x2d, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, + 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x69, + 0x74, 0x65, 0x6d, 0x73, 0x5f, 0x70, 0x65, 0x72, 0x5f, 0x70, 0x61, + 0x67, 0x65, 0x7d, 0x7d, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, + 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, + 0x65, 0x35, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x70, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x35, 0x7d, 0x7d, 0x3e, 0x3c, + 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, + 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, + 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x70, 0x65, 0x72, 0x70, 0x61, 0x67, 0x65, 0x3d, 0x22, 0x35, + 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, 0x63, + 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, + 0x65, 0x35, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, 0x2f, 0x70, 0x65, + 0x72, 0x50, 0x61, 0x67, 0x65, 0x35, 0x7d, 0x7d, 0x22, 0x3e, 0x3c, + 0x2f, 0x69, 0x3e, 0x20, 0x35, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x70, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x37, 0x7d, 0x7d, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, + 0x22, 0x7b, 0x7b, 0x2f, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, + 0x37, 0x7d, 0x7d, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, + 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x70, 0x65, 0x72, 0x70, 0x61, + 0x67, 0x65, 0x3d, 0x22, 0x37, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, + 0x2d, 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x70, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x37, 0x7d, 0x7d, 0x2d, 0x6f, + 0x7b, 0x7b, 0x2f, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x37, + 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x37, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, + 0x20, 0x7b, 0x7b, 0x23, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, + 0x31, 0x30, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x70, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x31, 0x30, 0x7d, 0x7d, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, + 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, + 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x70, 0x65, 0x72, 0x70, 0x61, 0x67, 0x65, 0x3d, 0x22, + 0x31, 0x30, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, + 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x70, 0x65, 0x72, 0x50, + 0x61, 0x67, 0x65, 0x31, 0x30, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, + 0x2f, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x31, 0x30, 0x7d, + 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x31, 0x30, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, + 0x20, 0x7b, 0x7b, 0x23, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, + 0x31, 0x35, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x70, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x31, 0x35, 0x7d, 0x7d, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, + 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, + 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x70, 0x65, 0x72, 0x70, 0x61, 0x67, 0x65, 0x3d, 0x22, + 0x31, 0x35, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, + 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x70, 0x65, 0x72, 0x50, + 0x61, 0x67, 0x65, 0x31, 0x35, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, + 0x2f, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x31, 0x35, 0x7d, + 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x31, 0x35, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, + 0x20, 0x7b, 0x7b, 0x23, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, + 0x32, 0x30, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x70, + 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x32, 0x30, 0x7d, 0x7d, 0x3e, + 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, + 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, + 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x64, 0x61, 0x74, + 0x61, 0x2d, 0x70, 0x65, 0x72, 0x70, 0x61, 0x67, 0x65, 0x3d, 0x22, + 0x32, 0x30, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, + 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x70, 0x65, 0x72, 0x50, + 0x61, 0x67, 0x65, 0x32, 0x30, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, + 0x2f, 0x70, 0x65, 0x72, 0x50, 0x61, 0x67, 0x65, 0x32, 0x30, 0x7d, + 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x32, 0x30, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, + 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x64, 0x72, 0x6f, + 0x70, 0x64, 0x6f, 0x77, 0x6e, 0x2d, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x73, 0x7d, 0x7d, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, + 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, + 0x2f, 0x73, 0x68, 0x6f, 0x77, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x7d, 0x7d, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x73, 0x68, 0x6f, 0x77, 0x2d, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3d, 0x22, 0x31, 0x22, 0x3e, 0x3c, + 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, + 0x20, 0x66, 0x61, 0x2d, 0x7b, 0x7b, 0x23, 0x73, 0x68, 0x6f, 0x77, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x7d, 0x7d, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x2d, 0x7b, 0x7b, 0x2f, 0x73, 0x68, 0x6f, 0x77, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x7d, 0x7d, 0x73, 0x71, 0x75, 0x61, + 0x72, 0x65, 0x2d, 0x6f, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, + 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x64, 0x69, + 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x74, 0x61, 0x62, 0x6c, 0x65, + 0x73, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, + 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x7b, 0x7b, 0x23, 0x61, 0x75, 0x74, + 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x61, 0x75, 0x74, + 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, + 0x7d, 0x7d, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, + 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, + 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, + 0x64, 0x61, 0x74, 0x61, 0x2d, 0x61, 0x75, 0x74, 0x6f, 0x68, 0x69, + 0x64, 0x65, 0x2d, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x3d, 0x22, + 0x31, 0x22, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3d, 0x22, 0x7b, + 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x61, 0x68, 0x5f, + 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x5f, 0x74, 0x69, 0x74, 0x6c, 0x65, + 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, + 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x7b, 0x7b, + 0x23, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x73, 0x7d, 0x7d, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x2d, 0x7b, 0x7b, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x48, 0x69, 0x64, + 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x7d, 0x7d, 0x73, 0x71, + 0x75, 0x61, 0x72, 0x65, 0x2d, 0x6f, 0x22, 0x3e, 0x3c, 0x2f, 0x69, + 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, + 0x61, 0x68, 0x5f, 0x73, 0x6d, 0x61, 0x6c, 0x6c, 0x7d, 0x7d, 0x3c, + 0x2f, 0x61, 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x2f, 0x75, + 0x6c, 0x3e, 0x3c, 0x68, 0x33, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, + 0x74, 0x68, 0x2d, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x22, 0x3e, 0x3c, + 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, 0x6c, + 0x73, 0x2e, 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x7d, 0x7d, 0x3c, + 0x2f, 0x68, 0x33, 0x3e, 0x3c, 0x75, 0x6c, 0x3e, 0x3c, 0x6c, 0x69, + 0x20, 0x7b, 0x7b, 0x23, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, + 0x74, 0x61, 0x6c, 0x7d, 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, + 0x22, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, + 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x7d, + 0x7d, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, + 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3a, + 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x22, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6c, 0x61, 0x79, 0x6f, 0x75, + 0x74, 0x2d, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, + 0x6c, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x69, 0x72, + 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, 0x7b, + 0x2f, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, + 0x7d, 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, + 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x68, 0x6f, 0x72, 0x69, + 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, + 0x3e, 0x3c, 0x2f, 0x6c, 0x69, 0x3e, 0x3c, 0x6c, 0x69, 0x20, 0x7b, + 0x7b, 0x23, 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x7d, + 0x7d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x65, 0x22, 0x7b, 0x7b, 0x2f, 0x76, 0x65, 0x72, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x7d, 0x7d, 0x3e, 0x3c, 0x61, 0x20, 0x68, + 0x72, 0x65, 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, + 0x72, 0x69, 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, + 0x29, 0x3b, 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x6c, 0x61, 0x79, 0x6f, 0x75, 0x74, 0x2d, 0x76, 0x65, 0x72, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x22, 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, + 0x63, 0x69, 0x72, 0x63, 0x6c, 0x65, 0x7b, 0x7b, 0x5e, 0x76, 0x65, + 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x7d, 0x7d, 0x2d, 0x6f, 0x7b, + 0x7b, 0x2f, 0x76, 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x7d, + 0x7d, 0x22, 0x3e, 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x73, 0x2e, 0x76, 0x65, 0x72, 0x74, 0x69, + 0x63, 0x61, 0x6c, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x6c, 0x69, 0x3e, 0x3c, 0x2f, 0x75, 0x6c, 0x3e, 0x3c, 0x68, 0x33, + 0x3e, 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, + 0x66, 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x6f, 0x67, 0x22, 0x3e, + 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x6f, 0x70, 0x74, + 0x73, 0x7d, 0x7d, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x3c, 0x75, 0x6c, + 0x3e, 0x3c, 0x6c, 0x69, 0x3e, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, + 0x66, 0x3d, 0x22, 0x6a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3a, 0x76, 0x6f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, + 0x22, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x65, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x2d, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x3e, + 0x3c, 0x69, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x66, + 0x61, 0x20, 0x66, 0x61, 0x2d, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x3e, + 0x3c, 0x2f, 0x69, 0x3e, 0x20, 0x7b, 0x7b, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x2e, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6a, + 0x73, 0x6f, 0x6e, 0x7d, 0x7d, 0x3c, 0x2f, 0x61, 0x3e, 0x3c, 0x2f, + 0x6c, 0x69, 0x3e, 0x3c, 0x2f, 0x75, 0x6c, 0x3e, 0x3c, 0x2f, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, + 0x54, 0x50, 0x4c, 0x20, 0x43, 0x68, 0x61, 0x72, 0x74, 0x20, 0x74, + 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x20, 0x2d, 0x2d, 0x3e, 0x3c, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, + 0x74, 0x70, 0x6c, 0x2d, 0x63, 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, + 0x6f, 0x6f, 0x6c, 0x74, 0x69, 0x70, 0x22, 0x20, 0x74, 0x79, 0x70, + 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x2f, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x3c, 0x74, 0x61, 0x62, + 0x6c, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x63, + 0x68, 0x61, 0x72, 0x74, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x74, 0x69, + 0x70, 0x22, 0x3e, 0x3c, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, + 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x68, 0x20, 0x63, 0x6f, 0x6c, 0x73, + 0x70, 0x61, 0x6e, 0x3d, 0x22, 0x32, 0x22, 0x3e, 0x7b, 0x7b, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x30, 0x7d, 0x7d, 0x3c, 0x2f, 0x74, 0x68, + 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x72, 0x3e, 0x3c, + 0x74, 0x64, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6e, + 0x61, 0x6d, 0x65, 0x22, 0x3e, 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x62, 0x6c, 0x75, 0x65, + 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x70, 0x61, 0x6e, 0x3e, 0x68, 0x69, + 0x74, 0x73, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x20, + 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3e, 0x7b, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x31, + 0x7d, 0x7d, 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, + 0x3e, 0x7b, 0x7b, 0x23, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x32, 0x7d, + 0x7d, 0x3c, 0x74, 0x72, 0x3e, 0x3c, 0x74, 0x64, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3e, + 0x3c, 0x73, 0x70, 0x61, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, + 0x3d, 0x22, 0x72, 0x65, 0x64, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x70, + 0x61, 0x6e, 0x3e, 0x76, 0x69, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x73, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x74, 0x64, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x3e, 0x7b, 0x7b, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x32, 0x7d, 0x7d, + 0x3c, 0x2f, 0x74, 0x64, 0x3e, 0x3c, 0x2f, 0x74, 0x72, 0x3e, 0x7b, + 0x7b, 0x2f, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x32, 0x7d, 0x7d, 0x3c, + 0x2f, 0x74, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c, 0x2f, 0x74, 0x61, + 0x62, 0x6c, 0x65, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x3e, 0x00 +}; + +const int tpls_length = 10299; diff --git a/goaccess++/src/ui.c b/goaccess++/src/ui.c new file mode 100644 index 0000000..e0e9565 --- /dev/null +++ b/goaccess++/src/ui.c @@ -0,0 +1,1965 @@ +/** + * ui.c -- various curses interfaces + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#define STDIN_FILENO 0 +#ifndef _BSD_SOURCE +#define _BSD_SOURCE /* include stuff from 4.3 BSD */ +#endif +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ui.h" + +#ifdef HAVE_LIBTOKYOCABINET +#include "tcabdb.h" +#else +#include "gkhash.h" +#endif + +#include "color.h" +#include "error.h" +#include "gmenu.h" +#include "goaccess.h" +#include "util.h" +#include "xmalloc.h" + +/* *INDENT-OFF* */ +/* Determine which metrics should be displayed per module/panel */ +static GOutput outputting[] = { + {VISITORS , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1} , + {REQUESTS , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0} , + {REQUESTS_STATIC , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0} , + {NOT_FOUND , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0} , + {HOSTS , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 0} , + {OS , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1} , + {BROWSERS , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1} , + {VISIT_TIMES , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 1 , 1} , + {VIRTUAL_HOSTS , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0} , + {REFERRERS , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0} , + {REFERRING_SITES , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0} , + {KEYPHRASES , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0} , + {STATUS_CODES , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0} , + {REMOTE_USER , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0} , +#ifdef HAVE_GEOLOCATION + {GEO_LOCATION , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0} , +#endif +}; +/* *INDENT-ON* */ + +/* Structure to display overall statistics */ +typedef struct Field_ +{ + const char *field; + /* char due to log, bw, log_file */ + char *value; + GColors *(*colorlbl) (void); + GColors *(*colorval) (void); + short oneliner; +} Field; + +/* Determine which metrics to output given a module + * + * On error, or if not found, NULL is returned. + * On success, the panel value is returned. */ +GOutput * +output_lookup (GModule module) +{ + int i, num_panels = ARRAY_SIZE (outputting); + + for (i = 0; i < num_panels; i++) { + if (outputting[i].module == module) + return &outputting[i]; + } + return NULL; +} + +/* Initialize curses colors */ +void +init_colors (int force) +{ + /* use default foreground/background colors */ + use_default_colors (); + /* first set a default normal color */ + set_normal_color (); + /* then parse custom colors and initialize them */ + set_colors (force); +} + +/* Ncurses' window handling */ +void +set_input_opts (void) +{ + initscr (); + clear (); + noecho (); + halfdelay (10); + nonl (); + intrflush (stdscr, FALSE); + keypad (stdscr, TRUE); + if (curs_set (0) == ERR) + LOG_DEBUG (("Unable to change cursor: %s\n", strerror (errno))); + + if (conf.mouse_support) + mousemask (BUTTON1_CLICKED, NULL); +} + +/* Deletes the given window, freeing all memory associated with it. */ +void +close_win (WINDOW * w) +{ + if (w == NULL) + return; + wclear (w); + wrefresh (w); + delwin (w); +} + +/* Get the current calendar time as a value of type time_t and convert + * time_t to tm as local time */ +void +generate_time (void) +{ + timestamp = time (NULL); + now_tm = localtime (×tamp); +} + +/* Set the loading spinner as ended and manage the mutex locking. */ +void +end_spinner (void) +{ + if (conf.no_parsing_spinner) + return; + + pthread_mutex_lock (&parsing_spinner->mutex); + parsing_spinner->state = SPN_END; + pthread_mutex_unlock (&parsing_spinner->mutex); +} + +/* Set background colors to all windows. */ +void +set_wbkgd (WINDOW * main_win, WINDOW * header_win) +{ + GColors *color = get_color (COLOR_BG); + + /* background colors */ + wbkgd (main_win, COLOR_PAIR (color->pair->idx)); + wbkgd (header_win, COLOR_PAIR (color->pair->idx)); + wbkgd (stdscr, COLOR_PAIR (color->pair->idx)); + wrefresh (main_win); +} + +/* Creates and the new terminal windows and set basic properties to + * each of them. e.g., background color, enable the reading of + * function keys. */ +void +init_windows (WINDOW ** header_win, WINDOW ** main_win) +{ + int row = 0, col = 0; + + /* init standard screen */ + getmaxyx (stdscr, row, col); + if (row < MIN_HEIGHT || col < MIN_WIDTH) + FATAL ("Minimum screen size - 0 columns by 7 lines"); + + /* init header screen */ + *header_win = newwin (6, col, 0, 0); + keypad (*header_win, TRUE); + if (*header_win == NULL) + FATAL ("Unable to allocate memory for header_win."); + + /* init main screen */ + *main_win = newwin (row - 8, col, 7, 0); + keypad (*main_win, TRUE); + if (*main_win == NULL) + FATAL ("Unable to allocate memory for main_win."); + set_wbkgd (*main_win, *header_win); +} + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +/* Draw a generic header with the ability to set a custom text to it. */ +void +draw_header (WINDOW * win, const char *s, const char *fmt, int y, int x, int w, + GColors * (*func) (void)) +{ + GColors *color = (*func) (); + char *buf; + + buf = xmalloc (snprintf (NULL, 0, fmt, s) + 1); + sprintf (buf, fmt, s); + + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwhline (win, y, x, ' ', w); + mvwaddnstr (win, y, x, buf, w); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); + + free (buf); +} + +#pragma GCC diagnostic warning "-Wformat-nonliteral" + +/* Determine the actual size of the main window. */ +void +term_size (WINDOW * main_win, int *main_win_height) +{ + int term_h = 0, term_w = 0; + + getmaxyx (stdscr, term_h, term_w); + + *main_win_height = term_h - (MAX_HEIGHT_HEADER + MAX_HEIGHT_FOOTER); + wresize (main_win, *main_win_height, term_w); + wmove (main_win, *main_win_height, 0); +} + +/* Get the module/panel label name for the given module enum value. + * + * On success, a string containing the label name is returned. */ +const char * +module_to_label (GModule module) +{ + static const char *modules[] = { + VISITORS_LABEL, + REQUESTS_LABEL, + REQUESTS_STATIC_LABEL, + NOT_FOUND_LABEL, + HOSTS_LABEL, + OS_LABEL, + BROWSERS_LABEL, + VISIT_TIMES_LABEL, + VIRTUAL_HOSTS_LABEL, + REFERRERS_LABEL, + REFERRING_SITES_LABEL, + KEYPHRASES_LABEL, + STATUS_CODES_LABEL, + REMOTE_USER_LABEL, +#ifdef HAVE_GEOLOCATION + GEO_LOCATION_LABEL, +#endif + }; + + return _(modules[module]); +} + +/* Get the module/panel label id for the given module enum value. + * + * On success, a string containing the label id is returned. */ +const char * +module_to_id (GModule module) +{ + static const char *modules[] = { + VISITORS_ID, + REQUESTS_ID, + REQUESTS_STATIC_ID, + NOT_FOUND_ID, + HOSTS_ID, + OS_ID, + BROWSERS_ID, + VISIT_TIMES_ID, + VIRTUAL_HOSTS_ID, + REFERRERS_ID, + REFERRING_SITES_ID, + KEYPHRASES_ID, + STATUS_CODES_ID, + REMOTE_USER_ID, +#ifdef HAVE_GEOLOCATION + GEO_LOCATION_ID, +#endif + }; + + return _(modules[module]); +} + +/* Get the module/panel label header for the given module enum value. + * + * On success, a string containing the label header is returned. */ +const char * +module_to_head (GModule module) +{ + static const char *modules[] = { + VISITORS_HEAD, + REQUESTS_HEAD, + REQUESTS_STATIC_HEAD, + NOT_FOUND_HEAD, + HOSTS_HEAD, + OS_HEAD, + BROWSERS_HEAD, + VISIT_TIMES_HEAD, + VIRTUAL_HOSTS_HEAD, + REFERRERS_HEAD, + REFERRING_SITES_HEAD, + KEYPHRASES_HEAD, + STATUS_CODES_HEAD, + REMOTE_USER_HEAD, +#ifdef HAVE_GEOLOCATION + GEO_LOCATION_HEAD, +#endif + }; + + if (!conf.ignore_crawlers) + modules[VISITORS] = VISITORS_HEAD_BOTS; + + return _(modules[module]); +} + +/* Get the module/panel label description for the given module enum + * value. + * + * On success, a string containing the label description is returned. */ +const char * +module_to_desc (GModule module) +{ + static const char *modules[] = { + VISITORS_DESC, + REQUESTS_DESC, + REQUESTS_STATIC_DESC, + NOT_FOUND_DESC, + HOSTS_DESC, + OS_DESC, + BROWSERS_DESC, + VISIT_TIMES_DESC, + VIRTUAL_HOSTS_DESC, + REFERRERS_DESC, + REFERRING_SITES_DESC, + KEYPHRASES_DESC, + STATUS_CODES_DESC, + REMOTE_USER_DESC, +#ifdef HAVE_GEOLOCATION + GEO_LOCATION_DESC, +#endif + }; + + return _(modules[module]); +} + +/* Rerender the header window to reflect active module. */ +void +update_active_module (WINDOW * header_win, GModule current) +{ + GColors *color = get_color (COLOR_ACTIVE_LABEL); + const char *module = module_to_label (current); + int col = getmaxx (stdscr); + + char *lbl = xmalloc (snprintf (NULL, 0, T_ACTIVE_PANEL, module) + 1); + sprintf (lbl, T_ACTIVE_PANEL, module); + + wmove (header_win, 0, 30); + + wattron (header_win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (header_win, 0, col - strlen (lbl) - 1, "%s", lbl); + wattroff (header_win, color->attr | COLOR_PAIR (color->pair->idx)); + + wrefresh (header_win); + + free (lbl); +} + +/* Print out (terminal) an overall field label. e.g., 'Processed Time' */ +static void +render_overall_field (WINDOW * win, const char *s, int y, int x, + GColors * color) +{ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, x, "%s", s); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); +} + +/* Print out (terminal) an overall field value. e.g., '120 secs' */ +static void +render_overall_value (WINDOW * win, const char *s, int y, int x, + GColors * color) +{ + wattron (win, color->attr | COLOR_PAIR (color->pair->idx)); + mvwprintw (win, y, x, "%s", s); + wattroff (win, color->attr | COLOR_PAIR (color->pair->idx)); +} + +/* Convert the number of excluded ips to a string. + * + * On success, the number of excluded ips as a string is returned. */ +static char * +get_str_excluded_ips (GLog * glog) +{ + return int2str (glog->excluded_ip, 0); +} + +/* Convert the number of failed requests to a string. + * + * On success, the number of failed requests as a string is returned. */ +static char * +get_str_failed_reqs (GLog * glog) +{ + return int2str (glog->invalid, 0); +} + +/* Convert the number of processed requests to a string. + * + * On success, the number of processed requests as a string is returned. */ +static char * +get_str_processed_reqs (GLog * glog) +{ + return int2str (glog->processed, 0); +} + +/* Convert the number of valid requests to a string. + * + * On success, the number of valid requests as a string is returned. */ +static char * +get_str_valid_reqs (GLog * glog) +{ + return int2str (glog->valid, 0); +} + +/* Convert the number of not found requests to a string. + * + * On success, the number of not found requests as a string is + * returned. */ +static char * +get_str_notfound_reqs (void) +{ + return int2str (ht_get_size_datamap (NOT_FOUND), 0); +} + +/* Convert the number of referrers to a string. + * + * On success, the number of referrers as a string is returned. */ +static char * +get_str_ref_reqs (void) +{ + return int2str (ht_get_size_datamap (REFERRERS), 0); +} + +/* Convert the number of requests to a string. + * + * On success, the number of requests as a string is returned. */ +static char * +get_str_reqs (void) +{ + return int2str (ht_get_size_datamap (REQUESTS), 0); +} + +/* Convert the number of static requests to a string. + * + * On success, the number of static requests as a string is returned. */ +static char * +get_str_static_reqs (void) +{ + return int2str (ht_get_size_datamap (REQUESTS_STATIC), 0); +} + +/* Convert the number of unique visitors to a string. + * + * On success, the number of unique visitors as a string is returned. */ +static char * +get_str_visitors (void) +{ + return int2str (ht_get_size_uniqmap (VISITORS), 0); +} + +/* Convert the time taken to process the log to a string. + * + * On success, the time taken to process the log as a string is + * returned. */ +static char * +get_str_proctime (void) +{ + char *s = NULL; + uint64_t secs = (long long) end_proc - start_proc; + +#ifdef TCB_BTREE + if (conf.store_accumulated_time) + secs = (uint64_t) ht_get_genstats ("accumulated_time"); +#endif + + s = xmalloc (snprintf (NULL, 0, "%" PRIu64 "s", secs) + 1); + sprintf (s, "%" PRIu64 "s", secs); + + return s; +} + +/* Get the log file size in a human readable format. + * + * On success, the log file size as a string is returned. */ +static char * +get_str_filesize (void) +{ + return filesize_str (get_log_sizes ()); +} + +/* Get the log file path. + * + * On success, the log file path as a string is returned. */ +static char * +get_str_logfile (void) +{ + int col = getmaxx (stdscr), left_padding = 20; + return get_log_source_str (col - left_padding); +} + +/* Get the bandwidth in a human readable format. + * + * On success, the bandwidth as a string is returned. */ +static char * +get_str_bandwidth (GLog * glog) +{ + return filesize_str ((float) glog->resp_size); +} + +/* Iterate over the visitors module and sort date in an ascending + * order. + * + * On success, an array of sorted dates is returned. */ +static char ** +get_visitors_dates (GHolder * h) +{ + char **dates = malloc (sizeof (char *) * h->holder_size); + int i; + + for (i = 0; i < h->idx; i++) { + dates[i] = h->items[i].metrics->data; + } + qsort (dates, h->holder_size, sizeof (char *), strcmp_asc); + + return dates; +} + +/* Get the overall statistics start and end dates. + * + * On failure, 1 is returned + * On success, 0 is returned and an string containing the overall + * header is returned. */ +int +get_start_end_parsing_dates (GHolder * h, char **start, char **end, + const char *f) +{ + char **dates = NULL; + const char *sndfmt = conf.spec_date_time_num_format; + + if (h->idx == 0) + return 1; + + dates = get_visitors_dates (h + VISITORS); + + /* just display the actual dates - no specificity */ + *start = get_visitors_date (dates[0], sndfmt, f); + *end = get_visitors_date (dates[h->idx - 1], sndfmt, f); + + free (dates); + + return 0; +} + +/* Get the overall statistics header (label). + * + * On success, an string containing the overall header is returned. */ +char * +get_overall_header (GHolder * h) +{ + const char *head = T_DASH_HEAD; + char *hd = NULL, *start = NULL, *end = NULL; + + if (h->idx == 0 || get_start_end_parsing_dates (h, &start, &end, "%d/%b/%Y")) + return xstrdup (head); + + hd = xmalloc (snprintf (NULL, 0, "%s (%s - %s)", head, start, end) + 1); + sprintf (hd, "%s (%s - %s)", head, start, end); + + free (end); + free (start); + + return hd; +} + +/* Print out (terminal dashboard) the overall statistics header. */ +static void +render_overall_header (WINDOW * win, GHolder * h) +{ + char *hd = get_overall_header (h); + int col = getmaxx (stdscr); + + draw_header (win, hd, " %s", 0, 0, col, color_panel_header); + free (hd); +} + +/* Render the overall statistics. This will attempt to determine the + * right X and Y position given the current values. */ +static void +render_overall_statistics (WINDOW * win, Field fields[], size_t n) +{ + GColors *color = NULL; + int x_field = 2, x_value = 0; + size_t i, j, k, max_field = 0, max_value = 0, mod_val, y; + + for (i = 0, k = 0, y = 2; i < n; i++) { + /* new line every OVERALL_NUM_COLS */ + mod_val = k % OVERALL_NUM_COLS; + + /* reset position & length and increment row */ + if (k > 0 && mod_val == 0) { + max_value = max_field = 0; + x_value = x_field = 2; + y++; + } + + /* x pos = max length of field */ + x_field += max_field; + + color = (*fields[i].colorlbl) (); + render_overall_field (win, fields[i].field, y, x_field, color); + + /* get max length of field in the same column */ + max_field = 0; + for (j = 0; j < n; j++) { + size_t len = strlen (fields[j].field); + if (j % OVERALL_NUM_COLS == mod_val && len > max_field && + !fields[j].oneliner) + max_field = len; + } + /* get max length of value in the same column */ + max_value = 0; + for (j = 0; j < n; j++) { + size_t len = strlen (fields[j].value); + if (j % OVERALL_NUM_COLS == mod_val && len > max_value && + !fields[j].oneliner) + max_value = len; + } + + /* spacers */ + x_value = max_field + x_field + 1; + max_field += max_value + 2; + + color = (*fields[i].colorval) (); + render_overall_value (win, fields[i].value, y, x_value, color); + k += fields[i].oneliner ? OVERALL_NUM_COLS : 1; + } +} + +/* The entry point to render the overall statistics and free its data. */ +void +display_general (WINDOW * win, GLog * glog, GHolder * h) +{ + GColors *(*colorlbl) (void) = color_overall_lbls; + GColors *(*colorpth) (void) = color_overall_path; + GColors *(*colorval) (void) = color_overall_vals; + + size_t n, i; + + /* *INDENT-OFF* */ + Field fields[] = { + {T_REQUESTS , get_str_processed_reqs (glog), colorlbl, colorval, 0}, + {T_UNIQUE_VISITORS , get_str_visitors () , colorlbl, colorval, 0}, + {T_UNIQUE_FILES , get_str_reqs () , colorlbl, colorval, 0}, + {T_REFERRER , get_str_ref_reqs () , colorlbl, colorval, 0}, + {T_VALID , get_str_valid_reqs (glog) , colorlbl, colorval, 0}, + {T_GEN_TIME , get_str_proctime () , colorlbl, colorval, 0}, + {T_STATIC_FILES , get_str_static_reqs () , colorlbl, colorval, 0}, + {T_LOG , get_str_filesize () , colorlbl, colorval, 0}, + {T_FAILED , get_str_failed_reqs (glog) , colorlbl, colorval, 0}, + {T_EXCLUDE_IP , get_str_excluded_ips (glog) , colorlbl, colorval, 0}, + {T_UNIQUE404 , get_str_notfound_reqs () , colorlbl, colorval, 0}, + {T_BW , get_str_bandwidth (glog) , colorlbl, colorval, 0}, + {T_LOG_PATH , get_str_logfile () , colorlbl, colorpth, 1} + }; + /* *INDENT-ON* */ + + werase (win); + render_overall_header (win, h); + + n = ARRAY_SIZE (fields); + render_overall_statistics (win, fields, n); + + for (i = 0; i < n; i++) { + free (fields[i].value); + } +} + +/* Implement a basic framework to build a field input. + * + * On success, the inputted string is returned. */ +char * +input_string (WINDOW * win, int pos_y, int pos_x, size_t max_width, + const char *str, int enable_case, int *toggle_case) +{ + char *s = xmalloc (max_width + 1), *tmp; + size_t i, c, pos = 0, x = 0, quit = 1, len = 0, size_x = 0, size_y = 0; + + getmaxyx (win, size_y, size_x); + size_x -= 4; + + /* are we setting a default string */ + if (str) { + len = MIN (max_width, strlen (str)); + memcpy (s, str, len); + s[len] = '\0'; + + x = pos = 0; + /* is the default str length greater than input field? */ + if (strlen (s) > size_x) { + tmp = xstrdup (&s[0]); + tmp[size_x] = '\0'; + mvwprintw (win, pos_y, pos_x, "%s", tmp); + free (tmp); + } else { + mvwprintw (win, pos_y, pos_x, "%s", s); + } + } else { + s[0] = '\0'; + } + + if (enable_case) + mvwprintw (win, size_y - 2, 1, " %s", CSENSITIVE); + + wmove (win, pos_y, pos_x + x); + wrefresh (win); + + curs_set (1); + while (quit) { + c = wgetch (stdscr); + switch (c) { + case 1: /* ^a */ + case 262: /* HOME */ + pos = x = 0; + break; + case 5: + case 360: /* END of line */ + if (strlen (s) > size_x) { + x = size_x; + pos = strlen (s) - size_x; + } else { + pos = 0; + x = strlen (s); + } + break; + case 7: /* ^g */ + case 27: /* ESC */ + pos = x = 0; + if (str && *str == '\0') + s[0] = '\0'; + quit = 0; + break; + case 9: /* TAB */ + if (!enable_case) + break; + *toggle_case = *toggle_case == 0 ? 1 : 0; + if (*toggle_case) + mvwprintw (win, size_y - 2, 1, " %s", CISENSITIVE); + else if (!*toggle_case) + mvwprintw (win, size_y - 2, 1, " %s", CSENSITIVE); + break; + case 21: /* ^u */ + s[0] = '\0'; + pos = x = 0; + break; + case 8: /* xterm-256color */ + case 127: + case KEY_BACKSPACE: + if (pos + x > 0) { + memmove (&s[(pos + x) - 1], &s[pos + x], (max_width - (pos + x)) + 1); + if (pos <= 0) + x--; + else + pos--; + } + break; + case KEY_LEFT: + if (x > 0) + x--; + else if (pos > 0) + pos--; + break; + case KEY_RIGHT: + if ((x + pos) < strlen (s)) { + if (x < size_x) + x++; + else + pos++; + } + break; + case 0x0a: + case 0x0d: + case KEY_ENTER: + quit = 0; + break; + default: + if (strlen (s) == max_width) + break; + if (!isprint (c)) + break; + + if (strlen (s) == pos) { + s[pos + x] = c; + s[pos + x + 1] = '\0'; + waddch (win, c); + } else { + memmove (&s[pos + x + 1], &s[pos + x], strlen (&s[pos + x]) + 1); + s[pos + x] = c; + } + if ((x + pos) < max_width) { + if (x < size_x) + x++; + else + pos++; + } + } + tmp = xstrdup (&s[pos > 0 ? pos : 0]); + tmp[MIN (strlen (tmp), size_x)] = '\0'; + for (i = strlen (tmp); i < size_x; i++) + mvwprintw (win, pos_y, pos_x + i, "%s", " "); + mvwprintw (win, pos_y, pos_x, "%s", tmp); + free (tmp); + + wmove (win, pos_y, pos_x + x); + wrefresh (win); + } + curs_set (0); + + return s; +} + +/* Fill the given terminal dashboard menu with user agent data. + * + * On error, the 1 is returned. + * On success, 0 is returned. */ +static int +fill_host_agents_gmenu (void *val, void *user_data) +{ + GMenu *menu = user_data; + char *agent = ht_get_host_agent_val ((*(int *) val)); + + if (agent == NULL) + return 1; + + menu->items[menu->size].name = agent; + menu->items[menu->size].checked = 0; + menu->size++; + + return 0; +} + +/* Iterate over the linked-list of user agents for the given host and + * load its data into the given menu. */ +static void +load_host_agents_gmenu (void *list, void *user_data, int count) +{ + GSLList *lst = list; + GMenu *menu = user_data; + + menu->items = (GItem *) xcalloc (count, sizeof (GItem)); + list_foreach (lst, fill_host_agents_gmenu, menu); +} + +/* Set host data from a linked-list and load its data into a GMenu + * structure. + * + * On error, the 1 is returned. + * On success, 0 is returned. */ +#ifdef TCB_BTREE +int +set_host_agents (const char *addr, void (*func) (void *, void *, int), + void *arr) +{ + TCLIST *tclist; + GSLList *list; + int key, count = 0; + + key = ht_get_keymap (HOSTS, addr); + if (key == 0) + return 1; + + tclist = ht_get_host_agent_tclist (HOSTS, key); + if (!tclist) + return 1; + + list = tclist_to_gsllist (tclist); + if ((count = list_count (list)) == 0) { + free (list); + return 1; + } + + func (list, arr, count); + + list_remove_nodes (list); + tclistdel (tclist); + + return 0; +} +#endif + +/* Set host data from a linked-list and load its data into a GMenu + * structure. + * + * On error, the 1 is returned. + * On success, 0 is returned. */ +#ifndef TCB_BTREE +int +set_host_agents (const char *addr, void (*func) (void *, void *, int), + void *arr) +{ + GSLList *list; + int data_nkey, count = 0; + + data_nkey = ht_get_keymap (HOSTS, addr); + if (data_nkey == 0) + return 1; + + list = ht_get_host_agent_list (HOSTS, data_nkey); + if (!list) + return 1; + + if ((count = list_count (list)) == 0) { + free (list); + return 1; + } + + func (list, arr, count); + +#ifdef TCB_MEMHASH + free (list); +#endif + + return 0; +} +#endif + +/* Render a list of agents if available for the selected host/IP. */ +void +load_agent_list (WINDOW * main_win, char *addr) +{ + GMenu *menu; + WINDOW *win; + + char buf[256]; + int c, quit = 1, i; + int y, x, list_h, list_w, menu_w, menu_h; + + if (!conf.list_agents) + return; + + getmaxyx (stdscr, y, x); + list_h = y / 2; /* list window - height */ + list_w = x - 4; /* list window - width */ + menu_h = list_h - AGENTS_MENU_Y - 1; /* menu window - height */ + menu_w = list_w - AGENTS_MENU_X - AGENTS_MENU_X; /* menu window - width */ + + win = newwin (list_h, list_w, (y - list_h) / 2, (x - list_w) / 2); + keypad (win, TRUE); + wborder (win, '|', '|', '-', '-', '+', '+', '+', '+'); + + /* create a new instance of GMenu and make it selectable */ + menu = new_gmenu (win, menu_h, menu_w, AGENTS_MENU_Y, AGENTS_MENU_X); + if (set_host_agents (addr, load_host_agents_gmenu, menu) == 1) + goto out; + + post_gmenu (menu); + snprintf (buf, sizeof buf, AGENTSDLG_HEAD, addr); + draw_header (win, buf, " %s", 1, 1, list_w - 2, color_panel_header); + mvwprintw (win, 2, 2, AGENTSDLG_DESC); + wrefresh (win); + + while (quit) { + c = wgetch (stdscr); + switch (c) { + case KEY_DOWN: + gmenu_driver (menu, REQ_DOWN); + break; + case KEY_UP: + gmenu_driver (menu, REQ_UP); + break; + case KEY_RESIZE: + case 'q': + quit = 0; + break; + } + wrefresh (win); + } + + touchwin (main_win); + close_win (win); + wrefresh (main_win); + +out: + + /* clean stuff up */ + for (i = 0; i < menu->size; ++i) + free (menu->items[i].name); + if (menu->items) + free (menu->items); + free (menu); +} + +/* Render the processing spinner. This runs within its own thread. */ +static void +ui_spinner (void *ptr_data) +{ + GSpinner *sp = (GSpinner *) ptr_data; + GColors *color = NULL; + + static char const spin_chars[] = "/-\\|"; + char buf[SPIN_LBL]; + int i = 0; + long long tdiff = 0, psec = 0; + time_t begin; + + if (sp->curses) + color = (*sp->color) (); + + time (&begin); + while (1) { + pthread_mutex_lock (&sp->mutex); + if (sp->state == SPN_END) + break; + + setlocale (LC_NUMERIC, ""); + if (conf.no_progress) { + snprintf (buf, sizeof buf, SPIN_FMT, sp->label); + } else { + tdiff = (long long) (time (NULL) - begin); + psec = tdiff >= 1 ? *(sp->processed) / tdiff : 0; + snprintf (buf, sizeof buf, SPIN_FMTM, sp->label, *(sp->processed), psec); + } + setlocale (LC_NUMERIC, "POSIX"); + + if (sp->curses) { + /* CURSES */ + draw_header (sp->win, buf, " %s", sp->y, sp->x, sp->w, sp->color); + /* caret */ + wattron (sp->win, COLOR_PAIR (color->pair->idx)); + mvwaddch (sp->win, sp->y, sp->spin_x, spin_chars[i++ & 3]); + wattroff (sp->win, COLOR_PAIR (color->pair->idx)); + wrefresh (sp->win); + } else if (!conf.no_progress) { + /* STDOUT */ + fprintf (stderr, "%s\r", buf); + } + + pthread_mutex_unlock (&sp->mutex); + usleep (100000); + } +} + +/* Create the processing spinner's thread */ +void +ui_spinner_create (GSpinner * spinner) +{ + if (conf.no_parsing_spinner) + return; + + pthread_create (&(spinner->thread), NULL, (void *) &ui_spinner, spinner); + pthread_detach (spinner->thread); +} + +/* Initialize processing spinner data. */ +void +set_curses_spinner (GSpinner * spinner) +{ + int y, x; + if (spinner == NULL) + return; + + getmaxyx (stdscr, y, x); + + spinner->color = color_progress; + spinner->curses = 1; + spinner->win = stdscr; + spinner->x = 0; + spinner->w = x; + spinner->spin_x = x - 2; + spinner->y = y - 1; +} + +/* Allocate memory for a spinner instance and initialize its data. + * + * On success, the newly allocated GSpinner is returned. */ +GSpinner * +new_gspinner (void) +{ + GSpinner *spinner; + + spinner = xcalloc (1, sizeof (GSpinner)); + spinner->label = "Parsing..."; + spinner->state = SPN_RUN; + spinner->curses = 0; + if (conf.load_from_disk) + conf.no_progress = 1; + + if (pthread_mutex_init (&(spinner->mutex), NULL)) + FATAL ("Failed init thread mutex"); + + return spinner; +} + +/* A wrapper call to clear the status bar on the config dialog + * (terminal output). */ +static void +clear_confdlg_status_bar (WINDOW * win, int y, int x, int w) +{ + draw_header (win, "", "%s", y, x, w + 1, color_default); +} + +/* Escape a date format string. + * + * If no conf.date_format is given, NULL is returned. + * On success, the newly escaped allocated string is returned. */ +static char * +get_input_date_format (void) +{ + char *date_format = NULL; + + if (conf.date_format) + date_format = escape_str (conf.date_format); + return date_format; +} + +/* Escape a time format string. + * + * If no conf.time_format is given, NULL is returned. + * On success, the newly escaped allocated string is returned. */ +static char * +get_input_time_format (void) +{ + char *time_format = NULL; + + if (conf.time_format) + time_format = escape_str (conf.time_format); + return time_format; +} + +/* Escape a log format string. + * + * If no conf.log_format is given, NULL is returned. + * On success, the newly escaped allocated string is returned. */ +static char * +get_input_log_format (void) +{ + char *log_format = NULL; + + if (conf.log_format) + log_format = escape_str (conf.log_format); + return log_format; +} + +static void +draw_formats (WINDOW * win, int w2) +{ + char *date_format = NULL, *log_format = NULL, *time_format = NULL; + + draw_header (win, CONFDLG_HEAD, " %s", 1, 1, w2, color_panel_header); + mvwprintw (win, 2, 2, CONFDLG_KEY_HINTS); + + /* set log format from config file if available */ + draw_header (win, CONFDLG_LOG_FORMAT, " %s", 11, 1, w2, color_panel_header); + if ((log_format = get_input_log_format ())) { + mvwprintw (win, 12, 2, "%.*s", CONF_MENU_W, log_format); + + free (log_format); + } + + /* set log format from config file if available */ + draw_header (win, CONFDLG_DATE_FORMAT, " %s", 14, 1, w2, color_panel_header); + if ((date_format = get_input_date_format ())) { + mvwprintw (win, 15, 2, "%.*s", CONF_MENU_W, date_format); + + free (date_format); + } + + /* set log format from config file if available */ + draw_header (win, CONFDLG_TIME_FORMAT, " %s", 17, 1, w2, color_panel_header); + if ((time_format = get_input_time_format ())) { + mvwprintw (win, 18, 2, "%.*s", CONF_MENU_W, time_format); + + free (time_format); + } +} + +static const char * +set_formats (char *date_format, char *log_format, char *time_format) +{ + /* display status bar error messages */ + if (!time_format && !conf.time_format) + return ERR_FORMAT_NO_TIME_FMT_DLG; + if (!date_format && !conf.date_format) + return ERR_FORMAT_NO_DATE_FMT_DLG; + if (!log_format && !conf.log_format) + return ERR_FORMAT_NO_LOG_FMT_DLG; + + if (time_format) { + free (conf.time_format); + conf.time_format = unescape_str (time_format); + } + + if (date_format) { + free (conf.date_format); + conf.date_format = unescape_str (date_format); + } + + if (log_format) { + free (conf.log_format); + conf.log_format = unescape_str (log_format); + } + + set_spec_date_format (); + + return NULL; +} + +/* Render the help dialog. */ +static void +load_confdlg_error (WINDOW * parent_win, char **errors, int nerrors) +{ + int c, quit = 1, i = 0; + int y, x, h = ERR_WIN_HEIGHT, w = ERR_WIN_WIDTH; + WINDOW *win; + GMenu *menu; + + getmaxyx (stdscr, y, x); + + win = newwin (h, w, (y - h) / 2, (x - w) / 2); + keypad (win, TRUE); + wborder (win, '|', '|', '-', '-', '+', '+', '+', '+'); + + /* create a new instance of GMenu and make it selectable */ + menu = + new_gmenu (win, ERR_MENU_HEIGHT, ERR_MENU_WIDTH, ERR_MENU_Y, ERR_MENU_X); + menu->size = nerrors; + + /* add items to GMenu */ + menu->items = (GItem *) xcalloc (nerrors, sizeof (GItem)); + for (i = 0; i < nerrors; ++i) { + menu->items[i].name = alloc_string (errors[i]); + menu->items[i].checked = 0; + free (errors[i]); + } + free (errors); + post_gmenu (menu); + + draw_header (win, ERR_FORMAT_HEADER, " %s", 1, 1, w - 2, color_error); + mvwprintw (win, 2, 2, CONFDLG_DESC); + + wrefresh (win); + while (quit) { + c = wgetch (stdscr); + switch (c) { + case KEY_DOWN: + gmenu_driver (menu, REQ_DOWN); + break; + case KEY_UP: + gmenu_driver (menu, REQ_UP); + break; + case KEY_RESIZE: + case 'q': + quit = 0; + break; + } + wrefresh (win); + } + /* clean stuff up */ + for (i = 0; i < nerrors; ++i) + free (menu->items[i].name); + free (menu->items); + free (menu); + + touchwin (parent_win); + close_win (win); + wrefresh (parent_win); +} + +/* Render the config log date/format dialog. + * + * On error, or if the selected format is invalid, 1 is returned. + * On success, 0 is returned. */ +int +render_confdlg (GLog * glog, GSpinner * spinner) +{ + GMenu *menu; + WINDOW *win; + + const char *log_err = NULL; + char *date_format = NULL, *log_format = NULL, *time_format = NULL; + char *cstm_log, *cstm_date, *cstm_time; + int c, quit = 1, invalid = 1, y, x, h = CONF_WIN_H, w = CONF_WIN_W; + int w2 = w - 2; + size_t i, n, sel; + + /* conf dialog menu options */ + const char *choices[] = { + "NCSA Combined Log Format", + "NCSA Combined Log Format with Virtual Host", + "Common Log Format (CLF)", + "Common Log Format (CLF) with Virtual Host", + "W3C", + "Squid Native Format", + "CloudFront (Download Distribution)", + "Google Cloud Storage", + "AWS Elastic Load Balancing (HTTP/S)", + "AWS Simple Storage Service (S3)", + }; + n = ARRAY_SIZE (choices); + getmaxyx (stdscr, y, x); + + win = newwin (h, w, (y - h) / 2, (x - w) / 2); + keypad (win, TRUE); + wborder (win, '|', '|', '-', '-', '+', '+', '+', '+'); + + /* create a new instance of GMenu and make it selectable */ + menu = new_gmenu (win, CONF_MENU_H, CONF_MENU_W, CONF_MENU_Y, CONF_MENU_X); + menu->size = n; + menu->selectable = 1; + + /* add items to GMenu */ + menu->items = (GItem *) xcalloc (n, sizeof (GItem)); + for (i = 0; i < n; ++i) { + menu->items[i].name = alloc_string (choices[i]); + sel = get_selected_format_idx (); + menu->items[i].checked = sel == i ? 1 : 0; + } + post_gmenu (menu); + draw_formats (win, w2); + + wrefresh (win); + while (quit) { + c = wgetch (stdscr); + switch (c) { + case KEY_DOWN: + gmenu_driver (menu, REQ_DOWN); + clear_confdlg_status_bar (win, 3, 2, CONF_MENU_W); + break; + case KEY_UP: + gmenu_driver (menu, REQ_UP); + clear_confdlg_status_bar (win, 3, 2, CONF_MENU_W); + break; + case 32: /* space */ + gmenu_driver (menu, REQ_SEL); + clear_confdlg_status_bar (win, 12, 1, CONF_MENU_W); + clear_confdlg_status_bar (win, 15, 1, CONF_MENU_W); + clear_confdlg_status_bar (win, 18, 1, CONF_MENU_W); + + if (time_format) + free (time_format); + if (date_format) + free (date_format); + if (log_format) + free (log_format); + + for (i = 0; i < n; ++i) { + if (menu->items[i].checked != 1) + continue; + + date_format = get_selected_date_str (i); + log_format = get_selected_format_str (i); + time_format = get_selected_time_str (i); + + mvwprintw (win, 12, 1, " %s", log_format); + mvwprintw (win, 15, 1, " %s", date_format); + mvwprintw (win, 18, 1, " %s", time_format); + break; + } + break; + case 99: /* c */ + /* clear top status bar */ + clear_confdlg_status_bar (win, 3, 2, CONF_MENU_W); + wmove (win, 12, 2); + + /* get input string */ + if (!log_format) + log_format = get_input_log_format (); + + cstm_log = input_string (win, 12, 2, 70, log_format, 0, 0); + if (cstm_log != NULL && *cstm_log != '\0') { + if (log_format) + free (log_format); + + log_format = alloc_string (cstm_log); + free (cstm_log); + } + /* did not set an input string */ + else { + if (cstm_log) + free (cstm_log); + if (log_format) { + free (log_format); + log_format = NULL; + } + } + break; + case 100: /* d */ + /* clear top status bar */ + clear_confdlg_status_bar (win, 3, 2, CONF_MENU_W); + wmove (win, 15, 0); + + /* get input string */ + if (!date_format) + date_format = get_input_date_format (); + + cstm_date = input_string (win, 15, 2, 14, date_format, 0, 0); + if (cstm_date != NULL && *cstm_date != '\0') { + if (date_format) + free (date_format); + + date_format = alloc_string (cstm_date); + free (cstm_date); + } + /* did not set an input string */ + else { + if (cstm_date) + free (cstm_date); + if (date_format) { + free (date_format); + date_format = NULL; + } + } + break; + case 116: /* t */ + /* clear top status bar */ + clear_confdlg_status_bar (win, 3, 2, CONF_MENU_W); + wmove (win, 15, 0); + + /* get input string */ + if (!time_format) + time_format = get_input_time_format (); + + cstm_time = input_string (win, 18, 2, 14, time_format, 0, 0); + if (cstm_time != NULL && *cstm_time != '\0') { + if (time_format) + free (time_format); + + time_format = alloc_string (cstm_time); + free (cstm_time); + } + /* did not set an input string */ + else { + if (cstm_time) + free (cstm_time); + if (time_format) { + free (time_format); + time_format = NULL; + } + } + break; + case 274: /* F10 */ + case 0x0a: + case 0x0d: + case KEY_ENTER: + if ((log_err = set_formats (date_format, log_format, time_format))) + draw_header (win, log_err, " %s", 3, 2, CONF_MENU_W, color_error); + + if (!log_err) { + char **errors = NULL; + int nerrors = 0; + + /* test log against selected settings */ + if ((errors = test_format (glog, &nerrors))) { + invalid = 1; + load_confdlg_error (win, errors, nerrors); + } + /* valid data, reset glog & start parsing */ + else { + reset_struct (glog); + /* start spinner thread */ + spinner->win = win; + spinner->y = 3; + spinner->x = 2; + spinner->spin_x = CONF_MENU_W; + spinner->w = CONF_MENU_W; + spinner->color = color_progress; + ui_spinner_create (spinner); + + invalid = 0; + quit = 0; + } + } + break; + case KEY_RESIZE: + case 'q': + quit = 0; + break; + } + + pthread_mutex_lock (&spinner->mutex); + wrefresh (win); + pthread_mutex_unlock (&spinner->mutex); + } + + free (time_format); + free (date_format); + free (log_format); + + /* clean stuff up */ + for (i = 0; i < n; ++i) + free (menu->items[i].name); + free (menu->items); + free (menu); + + return invalid ? 1 : 0; +} + +/* Given the name of the selected scheme, set it under our config + * options. */ +static void +scheme_chosen (const char *name) +{ + int force = 0; + + free_color_lists (); + if (strcmp ("Green", name) == 0) { + conf.color_scheme = STD_GREEN; + force = 1; + } else if (strcmp ("Monochrome", name) == 0) { + conf.color_scheme = MONOCHROME; + force = 1; + } else if (strcmp ("Monokai", name) == 0) { + conf.color_scheme = MONOKAI; + force = 1; + } else if (strcmp ("Custom Scheme", name) == 0) { + force = 0; + } + init_colors (force); +} + +static const char ** +get_color_schemes (size_t * size) +{ + const char *choices[] = { + "Monokai", + "Monochrome", + "Green", + "Custom Scheme" + }; + int i, j, n = ARRAY_SIZE (choices); + const char **opts = xmalloc (sizeof (char *) * n); + + for (i = 0, j = 0; i < n; ++i) { + if (!conf.color_idx && !strcmp ("Custom Scheme", choices[i])) + continue; + if (COLORS < 256 && !strcmp ("Monokai", choices[i])) + continue; + opts[j++] = choices[i]; + } + *size = j; + + return opts; +} + +/* Render the schemes dialog. */ +void +load_schemes_win (WINDOW * main_win) +{ + GMenu *menu; + WINDOW *win; + int c, quit = 1; + size_t i, n = 0; + int y, x, h = SCHEME_WIN_H, w = SCHEME_WIN_W; + int w2 = w - 2; + const char **choices = get_color_schemes (&n); + + getmaxyx (stdscr, y, x); + + win = newwin (h, w, (y - h) / 2, (x - w) / 2); + keypad (win, TRUE); + wborder (win, '|', '|', '-', '-', '+', '+', '+', '+'); + + /* create a new instance of GMenu and make it selectable */ + menu = + new_gmenu (win, SCHEME_MENU_H, SCHEME_MENU_W, SCHEME_MENU_Y, SCHEME_MENU_X); + /* remove custom color option if no custom scheme used */ + menu->size = n; + + /* add items to GMenu */ + menu->items = (GItem *) xcalloc (n, sizeof (GItem)); + for (i = 0; i < n; ++i) { + menu->items[i].name = alloc_string (choices[i]); + menu->items[i].checked = 0; + } + post_gmenu (menu); + + draw_header (win, SCHEMEDLG_HEAD, " %s", 1, 1, w2, color_panel_header); + mvwprintw (win, 2, 2, SCHEMEDLG_DESC); + + wrefresh (win); + while (quit) { + c = wgetch (stdscr); + switch (c) { + case KEY_DOWN: + gmenu_driver (menu, REQ_DOWN); + break; + case KEY_UP: + gmenu_driver (menu, REQ_UP); + break; + case 32: + case 0x0a: + case 0x0d: + case KEY_ENTER: + gmenu_driver (menu, REQ_SEL); + for (i = 0; i < n; ++i) { + if (menu->items[i].checked != 1) + continue; + scheme_chosen (choices[i]); + break; + } + quit = 0; + break; + case KEY_RESIZE: + case 'q': + quit = 0; + break; + } + wrefresh (win); + } + /* clean stuff up */ + for (i = 0; i < n; ++i) + free (menu->items[i].name); + free (menu->items); + free (menu); + free (choices); + + touchwin (main_win); + close_win (win); + wrefresh (main_win); +} + +/* Render the sort dialog. */ +void +load_sort_win (WINDOW * main_win, GModule module, GSort * sort) +{ + GMenu *menu; + WINDOW *win; + GSortField opts[SORT_MAX_OPTS]; + + int c, quit = 1; + int i = 0, k, n = 0; + int y, x, h = SORT_WIN_H, w = SORT_WIN_W; + int w2 = w - 2; + + getmaxyx (stdscr, y, x); + + /* determine amount of sort choices */ + for (i = 0, k = 0; -1 != sort_choices[module][i]; i++) { + GSortField field = sort_choices[module][i]; + if (SORT_BY_CUMTS == field && !conf.serve_usecs) + continue; + else if (SORT_BY_MAXTS == field && !conf.serve_usecs) + continue; + else if (SORT_BY_AVGTS == field && !conf.serve_usecs) + continue; + else if (SORT_BY_BW == field && !conf.bandwidth) + continue; + else if (SORT_BY_PROT == field && !conf.append_protocol) + continue; + else if (SORT_BY_MTHD == field && !conf.append_method) + continue; + opts[k++] = field; + n++; + } + + win = newwin (h, w, (y - h) / 2, (x - w) / 2); + keypad (win, TRUE); + wborder (win, '|', '|', '-', '-', '+', '+', '+', '+'); + + /* create a new instance of GMenu and make it selectable */ + menu = new_gmenu (win, SORT_MENU_H, SORT_MENU_W, SORT_MENU_Y, SORT_MENU_X); + menu->size = n; + menu->selectable = 1; + + /* add items to GMenu */ + menu->items = (GItem *) xcalloc (n, sizeof (GItem)); + + /* set choices, checked option and index */ + for (i = 0; i < n; ++i) { + GSortField field = sort_choices[module][opts[i]]; + if (SORT_BY_HITS == field) { + menu->items[i].name = alloc_string (MTRC_HITS_LBL); + if (sort->field == SORT_BY_HITS) { + menu->items[i].checked = 1; + menu->idx = i; + } + } else if (SORT_BY_VISITORS == field) { + menu->items[i].name = alloc_string (MTRC_VISITORS_LBL); + if (sort->field == SORT_BY_VISITORS) { + menu->items[i].checked = 1; + menu->idx = i; + } + } else if (SORT_BY_DATA == field) { + menu->items[i].name = alloc_string (MTRC_DATA_LBL); + if (sort->field == SORT_BY_DATA) { + menu->items[i].checked = 1; + menu->idx = i; + } + } else if (SORT_BY_BW == field) { + menu->items[i].name = alloc_string (MTRC_BW_LBL); + if (sort->field == SORT_BY_BW) { + menu->items[i].checked = 1; + menu->idx = i; + } + } else if (SORT_BY_AVGTS == field) { + menu->items[i].name = alloc_string (MTRC_AVGTS_LBL); + if (sort->field == SORT_BY_AVGTS) { + menu->items[i].checked = 1; + menu->idx = i; + } + } else if (SORT_BY_CUMTS == field) { + menu->items[i].name = alloc_string (MTRC_CUMTS_LBL); + if (sort->field == SORT_BY_CUMTS) { + menu->items[i].checked = 1; + menu->idx = i; + } + } else if (SORT_BY_MAXTS == field) { + menu->items[i].name = alloc_string (MTRC_MAXTS_LBL); + if (sort->field == SORT_BY_MAXTS) { + menu->items[i].checked = 1; + menu->idx = i; + } + } else if (SORT_BY_PROT == field) { + menu->items[i].name = alloc_string (MTRC_PROTOCOLS_LBL); + if (sort->field == SORT_BY_PROT) { + menu->items[i].checked = 1; + menu->idx = i; + } + } else if (SORT_BY_MTHD == field) { + menu->items[i].name = alloc_string (MTRC_METHODS_LBL); + if (sort->field == SORT_BY_MTHD) { + menu->items[i].checked = 1; + menu->idx = i; + } + } + } + post_gmenu (menu); + + draw_header (win, SORTDLG_HEAD, " %s", 1, 1, w2, color_panel_header); + mvwprintw (win, 2, 2, SORTDLG_DESC); + + if (sort->sort == SORT_ASC) + mvwprintw (win, SORT_WIN_H - 2, 1, " %s", SORT_ASC_SEL); + else + mvwprintw (win, SORT_WIN_H - 2, 1, " %s", SORT_DESC_SEL); + + wrefresh (win); + while (quit) { + c = wgetch (stdscr); + switch (c) { + case KEY_DOWN: + gmenu_driver (menu, REQ_DOWN); + break; + case KEY_UP: + gmenu_driver (menu, REQ_UP); + break; + case 9: /* TAB */ + if (sort->sort == SORT_ASC) { + /* ascending */ + sort->sort = SORT_DESC; + mvwprintw (win, SORT_WIN_H - 2, 1, " %s", SORT_DESC_SEL); + } else { + /* descending */ + sort->sort = SORT_ASC; + mvwprintw (win, SORT_WIN_H - 2, 1, " %s", SORT_ASC_SEL); + } + break; + case 32: + case 0x0a: + case 0x0d: + case KEY_ENTER: + gmenu_driver (menu, REQ_SEL); + for (i = 0; i < n; ++i) { + if (menu->items[i].checked != 1) + continue; + if (strcmp ("Hits", menu->items[i].name) == 0) + sort->field = SORT_BY_HITS; + else if (strcmp ("Visitors", menu->items[i].name) == 0) + sort->field = SORT_BY_VISITORS; + else if (strcmp ("Data", menu->items[i].name) == 0) + sort->field = SORT_BY_DATA; + else if (strcmp ("Tx. Amount", menu->items[i].name) == 0) + sort->field = SORT_BY_BW; + else if (strcmp ("Avg. T.S.", menu->items[i].name) == 0) + sort->field = SORT_BY_AVGTS; + else if (strcmp ("Cum. T.S.", menu->items[i].name) == 0) + sort->field = SORT_BY_CUMTS; + else if (strcmp ("Max. T.S.", menu->items[i].name) == 0) + sort->field = SORT_BY_MAXTS; + else if (strcmp ("Protocol", menu->items[i].name) == 0) + sort->field = SORT_BY_PROT; + else if (strcmp ("Method", menu->items[i].name) == 0) + sort->field = SORT_BY_MTHD; + quit = 0; + break; + } + break; + case KEY_RESIZE: + case 'q': + quit = 0; + break; + } + wrefresh (win); + } + + /* clean stuff up */ + for (i = 0; i < n; ++i) + free (menu->items[i].name); + free (menu->items); + free (menu); + + touchwin (main_win); + close_win (win); + wrefresh (main_win); +} + +/* Help menu data (F1/h). */ +static const char *help_main[] = { + "Copyright (C) 2009-2017 by Gerardo Orellana", + "http://goaccess.io - ", + "Released under the MIT License.", + "", + "See `man` page for more details", + "", + "GoAccess is an open source real-time web log analyzer and", + "interactive viewer that runs in a terminal in *nix systems.", + "It provides fast and valuable HTTP statistics for system", + "administrators that require a visual server report on the", + "fly.", + "", + "The data collected based on the parsing of the log is", + "divided into different modules. Modules are automatically", + "generated and presented to the user.", + "", + "The main dashboard displays general statistics, top", + "visitors, requests, browsers, operating systems,", + "hosts, etc.", + "", + "The user can make use of the following keys:", + " ^F1^ or ^h^ Main help", + " ^F5^ Redraw [main window]", + " ^q^ Quit the program, current window or module", + " ^o^ or ^ENTER^ Expand selected module", + " ^[Shift]0-9^ Set selected module to active", + " ^Up^ arrow Scroll up main dashboard", + " ^Down^ arrow Scroll down main dashboard", + " ^j^ Scroll down within expanded module", + " ^k^ Scroll up within expanded module", + " ^c^ Set or change scheme color", + " ^CTRL^ + ^f^ Scroll forward one screen within", + " active module", + " ^CTRL^ + ^b^ Scroll backward one screen within", + " active module", + " ^TAB^ Iterate modules (forward)", + " ^SHIFT^ + ^TAB^ Iterate modules (backward)", + " ^s^ Sort options for current module", + " ^/^ Search across all modules", + " ^n^ Find position of the next occurrence", + " ^g^ Move to the first item or top of screen", + " ^G^ Move to the last item or bottom of screen", + "", + "Examples can be found by running `man goaccess`.", + "", + "If you believe you have found a bug, please drop me", + "an email with details.", + "", + "Feedback? Just shoot me an email to:", + "hello@goaccess.io", +}; + +/* Render the help dialog. */ +void +load_help_popup (WINDOW * main_win) +{ + int c, quit = 1; + size_t i, n; + int y, x, h = HELP_WIN_HEIGHT, w = HELP_WIN_WIDTH; + int w2 = w - 2; + WINDOW *win; + GMenu *menu; + + n = ARRAY_SIZE (help_main); + getmaxyx (stdscr, y, x); + + win = newwin (h, w, (y - h) / 2, (x - w) / 2); + keypad (win, TRUE); + wborder (win, '|', '|', '-', '-', '+', '+', '+', '+'); + + /* create a new instance of GMenu and make it selectable */ + menu = + new_gmenu (win, HELP_MENU_HEIGHT, HELP_MENU_WIDTH, HELP_MENU_Y, + HELP_MENU_X); + menu->size = n; + + /* add items to GMenu */ + menu->items = (GItem *) xcalloc (n, sizeof (GItem)); + for (i = 0; i < n; ++i) { + menu->items[i].name = alloc_string (help_main[i]); + menu->items[i].checked = 0; + } + post_gmenu (menu); + + draw_header (win, HELPDLG_HEAD, " %s", 1, 1, w2, color_panel_header); + mvwprintw (win, 2, 2, HELPDLG_DESC); + + wrefresh (win); + while (quit) { + c = wgetch (stdscr); + switch (c) { + case KEY_DOWN: + gmenu_driver (menu, REQ_DOWN); + break; + case KEY_UP: + gmenu_driver (menu, REQ_UP); + break; + case KEY_RESIZE: + case 'q': + quit = 0; + break; + } + wrefresh (win); + } + /* clean stuff up */ + for (i = 0; i < n; ++i) + free (menu->items[i].name); + free (menu->items); + free (menu); + + touchwin (main_win); + close_win (win); + wrefresh (main_win); +} diff --git a/goaccess++/src/ui.h b/goaccess++/src/ui.h new file mode 100644 index 0000000..aea69b6 --- /dev/null +++ b/goaccess++/src/ui.h @@ -0,0 +1,257 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef UI_H_INCLUDED +#define UI_H_INCLUDED + +#ifdef HAVE_NCURSESW_NCURSES_H +#include +#elif HAVE_NCURSES_NCURSES_H +#include +#elif HAVE_NCURSES_H +#include +#elif HAVE_CURSES_H +#include +#endif + +#ifdef HAVE_LIBPTHREAD +#include +#endif + +/* string literals and translations */ +#include "labels.h" + +/* Global UI defaults */ +#define MIN_HEIGHT 8 /* minimum window height */ +#define MIN_WIDTH 0 /* minimum window width */ +#define MAX_HEIGHT_FOOTER 1 /* height of the footer window */ +#define MAX_HEIGHT_HEADER 7 /* height of the header window */ +#define OVERALL_NUM_COLS 4 /* number of columns on the overall stats win */ + +/* Spinner Label Format */ +#define SPIN_FMT "%s" +#define SPIN_FMTM "%s [%'d] [%'lld/s]" +#define SPIN_LBL 50 /* max length of the progress spinner */ + +/* Module JSON keys */ +#define VISITORS_ID "visitors" +#define REQUESTS_ID "requests" +#define REQUESTS_STATIC_ID "static_requests" +#define VISIT_TIMES_ID "visit_time" +#define VIRTUAL_HOSTS_ID "vhosts" +#define REMOTE_USER_ID "remote_user" +#define NOT_FOUND_ID "not_found" +#define HOSTS_ID "hosts" +#define OS_ID "os" +#define BROWSERS_ID "browsers" +#define REFERRERS_ID "referrers" +#define REFERRING_SITES_ID "referring_sites" +#define KEYPHRASES_ID "keyphrases" +#define GEO_LOCATION_ID "geolocation" +#define STATUS_CODES_ID "status_codes" +#define GENER_ID "general" + +/* Overall Statistics CSV/JSON Keys */ +#define OVERALL_STARTDATE "start_date" +#define OVERALL_ENDDATE "end_date" +#define OVERALL_DATETIME "date_time" +#define OVERALL_REQ "total_requests" +#define OVERALL_VALID "valid_requests" +#define OVERALL_GENTIME "generation_time" +#define OVERALL_FAILED "failed_requests" +#define OVERALL_VISITORS "unique_visitors" +#define OVERALL_FILES "unique_files" +#define OVERALL_EXCL_HITS "excluded_hits" +#define OVERALL_REF "unique_referrers" +#define OVERALL_NOTFOUND "unique_not_found" +#define OVERALL_STATIC "unique_static_files" +#define OVERALL_LOGSIZE "log_size" +#define OVERALL_BANDWIDTH "bandwidth" +#define OVERALL_LOG "log_path" + +/* CONFIG DIALOG */ +#define CONF_MENU_H 6 +#define CONF_MENU_W 57 +#define CONF_MENU_X 2 +#define CONF_MENU_Y 4 +#define CONF_WIN_H 20 +#define CONF_WIN_W 61 + +/* FIND DIALOG */ +#define FIND_DLG_HEIGHT 8 +#define FIND_DLG_WIDTH 50 +#define FIND_MAX_MATCHES 1 + +/* COLOR SCHEME DIALOG */ +#define SCHEME_MENU_H 4 +#define SCHEME_MENU_W 38 +#define SCHEME_MENU_X 2 +#define SCHEME_MENU_Y 4 +#define SCHEME_WIN_H 10 +#define SCHEME_WIN_W 42 + +/* SORT DIALOG */ +#define SORT_MENU_H 6 +#define SORT_MENU_W 38 +#define SORT_MENU_X 2 +#define SORT_MENU_Y 4 +#define SORT_WIN_H 13 +#define SORT_WIN_W 42 + +/* AGENTS DIALOG */ +#define AGENTS_MENU_X 2 +#define AGENTS_MENU_Y 4 + +/* HELP DIALOG */ +#define HELP_MENU_HEIGHT 12 +#define HELP_MENU_WIDTH 60 +#define HELP_MENU_X 2 +#define HELP_MENU_Y 4 +#define HELP_WIN_HEIGHT 17 +#define HELP_WIN_WIDTH 64 + +/* CONF ERROR DIALOG */ +#define ERR_MENU_HEIGHT 10 +#define ERR_MENU_WIDTH 57 +#define ERR_MENU_X 2 +#define ERR_MENU_Y 4 +#define ERR_WIN_HEIGHT 15 +#define ERR_WIN_WIDTH 61 + +/* Convenient macros */ +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#include "color.h" +#include "commons.h" +#include "sort.h" + +/* Curses dashboard find */ +typedef struct GFind_ +{ + GModule module; + char *pattern; + int next_idx; + int next_parent_idx; + int next_sub_idx; + int look_in_sub; + int done; + int icase; +} GFind; + +/* Each panel contains its own scrolling and offset */ +typedef struct GScrollModule_ +{ + int scroll; + int offset; +} GScrollModule; + +/* Curses Scrolling */ +typedef struct GScroll_ +{ + GScrollModule module[TOTAL_MODULES]; + GModule current; + int dash; + int expanded; +} GScroll; + +/* Spinner or Progress Indicator */ +typedef struct GSpinner_ +{ + const char *label; + GColors *(*color) (void); + int curses; + int spin_x; + int w; + int x; + int y; + pthread_mutex_t mutex; + pthread_t thread; + unsigned int *processed; + WINDOW *win; + enum + { + SPN_RUN, + SPN_END + } state; +} GSpinner; + +/* Controls metric output. + * i.e., which metrics it should display */ +typedef struct GOutput_ +{ + GModule module; + int8_t visitors; + int8_t hits; + int8_t percent; + int8_t bw; + int8_t avgts; + int8_t cumts; + int8_t maxts; + int8_t protocol; + int8_t method; + int8_t data; + int8_t graph; /* display bars when collapsed */ + int8_t sub_graph; /* display bars upon expanding it */ +} GOutput; + +/* *INDENT-OFF* */ +GOutput *output_lookup (GModule module); +GSpinner *new_gspinner (void); + +char *get_browser_type (char *line); +char *get_overall_header (GHolder *h); +char *input_string (WINDOW * win, int pos_y, int pos_x, size_t max_width, const char *str, int enable_case, int *toggle_case); +const char *module_to_desc (GModule module); +const char *module_to_head (GModule module); +const char *module_to_id (GModule module); +const char *module_to_label (GModule module); +int get_start_end_parsing_dates (GHolder * h, char **start, char **end, const char *f); +int render_confdlg (GLog * glog, GSpinner * spinner); +int set_host_agents (const char *addr, void (*func) (void *, void *, int), void *arr); +void close_win (WINDOW * w); +void display_general (WINDOW * win, GLog * glog, GHolder *h); +void draw_header (WINDOW * win, const char *s, const char *fmt, int y, int x, int w, GColors * (*func) (void)); +void end_spinner (void); +void generate_time (void); +void init_colors (int force); +void init_windows (WINDOW ** header_win, WINDOW ** main_win); +void load_agent_list (WINDOW * main_win, char *addr); +void load_help_popup (WINDOW * main_win); +void load_schemes_win (WINDOW * main_win); +void load_sort_win (WINDOW * main_win, GModule module, GSort * sort); +void set_curses_spinner (GSpinner *spinner); +void set_input_opts (void); +void set_wbkgd (WINDOW *main_win, WINDOW *header_win); +void term_size (WINDOW * main_win, int *main_win_height); +void ui_spinner_create (GSpinner * spinner); +void update_active_module (WINDOW * header_win, GModule current); +void update_header (WINDOW * header_win, int current); +/* *INDENT-ON* */ + +#endif diff --git a/goaccess++/src/ui.o b/goaccess++/src/ui.o new file mode 100644 index 0000000..007bcc3 Binary files /dev/null and b/goaccess++/src/ui.o differ diff --git a/goaccess++/src/util.c b/goaccess++/src/util.c new file mode 100644 index 0000000..a3926a7 --- /dev/null +++ b/goaccess++/src/util.c @@ -0,0 +1,1006 @@ +/** + * util.c -- a set of handy functions to help parsing + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE +#define _FILE_OFFSET_BITS 64 + +#define _XOPEN_SOURCE 700 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "util.h" + +#include "error.h" +#include "labels.h" +#include "xmalloc.h" + +/* HTTP status codes categories */ +static const char *code_type[][2] = { + {"1", STATUS_CODE_1XX}, + {"2", STATUS_CODE_2XX}, + {"3", STATUS_CODE_3XX}, + {"4", STATUS_CODE_4XX}, + {"5", STATUS_CODE_5XX}, +}; + +/* HTTP status codes */ +static const char *codes[][2] = { + {"100", STATUS_CODE_100}, + {"101", STATUS_CODE_101}, + {"200", STATUS_CODE_200}, + {"201", STATUS_CODE_201}, + {"202", STATUS_CODE_202}, + {"203", STATUS_CODE_203}, + {"204", STATUS_CODE_204}, + {"205", STATUS_CODE_205}, + {"206", STATUS_CODE_206}, + {"207", STATUS_CODE_207}, + {"208", STATUS_CODE_208}, + {"300", STATUS_CODE_300}, + {"301", STATUS_CODE_301}, + {"302", STATUS_CODE_302}, + {"303", STATUS_CODE_303}, + {"304", STATUS_CODE_304}, + {"305", STATUS_CODE_305}, + {"307", STATUS_CODE_307}, + {"400", STATUS_CODE_400}, + {"401", STATUS_CODE_401}, + {"402", STATUS_CODE_402}, + {"403", STATUS_CODE_403}, + {"404", STATUS_CODE_404}, + {"405", STATUS_CODE_405}, + {"406", STATUS_CODE_406}, + {"407", STATUS_CODE_407}, + {"408", STATUS_CODE_408}, + {"409", STATUS_CODE_409}, + {"410", STATUS_CODE_410}, + {"411", STATUS_CODE_411}, + {"412", STATUS_CODE_412}, + {"413", STATUS_CODE_413}, + {"414", STATUS_CODE_414}, + {"415", STATUS_CODE_415}, + {"416", STATUS_CODE_416}, + {"417", STATUS_CODE_417}, + {"421", STATUS_CODE_421}, + {"422", STATUS_CODE_422}, + {"423", STATUS_CODE_423}, + {"424", STATUS_CODE_424}, + {"426", STATUS_CODE_426}, + {"428", STATUS_CODE_428}, + {"429", STATUS_CODE_429}, + {"431", STATUS_CODE_431}, + {"444", STATUS_CODE_444}, + {"451", STATUS_CODE_451}, + {"494", STATUS_CODE_494}, + {"495", STATUS_CODE_495}, + {"496", STATUS_CODE_496}, + {"497", STATUS_CODE_497}, + {"499", STATUS_CODE_499}, + {"500", STATUS_CODE_500}, + {"501", STATUS_CODE_501}, + {"502", STATUS_CODE_502}, + {"503", STATUS_CODE_503}, + {"504", STATUS_CODE_504}, + {"505", STATUS_CODE_505}, + {"520", STATUS_CODE_520}, + {"521", STATUS_CODE_521}, + {"522", STATUS_CODE_522}, + {"523", STATUS_CODE_523}, + {"524", STATUS_CODE_524} +}; + +/* Return part of a string + * + * On error NULL is returned. + * On success the extracted part of string is returned */ +char * +substring (const char *str, int begin, int len) +{ + char *buffer; + if (str == NULL) + return NULL; + if (begin < 0) + begin = strlen (str) + begin; + if (begin < 0) + begin = 0; + if (len < 0) + len = 0; + if (((size_t) begin) > strlen (str)) + begin = strlen (str); + if (((size_t) len) > strlen (&str[begin])) + len = strlen (&str[begin]); + if ((buffer = xmalloc (len + 1)) == NULL) + return NULL; + memcpy (buffer, &(str[begin]), len); + buffer[len] = '\0'; + + return buffer; +} + +/* A pointer to the allocated memory of the new string + * + * On success, a pointer to a new string is returned */ +char * +alloc_string (const char *str) +{ + char *new = xmalloc (strlen (str) + 1); + strcpy (new, str); + return new; +} + +/* A wrapper function to copy the first num characters of source to + * destination. */ +void +xstrncpy (char *dest, const char *source, const size_t dest_size) +{ + strncpy (dest, source, dest_size); + if (dest_size > 0) { + dest[dest_size - 1] = '\0'; + } else { + dest[0] = '\0'; + } +} + +/* A random string generator. */ +void +genstr (char *dest, size_t len) +{ + char set[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + while (len-- > 0) + *dest++ = set[rand () % (sizeof (set) - 1)]; + *dest = '\0'; +} + +/* Count the number of matches on the string `s1` given a character `c` + * + * If the character is not found, 0 is returned + * On success, the number of characters found */ +int +count_matches (const char *s1, char c) +{ + const char *ptr = s1; + int n = 0; + do { + if (*ptr == c) + n++; + } while (*(ptr++)); + return n; +} + +/* String matching where one string contains wildcard characters. + * + * If no match found, 1 is returned. + * If match found, 0 is returned. */ +static int +wc_match (const char *wc, char *str) +{ + while (*wc && *str) { + if (*wc == '*') { + while (*wc && *wc == '*') + wc++; + if (!*wc) + return 1; + + while (*str && *str != *wc) + str++; + } else if (*wc == '?' || *wc == *str) { + wc++; + str++; + } else { + break; + } + } + if (!*wc && !*str) + return 1; + return 0; +} + +/* Determine if the given host needs to be ignored given the list of + * referrers to ignore. + * + * On error, or the referrer is not found, 0 is returned + * On success, or if the host needs to be ignored, 1 is returned */ +int +ignore_referer (const char *host) +{ + char *needle = NULL; + int i, ignore = 0; + + if (conf.ignore_referer_idx == 0) + return 0; + if (host == NULL || *host == '\0') + return 0; + + needle = xstrdup (host); + for (i = 0; i < conf.ignore_referer_idx; ++i) { + if (conf.ignore_referers[i] == NULL || *conf.ignore_referers[i] == '\0') + continue; + + if (wc_match (conf.ignore_referers[i], needle)) { + ignore = 1; + goto out; + } + } +out: + free (needle); + + return ignore; +} + +/* Determine if the given host needs to be hidden given the list of + * referrers to hide. + * + * On error, or the referrer is not found, 0 is returned + * On success, or if the host needs to be ignored, 1 is returned */ +int +hide_referer (const char *host) +{ + char *needle = NULL; + int i, ignore = 0; + + if (conf.hide_referer_idx == 0) + return 0; + if (host == NULL || *host == '\0') + return 0; + + needle = xstrdup (host); + for (i = 0; i < conf.hide_referer_idx; ++i) { + if (conf.hide_referers[i] == NULL || *conf.hide_referers[i] == '\0') + continue; + + if (wc_match (conf.hide_referers[i], needle)) { + ignore = 1; + goto out; + } + } +out: + free (needle); + + return ignore; +} + +/* Determine if the given ip is within a range of IPs. + * + * On error, or not within the range, 0 is returned + * On success, or if within the range, 1 is returned */ +static int +within_range (const char *ip, const char *start, const char *end) +{ + struct in6_addr addr6, start6, end6; + struct in_addr addr4, start4, end4; + + if (start == NULL || *start == '\0') + return 0; + if (end == NULL || *end == '\0') + return 0; + if (ip == NULL || *ip == '\0') + return 0; + + /* IPv4 */ + if (1 == inet_pton (AF_INET, ip, &addr4)) { + if (1 != inet_pton (AF_INET, start, &start4)) + return 0; + if (1 != inet_pton (AF_INET, end, &end4)) + return 0; + if (memcmp (&addr4, &start4, sizeof (addr4)) >= 0 && + memcmp (&addr4, &end4, sizeof (addr4)) <= 0) + return 1; + } + /* IPv6 */ + else if (1 == inet_pton (AF_INET6, ip, &addr6)) { + if (1 != inet_pton (AF_INET6, start, &start6)) + return 0; + if (1 != inet_pton (AF_INET6, end, &end6)) + return 0; + if (memcmp (&addr6, &start6, sizeof (addr6)) >= 0 && + memcmp (&addr6, &end6, sizeof (addr6)) <= 0) + return 1; + } + + return 0; +} + +/* Determine if the given IP needs to be ignored given the list of IPs + * to ignore. + * + * On error, or not within the range, 0 is returned + * On success, or if within the range, 1 is returned */ +int +ip_in_range (const char *ip) +{ + char *start = NULL, *end, *dash; + int i; + + for (i = 0; i < conf.ignore_ip_idx; ++i) { + end = NULL; + if (conf.ignore_ips[i] == NULL || *conf.ignore_ips[i] == '\0') + continue; + + start = xstrdup (conf.ignore_ips[i]); + /* split range */ + if ((dash = strchr (start, '-')) != NULL) { + *dash = '\0'; + end = dash + 1; + } + + /* matches single IP */ + if (end == NULL && start) { + if (strcmp (ip, start) == 0) { + free (start); + return 1; + } + } + /* within range */ + else if (start && end) { + if (within_range (ip, start, end)) { + free (start); + return 1; + } + } + free (start); + } + + return 0; +} + +/* Searches the array of output formats for the given extension value. + * + * If not found, 1 is returned. + * On success, the given filename is malloc'd and assigned and 0 is + * returned. */ +int +find_output_type (char **filename, const char *ext, int alloc) +{ + int i; + const char *dot = NULL; + + for (i = 0; i < conf.output_format_idx; ++i) { + /* for backwards compatibility. i.e., -o json */ + if (strcmp (conf.output_formats[i], ext) == 0) + return 0; + + if ((dot = strrchr (conf.output_formats[i], '.')) != NULL && + strcmp (dot + 1, ext) == 0) { + if (alloc) + *filename = xstrdup (conf.output_formats[i]); + return 0; + } + } + + return 1; +} + +/* Validates the '-o' filename extension for any of: + * 1) .csv + * 2) .json + * 3) .html + * + * Return Value + * 1: valid + * 0: invalid + * -1: non-existent extension + */ +int +valid_output_type (const char *filename) +{ + const char *ext = NULL; + size_t sl; + + if ((ext = strrchr (filename, '.')) == NULL) + return -1; + + ext++; + /* Is extension 3<=len<=4? */ + sl = strlen (ext); + if (sl < 3 || sl > 4) + return 0; + + if (strcmp ("html", ext) == 0) + return 1; + + if (strcmp ("json", ext) == 0) + return 1; + + if (strcmp ("csv", ext) == 0) + return 1; + + return 0; +} + +/* Search the environment HOME variable and append GoAccess' config + * file. + * + * On error, it outputs an error message and the program terminates. + * On success, the path of HOME and the config file is returned. */ +char * +get_home (void) +{ + char *user_home = NULL, *path = NULL; + + user_home = getenv ("HOME"); + if (user_home == NULL) + FATAL ("Unable to determine the HOME environment variable."); + + path = xmalloc (snprintf (NULL, 0, "%s/.goaccessrc", user_home) + 1); + sprintf (path, "%s/.goaccessrc", user_home); + + return path; +} + +/* Get the path to the global config file. + * + * On success, the path of the global config file is returned. */ +char * +get_global_config (void) +{ + char *path = NULL; + + path = xmalloc (snprintf (NULL, 0, "%s/goaccess.conf", SYSCONFDIR) + 1); + sprintf (path, "%s/goaccess.conf", SYSCONFDIR); + + return path; +} + +/* A self-checking wrapper to convert_date(). + * + * On error, a newly malloc'd '---' string is returned. + * On success, a malloc'd 'Ymd' date is returned. */ +char * +get_visitors_date (const char *odate, const char *from, const char *to) +{ + char date[DATE_TIME] = ""; /* Ymd */ + + memset (date, 0, sizeof *date); + /* verify we have a valid date conversion */ + if (convert_date (date, odate, from, to, DATE_TIME) == 0) + return xstrdup (date); + + LOG_DEBUG (("invalid date: %s", odate)); + return xstrdup ("---"); +} + +/* Format the given date/time according the given format. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +int +str_to_time (const char *str, const char *fmt, struct tm *tm) +{ + char *end = NULL, *sEnd = NULL; + unsigned long long usecs = 0; + + if (str == NULL || *str == '\0' || fmt == NULL || *fmt == '\0') + return 1; + + /* check if char string needs to be converted from microseconds */ + if (strcmp ("%f", fmt) == 0) { + errno = 0; + tm->tm_year = 1970 - 1900; + tm->tm_mday = 1; + + usecs = strtoull (str, &sEnd, 10); + if (str == sEnd || *sEnd != '\0' || errno == ERANGE) + return 1; + + tm->tm_sec = usecs / SECS; + tm->tm_isdst = -1; + if (mktime (tm) == -1) + return 1; + + return 0; + } + + end = strptime (str, fmt, tm); + if (end == NULL || *end != '\0') + return 1; + + return 0; +} + +/* Convert a date from one format to another and store inot the given buffer. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +int +convert_date (char *res, const char *data, const char *from, const char *to, + int size) +{ + struct tm tm; + + memset (&tm, 0, sizeof (tm)); + timestamp = time (NULL); + now_tm = localtime (×tamp); + + if (str_to_time (data, from, &tm) != 0) + return 1; + + /* if not a timestamp, use current year if not passed */ + if (!has_timestamp (from) && strpbrk (from, "Yy") == NULL) + tm.tm_year = now_tm->tm_year; + + if (strftime (res, size, to, &tm) <= 0) + return 1; + + return 0; +} + +#pragma GCC diagnostic warning "-Wformat-nonliteral" + +/* Determine if the given IP is a valid IPv4/IPv6 address. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +int +invalid_ipaddr (char *str, int *ipvx) +{ + union + { + struct sockaddr addr; + struct sockaddr_in6 addr6; + struct sockaddr_in addr4; + } a; + + (*ipvx) = TYPE_IPINV; + if (str == NULL || *str == '\0') + return 1; + + memset (&a, 0, sizeof (a)); + if (1 == inet_pton (AF_INET, str, &a.addr4.sin_addr)) { + (*ipvx) = TYPE_IPV4; + return 0; + } else if (1 == inet_pton (AF_INET6, str, &a.addr6.sin6_addr)) { + (*ipvx) = TYPE_IPV6; + return 0; + } + + return 1; +} + +/* Get information about the filename. + * + * On error, -1 is returned. + * On success, the file size of the given filename. */ +off_t +file_size (const char *filename) +{ + struct stat st; + + if (stat (filename, &st) == 0) + return st.st_size; + + LOG_DEBUG (("Can't determine size of %s: %s\n", filename, strerror (errno))); + + return -1; +} + +/* Determine if the given status code is within the list of status + * codes and find out the status type/category. + * + * If not found, "Unknown" is returned. + * On success, the status code type/category is returned. */ +const char * +verify_status_code_type (const char *str) +{ + size_t i; + for (i = 0; i < ARRAY_SIZE (code_type); i++) + if (strchr (code_type[i][0], str[0]) != NULL) + return _(code_type[i][1]); + + return "Unknown"; +} + +/* Determine if the given status code is within the list of status + * codes. + * + * If not found, "Unknown" is returned. + * On success, the status code is returned. */ +const char * +verify_status_code (char *str) +{ + size_t i; + for (i = 0; i < ARRAY_SIZE (codes); i++) + if (strstr (str, codes[i][0]) != NULL) + return _(codes[i][1]); + + return "Unknown"; +} + +/* Checks if the given string is within the given array. + * + * If not found, -1 is returned. + * If found, the key for needle in the array is returned. */ +int +str_inarray (const char *s, const char *arr[], int size) +{ + int i; + for (i = 0; i < size; i++) { + if (strcmp (arr[i], s) == 0) + return i; + } + return -1; +} + +/* Strip whitespace from the beginning of a string. + * + * On success, a string with whitespace stripped from the beginning of + * the string is returned. */ +char * +ltrim (char *s) +{ + char *begin = s; + + while (isspace (*begin)) + ++begin; + memmove (s, begin, strlen (begin) + 1); + + return s; +} + +/* Strip whitespace from the end of a string. + * + * On success, a string with whitespace stripped from the end of the + * string is returned. */ +char * +rtrim (char *s) +{ + char *end = s + strlen (s); + + while ((end != s) && isspace (*(end - 1))) + --end; + *end = '\0'; + + return s; +} + +/* Strip whitespace from the beginning and end of the string. + * + * On success, the trimmed string is returned. */ +char * +trim_str (char *str) +{ + return rtrim (ltrim (str)); +} + +/* Convert the file size in bytes to a human readable format. + * + * On error, the original size of the string in bytes is returned. + * On success, the file size in a human readable format is returned. */ +char * +filesize_str (unsigned long long log_size) +{ + char *size = xmalloc (sizeof (char) * 12); + if (log_size >= (1ULL << 50)) + snprintf (size, 12, "%.2f PiB", (double) (log_size) / PIB (1ULL)); + else if (log_size >= (1ULL << 40)) + snprintf (size, 12, "%.2f TiB", (double) (log_size) / TIB (1ULL)); + else if (log_size >= (1ULL << 30)) + snprintf (size, 12, "%.2f GiB", (double) (log_size) / GIB (1ULL)); + else if (log_size >= (1ULL << 20)) + snprintf (size, 12, "%.2f MiB", (double) (log_size) / MIB (1ULL)); + else if (log_size >= (1ULL << 10)) + snprintf (size, 12, "%.2f KiB", (double) (log_size) / KIB (1ULL)); + else + snprintf (size, 12, "%.1f B", (double) (log_size)); + + return size; +} + +/* Convert microseconds to a human readable format. + * + * On error, a malloc'd string in microseconds is returned. + * On success, the time in a human readable format is returned. */ +char * +usecs_to_str (unsigned long long usec) +{ + char *size = xmalloc (sizeof (char) * 11); + if (usec >= DAY) + snprintf (size, 11, "%.2f d", (double) (usec) / DAY); + else if (usec >= HOUR) + snprintf (size, 11, "%.2f hr", (double) (usec) / HOUR); + else if (usec >= MINS) + snprintf (size, 11, "%.2f mn", (double) (usec) / MINS); + else if (usec >= SECS) + snprintf (size, 11, "%.2f s", (double) (usec) / SECS); + else if (usec >= MILS) + snprintf (size, 11, "%.2f ms", (double) (usec) / MILS); + else + snprintf (size, 11, "%.2f us", (double) (usec)); + + return size; +} + +/* Convert the given int to a string with the ability to add some + * padding. + * + * On success, the given number as a string is returned. */ +char * +int2str (int d, int width) +{ + char *s = xmalloc (snprintf (NULL, 0, "%*d", width, d) + 1); + sprintf (s, "%*d", width, d); + + return s; +} + +/* Convert the given float to a string with the ability to add some + * padding. + * + * On success, the given number as a string is returned. */ +char * +float2str (float d, int width) +{ + char *s = xmalloc (snprintf (NULL, 0, "%*.2f", width, d) + 1); + sprintf (s, "%*.2f", width, d); + + return s; +} + +/* Determine the length of an integer (number of digits). + * + * On success, the length of the number is returned. */ +int +intlen (int num) +{ + int l = 1; + while (num > 9) { + l++; + num /= 10; + } + + return l; +} + +/* Allocate a new string and fill it with the given character. + * + * On success, the newly allocated string is returned. */ +char * +char_repeat (int n, char c) +{ + char *dest = xmalloc (n + 1); + memset (dest, c, n); + dest[n] = '\0'; + + return dest; +} + +/* Replace all occurrences of the given char with the replacement + * char. + * + * On error the original string is returned. + * On success, a string with the replaced values is returned. */ +char * +char_replace (char *str, char o, char n) +{ + char *p = str; + + if (str == NULL || *str == '\0') + return str; + + while ((p = strchr (p, o)) != NULL) + *p++ = n; + + return str; +} + +/* Remove all occurrences of a new line. + * + * On success, a string with the replaced new lines is returned. */ +void +strip_newlines (char *str) +{ + char *src, *dst; + for (src = dst = str; *src != '\0'; src++) { + *dst = *src; + if (*dst != '\r' && *dst != '\n') + dst++; + } + *dst = '\0'; +} + +/* Strip blanks from a string. + * + * On success, a string without whitespace is returned. */ +char * +deblank (char *str) +{ + char *out = str, *put = str; + + for (; *str != '\0'; ++str) { + if (*str != ' ') + *put++ = *str; + } + *put = '\0'; + + return out; +} + +/* Make a string uppercase. + * + * On error the original string is returned. + * On success, the uppercased string is returned. */ +char * +strtoupper (char *str) +{ + char *p = str; + if (str == NULL || *str == '\0') + return str; + + while (*p != '\0') { + *p = toupper (*p); + p++; + } + + return str; +} + +/* Left-pad a string with n amount of spaces. + * + * On success, a left-padded string is returned. */ +char * +left_pad_str (const char *s, int indent) +{ + char *buf = NULL; + + indent = strlen (s) + indent; + buf = xmalloc (snprintf (NULL, 0, "%*s", indent, s) + 1); + sprintf (buf, "%*s", indent, s); + + return buf; +} + +/* Append the source string to destination and reallocates and + * updating the destination buffer appropriately. */ +void +append_str (char **dest, const char *src) +{ + size_t curlen = strlen (*dest); + size_t srclen = strlen (src); + size_t newlen = curlen + srclen; + + char *str = xrealloc (*dest, newlen + 1); + memcpy (str + curlen, src, srclen + 1); + *dest = str; +} + +/* Escapes the special characters, e.g., '\n', '\r', '\t', '\' + * in the string source by inserting a '\' before them. + * + * On error NULL is returned. + * On success the escaped string is returned */ +char * +escape_str (const char *src) +{ + char *dest, *q; + const unsigned char *p; + + if (src == NULL || *src == '\0') + return NULL; + + p = (unsigned char *) src; + q = dest = xmalloc (strlen (src) * 4 + 1); + + while (*p) { + switch (*p) { + case '\\': + *q++ = '\\'; + *q++ = '\\'; + break; + case '\n': + *q++ = '\\'; + *q++ = 'n'; + break; + case '\r': + *q++ = '\\'; + *q++ = 'r'; + break; + case '\t': + *q++ = '\\'; + *q++ = 't'; + break; + default: + /* not ASCII */ + if ((*p < ' ') || (*p >= 0177)) { + *q++ = '\\'; + *q++ = '0' + (((*p) >> 6) & 07); + *q++ = '0' + (((*p) >> 3) & 07); + *q++ = '0' + ((*p) & 07); + } else + *q++ = *p; + break; + } + p++; + } + *q = 0; + return dest; +} + +/* Get an unescaped malloc'd string + * + * On error NULL is returned. + * On success the unescaped string is returned */ +char * +unescape_str (const char *src) +{ + char *dest, *q; + const char *p = src; + + if (src == NULL || *src == '\0') + return NULL; + + dest = xmalloc (strlen (src) + 1); + q = dest; + + while (*p) { + if (*p == '\\') { + p++; + switch (*p) { + case '\0': + /* warning... */ + goto out; + case 'n': + *q++ = '\n'; + break; + case 'r': + *q++ = '\r'; + break; + case 't': + *q++ = '\t'; + break; + default: + *q++ = *p; + break; + } + } else + *q++ = *p; + p++; + } +out: + *q = 0; + + return dest; +} diff --git a/goaccess++/src/util.h b/goaccess++/src/util.h new file mode 100644 index 0000000..1b0bfd9 --- /dev/null +++ b/goaccess++/src/util.h @@ -0,0 +1,97 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef UTIL_H_INCLUDED +#define UTIL_H_INCLUDED + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +#define REGEX_ERROR 100 + +#define KIB(n) (n << 10) +#define MIB(n) (n << 20) +#define GIB(n) (n << 30) +#define TIB(n) (n << 40) +#define PIB(n) (n << 50) + +#define MILS 1000ULL +#define SECS 1000000ULL +#define MINS 60000000ULL +#define HOUR 3600000000ULL +#define DAY 86400000000ULL + +/* *INDENT-OFF* */ +#include +#include +#include + +char *alloc_string (const char *str); +char *char_repeat (int n, char c); +char *char_replace (char *str, char o, char n); +char *deblank (char *str); +char *escape_str (const char *src); +char *filesize_str (unsigned long long log_size); +char *float2str (float d, int width); +char *get_global_config (void); +char *get_home (void); +char *get_visitors_date (const char *odate, const char *from, const char *to); +char *int2str (int d, int width); +char *left_pad_str (const char *s, int indent); +char *ltrim (char *s); +char *replace_str (const char *str, const char *old, const char *new); +char *rtrim (char *s); +char *secs_to_str (int secs); +char *strtoupper(char *str); +char *substring (const char *str, int begin, int len); +char *trim_str (char *str); +char *unescape_str (const char *src); +char *usecs_to_str (unsigned long long usec); +const char *verify_status_code (char *str); +const char *verify_status_code_type (const char *str); +int convert_date (char *res, const char *data, const char *from, const char *to, int size); +int count_matches (const char *s1, char c); +int find_output_type (char **filename, const char *ext, int alloc); +int hide_referer (const char *ref); +int ignore_referer (const char *ref); +int intlen (int num); +int invalid_ipaddr (char *str, int *ipvx); +int ip_in_range (const char *ip); +int str_inarray (const char *s, const char *arr[], int size); +int str_to_time (const char *str, const char *fmt, struct tm *tm); +int valid_output_type (const char *filename); +off_t file_size (const char *filename); +uint32_t ip_to_binary (const char *ip); +void append_str (char **dest, const char *src); +void genstr(char *dest, size_t len); +void strip_newlines (char *str); +void xstrncpy (char *dest, const char *source, const size_t dest_size); + +/* *INDENT-ON* */ + +#endif diff --git a/goaccess++/src/util.o b/goaccess++/src/util.o new file mode 100644 index 0000000..5b1a5a3 Binary files /dev/null and b/goaccess++/src/util.o differ diff --git a/goaccess++/src/websocket.c b/goaccess++/src/websocket.c new file mode 100644 index 0000000..6f0d90a --- /dev/null +++ b/goaccess++/src/websocket.c @@ -0,0 +1,3018 @@ +/** + * websocket.c -- An rfc6455-complaint Web Socket Server + * _______ _______ __ __ + * / ____/ | / / ___/____ _____/ /_____ / /_ + * / / __ | | /| / /\__ \/ __ \/ ___/ //_/ _ \/ __/ + * / /_/ / | |/ |/ /___/ / /_/ / /__/ ,< / __/ /_ + * \____/ |__/|__//____/\____/\___/_/|_|\___/\__/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if HAVE_CONFIG_H +#include +#endif + +#include "websocket.h" + +#include "base64.h" +#include "error.h" +#include "gslist.h" +#include "sha1.h" +#include "xmalloc.h" + +/* *INDENT-OFF* */ + +/* UTF-8 Decoder */ +/* Copyright (c) 2008-2009 Bjoern Hoehrmann + * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. */ +#define UTF8_VALID 0 +#define UTF8_INVAL 1 +static const uint8_t utf8d[] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 00..1f */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 20..3f */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40..5f */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 60..7f */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, /* 80..9f */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* a0..bf */ + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, /* c0..df */ + 0xa,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x4,0x3,0x3, /* e0..ef */ + 0xb,0x6,0x6,0x6,0x5,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8, /* f0..ff */ + 0x0,0x1,0x2,0x3,0x5,0x8,0x7,0x1,0x1,0x1,0x4,0x6,0x1,0x1,0x1,0x1, /* s0..s0 */ + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,0,1,1,1,1,1,1, /* s1..s2 */ + 1,2,1,1,1,1,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1, /* s3..s4 */ + 1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,3,1,1,1,1,1,1, /* s5..s6 */ + 1,3,1,1,1,1,1,3,1,3,1,1,1,1,1,1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* s7..s8 */ +}; +/* *INDENT-ON* */ + +static int max_file_fd = 0; +static WSEState fdstate; +static WSConfig wsconfig = { 0 }; + +static void handle_read_close (int conn, WSClient * client, WSServer * server); +static void handle_reads (int conn, WSServer * server); +static void handle_writes (int conn, WSServer * server); +#ifdef HAVE_LIBSSL +static int shutdown_ssl (WSClient * client); +#endif + +/* Determine if the given string is valid UTF-8. + * + * The state after the by has been processed is returned. */ +static uint32_t +verify_utf8 (uint32_t * state, const char *str, int len) +{ + int i; + uint32_t type; + + for (i = 0; i < len; ++i) { + type = utf8d[(uint8_t) str[i]]; + *state = utf8d[256 + (*state) * 16 + type]; + + if (*state == UTF8_INVAL) + break; + } + + return *state; +} + +/* Decode a character maintaining state and a byte, and returns the + * state achieved after processing the byte. + * + * The state after the by has been processed is returned. */ +static uint32_t +utf8_decode (uint32_t * state, uint32_t * p, uint32_t b) +{ + uint32_t type = utf8d[(uint8_t) b]; + + *p = (*state != UTF8_VALID) ? (b & 0x3fu) | (*p << 6) : (0xff >> type) & (b); + *state = utf8d[256 + *state * 16 + type]; + + return *state; +} + +/* Replace malformed sequences with a substitute character. + * + * On success, it replaces the whole sequence and return a malloc'd buffer. */ +static char * +sanitize_utf8 (const char *str, int len) +{ + char *buf = NULL; + uint32_t state = UTF8_VALID, prev = UTF8_VALID, cp = 0; + int i = 0, j = 0, k = 0, l = 0; + + buf = xcalloc (len + 1, sizeof (char)); + for (; i < len; prev = state, ++i) { + switch (utf8_decode (&state, &cp, (unsigned char) str[i])) { + case UTF8_INVAL: + /* replace the whole sequence */ + if (k) { + for (l = i - k; l < i; ++l) + buf[j++] = '?'; + } else { + buf[j++] = '?'; + } + state = UTF8_VALID; + if (prev != UTF8_VALID) + i--; + k = 0; + break; + case UTF8_VALID: + /* fill i - k valid continuation bytes */ + if (k) + for (l = i - k; l < i; ++l) + buf[j++] = str[l]; + buf[j++] = str[i]; + k = 0; + break; + default: + /* UTF8_VALID + continuation bytes */ + k++; + break; + } + } + + return buf; +} + +/* Allocate memory for a websocket server */ +static WSServer * +new_wsserver (void) +{ + WSServer *server = xcalloc (1, sizeof (WSServer)); + + return server; +} + +/* Allocate memory for a websocket client */ +static WSClient * +new_wsclient (void) +{ + WSClient *client = xcalloc (1, sizeof (WSClient)); + client->status = WS_OK; + + return client; +} + +/* Allocate memory for a websocket header */ +static WSHeaders * +new_wsheader (void) +{ + WSHeaders *headers = xcalloc (1, sizeof (WSHeaders)); + memset (headers->buf, 0, sizeof (headers->buf)); + headers->reading = 1; + + return headers; +} + +/* Allocate memory for a websocket frame */ +static WSFrame * +new_wsframe (void) +{ + WSFrame *frame = xcalloc (1, sizeof (WSFrame)); + memset (frame->buf, 0, sizeof (frame->buf)); + frame->reading = 1; + + return frame; +} + +/* Allocate memory for a websocket message */ +static WSMessage * +new_wsmessage (void) +{ + WSMessage *msg = xcalloc (1, sizeof (WSMessage)); + + return msg; +} + +/* Allocate memory for a websocket pipeout */ +static WSPipeOut * +new_wspipeout (void) +{ + WSPipeOut *pipeout = xcalloc (1, sizeof (WSPipeOut)); + pipeout->fd = -1; + + return pipeout; +} + +/* Allocate memory for a websocket pipein */ +static WSPipeIn * +new_wspipein (void) +{ + WSPipeIn *pipein = xcalloc (1, sizeof (WSPipeIn)); + pipein->fd = -1; + + return pipein; +} + +/* Escapes the special characters, e.g., '\n', '\r', '\t', '\' + * in the string source by inserting a '\' before them. + * + * On error NULL is returned. + * On success the escaped string is returned */ +static char * +escape_http_request (const char *src) +{ + char *dest, *q; + const unsigned char *p; + + if (src == NULL || *src == '\0') + return NULL; + + p = (unsigned char *) src; + q = dest = xmalloc (strlen (src) * 4 + 1); + + while (*p) { + switch (*p) { + case '\\': + *q++ = '\\'; + *q++ = '\\'; + break; + case '\n': + *q++ = '\\'; + *q++ = 'n'; + break; + case '\r': + *q++ = '\\'; + *q++ = 'r'; + break; + case '\t': + *q++ = '\\'; + *q++ = 't'; + break; + case '"': + *q++ = '\\'; + *q++ = '"'; + break; + default: + if ((*p < ' ') || (*p >= 0177)) { + /* not ASCII */ + } else { + *q++ = *p; + } + break; + } + p++; + } + *q = 0; + return dest; +} + +/* Make a string uppercase. + * + * On error the original string is returned. + * On success, the uppercased string is returned. */ +static char * +strtoupper (char *str) +{ + char *p = str; + if (str == NULL || *str == '\0') + return str; + + while (*p != '\0') { + *p = toupper (*p); + p++; + } + + return str; +} + +/* Chop n characters from the beginning of the supplied buffer. + * + * The new length of the string is returned. */ +static size_t +chop_nchars (char *str, size_t n, size_t len) +{ + if (n == 0 || str == 0) + return 0; + + if (n > len) + n = len; + memmove (str, str + n, len - n); + + return (len - n); +} + +/* Match a client given a socket id and an item from the list. + * + * On match, 1 is returned, else 0. */ +static int +ws_find_client_sock_in_list (void *data, void *needle) +{ + WSClient *client = data; + + return client->listener == (*(int *) needle); +} + +/* Find a client given a socket id. + * + * On success, an instance of a GSLList node is returned, else NULL. */ +static GSLList * +ws_get_list_node_from_list (int listener, GSLList ** colist) +{ + GSLList *match = NULL; + + /* Find the client data for the socket in use */ + if (!(match = list_find (*colist, ws_find_client_sock_in_list, &listener))) + return NULL; + return match; +} + +/* Find a client given a socket id. + * + * On success, an instance of a WSClient is returned, else NULL. */ +static WSClient * +ws_get_client_from_list (int listener, GSLList ** colist) +{ + GSLList *match = NULL; + + /* Find the client data for the socket in use */ + if (!(match = list_find (*colist, ws_find_client_sock_in_list, &listener))) + return NULL; + return (WSClient *) match->data; +} + +/* Free a frame structure and its data for the given client. */ +static void +ws_free_frame (WSClient * client) +{ + if (client->frame) + free (client->frame); + client->frame = NULL; +} + +/* Free a message structure and its data for the given client. */ +static void +ws_free_message (WSClient * client) +{ + if (client->message && client->message->payload) + free (client->message->payload); + if (client->message) + free (client->message); + client->message = NULL; +} + +/* Free all HTTP handshake headers data for the given client. */ +static void +ws_free_header_fields (WSHeaders * headers) +{ + if (headers->connection) + free (headers->connection); + if (headers->host) + free (headers->host); + if (headers->agent) + free (headers->agent); + if (headers->method) + free (headers->method); + if (headers->origin) + free (headers->origin); + if (headers->path) + free (headers->path); + if (headers->protocol) + free (headers->protocol); + if (headers->upgrade) + free (headers->upgrade); + if (headers->ws_accept) + free (headers->ws_accept); + if (headers->ws_key) + free (headers->ws_key); + if (headers->ws_protocol) + free (headers->ws_protocol); + if (headers->ws_resp) + free (headers->ws_resp); + if (headers->ws_sock_ver) + free (headers->ws_sock_ver); + if (headers->referer) + free (headers->referer); +} + +/* Clear the client's sent queue and its data. */ +static void +ws_clear_queue (WSClient * client) +{ + WSQueue **queue = &client->sockqueue; + if (!(*queue)) + return; + + if ((*queue)->queued) + free ((*queue)->queued); + (*queue)->queued = NULL; + (*queue)->qlen = 0; + + free ((*queue)); + (*queue) = NULL; + + /* done sending the whole queue, stop throttling */ + client->status &= ~WS_THROTTLING; + /* done sending, close connection if set to close */ + if ((client->status & WS_CLOSE) && (client->status & WS_SENDING)) + client->status = WS_CLOSE; +} + +/* Free all HTTP handshake headers and structure. */ +static void +ws_clear_handshake_headers (WSHeaders * headers) +{ + ws_free_header_fields (headers); + free (headers); + headers = NULL; +} + +/* Remove the given client from the list. */ +static void +ws_remove_client_from_list (WSClient * client, WSServer * server) +{ + GSLList *node = NULL; + + if (!(node = ws_get_list_node_from_list (client->listener, &server->colist))) + return; + + if (client->headers) + ws_clear_handshake_headers (client->headers); + list_remove_node (&server->colist, node); +} + +#if HAVE_LIBSSL +/* Attempt to send the TLS/SSL "close notify" shutdown and and removes + * the SSL structure pointed to by ssl and frees up the allocated + * memory. */ +static void +ws_shutdown_dangling_clients (WSClient * client) +{ + shutdown_ssl (client); + SSL_free (client->ssl); + client->ssl = NULL; +} + +/* Attempt to remove the SSL_CTX object pointed to by ctx and frees up + * the allocated memory and cleans some more generally used TLS/SSL + * memory. */ +static void +ws_ssl_cleanup (WSServer * server) +{ + if (!wsconfig.use_ssl) + return; + + if (server->ctx) + SSL_CTX_free (server->ctx); + + CRYPTO_cleanup_all_ex_data (); + CRYPTO_set_id_callback (NULL); + CRYPTO_set_locking_callback (NULL); + ERR_free_strings (); +#if OPENSSL_VERSION_NUMBER < 0x10100000L + ERR_remove_state (0); +#endif + EVP_cleanup (); +} +#endif + +/* Remove all clients that are still hanging out. */ +static int +ws_remove_dangling_clients (void *value, void *user_data) +{ + WSClient *client = value; + (void) (user_data); + + if (client == NULL) + return 1; + + if (client->headers) + ws_clear_handshake_headers (client->headers); + if (client->sockqueue) + ws_clear_queue (client); +#ifdef HAVE_LIBSSL + if (client->ssl) + ws_shutdown_dangling_clients (client); +#endif + + return 0; +} + +/* Do some housekeeping on the named pipe data packet. */ +static void +ws_clear_fifo_packet (WSPacket * packet) +{ + if (!packet) + return; + + if (packet->data) + free (packet->data); + free (packet); +} + +/* Do some housekeeping on the named pipe. */ +static void +ws_clear_pipein (WSPipeIn * pipein) +{ + WSPacket **packet = &pipein->packet; + if (!pipein) + return; + + if (pipein->fd != -1) + close (pipein->fd); + + ws_clear_fifo_packet (*packet); + free (pipein); + + if (wsconfig.pipein && access (wsconfig.pipein, F_OK) != -1) + unlink (wsconfig.pipein); +} + +/* Do some housekeeping on the named pipe. */ +static void +ws_clear_pipeout (WSPipeOut * pipeout) +{ + if (!pipeout) + return; + + if (pipeout->fd != -1) + close (pipeout->fd); + + free (pipeout); + + if (wsconfig.pipeout && access (wsconfig.pipeout, F_OK) != -1) + unlink (wsconfig.pipeout); +} + +/* Stop the server and do some cleaning. */ +void +ws_stop (WSServer * server) +{ + WSPipeIn **pipein = &server->pipein; + WSPipeOut **pipeout = &server->pipeout; + + ws_clear_pipein (*pipein); + ws_clear_pipeout (*pipeout); + + /* close access log (if any) */ + if (wsconfig.accesslog) + access_log_close (); + + /* remove dangling clients */ + if (list_count (server->colist) > 0) + list_foreach (server->colist, ws_remove_dangling_clients, NULL); + + if (server->colist) + list_remove_nodes (server->colist); + +#ifdef HAVE_LIBSSL + ws_ssl_cleanup (server); +#endif + + free (server); +} + +/* A wrapper to close a socket. */ +static void +ws_close (int listener) +{ + close (listener); +} + +/* Set the connection status for the given client and return the given + * bytes. + * + * The given number of bytes are returned. */ +static int +ws_set_status (WSClient * client, WSStatus status, int bytes) +{ + client->status = status; + return bytes; +} + +/* Append the source string to destination and reallocates and + * updating the destination buffer appropriately. */ +static void +ws_append_str (char **dest, const char *src) +{ + size_t curlen = strlen (*dest); + size_t srclen = strlen (src); + size_t newlen = curlen + srclen; + + char *str = xrealloc (*dest, newlen + 1); + memcpy (str + curlen, src, srclen + 1); + *dest = str; +} + +#if HAVE_LIBSSL +/* Create a new SSL_CTX object as framework to establish TLS/SSL + * enabled connections. + * + * On error 1 is returned. + * On success, SSL_CTX object is malloc'd and 0 is returned. + */ +static int +initialize_ssl_ctx (WSServer * server) +{ + int ret = 1; + SSL_CTX *ctx = NULL; + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + SSL_library_init (); + SSL_load_error_strings (); +#endif + + /* Ciphers and message digests */ + OpenSSL_add_ssl_algorithms (); + + /* ssl context */ + if (!(ctx = SSL_CTX_new (SSLv23_server_method ()))) + goto out; + /* set certificate */ + if (!SSL_CTX_use_certificate_file (ctx, wsconfig.sslcert, SSL_FILETYPE_PEM)) + goto out; + /* ssl private key */ + if (!SSL_CTX_use_PrivateKey_file (ctx, wsconfig.sslkey, SSL_FILETYPE_PEM)) + goto out; + if (!SSL_CTX_check_private_key (ctx)) + goto out; + + /* since we queued up the send data, a retry won't be the same buffer, + * thus we need the following flags */ + SSL_CTX_set_mode (ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | + SSL_MODE_ENABLE_PARTIAL_WRITE); + + server->ctx = ctx; + ret = 0; +out: + if (ret) { + SSL_CTX_free (ctx); + LOG (("Error: %s\n", ERR_error_string (ERR_get_error (), NULL))); + } + + return ret; +} + +/* Log result code for TLS/SSL I/O operation */ +static void +log_return_message (int ret, int err, const char *fn) +{ + unsigned long e; + + switch (err) { + case SSL_ERROR_NONE: + LOG (("SSL: %s -> SSL_ERROR_NONE\n", fn)); + LOG (("SSL: TLS/SSL I/O operation completed\n")); + break; + case SSL_ERROR_WANT_READ: + LOG (("SSL: %s -> SSL_ERROR_WANT_READ\n", fn)); + LOG (("SSL: incomplete, data available for reading\n")); + break; + case SSL_ERROR_WANT_WRITE: + LOG (("SSL: %s -> SSL_ERROR_WANT_WRITE\n", fn)); + LOG (("SSL: incomplete, data available for writing\n")); + break; + case SSL_ERROR_ZERO_RETURN: + LOG (("SSL: %s -> SSL_ERROR_ZERO_RETURN\n", fn)); + LOG (("SSL: TLS/SSL connection has been closed\n")); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + LOG (("SSL: %s -> SSL_ERROR_WANT_X509_LOOKUP\n", fn)); + break; + case SSL_ERROR_SYSCALL: + LOG (("SSL: %s -> SSL_ERROR_SYSCALL\n", fn)); + + e = ERR_get_error (); + if (e > 0) + LOG (("SSL: %s -> %s\n", fn, ERR_error_string (e, NULL))); + + /* call was not successful because a fatal error occurred either at the + * protocol level or a connection failure occurred. */ + if (ret != 0) { + LOG (("SSL bogus handshake interrupt: \n", strerror (errno))); + break; + } + /* call not yet finished. */ + LOG (("SSL: handshake interrupted, got EOF\n")); + if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) + LOG (("SSL: %s -> not yet finished %s\n", fn, strerror (errno))); + break; + default: + LOG (("SSL: %s -> failed fatal error code: %d\n", fn, err)); + LOG (("SSL: %s\n", ERR_error_string (ERR_get_error (), NULL))); + break; + } +} + +/* Shut down the client's TLS/SSL connection + * + * On fatal error, 1 is returned. + * If data still needs to be read/written, -1 is returned. + * On success, the TLS/SSL connection is closed and 0 is returned */ +static int +shutdown_ssl (WSClient * client) +{ + int ret = -1, err = 0; + + /* all good */ + if ((ret = SSL_shutdown (client->ssl)) > 0) + return ws_set_status (client, WS_CLOSE, 0); + + err = SSL_get_error (client->ssl, ret); + log_return_message (ret, err, "SSL_shutdown"); + + switch (err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + client->sslstatus = WS_TLS_SHUTTING; + break; + case SSL_ERROR_SYSCALL: + if (ret == 0) { + LOG (("SSL: SSL_shutdown, connection unexpectedly closed by peer.\n")); + /* The shutdown is not yet finished. */ + if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) + client->sslstatus = WS_TLS_SHUTTING; + break; + } + LOG (("SSL: SSL_shutdown, probably unrecoverable, forcing close.\n")); + case SSL_ERROR_ZERO_RETURN: + case SSL_ERROR_WANT_X509_LOOKUP: + default: + return ws_set_status (client, WS_ERR | WS_CLOSE, 1); + } + + return ret; +} + +/* Wait for a TLS/SSL client to initiate a TLS/SSL handshake + * + * On fatal error, the connection is shut down. + * If data still needs to be read/written, -1 is returned. + * On success, the TLS/SSL connection is completed and 0 is returned */ +static int +accept_ssl (WSClient * client) +{ + int ret = -1, err = 0; + + /* all good on TLS handshake */ + if ((ret = SSL_accept (client->ssl)) > 0) { + client->sslstatus &= ~WS_TLS_ACCEPTING; + return 0; + } + + err = SSL_get_error (client->ssl, ret); + log_return_message (ret, err, "SSL_accept"); + + switch (err) { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + client->sslstatus = WS_TLS_ACCEPTING; + break; + case SSL_ERROR_SYSCALL: + /* Wait for more activity else bail out, for instance if the socket is closed + * during the handshake. */ + if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)) { + client->sslstatus = WS_TLS_ACCEPTING; + break; + } + /* The peer notified that it is shutting down through a SSL "close_notify" so + * we shutdown too */ + case SSL_ERROR_ZERO_RETURN: + case SSL_ERROR_WANT_X509_LOOKUP: + default: + client->sslstatus &= ~WS_TLS_ACCEPTING; + return ws_set_status (client, WS_ERR | WS_CLOSE, 1); + } + + return ret; +} + +/* Create a new SSL structure for a connection and perform handshake */ +static void +handle_accept_ssl (WSClient * client, WSServer * server) +{ + /* attempt to create SSL connection if we don't have one yet */ + if (!client->ssl) { + if (!(client->ssl = SSL_new (server->ctx))) { + LOG (("SSL: SSL_new, new SSL structure failed.\n")); + return; + } + if (!SSL_set_fd (client->ssl, client->listener)) { + LOG (("SSL: unable to set file descriptor\n")); + return; + } + } + + /* attempt to initiate the TLS/SSL handshake */ + if (accept_ssl (client) == 0) { + LOG (("SSL Accepted: %d %s\n", client->listener, client->remote_ip)); + } +} + +/* Given the current status of the SSL buffer, perform that action. + * + * On error or if no SSL pending status, 1 is returned. + * On success, the TLS/SSL pending action is called and 0 is returned */ +static int +handle_ssl_pending_rw (int conn, WSServer * server, WSClient * client) +{ + if (!wsconfig.use_ssl) + return 1; + + /* trying to write but still waiting for a successful SSL_accept */ + if (client->sslstatus & WS_TLS_ACCEPTING) { + handle_accept_ssl (client, server); + return 0; + } + /* trying to read but still waiting for a successful SSL_read */ + if (client->sslstatus & WS_TLS_READING) { + handle_reads (conn, server); + return 0; + } + /* trying to write but still waiting for a successful SSL_write */ + if (client->sslstatus & WS_TLS_WRITING) { + handle_writes (conn, server); + return 0; + } + /* trying to write but still waiting for a successful SSL_shutdown */ + if (client->sslstatus & WS_TLS_SHUTTING) { + if (shutdown_ssl (client) == 0) + handle_read_close (conn, client, server); + return 0; + } + + return 1; +} + +/* Write bytes to a TLS/SSL connection for a given client. + * + * On error or if no write is performed <=0 is returned. + * On success, the number of bytes actually written to the TLS/SSL + * connection are returned */ +static int +send_ssl_buffer (WSClient * client, const char *buffer, int len) +{ + int bytes = 0, err = 0; + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + ERR_clear_error (); +#endif + if ((bytes = SSL_write (client->ssl, buffer, len)) > 0) + return bytes; + + err = SSL_get_error (client->ssl, bytes); + log_return_message (bytes, err, "SSL_write"); + + switch (err) { + case SSL_ERROR_WANT_WRITE: + break; + case SSL_ERROR_WANT_READ: + client->sslstatus = WS_TLS_WRITING; + break; + case SSL_ERROR_SYSCALL: + if ((bytes < 0 && + (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR))) + break; + /* The connection was shut down cleanly */ + case SSL_ERROR_ZERO_RETURN: + case SSL_ERROR_WANT_X509_LOOKUP: + default: + return ws_set_status (client, WS_ERR | WS_CLOSE, -1); + } + + return bytes; +} + +/* Read data from the given client's socket and set a connection + * status given the output of recv(). + * + * On error, -1 is returned and the connection status is set. + * On success, the number of bytes read is returned. */ +static int +read_ssl_socket (WSClient * client, char *buffer, int size) +{ + int bytes = 0, done = 0, err = 0; + do { +#if OPENSSL_VERSION_NUMBER < 0x10100000L + ERR_clear_error (); +#endif + + done = 0; + if ((bytes = SSL_read (client->ssl, buffer, size)) > 0) + break; + + err = SSL_get_error (client->ssl, bytes); + log_return_message (bytes, err, "SSL_read"); + + switch (err) { + case SSL_ERROR_WANT_WRITE: + client->sslstatus = WS_TLS_READING; + done = 1; + break; + case SSL_ERROR_WANT_READ: + done = 1; + break; + case SSL_ERROR_SYSCALL: + if ((bytes < 0 && + (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR))) + break; + case SSL_ERROR_ZERO_RETURN: + case SSL_ERROR_WANT_X509_LOOKUP: + default: + return ws_set_status (client, WS_ERR | WS_CLOSE, -1); + } + } while (SSL_pending (client->ssl) && !done); + + return bytes; +} +#endif + +/* Get sockaddr, either IPv4 or IPv6 */ +static void * +ws_get_raddr (struct sockaddr *sa) +{ + if (sa->sa_family == AF_INET) + return &(((struct sockaddr_in *) sa)->sin_addr); + + return &(((struct sockaddr_in6 *) sa)->sin6_addr); +} + +/* Set the given file descriptor as NON BLOCKING. */ +void +set_nonblocking (int sock) +{ + if (fcntl (sock, F_SETFL, fcntl (sock, F_GETFL, 0) | O_NONBLOCK) == -1) + FATAL ("Unable to set socket as non-blocking: %s.", strerror (errno)); +} + +/* Accept a new connection on a socket and add it to the list of + * current connected clients. + * + * The newly assigned socket is returned. */ +static int +accept_client (int listener, GSLList ** colist) +{ + WSClient *client; + struct sockaddr_storage raddr; + int newfd; + const void *src = NULL; + socklen_t alen; + + alen = sizeof (raddr); + if ((newfd = accept (listener, (struct sockaddr *) &raddr, &alen)) == -1) + FATAL ("Unable to set accept: %s.", strerror (errno)); + + if (newfd == -1) { + LOG (("Unable to accept: %s.", strerror (errno))); + return newfd; + } + src = ws_get_raddr ((struct sockaddr *) &raddr); + + /* malloc a new client */ + client = new_wsclient (); + client->listener = newfd; + inet_ntop (raddr.ss_family, src, client->remote_ip, INET6_ADDRSTRLEN); + + /* add up our new client to keep track of */ + if (*colist == NULL) + *colist = list_create (client); + else + *colist = list_insert_prepend (*colist, client); + + /* make the socket non-blocking */ + set_nonblocking (client->listener); + + return newfd; +} + +/* Extract the HTTP method. + * + * On error, or if not found, NULL is returned. + * On success, the HTTP method is returned. */ +static const char * +ws_get_method (const char *token) +{ + const char *lookfor = NULL; + + if ((lookfor = "GET", !memcmp (token, "GET ", 4)) || + (lookfor = "get", !memcmp (token, "get ", 4))) + return lookfor; + return NULL; +} + +/* Parse a request containing the method and protocol. + * + * On error, or unable to parse, NULL is returned. + * On success, the HTTP request is returned and the method and + * protocol are assigned to the corresponding buffers. */ +static char * +ws_parse_request (char *line, char **method, char **protocol) +{ + const char *meth; + char *req = NULL, *request = NULL, *proto = NULL; + ptrdiff_t rlen; + + if ((meth = ws_get_method (line)) == NULL) { + return NULL; + } else { + req = line + strlen (meth); + if ((proto = strstr (line, " HTTP/1.0")) == NULL && + (proto = strstr (line, " HTTP/1.1")) == NULL) + return NULL; + + req++; + if ((rlen = proto - req) <= 0) + return NULL; + + request = xmalloc (rlen + 1); + strncpy (request, req, rlen); + request[rlen] = 0; + + (*method) = strtoupper (xstrdup (meth)); + (*protocol) = strtoupper (xstrdup (++proto)); + } + + return request; +} + +/* Given a pair of key/values, assign it to our HTTP headers + * structure. */ +static void +ws_set_header_key_value (WSHeaders * headers, char *key, char *value) +{ + if (strcasecmp ("Host", key) == 0) + headers->host = xstrdup (value); + else if (strcasecmp ("Origin", key) == 0) + headers->origin = xstrdup (value); + else if (strcasecmp ("Upgrade", key) == 0) + headers->upgrade = xstrdup (value); + else if (strcasecmp ("Connection", key) == 0) + headers->connection = xstrdup (value); + else if (strcasecmp ("Sec-WebSocket-Protocol", key) == 0) + headers->ws_protocol = xstrdup (value); + else if (strcasecmp ("Sec-WebSocket-Key", key) == 0) + headers->ws_key = xstrdup (value); + else if (strcasecmp ("Sec-WebSocket-Version", key) == 0) + headers->ws_sock_ver = xstrdup (value); + else if (strcasecmp ("User-Agent", key) == 0) + headers->agent = xstrdup (value); + else if (strcasecmp ("Referer", key) == 0) + headers->referer = xstrdup (value); +} + +/* Verify that the given HTTP headers were passed upon doing the + * websocket handshake. + * + * On error, or header missing, 1 is returned. + * On success, 0 is returned. */ +static int +ws_verify_req_headers (WSHeaders * headers) +{ + if (!headers->host) + return 1; + if (!headers->method) + return 1; + if (!headers->protocol) + return 1; + if (!headers->path) + return 1; + if (wsconfig.origin && !headers->origin) + return 1; + if (wsconfig.origin && strcasecmp (wsconfig.origin, headers->origin) != 0) + return 1; + if (!headers->connection) + return 1; + if (!headers->ws_key) + return 1; + if (!headers->ws_sock_ver) + return 1; + return 0; +} + +/* From RFC2616, each header field consists of a name followed by a + * colon (":") and the field value. Field names are case-insensitive. + * The field value MAY be preceded by any amount of LWS, though a + * single SP is preferred */ +static int +ws_set_header_fields (char *line, WSHeaders * headers) +{ + char *path = NULL, *method = NULL, *proto = NULL, *p, *value; + + if (line[0] == '\n' || line[0] == '\r') + return 1; + + if ((strstr (line, "GET ")) || (strstr (line, "get "))) { + if ((path = ws_parse_request (line, &method, &proto)) == NULL) + return 1; + headers->path = path; + headers->method = method; + headers->protocol = proto; + + return 0; + } + + if ((p = strchr (line, ':')) == NULL) + return 1; + + value = p + 1; + while (p != line && isspace ((unsigned char) *(p - 1))) + p--; + + if (p == line) + return 1; + + *p = '\0'; + if (strpbrk (line, " \t") != NULL) { + *p = ' '; + return 1; + } + while (isspace ((unsigned char) *value)) + value++; + + ws_set_header_key_value (headers, line, value); + + return 0; +} + +/* Parse the given HTTP headers and set the expected websocket + * handshake. + * + * On error, or 1 is returned. + * On success, 0 is returned. */ +static int +parse_headers (WSHeaders * headers) +{ + char *tmp = NULL; + const char *buffer = headers->buf; + const char *line = buffer, *next = NULL; + int len = 0; + + while (line) { + if ((next = strstr (line, "\r\n")) != NULL) + len = (next - line); + else + len = strlen (line); + + if (len <= 0) + return 1; + + tmp = xmalloc (len + 1); + memcpy (tmp, line, len); + tmp[len] = '\0'; + + if (ws_set_header_fields (tmp, headers) == 1) { + free (tmp); + return 1; + } + + free (tmp); + line = next ? (next + 2) : NULL; + + if (strcmp (next, "\r\n\r\n") == 0) + break; + } + + return 0; +} + +/* Set into a queue the data that couldn't be sent. */ +static void +ws_queue_sockbuf (WSClient * client, const char *buffer, int len, int bytes) +{ + WSQueue *queue = xcalloc (1, sizeof (WSQueue)); + + if (bytes < 1) + bytes = 0; + + queue->queued = xcalloc (len - bytes, sizeof (char)); + memcpy (queue->queued, buffer + bytes, len - bytes); + queue->qlen = len - bytes; + client->sockqueue = queue; + + client->status |= WS_SENDING; +} + +/* Read data from the given client's socket and set a connection + * status given the output of recv(). + * + * On error, -1 is returned and the connection status is set. + * On success, the number of bytes read is returned. */ +static int +read_plain_socket (WSClient * client, char *buffer, int size) +{ + int bytes = 0; + + bytes = recv (client->listener, buffer, size, 0); + + if (bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) + return ws_set_status (client, WS_READING, bytes); + else if (bytes == -1 || bytes == 0) + return ws_set_status (client, WS_ERR | WS_CLOSE, bytes); + + return bytes; +} + +/* Read data from the given client's socket and set a connection + * status given the output of recv(). + * + * On error, -1 is returned and the connection status is set. + * On success, the number of bytes read is returned. */ +static int +read_socket (WSClient * client, char *buffer, int size) +{ +#ifdef HAVE_LIBSSL + if (wsconfig.use_ssl) + return read_ssl_socket (client, buffer, size); + else + return read_plain_socket (client, buffer, size); +#else + return read_plain_socket (client, buffer, size); +#endif +} + +static int +send_plain_buffer (WSClient * client, const char *buffer, int len) +{ + return send (client->listener, buffer, len, 0); +} + +static int +send_buffer (WSClient * client, const char *buffer, int len) +{ +#ifdef HAVE_LIBSSL + if (wsconfig.use_ssl) + return send_ssl_buffer (client, buffer, len); + else + return send_plain_buffer (client, buffer, len); +#else + return send_plain_buffer (client, buffer, len); +#endif +} + +/* Attmpt to send the given buffer to the given socket. + * + * On error, -1 is returned and the connection status is set. + * On success, the number of bytes sent is returned. */ +static int +ws_respond_data (WSClient * client, const char *buffer, int len) +{ + int bytes = 0; + + bytes = send_buffer (client, buffer, len); + if (bytes == -1 && errno == EPIPE) + return ws_set_status (client, WS_ERR | WS_CLOSE, bytes); + + /* did not send all of it... buffer it for a later attempt */ + if (bytes < len || (bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))) + ws_queue_sockbuf (client, buffer, len, bytes); + + return bytes; +} + +/* Attempt to send the queued up client's data to the given socket. + * + * On error, -1 is returned and the connection status is set. + * On success, the number of bytes sent is returned. */ +static int +ws_respond_cache (WSClient * client) +{ + WSQueue *queue = client->sockqueue; + int bytes = 0; + + bytes = send_buffer (client, queue->queued, queue->qlen); + if (bytes == -1 && errno == EPIPE) + return ws_set_status (client, WS_ERR | WS_CLOSE, bytes); + + if (bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) + return bytes; + + if (chop_nchars (queue->queued, bytes, queue->qlen) == 0) + ws_clear_queue (client); + else + queue->qlen -= bytes; + + return bytes; +} + +/* Attempt to realloc the current sent queue. + * + * On error, 1 is returned and the connection status is set. + * On success, 0 is returned. */ +static int +ws_realloc_send_buf (WSClient * client, const char *buf, int len) +{ + WSQueue *queue = client->sockqueue; + char *tmp = NULL; + int newlen = 0; + + newlen = queue->qlen + len; + tmp = realloc (queue->queued, newlen); + if (tmp == NULL && newlen > 0) { + ws_clear_queue (client); + return ws_set_status (client, WS_ERR | WS_CLOSE, 1); + } + queue->queued = tmp; + memcpy (queue->queued + queue->qlen, buf, len); + queue->qlen += len; + + /* client probably too slow, so stop queueing until everything is + * sent */ + if (queue->qlen >= WS_THROTTLE_THLD) + client->status |= WS_THROTTLING; + + return 0; +} + +/* An entry point to attempt to send the client's data. + * + * On error, 1 is returned and the connection status is set. + * On success, the number of bytes sent is returned. */ +static int +ws_respond (WSClient * client, const char *buffer, int len) +{ + int bytes = 0; + + /* attempt to send the whole buffer buffer */ + if (client->sockqueue == NULL) + bytes = ws_respond_data (client, buffer, len); + /* buffer not empty, just append new data iff we're not throttling the + * client */ + else if (client->sockqueue != NULL && buffer != NULL && + !(client->status & WS_THROTTLING)) { + if (ws_realloc_send_buf (client, buffer, len) == 1) + return bytes; + } + /* send from cache buffer */ + else { + bytes = ws_respond_cache (client); + } + + return bytes; +} + +/* Encode a websocket frame (header/message) and attempt to send it + * through the client's socket. + * + * On success, 0 is returned. */ +static int +ws_send_frame (WSClient * client, WSOpcode opcode, const char *p, int sz) +{ + unsigned char buf[32] = { 0 }; + char *frm = NULL; + uint64_t payloadlen = 0, u64; + int hsize = 2; + + if (sz < 126) { + payloadlen = sz; + } else if (sz < (1 << 16)) { + payloadlen = WS_PAYLOAD_EXT16; + hsize += 2; + } else { + payloadlen = WS_PAYLOAD_EXT64; + hsize += 8; + } + + buf[0] = 0x80 | ((uint8_t) opcode); + switch (payloadlen) { + case WS_PAYLOAD_EXT16: + buf[1] = WS_PAYLOAD_EXT16; + buf[2] = (sz & 0xff00) >> 8; + buf[3] = (sz & 0x00ff) >> 0; + break; + case WS_PAYLOAD_EXT64: + buf[1] = WS_PAYLOAD_EXT64; + u64 = htobe64 (sz); + memcpy (buf + 2, &u64, sizeof (uint64_t)); + break; + default: + buf[1] = (sz & 0xff); + } + frm = xcalloc (hsize + sz, sizeof (unsigned char)); + memcpy (frm, buf, hsize); + if (p != NULL && sz > 0) + memcpy (frm + hsize, p, sz); + + ws_respond (client, frm, hsize + sz); + free (frm); + + return 0; +} + +/* Send an error message to the given client. + * + * On success, the number of sent bytes is returned. */ +static int +ws_error (WSClient * client, unsigned short code, const char *err) +{ + unsigned int len; + unsigned short code_be; + char buf[128] = { 0 }; + + len = 2; + code_be = htobe16 (code); + memcpy (buf, &code_be, 2); + if (err) + len += snprintf (buf + 2, sizeof buf - 4, "%s", err); + + return ws_send_frame (client, WS_OPCODE_CLOSE, buf, len); +} + +/* Log hit to the access log. + * + * On success, the hit/entry is logged. */ +static void +access_log (WSClient * client, int status_code) +{ + WSHeaders *hdrs = client->headers; + char buf[64] = { 0 }; + uint32_t elapsed = 0; + struct timeval tv; + char *req = NULL, *ref = NULL, *ua = NULL; + + gettimeofday (&tv, NULL); + strftime (buf, sizeof (buf) - 1, "[%d/%b/%Y:%H:%M:%S %z]", + localtime (&tv.tv_sec)); + + elapsed = (client->end_proc.tv_sec - client->start_proc.tv_sec) * 1000.0; + elapsed += (client->end_proc.tv_usec - client->start_proc.tv_usec) / 1000.0; + + req = escape_http_request (hdrs->path); + ref = escape_http_request (hdrs->referer); + ua = escape_http_request (hdrs->agent); + + ACCESS_LOG (("%s ", client->remote_ip)); + ACCESS_LOG (("- - ")); + ACCESS_LOG (("%s ", buf)); + ACCESS_LOG (("\"%s ", hdrs->method)); + ACCESS_LOG (("%s ", req ? req : "-")); + ACCESS_LOG (("%s\" ", hdrs->protocol)); + ACCESS_LOG (("%d ", status_code)); + ACCESS_LOG (("%d ", hdrs->buflen)); + ACCESS_LOG (("\"%s\" ", ref ? ref : "-")); + ACCESS_LOG (("\"%s\" ", ua ? ua : "-")); + ACCESS_LOG (("%zu\n", elapsed)); + + if (req) + free (req); + if (ref) + free (ref); + if (ua) + free (ua); +} + +/* Send an HTTP error status to the given client. + * + * On success, the number of sent bytes is returned. */ +static int +http_error (WSClient * client, const char *buffer) +{ + /* do access logging */ + gettimeofday (&client->end_proc, NULL); + if (wsconfig.accesslog) + access_log (client, 400); + + return ws_respond (client, buffer, strlen (buffer)); +} + +/* Compute the SHA1 for the handshake. */ +static void +ws_sha1_digest (const char *s, int len, unsigned char *digest) +{ + SHA1_CTX sha; + + SHA1Init (&sha); + SHA1Update (&sha, (uint8_t *) s, len); + SHA1Final (digest, &sha); +} + +/* Set the parsed websocket handshake headers. */ +static void +ws_set_handshake_headers (WSHeaders * headers) +{ + size_t klen = strlen (headers->ws_key); + size_t mlen = strlen (WS_MAGIC_STR); + size_t len = klen + mlen; + char *s = xmalloc (klen + mlen + 1); + uint8_t digest[SHA_DIGEST_LENGTH]; + + memset (digest, 0, sizeof *digest); + + memcpy (s, headers->ws_key, klen); + memcpy (s + klen, WS_MAGIC_STR, mlen + 1); + + ws_sha1_digest (s, len, digest); + + /* set response headers */ + headers->ws_accept = + base64_encode ((unsigned char *) digest, sizeof (digest)); + headers->ws_resp = xstrdup (WS_SWITCH_PROTO_STR); + + if (!headers->upgrade) + headers->upgrade = xstrdup ("websocket"); + if (!headers->connection) + headers->upgrade = xstrdup ("Upgrade"); + + free (s); +} + +/* Send the websocket handshake headers to the given client. + * + * On success, the number of sent bytes is returned. */ +static int +ws_send_handshake_headers (WSClient * client, WSHeaders * headers) +{ + int bytes = 0; + char *str = xstrdup (""); + + ws_append_str (&str, headers->ws_resp); + ws_append_str (&str, CRLF); + + ws_append_str (&str, "Upgrade: "); + ws_append_str (&str, headers->upgrade); + ws_append_str (&str, CRLF); + + ws_append_str (&str, "Connection: "); + ws_append_str (&str, headers->connection); + ws_append_str (&str, CRLF); + + ws_append_str (&str, "Sec-WebSocket-Accept: "); + ws_append_str (&str, headers->ws_accept); + ws_append_str (&str, CRLF CRLF); + + bytes = ws_respond (client, str, strlen (str)); + free (str); + + return bytes; +} + +/* Given the HTTP connection headers, attempt to parse the web socket + * handshake headers. + * + * On success, the number of sent bytes is returned. */ +static int +ws_get_handshake (WSClient * client, WSServer * server) +{ + int bytes = 0, readh = 0; + char *buf = NULL; + + if (client->headers == NULL) + client->headers = new_wsheader (); + + buf = client->headers->buf; + readh = client->headers->buflen; + /* Probably the connection was closed before finishing handshake */ + if ((bytes = read_socket (client, buf + readh, BUFSIZ - readh)) < 1) { + if (client->status & WS_CLOSE) + http_error (client, WS_BAD_REQUEST_STR); + return bytes; + } + client->headers->buflen += bytes; + + buf[client->headers->buflen] = '\0'; /* null-terminate */ + + /* Must have a \r\n\r\n */ + if (strstr (buf, "\r\n\r\n") == NULL) { + if (strlen (buf) < BUFSIZ) + return ws_set_status (client, WS_READING, bytes); + + http_error (client, WS_BAD_REQUEST_STR); + return ws_set_status (client, WS_CLOSE, bytes); + } + + /* Ensure we have valid HTTP headers for the handshake */ + if (parse_headers (client->headers) != 0) { + http_error (client, WS_BAD_REQUEST_STR); + return ws_set_status (client, WS_CLOSE, bytes); + } + + /* Ensure we have the required headers */ + if (ws_verify_req_headers (client->headers) != 0) { + http_error (client, WS_BAD_REQUEST_STR); + return ws_set_status (client, WS_CLOSE, bytes); + } + + ws_set_handshake_headers (client->headers); + + /* handshake response */ + ws_send_handshake_headers (client, client->headers); + + /* upon success, call onopen() callback */ + if (server->onopen && wsconfig.strict && !wsconfig.echomode) + server->onopen (server->pipeout, client); + client->headers->reading = 0; + + /* do access logging */ + gettimeofday (&client->end_proc, NULL); + if (wsconfig.accesslog) + access_log (client, 101); + LOG (("Active: %d\n", list_count (server->colist))); + + return ws_set_status (client, WS_OK, bytes); +} + +/* Send a data message to the given client. + * + * On success, 0 is returned. */ +int +ws_send_data (WSClient * client, WSOpcode opcode, const char *p, int sz) +{ + char *buf = NULL; + + buf = sanitize_utf8 (p, sz); + ws_send_frame (client, opcode, buf, sz); + free (buf); + + return 0; +} + +/* Read a websocket frame's header. + * + * On success, the number of bytesr read is returned. */ +static int +ws_read_header (WSClient * client, WSFrame * frm, int pos, int need) +{ + char *buf = frm->buf; + int bytes = 0; + + /* read the first 2 bytes for basic frame info */ + if ((bytes = read_socket (client, buf + pos, need)) < 1) { + if (client->status & WS_CLOSE) + ws_error (client, WS_CLOSE_UNEXPECTED, "Unable to read header"); + return bytes; + } + frm->buflen += bytes; + frm->buf[frm->buflen] = '\0'; /* null-terminate */ + + return bytes; +} + +/* Read a websocket frame's payload. + * + * On success, the number of bytesr read is returned. */ +static int +ws_read_payload (WSClient * client, WSMessage * msg, int pos, int need) +{ + char *buf = msg->payload; + int bytes = 0; + + /* read the first 2 bytes for basic frame info */ + if ((bytes = read_socket (client, buf + pos, need)) < 1) { + if (client->status & WS_CLOSE) + ws_error (client, WS_CLOSE_UNEXPECTED, "Unable to read payload"); + return bytes; + } + msg->buflen += bytes; + msg->payloadsz += bytes; + + return bytes; +} + +/* Set the basic frame headers on a frame structure. + * + * On success, 0 is returned. */ +static int +ws_set_front_header_fields (WSClient * client) +{ + WSFrame **frm = &client->frame; + char *buf = (*frm)->buf; + + (*frm)->fin = WS_FRM_FIN (*(buf)); + (*frm)->masking = WS_FRM_MASK (*(buf + 1)); + (*frm)->opcode = WS_FRM_OPCODE (*(buf)); + (*frm)->res = WS_FRM_R1 (*(buf)) || WS_FRM_R2 (*(buf)) || WS_FRM_R3 (*(buf)); + + /* should be masked and can't be using RESVd bits */ + if (!(*frm)->masking || (*frm)->res) + return ws_set_status (client, WS_ERR | WS_CLOSE, 1); + + return 0; +} + +/* Unmask the payload given the current frame's masking key. */ +static void +ws_unmask_payload (char *buf, int len, int offset, unsigned char mask[]) +{ + int i, j = 0; + + /* unmask data */ + for (i = offset; i < len; ++i, ++j) { + buf[i] ^= mask[j % 4]; + } +} + +/* Close a websocket connection. */ +static int +ws_handle_close (WSClient * client) +{ + client->status = WS_ERR | WS_CLOSE; + return ws_send_frame (client, WS_OPCODE_CLOSE, NULL, 0); +} + +/* Handle a websocket error. + * + * On success, the number of bytes sent is returned. */ +static int +ws_handle_err (WSClient * client, unsigned short code, WSStatus status, + const char *m) +{ + client->status = status; + return ws_error (client, code, m); +} + +/* Handle a websocket pong. */ +static void +ws_handle_pong (WSClient * client) +{ + WSFrame **frm = &client->frame; + + if (!(*frm)->fin) { + ws_handle_err (client, WS_CLOSE_PROTO_ERR, WS_ERR | WS_CLOSE, NULL); + return; + } + ws_free_message (client); +} + +/* Handle a websocket ping from the client and it attempts to send + * back a pong as soon as possible. */ +static void +ws_handle_ping (WSClient * client) +{ + WSFrame **frm = &client->frame; + WSMessage **msg = &client->message; + char *buf = NULL, *tmp = NULL; + int pos = 0, len = (*frm)->payloadlen, newlen = 0; + + /* RFC states that Control frames themselves MUST NOT be + * fragmented. */ + if (!(*frm)->fin) { + ws_handle_err (client, WS_CLOSE_PROTO_ERR, WS_ERR | WS_CLOSE, NULL); + return; + } + + /* Control frames are only allowed to have payload up to and + * including 125 octets */ + if ((*frm)->payloadlen > 125) { + ws_handle_err (client, WS_CLOSE_PROTO_ERR, WS_ERR | WS_CLOSE, NULL); + return; + } + + /* No payload from ping */ + if (len == 0) { + ws_send_frame (client, WS_OPCODE_PONG, NULL, 0); + return; + } + + /* Copy the ping payload */ + pos = (*msg)->payloadsz - len; + buf = xcalloc (len, sizeof (char)); + memcpy (buf, (*msg)->payload + pos, len); + + /* Unmask it */ + ws_unmask_payload (buf, len, 0, (*frm)->mask); + + /* Resize the current payload (keep an eye on this realloc) */ + newlen = (*msg)->payloadsz - len; + tmp = realloc ((*msg)->payload, newlen); + if (tmp == NULL && newlen > 0) { + free ((*msg)->payload); + free (buf); + + (*msg)->payload = NULL; + client->status = WS_ERR | WS_CLOSE; + return; + } + + (*msg)->payload = tmp; + (*msg)->payloadsz -= len; + + ws_send_frame (client, WS_OPCODE_PONG, buf, len); + + (*msg)->buflen = 0; /* done with the current frame's payload */ + /* Control frame injected in the middle of a fragmented message. */ + if (!(*msg)->fragmented) { + ws_free_message (client); + } + free (buf); +} + +/* Ensure we have valid UTF-8 text payload. + * + * On error, or if the message is invalid, 1 is returned. + * On success, or if the message is valid, 0 is returned. */ +int +ws_validate_string (const char *str, int len) +{ + uint32_t state = UTF8_VALID; + + if (verify_utf8 (&state, str, len) == UTF8_INVAL) { + LOG (("Invalid UTF8 data!\n")); + return 1; + } + if (state != UTF8_VALID) { + LOG (("Invalid UTF8 data!\n")); + return 1; + } + + return 0; +} + +/* It handles a text or binary message frame from the client. */ +static void +ws_handle_text_bin (WSClient * client, WSServer * server) +{ + WSFrame **frm = &client->frame; + WSMessage **msg = &client->message; + int offset = (*msg)->mask_offset; + + /* All data frames after the initial data frame must have opcode 0 */ + if ((*msg)->fragmented && (*frm)->opcode != WS_OPCODE_CONTINUATION) { + client->status = WS_ERR | WS_CLOSE; + return; + } + + /* RFC states that there is a new masking key per frame, therefore, + * time to unmask... */ + ws_unmask_payload ((*msg)->payload, (*msg)->payloadsz, offset, (*frm)->mask); + /* Done with the current frame's payload */ + (*msg)->buflen = 0; + /* Reading a fragmented frame */ + (*msg)->fragmented = 1; + + if (!(*frm)->fin) + return; + + /* validate text data encoded as UTF-8 */ + if ((*msg)->opcode == WS_OPCODE_TEXT) { + if (ws_validate_string ((*msg)->payload, (*msg)->payloadsz) != 0) { + ws_handle_err (client, WS_CLOSE_INVALID_UTF8, WS_ERR | WS_CLOSE, NULL); + return; + } + } + + if ((*msg)->opcode != WS_OPCODE_CONTINUATION && server->onmessage) { + /* just echo the message to the client */ + if (wsconfig.echomode) + ws_send_data (client, (*msg)->opcode, (*msg)->payload, (*msg)->payloadsz); + /* just pipe out the message */ + else if (!wsconfig.strict) + ws_write_fifo (server->pipeout, (*msg)->payload, (*msg)->payloadsz); + else + server->onmessage (server->pipeout, client); + } + ws_free_message (client); +} + +/* Depending on the frame opcode, then we take certain decisions. */ +static void +ws_manage_payload_opcode (WSClient * client, WSServer * server) +{ + WSFrame **frm = &client->frame; + WSMessage **msg = &client->message; + + switch ((*frm)->opcode) { + case WS_OPCODE_CONTINUATION: + LOG (("CONTINUATION\n")); + /* first frame can't be a continuation frame */ + if (!(*msg)->fragmented) { + client->status = WS_ERR | WS_CLOSE; + break; + } + ws_handle_text_bin (client, server); + break; + case WS_OPCODE_TEXT: + case WS_OPCODE_BIN: + LOG (("TEXT\n")); + client->message->opcode = (*frm)->opcode; + ws_handle_text_bin (client, server); + break; + case WS_OPCODE_PONG: + LOG (("PONG\n")); + ws_handle_pong (client); + break; + case WS_OPCODE_PING: + LOG (("PING\n")); + ws_handle_ping (client); + break; + default: + LOG (("CLOSE\n")); + ws_handle_close (client); + } +} + +/* Set the extended payload length into the given pointer. */ +static void +ws_set_extended_header_size (const char *buf, int *extended) +{ + uint64_t payloadlen = 0; + /* determine the payload length, else read more data */ + payloadlen = WS_FRM_PAYLOAD (*(buf + 1)); + switch (payloadlen) { + case WS_PAYLOAD_EXT16: + *extended = 2; + break; + case WS_PAYLOAD_EXT64: + *extended = 8; + break; + } +} + +/* Set the extended payload length into our frame structure. */ +static void +ws_set_payloadlen (WSFrame * frm, const char *buf) +{ + uint64_t payloadlen = 0, len64; + uint16_t len16; + + /* determine the payload length, else read more data */ + payloadlen = WS_FRM_PAYLOAD (*(buf + 1)); + switch (payloadlen) { + case WS_PAYLOAD_EXT16: + memcpy (&len16, (buf + 2), sizeof (uint16_t)); + frm->payloadlen = ntohs (len16); + break; + case WS_PAYLOAD_EXT64: + memcpy (&len64, (buf + 2), sizeof (uint64_t)); + frm->payloadlen = be64toh (len64); + break; + default: + frm->payloadlen = payloadlen; + } +} + +/* Set the masking key into our frame structure. */ +static void +ws_set_masking_key (WSFrame * frm, const char *buf) +{ + uint64_t payloadlen = 0; + + /* determine the payload length, else read more data */ + payloadlen = WS_FRM_PAYLOAD (*(buf + 1)); + switch (payloadlen) { + case WS_PAYLOAD_EXT16: + memcpy (&frm->mask, buf + 4, sizeof (frm->mask)); + break; + case WS_PAYLOAD_EXT64: + memcpy (&frm->mask, buf + 10, sizeof (frm->mask)); + break; + default: + memcpy (&frm->mask, buf + 2, sizeof (frm->mask)); + } +} + +/* Attempt to read the frame's header and set the relavant data into + * our frame structure. + * + * On error, or if no data available to read, the number of bytes is + * returned and the appropriate connection status is set. + * On success, the number of bytes is returned. */ +static int +ws_get_frm_header (WSClient * client) +{ + WSFrame **frm = NULL; + int bytes = 0, readh = 0, need = 0, offset = 0, extended = 0; + + if (client->frame == NULL) + client->frame = new_wsframe (); + + frm = &client->frame; + + /* Read the first 2 bytes for basic frame info */ + readh = (*frm)->buflen; /* read from header so far */ + need = 2 - readh; /* need to read */ + if (need > 0) { + if ((bytes = ws_read_header (client, (*frm), readh, need)) < 1) + return bytes; + if (bytes != need) + return ws_set_status (client, WS_READING, bytes); + } + offset += 2; + + if (ws_set_front_header_fields (client) != 0) + return bytes; + + ws_set_extended_header_size ((*frm)->buf, &extended); + /* read the extended header */ + readh = (*frm)->buflen; /* read from header so far */ + need = (extended + offset) - readh; /* read from header field so far */ + if (need > 0) { + if ((bytes = ws_read_header (client, (*frm), readh, need)) < 1) + return bytes; + if (bytes != need) + return ws_set_status (client, WS_READING, bytes); + } + offset += extended; + + /* read the masking key */ + readh = (*frm)->buflen; /* read from header so far */ + need = (4 + offset) - readh; + if (need > 0) { + if ((bytes = ws_read_header (client, (*frm), readh, need)) < 1) + return bytes; + if (bytes != need) + return ws_set_status (client, WS_READING, bytes); + } + offset += 4; + + ws_set_payloadlen ((*frm), (*frm)->buf); + ws_set_masking_key ((*frm), (*frm)->buf); + + if ((*frm)->payloadlen > wsconfig.max_frm_size) { + ws_error (client, WS_CLOSE_TOO_LARGE, "Frame is too big"); + return ws_set_status (client, WS_ERR | WS_CLOSE, bytes); + } + + (*frm)->buflen = 0; + (*frm)->reading = 0; + (*frm)->payload_offset = offset; + + return ws_set_status (client, WS_OK, bytes); +} + +/* Attempt to realloc the message payload. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +static int +ws_realloc_frm_payload (WSFrame * frm, WSMessage * msg) +{ + char *tmp = NULL; + uint64_t newlen = 0; + + newlen = msg->payloadsz + frm->payloadlen; + tmp = realloc (msg->payload, newlen); + if (tmp == NULL && newlen > 0) { + free (msg->payload); + msg->payload = NULL; + return 1; + } + msg->payload = tmp; + + return 0; +} + +/* Attempt to read the frame's payload and set the relavant data into + * our message structure. + * + * On error, or if no data available to read, the number of bytes is + * returned and the appropriate connection status is set. + * On success, the number of bytes is returned. */ +static int +ws_get_frm_payload (WSClient * client, WSServer * server) +{ + WSFrame **frm = NULL; + WSMessage **msg = NULL; + int bytes = 0, readh = 0, need = 0; + + if (client->message == NULL) + client->message = new_wsmessage (); + + frm = &client->frame; + msg = &client->message; + + /* message within the same frame */ + if ((*msg)->payload == NULL && (*frm)->payloadlen) + (*msg)->payload = xcalloc ((*frm)->payloadlen, sizeof (char)); + /* handle a new frame */ + else if ((*msg)->buflen == 0 && (*frm)->payloadlen) { + if (ws_realloc_frm_payload ((*frm), (*msg)) == 1) + return ws_set_status (client, WS_ERR | WS_CLOSE, 0); + } + + readh = (*msg)->buflen; /* read from so far */ + need = (*frm)->payloadlen - readh; /* need to read */ + if (need > 0) { + if ((bytes = ws_read_payload (client, (*msg), (*msg)->payloadsz, need)) < 0) + return bytes; + if (bytes != need) + return ws_set_status (client, WS_READING, bytes); + } + + (*msg)->mask_offset = (*msg)->payloadsz - (*msg)->buflen; + + ws_manage_payload_opcode (client, server); + ws_free_frame (client); + + return bytes; +} + +/* Determine if we need to read a frame's header or its payload. + * + * On success, the number of bytes is returned. */ +static int +ws_get_message (WSClient * client, WSServer * server) +{ + int bytes = 0; + if ((client->frame == NULL) || (client->frame->reading)) + if ((bytes = ws_get_frm_header (client)) < 1 || client->frame->reading) + return bytes; + return ws_get_frm_payload (client, server); +} + +/* Determine if we need to read an HTTP request or a websocket frame. + * + * On success, the number of bytes is returned. */ +static int +read_client_data (WSClient * client, WSServer * server) +{ + int bytes = 0; + + /* Handshake */ + if ((!(client->headers) || (client->headers->reading))) + bytes = ws_get_handshake (client, server); + /* Message */ + else + bytes = ws_get_message (client, server); + + return bytes; +} + +/* Handle a tcp close connection. */ +static void +handle_tcp_close (int conn, WSClient * client, WSServer * server) +{ +#ifdef HAVE_LIBSSL + if (client->ssl) + shutdown_ssl (client); +#endif + + shutdown (conn, SHUT_RDWR); + /* upon close, call onclose() callback */ + if (server->onclose && wsconfig.strict && !wsconfig.echomode) + (*server->onclose) (server->pipeout, client); + + /* do access logging */ + gettimeofday (&client->end_proc, NULL); + if (wsconfig.accesslog) + access_log (client, 200); + + /* errored out while parsing a frame or a message */ + if (client->status & WS_ERR) { + ws_clear_queue (client); + ws_free_frame (client); + ws_free_message (client); + } + + server->closing = 0; + ws_close (conn); + +#ifdef HAVE_LIBSSL + if (client->ssl) + SSL_free (client->ssl); + client->ssl = NULL; +#endif + + /* remove client from our list */ + ws_remove_client_from_list (client, server); + LOG (("Active: %d\n", list_count (server->colist))); +} + +/* Handle a tcp read close connection. */ +static void +handle_read_close (int conn, WSClient * client, WSServer * server) +{ + if (client->status & WS_SENDING) { + server->closing = 1; + return; + } + handle_tcp_close (conn, client, server); +} + +/* Handle a new socket connection. */ +static void +handle_accept (int listener, WSServer * server) +{ + WSClient *client = NULL; + int newfd; + + newfd = accept_client (listener, &server->colist); + if (newfd == -1) + return; + + client = ws_get_client_from_list (newfd, &server->colist); + if (newfd > FD_SETSIZE - 1) { + LOG (("Too busy: %d %s.\n", newfd, client->remote_ip)); + + http_error (client, WS_TOO_BUSY_STR); + handle_read_close (newfd, client, server); + return; + } +#ifdef HAVE_LIBSSL + /* set flag to do TLS handshake */ + if (wsconfig.use_ssl) + client->sslstatus |= WS_TLS_ACCEPTING; +#endif + + LOG (("Accepted: %d %s\n", newfd, client->remote_ip)); +} + +/* Handle a tcp read. */ +static void +handle_reads (int conn, WSServer * server) +{ + WSClient *client = NULL; + + if (!(client = ws_get_client_from_list (conn, &server->colist))) + return; + +#ifdef HAVE_LIBSSL + if (handle_ssl_pending_rw (conn, server, client) == 0) + return; +#endif + + /* *INDENT-OFF* */ + client->start_proc = client->end_proc = (struct timeval) {0}; + /* *INDENT-ON* */ + gettimeofday (&client->start_proc, NULL); + read_client_data (client, server); + /* An error ocurred while reading data or connection closed */ + if ((client->status & WS_CLOSE)) { + handle_read_close (conn, client, server); + } +} + +/* Handle a tcp write close connection. */ +static void +handle_write_close (int conn, WSClient * client, WSServer * server) +{ + handle_tcp_close (conn, client, server); +} + +/* Handle a tcp write. */ +static void +handle_writes (int conn, WSServer * server) +{ + WSClient *client = NULL; + + if (!(client = ws_get_client_from_list (conn, &server->colist))) + return; + +#ifdef HAVE_LIBSSL + if (handle_ssl_pending_rw (conn, server, client) == 0) + return; +#endif + + ws_respond (client, NULL, 0); /* buffered data */ + /* done sending data */ + if (client->sockqueue == NULL) + client->status &= ~WS_SENDING; + + /* An error ocurred while sending data or while reading data but still + * waiting from the last send() from the server to the client. e.g., + * sending status code */ + if ((client->status & WS_CLOSE) && !(client->status & WS_SENDING)) + handle_write_close (conn, client, server); +} + +/* Handle reads/writes on a TCP connection. */ +static void +ws_listen (int listener, int conn, WSServer * server) +{ + /* handle new connections */ + if (FD_ISSET (conn, &fdstate.rfds) && conn == listener) + handle_accept (listener, server); + /* handle data from a client */ + else if (FD_ISSET (conn, &fdstate.rfds) && conn != listener) + handle_reads (conn, server); + /* handle sending data to a client */ + else if (FD_ISSET (conn, &fdstate.wfds) && conn != listener) + handle_writes (conn, server); +} + +/* Create named pipe (FIFO) with the given pipe name. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +int +ws_setfifo (const char *pipename) +{ + struct stat fistat; + const char *f = pipename; + + if (access (f, F_OK) == 0) + return 0; + + if (mkfifo (f, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0) + FATAL ("Unable to set fifo: %s.", strerror (errno)); + if (stat (f, &fistat) < 0) + FATAL ("Unable to stat fifo: %s.", strerror (errno)); + if (!S_ISFIFO (fistat.st_mode)) + FATAL ("pipe is not a fifo: %s.", strerror (errno)); + + return 0; +} + +/* Open a named pipe (FIFO) for input to the server (reader). */ +static int +ws_openfifo_in (WSPipeIn * pipein) +{ + ws_setfifo (wsconfig.pipein); + /* we should be able to open it at as reader */ + if ((pipein->fd = open (wsconfig.pipein, O_RDWR | O_NONBLOCK)) < 0) + FATAL ("Unable to open fifo in: %s.", strerror (errno)); + + return pipein->fd; +} + + +/* Open a named pipe (FIFO) for output from the server (writer). */ +static int +ws_openfifo_out (WSPipeOut * pipeout) +{ + int status = 0; + + ws_setfifo (wsconfig.pipeout); + status = open (wsconfig.pipeout, O_WRONLY | O_NONBLOCK); + /* will attempt on the next write */ + if (status == -1 && errno == ENXIO) + LOG (("Unable to open fifo out: %s.\n", strerror (errno))); + else if (status < 0) + FATAL ("Unable to open fifo out: %s.", strerror (errno)); + pipeout->fd = status; + + if (status != -1 && status > max_file_fd) + max_file_fd = status; + + return status; +} + +/* Set a new named pipe for incoming messages and one for outgoing + * messages from the client. */ +static void +ws_fifo (WSServer * server) +{ + wsconfig.pipein = wsconfig.pipein ? wsconfig.pipein : WS_PIPEIN; + wsconfig.pipeout = wsconfig.pipeout ? wsconfig.pipeout : WS_PIPEOUT; + + ws_openfifo_in (server->pipein); + ws_openfifo_out (server->pipeout); +} + +/* Clear the queue for an outgoing named pipe. */ +static void +clear_fifo_queue (WSPipeOut * pipeout) +{ + WSQueue **queue = &pipeout->fifoqueue; + if (!(*queue)) + return; + + if ((*queue)->queued) + free ((*queue)->queued); + (*queue)->queued = NULL; + (*queue)->qlen = 0; + + free ((*queue)); + (*queue) = NULL; +} + +/* Attempt to realloc the current sent queue for an outgoing named pip + * (FIFO). + * + * On error, 1 is returned and the connection status is closed and + * reopened. + * On success, 0 is returned. */ +static int +ws_realloc_fifobuf (WSPipeOut * pipeout, const char *buf, int len) +{ + WSQueue *queue = pipeout->fifoqueue; + char *tmp = NULL; + int newlen = 0; + + newlen = queue->qlen + len; + tmp = realloc (queue->queued, newlen); + if (tmp == NULL && newlen > 0) { + close (pipeout->fd); + clear_fifo_queue (pipeout); + ws_openfifo_out (pipeout); + return 1; + } + + queue->queued = tmp; + memcpy (queue->queued + queue->qlen, buf, len); + queue->qlen += len; + + return 0; +} + +/* Set into a queue the data that couldn't be sent in the outgoing + * FIFO. */ +static void +ws_queue_fifobuf (WSPipeOut * pipeout, const char *buffer, int len, int bytes) +{ + WSQueue **queue = &pipeout->fifoqueue; + + if (bytes < 1) + bytes = 0; + + (*queue) = xcalloc (1, sizeof (WSQueue)); + (*queue)->queued = xcalloc (len - bytes, sizeof (char)); + memcpy ((*queue)->queued, buffer + bytes, len - bytes); + (*queue)->qlen = len - bytes; + + pipeout->status |= WS_SENDING; +} + +/* Attmpt to send the given buffer to the given outgoing FIFO. + * + * On error, the data is queued up. + * On success, the number of bytes sent is returned. */ +static int +ws_write_fifo_data (WSPipeOut * pipeout, char *buffer, int len) +{ + int bytes = 0; + + bytes = write (pipeout->fd, buffer, len); + + /* At this point, the reader probably closed the pipe, so a cheap *hack* for + * this is to close the pipe on our end and attempt to reopen it. If unable to + * do so, then let it be -1 and try on the next attempt to write. */ + if (bytes == -1 && errno == EPIPE) { + close (pipeout->fd); + ws_openfifo_out (pipeout); + return bytes; + } + if (bytes < len || (bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))) + ws_queue_fifobuf (pipeout, buffer, len, bytes); + + return bytes; +} + +/* Attempt to send the queued up client's data through the outgoing + * named pipe (FIFO) . + * + * On error, 1 is returned and the connection status is set. + * On success, the number of bytes sent is returned. */ +static int +ws_write_fifo_cache (WSPipeOut * pipeout) +{ + WSQueue *queue = pipeout->fifoqueue; + int bytes = 0; + + bytes = write (pipeout->fd, queue->queued, queue->qlen); + + /* At this point, the reader probably closed the pipe, so a cheap *hack* for + * this is to close the pipe on our end and attempt to reopen it. If unable to + * do so, then let it be -1 and try on the next attempt to write. */ + if (bytes == -1 && errno == EPIPE) { + close (pipeout->fd); + ws_openfifo_out (pipeout); + return bytes; + } + + if (chop_nchars (queue->queued, bytes, queue->qlen) == 0) + clear_fifo_queue (pipeout); + else + queue->qlen -= bytes; + + return bytes; +} + +/* An entry point to attempt to send the client's data into an + * outgoing named pipe (FIFO). + * + * On success, the number of bytes sent is returned. */ +int +ws_write_fifo (WSPipeOut * pipeout, char *buffer, int len) +{ + int bytes = 0; + + if (pipeout->fd == -1 && ws_openfifo_out (pipeout) == -1) + return bytes; + + /* attempt to send the whole buffer buffer */ + if (pipeout->fifoqueue == NULL) + bytes = ws_write_fifo_data (pipeout, buffer, len); + /* buffer not empty, just append new data */ + else if (pipeout->fifoqueue != NULL && buffer != NULL) { + if (ws_realloc_fifobuf (pipeout, buffer, len) == 1) + return bytes; + } + /* send from cache buffer */ + else { + bytes = ws_write_fifo_cache (pipeout); + } + + if (pipeout->fifoqueue == NULL) + pipeout->status &= ~WS_SENDING; + + return bytes; +} + +/* Clear an incoming FIFO packet and header data. */ +static void +clear_fifo_packet (WSPipeIn * pipein) +{ + memset (pipein->hdr, 0, sizeof (pipein->hdr)); + pipein->hlen = 0; + + if (pipein->packet == NULL) + return; + + if (pipein->packet->data) + free (pipein->packet->data); + free (pipein->packet); + pipein->packet = NULL; +} + +/* Broadcast to all connected clients the given message. */ +static int +ws_broadcast_fifo (void *value, void *user_data) +{ + WSClient *client = value; + WSPacket *packet = user_data; + + if (client == NULL || user_data == NULL) + return 1; + /* no handshake for this client */ + if (client->headers == NULL || client->headers->ws_accept == NULL) + return 1; + + ws_send_data (client, packet->type, packet->data, packet->size); + + return 0; +} + +/* Send a message from the incoming named pipe to specific client + * given the socket id. */ +static void +ws_send_strict_fifo_to_client (WSServer * server, int listener, WSPacket * pa) +{ + WSClient *client = NULL; + + if (!(client = ws_get_client_from_list (listener, &server->colist))) + return; + /* no handshake for this client */ + if (client->headers == NULL || client->headers->ws_accept == NULL) + return; + ws_send_data (client, pa->type, pa->data, pa->len); +} + +/* Attempt to read message from a named pipe (FIFO). + * + * On error, -1 is returned. + * On success, the number of bytes read is returned. */ +int +ws_read_fifo (int fd, char *buf, int *buflen, int pos, int need) +{ + int bytes = 0; + + bytes = read (fd, buf + pos, need); + if (bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) + return bytes; + else if (bytes == -1) + return bytes; + *buflen += bytes; + + return bytes; +} + +/* Pack the given value into a network byte order. + * + * On success, the number size of uint32_t is returned. */ +size_t +pack_uint32 (void *buf, uint32_t val) +{ + uint32_t v32 = htonl (val); + memcpy (buf, &v32, sizeof (uint32_t)); + + return sizeof (uint32_t); +} + +/* Unpack the given value into a host byte order. + * + * On success, the number size of uint32_t is returned. */ +size_t +unpack_uint32 (const void *buf, uint32_t * val) +{ + uint32_t v32 = 0; + memcpy (&v32, buf, sizeof (uint32_t)); + *val = ntohl (v32); + + return sizeof (uint32_t); +} + +/* Ensure the fields coming from the named pipe are valid. + * + * On error, 1 is returned. + * On success, 0 is returned. */ +static int +validate_fifo_packet (uint32_t listener, uint32_t type, int size) +{ + if (listener > FD_SETSIZE) { + LOG (("Invalid listener\n")); + return 1; + } + + if (type != WS_OPCODE_TEXT && type != WS_OPCODE_BIN) { + LOG (("Invalid fifo packet type\n")); + return 1; + } + + if (size > wsconfig.max_frm_size) { + LOG (("Invalid fifo packet size\n")); + return 1; + } + + return 0; +} + +/* Handle reading and sending the incoming data from the named pipe on + * strict mode. */ +static void +handle_strict_fifo (WSServer * server) +{ + WSPipeIn *pi = server->pipein; + WSPacket **pa = &pi->packet; + int bytes = 0, readh = 0, need = 0; + + char *ptr = NULL; + uint32_t listener = 0, type = 0, size = 0; + + readh = pi->hlen; /* read from header so far */ + need = HDR_SIZE - readh; /* need to read */ + if (need > 0) { + if ((bytes = ws_read_fifo (pi->fd, pi->hdr, &pi->hlen, readh, need)) < 0) + return; + if (bytes != need) + return; + } + + /* unpack size, and type */ + ptr = pi->hdr; + ptr += unpack_uint32 (ptr, &listener); + ptr += unpack_uint32 (ptr, &type); + ptr += unpack_uint32 (ptr, &size); + + if (validate_fifo_packet (listener, type, size) == 1) { + close (pi->fd); + clear_fifo_packet (pi); + ws_openfifo_in (pi); + return; + } + + if ((*pa) == NULL) { + (*pa) = xcalloc (1, sizeof (WSPacket)); + (*pa)->type = type; + (*pa)->size = size; + (*pa)->data = xcalloc (size, sizeof (char)); + } + + readh = (*pa)->len; /* read from payload so far */ + need = (*pa)->size - readh; /* need to read */ + if (need > 0) { + if ((bytes = + ws_read_fifo (pi->fd, (*pa)->data, &(*pa)->len, readh, need)) < 0) + return; + if (bytes != need) + return; + } + + /* no clients to send data to */ + if (list_count (server->colist) == 0) { + clear_fifo_packet (pi); + return; + } + + /* Either send it to a specific client or brodcast message to all + * clients */ + if (listener != 0) + ws_send_strict_fifo_to_client (server, listener, *pa); + else + list_foreach (server->colist, ws_broadcast_fifo, *pa); + clear_fifo_packet (pi); +} + +/* Handle reading and sending the incoming data from the named pipe on + * a fixed buffer mode. */ +static void +handle_fixed_fifo (WSServer * server) +{ + WSPipeIn *pi = server->pipein; + WSPacket **pa = &pi->packet; + + int bytes = 0; + char buf[PIPE_BUF] = { 0 }; + + if ((bytes = read (pi->fd, buf, PIPE_BUF)) < 0) + return; + + buf[bytes] = '\0'; /* null-terminate */ + if (ws_validate_string (buf, bytes) != 0) + return; + + (*pa) = xcalloc (1, sizeof (WSPacket)); + (*pa)->type = WS_OPCODE_TEXT; + (*pa)->size = bytes; + (*pa)->data = xstrdup (buf); + + /* no clients to send data to */ + if (list_count (server->colist) == 0) { + clear_fifo_packet (pi); + return; + } + + /* brodcast message to all clients */ + list_foreach (server->colist, ws_broadcast_fifo, *pa); + clear_fifo_packet (pi); +} + +/* Determine which mode should use the incoming message from the FIFO. */ +static void +handle_fifo (WSServer * server) +{ + if (wsconfig.strict) + handle_strict_fifo (server); + else + handle_fixed_fifo (server); +} + +/* Creates an endpoint for communication and start listening for + * connections on a socket */ +static void +ws_socket (int *listener) +{ + int ov = 1; + struct addrinfo hints, *ai; + + /* get a socket and bind it */ + memset (&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + /*hints.ai_flags = AI_PASSIVE; */ + if (getaddrinfo (wsconfig.host, wsconfig.port, &hints, &ai) != 0) + FATAL ("Unable to set server: %s.", gai_strerror (errno)); + + /* Create a TCP socket. */ + *listener = socket (ai->ai_family, ai->ai_socktype, ai->ai_protocol); + + /* Options */ + if (setsockopt (*listener, SOL_SOCKET, SO_REUSEADDR, &ov, sizeof (ov)) == -1) + FATAL ("Unable to set setsockopt: %s.", strerror (errno)); + + /* Bind the socket to the address. */ + if (bind (*listener, ai->ai_addr, ai->ai_addrlen) != 0) + FATAL ("Unable to set bind: %s.", strerror (errno)); + freeaddrinfo (ai); + + /* Tell the socket to accept connections. */ + if (listen (*listener, SOMAXCONN) == -1) + FATAL ("Unable to listen: %s.", strerror (errno)); +} + +/* Handle incoming messages through a pipe (let gwsocket be the + * reader) and outgoing messages through the pipe (writer). */ +static void +ws_fifos (WSServer * server, WSPipeIn * pi, WSPipeOut * po) +{ + /* handle data via fifo */ + if (pi->fd != -1 && FD_ISSET (pi->fd, &fdstate.rfds)) + handle_fifo (server); + /* handle data via fifo */ + if (po->fd != -1 && FD_ISSET (po->fd, &fdstate.wfds)) + ws_write_fifo (po, NULL, 0); +} + +/* Check each client to determine if: + * 1. We want to see if it has data for reading + * 2. We want to write data to it. + * If so, set the client's socket descriptor in the descriptor set. */ +static void +set_rfds_wfds (int listener, WSServer * server, WSPipeIn * pi, WSPipeOut * po) +{ + WSClient *client = NULL; + int conn; + + /* pipe out */ + if (po->fd != -1) { + if (po->status & WS_SENDING) + FD_SET (po->fd, &fdstate.wfds); + } + /* pipe in */ + if (pi->fd != -1) + FD_SET (pi->fd, &fdstate.rfds); + + /* self-pipe trick to stop the event loop */ + FD_SET (server->self_pipe[0], &fdstate.rfds); + /* server socket, ready for accept() */ + FD_SET (listener, &fdstate.rfds); + + for (conn = 0; conn < FD_SETSIZE; ++conn) { + if (conn == pi->fd || conn == po->fd) + continue; + if (!(client = ws_get_client_from_list (conn, &server->colist))) + continue; + + /* As long as we are not closing a connection, we assume we always + * check a client for reading */ + if (!server->closing) { + FD_SET (conn, &fdstate.rfds); + if (conn > max_file_fd) + max_file_fd = conn; + } + /* Only if we have data to send the client */ + if (client->status & WS_SENDING) { + FD_SET (conn, &fdstate.wfds); + if (conn > max_file_fd) + max_file_fd = conn; + } + } +} + +/* Start the websocket server and start to monitor multiple file + * descriptors until we have something to read or write. */ +void +ws_start (WSServer * server) +{ + WSPipeIn *pipein = server->pipein; + WSPipeOut *pipeout = server->pipeout; + int listener = 0, conn = 0; + +#ifdef HAVE_LIBSSL + if (wsconfig.sslcert && wsconfig.sslkey) { + LOG (("==Using TLS/SSL==\n")); + wsconfig.use_ssl = 1; + if (initialize_ssl_ctx (server)) { + LOG (("Unable to initialize_ssl_ctx\n")); + return; + } + } +#endif + + memset (&fdstate, 0, sizeof fdstate); + ws_socket (&listener); + + while (1) { + /* If the pipeout file descriptor was opened after the server socket + * was opened, then it's possible the max file descriptor would be the + * pipeout fd, in any case we check this here */ + max_file_fd = MAX (listener, pipeout->fd); + /* Clear out the fd sets for this iteration. */ + FD_ZERO (&fdstate.rfds); + FD_ZERO (&fdstate.wfds); + + set_rfds_wfds (listener, server, pipein, pipeout); + max_file_fd += 1; + + /* yep, wait patiently */ + /* should it be using epoll/kqueue? will see... */ + if (select (max_file_fd, &fdstate.rfds, &fdstate.wfds, NULL, NULL) == -1) { + switch (errno) { + case EINTR: + LOG (("A signal was caught on select(2)\n")); + break; + default: + FATAL ("Unable to select: %s.", strerror (errno)); + } + } + /* handle self-pipe trick */ + if (FD_ISSET (server->self_pipe[0], &fdstate.rfds)) { + LOG (("Handled self-pipe to close event loop.\n")); + break; + } + + /* iterate over existing connections */ + for (conn = 0; conn < max_file_fd; ++conn) { + if (conn != pipein->fd && conn != pipeout->fd) { + ws_listen (listener, conn, server); + } + } + /* handle FIFOs */ + ws_fifos (server, pipein, pipeout); + } +} + +/* Set the origin so the server can force connections to have the + * given HTTP origin. */ +void +ws_set_config_origin (const char *origin) +{ + wsconfig.origin = origin; +} + +/* Set the the maximum websocket frame size. */ +void +ws_set_config_frame_size (int max_frm_size) +{ + wsconfig.max_frm_size = max_frm_size; +} + +/* Set specific name for the reader named pipe. */ +void +ws_set_config_pipein (const char *pipein) +{ + wsconfig.pipein = pipein; +} + +/* Set specific name for the writer named pipe. */ +void +ws_set_config_pipeout (const char *pipeout) +{ + wsconfig.pipeout = pipeout; +} + +/* Set a path and a file for the access log. */ +void +ws_set_config_accesslog (const char *accesslog) +{ + wsconfig.accesslog = accesslog; + + if (access_log_open (wsconfig.accesslog) == 1) + FATAL ("Unable to open access log: %s.", strerror (errno)); +} + +/* Set if the server should handle strict named pipe handling. */ +void +ws_set_config_strict (int strict) +{ + wsconfig.strict = strict; +} + +/* Set the server into echo mode. */ +void +ws_set_config_echomode (int echomode) +{ + wsconfig.echomode = echomode; +} + +/* Set the server host bind address. */ +void +ws_set_config_host (const char *host) +{ + wsconfig.host = host; +} + +/* Set the server port bind address. */ +void +ws_set_config_port (const char *port) +{ + wsconfig.port = port; +} + +/* Set specific name for the SSL certificate. */ +void +ws_set_config_sslcert (const char *sslcert) +{ + wsconfig.sslcert = sslcert; +} + +/* Set specific name for the SSL key. */ +void +ws_set_config_sslkey (const char *sslkey) +{ + wsconfig.sslkey = sslkey; +} + +/* Create a new websocket server context. */ +WSServer * +ws_init (const char *host, const char *port, void (*initopts) (void)) +{ + WSServer *server = new_wsserver (); + server->pipein = new_wspipein (); + server->pipeout = new_wspipeout (); + memset (server->self_pipe, 0, sizeof (server->self_pipe)); + + wsconfig.accesslog = NULL; + wsconfig.host = host; + wsconfig.max_frm_size = WS_MAX_FRM_SZ; + wsconfig.origin = NULL; + wsconfig.pipein = NULL; + wsconfig.pipeout = NULL; + wsconfig.sslcert = NULL; + wsconfig.sslkey = NULL; + wsconfig.port = port; + wsconfig.strict = 0; + wsconfig.use_ssl = 0; + + initopts (); + ws_fifo (server); + + return server; +} diff --git a/goaccess++/src/websocket.h b/goaccess++/src/websocket.h new file mode 100644 index 0000000..0b98618 --- /dev/null +++ b/goaccess++/src/websocket.h @@ -0,0 +1,341 @@ +/** + * _______ _______ __ __ + * / ____/ | / / ___/____ _____/ /_____ / /_ + * / / __ | | /| / /\__ \/ __ \/ ___/ //_/ _ \/ __/ + * / /_/ / | |/ |/ /___/ / /_/ / /__/ ,< / __/ /_ + * \____/ |__/|__//____/\____/\___/_/|_|\___/\__/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef WEBSOCKET_H_INCLUDED +#define WEBSOCKET_H_INCLUDED + +#include +#include +#include + +#if HAVE_LIBSSL +#include +#include +#include +#endif + +#if defined(__linux__) || defined(__CYGWIN__) +# include +#if ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 9)) +#if defined(__BYTE_ORDER) && (__BYTE_ORDER == __LITTLE_ENDIAN) +# include +# define htobe16(x) htons(x) +# define htobe64(x) (((uint64_t)htonl(((uint32_t)(((uint64_t)(x)) >> 32)))) | \ + (((uint64_t)htonl(((uint32_t)(x)))) << 32)) +# define be16toh(x) ntohs(x) +# define be32toh(x) ntohl(x) +# define be64toh(x) (((uint64_t)ntohl(((uint32_t)(((uint64_t)(x)) >> 32)))) | \ + (((uint64_t)ntohl(((uint32_t)(x)))) << 32)) +#else +# error Byte Order not supported! +#endif +#endif +#elif defined(__sun__) +# include +# define htobe16(x) BE_16(x) +# define htobe64(x) BE_64(x) +# define be16toh(x) BE_IN16(x) +# define be32toh(x) BE_IN32(x) +# define be64toh(x) BE_IN64(x) +#elif defined(__FreeBSD__) || defined(__NetBSD__) +# include +#elif defined(__OpenBSD__) +# include +# if !defined(be16toh) +# define be16toh(x) betoh16(x) +# endif +# if !defined(be32toh) +# define be32toh(x) betoh32(x) +# endif +# if !defined(be64toh) +# define be64toh(x) betoh64(x) +# endif +#elif defined(__APPLE__) +# include +# define htobe16(x) OSSwapHostToBigInt16(x) +# define htobe64(x) OSSwapHostToBigInt64(x) +# define be16toh(x) OSSwapBigToHostInt16(x) +# define be32toh(x) OSSwapBigToHostInt32(x) +# define be64toh(x) OSSwapBigToHostInt64(x) +#else +# error Platform not supported! +#endif + +#define MAX(a,b) (((a)>(b))?(a):(b)) +#include "gslist.h" + +#define WS_PIPEIN "/tmp/wspipein.fifo" +#define WS_PIPEOUT "/tmp/wspipeout.fifo" + +#define WS_BAD_REQUEST_STR "HTTP/1.1 400 Invalid Request\r\n\r\n" +#define WS_SWITCH_PROTO_STR "HTTP/1.1 101 Switching Protocols" +#define WS_TOO_BUSY_STR "HTTP/1.1 503 Service Unavailable\r\n\r\n" + +#define CRLF "\r\n" +#define SHA_DIGEST_LENGTH 20 + +/* packet header is 3 unit32_t : type, size, listener */ +#define HDR_SIZE 3 * 4 +#define WS_MAX_FRM_SZ 1048576 /* 1 MiB max frame size */ +#define WS_THROTTLE_THLD 2097152 /* 2 MiB throttle threshold */ + +#define WS_MAGIC_STR "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" +#define WS_PAYLOAD_EXT16 126 +#define WS_PAYLOAD_EXT64 127 +#define WS_PAYLOAD_FULL 125 +#define WS_FRM_HEAD_SZ 16 /* frame header size */ + +#define WS_FRM_FIN(x) (((x) >> 7) & 0x01) +#define WS_FRM_MASK(x) (((x) >> 7) & 0x01) +#define WS_FRM_R1(x) (((x) >> 6) & 0x01) +#define WS_FRM_R2(x) (((x) >> 5) & 0x01) +#define WS_FRM_R3(x) (((x) >> 4) & 0x01) +#define WS_FRM_OPCODE(x) ((x) & 0x0F) +#define WS_FRM_PAYLOAD(x) ((x) & 0x7F) + +#define WS_CLOSE_NORMAL 1000 +#define WS_CLOSE_GOING_AWAY 1001 +#define WS_CLOSE_PROTO_ERR 1002 +#define WS_CLOSE_INVALID_UTF8 1007 +#define WS_CLOSE_TOO_LARGE 1009 +#define WS_CLOSE_UNEXPECTED 1011 + +typedef enum WSSTATUS +{ + WS_OK = 0, + WS_ERR = (1 << 0), + WS_CLOSE = (1 << 1), + WS_READING = (1 << 2), + WS_SENDING = (1 << 3), + WS_THROTTLING = (1 << 4), + WS_TLS_ACCEPTING = (1 << 5), + WS_TLS_READING = (1 << 6), + WS_TLS_WRITING = (1 << 7), + WS_TLS_SHUTTING = (1 << 8), +} WSStatus; + +typedef enum WSOPCODE +{ + WS_OPCODE_CONTINUATION = 0x00, + WS_OPCODE_TEXT = 0x01, + WS_OPCODE_BIN = 0x02, + WS_OPCODE_END = 0x03, + WS_OPCODE_CLOSE = 0x08, + WS_OPCODE_PING = 0x09, + WS_OPCODE_PONG = 0x0A, +} WSOpcode; + +typedef struct WSQueue_ +{ + char *queued; /* queue data */ + int qlen; /* queue length */ +} WSQueue; + +typedef struct WSPacket_ +{ + uint32_t type; /* packet type (fixed-size) */ + uint32_t size; /* payload size in bytes (fixed-size) */ + char *data; /* payload */ + int len; /* payload buffer len */ +} WSPacket; + +/* WS HTTP Headers */ +typedef struct WSHeaders_ +{ + int reading; + int buflen; + char buf[BUFSIZ + 1]; + + char *agent; + char *path; + char *method; + char *protocol; + char *host; + char *origin; + char *upgrade; + char *referer; + char *connection; + char *ws_protocol; + char *ws_key; + char *ws_sock_ver; + + char *ws_accept; + char *ws_resp; +} WSHeaders; + +/* A WebSocket Message */ +typedef struct WSFrame_ +{ + /* frame format */ + WSOpcode opcode; /* frame opcode */ + unsigned char fin; /* frame fin flag */ + unsigned char mask[4]; /* mask key */ + uint8_t res; /* extensions */ + int payload_offset; /* end of header/start of payload */ + int payloadlen; /* payload length (for each frame) */ + + /* status flags */ + int reading; /* still reading frame's header part? */ + int masking; /* are we masking the frame? */ + + char buf[WS_FRM_HEAD_SZ + 1]; /* frame's header */ + int buflen; /* recv'd buf length so far (for each frame) */ +} WSFrame; + +/* A WebSocket Message */ +typedef struct WSMessage_ +{ + WSOpcode opcode; /* frame opcode */ + int fragmented; /* reading a fragmented frame */ + int mask_offset; /* for fragmented frames */ + + char *payload; /* payload message */ + int payloadsz; /* total payload size (whole message) */ + int buflen; /* recv'd buf length so far (for each frame) */ +} WSMessage; + +/* FD event states */ +typedef struct WSEState_ +{ + fd_set master; + fd_set rfds; + fd_set wfds; +} WSEState; + +/* A WebSocket Client */ +typedef struct WSClient_ +{ + /* socket data */ + int listener; /* socket */ + char remote_ip[INET6_ADDRSTRLEN]; /* client IP */ + + WSQueue *sockqueue; /* sending buffer */ + WSEState *state; /* FDs states */ + WSHeaders *headers; /* HTTP headers */ + WSFrame *frame; /* frame headers */ + WSMessage *message; /* message */ + WSStatus status; /* connection status */ + + struct timeval start_proc; + struct timeval end_proc; + +#ifdef HAVE_LIBSSL + SSL *ssl; + WSStatus sslstatus; /* ssl connection status */ +#endif +} WSClient; + +/* Config OOptions */ +typedef struct WSPipeIn_ +{ + int fd; /* named pipe FD */ + + WSPacket *packet; /* FIFO data's buffer */ + WSEState *state; /* FDs states */ + + char hdr[HDR_SIZE]; /* FIFO header's buffer */ + int hlen; +} WSPipeIn; + +/* Pipe Out */ +typedef struct WSPipeOut_ +{ + int fd; /* named pipe FD */ + WSEState *state; /* FDs states */ + WSQueue *fifoqueue; /* FIFO out queue */ + WSStatus status; /* connection status */ +} WSPipeOut; + +/* Config OOptions */ +typedef struct WSConfig_ +{ + /* Config Options */ + const char *accesslog; + const char *host; + const char *origin; + const char *pipein; + const char *pipeout; + const char *port; + const char *sslcert; + const char *sslkey; + int echomode; + int strict; + int max_frm_size; + int use_ssl; +} WSConfig; + +/* A WebSocket Instance */ +typedef struct WSServer_ +{ + /* Server Status */ + int closing; + + /* Callbacks */ + int (*onclose) (WSPipeOut * pipeout, WSClient * client); + int (*onmessage) (WSPipeOut * pipeout, WSClient * client); + int (*onopen) (WSPipeOut * pipeout, WSClient * client); + + /* self-pipe */ + int self_pipe[2]; + /* FIFO reader */ + WSPipeIn *pipein; + /* FIFO writer */ + WSPipeOut *pipeout; + /* Connected Clients */ + GSLList *colist; + +#ifdef HAVE_LIBSSL + SSL_CTX *ctx; +#endif +} WSServer; + +int ws_read_fifo (int fd, char *buf, int *buflen, int pos, int need); +int ws_send_data (WSClient * client, WSOpcode opcode, const char *p, int sz); +int ws_setfifo (const char *pipename); +int ws_validate_string (const char *str, int len); +int ws_write_fifo (WSPipeOut * pipeout, char *buffer, int len); +size_t pack_uint32 (void *buf, uint32_t val); +size_t unpack_uint32 (const void *buf, uint32_t * val); +void set_nonblocking (int listener); +void ws_set_config_accesslog (const char *accesslog); +void ws_set_config_echomode (int echomode); +void ws_set_config_frame_size (int max_frm_size); +void ws_set_config_host (const char *host); +void ws_set_config_origin (const char *origin); +void ws_set_config_pipein (const char *pipein); +void ws_set_config_pipeout (const char *pipeout); +void ws_set_config_port (const char *port); +void ws_set_config_sslcert (const char *sslcert); +void ws_set_config_sslkey (const char *sslkey); +void ws_set_config_strict (int strict); +void ws_start (WSServer * server); +void ws_stop (WSServer * server); +WSServer *ws_init (const char *host, const char *port, void (*initopts) (void)); + +#endif // for #ifndef WEBSOCKET_H diff --git a/goaccess++/src/websocket.o b/goaccess++/src/websocket.o new file mode 100644 index 0000000..0db5191 Binary files /dev/null and b/goaccess++/src/websocket.o differ diff --git a/goaccess++/src/xmalloc.c b/goaccess++/src/xmalloc.c new file mode 100644 index 0000000..ba4bb92 --- /dev/null +++ b/goaccess++/src/xmalloc.c @@ -0,0 +1,88 @@ +/** + * xmalloc.c -- *alloc functions with error handling + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#if !defined __SUNPRO_C +#include +#endif +#include +#include + +#include "error.h" +#include "xmalloc.h" + +/* Self-checking wrapper to malloc() */ +void * +xmalloc (size_t size) +{ + void *ptr; + + if ((ptr = malloc (size)) == NULL) + FATAL ("Unable to allocate memory - failed."); + + return (ptr); +} + +char * +xstrdup (const char *s) +{ + char *ptr; + size_t len; + + len = strlen (s) + 1; + ptr = xmalloc (len); + + strncpy (ptr, s, len); + return (ptr); +} + +/* Self-checking wrapper to calloc() */ +void * +xcalloc (size_t nmemb, size_t size) +{ + void *ptr; + + if ((ptr = calloc (nmemb, size)) == NULL) + FATAL ("Unable to calloc memory - failed."); + + return (ptr); +} + +/* Self-checking wrapper to realloc() */ +void * +xrealloc (void *oldptr, size_t size) +{ + void *newptr; + + if ((newptr = realloc (oldptr, size)) == NULL) + FATAL ("Unable to reallocate memory - failed"); + + return (newptr); +} diff --git a/goaccess++/src/xmalloc.h b/goaccess++/src/xmalloc.h new file mode 100644 index 0000000..dafd739 --- /dev/null +++ b/goaccess++/src/xmalloc.h @@ -0,0 +1,38 @@ +/** + * ______ ___ + * / ____/___ / | _____________ __________ + * / / __/ __ \/ /| |/ ___/ ___/ _ \/ ___/ ___/ + * / /_/ / /_/ / ___ / /__/ /__/ __(__ |__ ) + * \____/\____/_/ |_\___/\___/\___/____/____/ + * + * The MIT License (MIT) + * Copyright (c) 2009-2016 Gerardo Orellana + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef XMALLOC_H_INCLUDED +#define XMALLOC_H_INCLUDED + +char *xstrdup (const char *s); +void *xcalloc (size_t nmemb, size_t size); +void *xmalloc (size_t size); +void *xrealloc (void *oldptr, size_t size); + +#endif diff --git a/goaccess++/src/xmalloc.o b/goaccess++/src/xmalloc.o new file mode 100644 index 0000000..d9a8311 Binary files /dev/null and b/goaccess++/src/xmalloc.o differ diff --git a/model/基于Nginx的高可用分布式网关管理系统的分析和设计UML模型.docx b/model/基于Nginx的高可用分布式网关管理系统的分析和设计UML模型.docx new file mode 100644 index 0000000..06e55cb Binary files /dev/null and b/model/基于Nginx的高可用分布式网关管理系统的分析和设计UML模型.docx differ