wpMandrill - Version 1.05

Version Description

Download this release

Release Info

Developer MC_Will
Plugin Icon wp plugin wpMandrill
Version 1.05
Comparing to
See all releases

Code changes from version 1.04 to 1.05

trunk/css/mandrill.css ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .wrap h2 small {
2
+ font-size: 10px;
3
+ }
4
+ .news_header {
5
+ background: url("../images/rss_icon.gif") no-repeat scroll 0 0 transparent;
6
+ padding-left: 30px;
7
+ line-height: 20px;
8
+ }
9
+ .news {
10
+ background: url("../images/FreddieHead.png") no-repeat bottom right #FFFFCC;
11
+ border: 1px solid yellow;
12
+ float: right;
13
+ padding: 15px;
14
+ margin-top: 45px;
15
+ padding-bottom: 80px;
16
+ width: 100%;
17
+ }
18
+ .mandrill {
19
+ background: url("../images/MandrillHead.png") no-repeat bottom right #FFFFCC;
20
+ }
21
+ .news ul li a {
22
+ color: #000;
23
+ }
24
+
25
+ .missing {
26
+ background-color: #FFEBE8;
27
+ border: 1px solid #CC0000;
28
+ padding: 3px;
29
+ font-weight: bold;
30
+ }
31
+
32
+ .stat_box {
33
+ background-color: #FFFFCC;
34
+ border: 1px solid yellow;
35
+ float: left;
36
+ font-size: 12px;
37
+ margin: 10px;
38
+ padding: 10px;
39
+ width: auto;
40
+ text-align: center;
41
+ }
42
+
43
+ .warning {
44
+ background-color: #FFCCCC;
45
+ border: 1px solid #FF3366;
46
+ }
47
+
48
+ .stat_box span {
49
+ font-weight: bold;
50
+ font-size: 14px;
51
+ }
52
+ #ajax-icon-container {
53
+ width: 20px;
54
+ height: 20px;
55
+ float: left;
56
+ }
57
+ #loading_data{
58
+ background: url("../images/icon-ajax-loading.gif") no-repeat transparent;
59
+ height: 20px;
60
+ width: 20px;
61
+ display: block;
62
+ }
63
+ .stuffbox {
64
+ max-width: 90% !important;
65
+ margin-top:15px;
66
+ }
67
+ .stuffbox h3 { cursor: default !important; padding: 3px 3px 3px 10px; }
68
+ .stuffbox div.inside { padding-bottom: 10px;}
trunk/how-tos.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class wpMandrill_HowTos {
4
+ static function show($section) {
5
+ $section = strtolower($section);
6
+ if ( !in_array($section, array('intro','auto','regular','filter','direct') ) ) $section = 'auto';
7
+
8
+ $title = '';
9
+
10
+ switch ($section) {
11
+ case 'intro':
12
+ break;
13
+ case 'auto':
14
+ $title = __('Mandrill: How to tell WordPress to use wpMandrill.', 'wpmandrill');
15
+ break;
16
+ case 'regular':
17
+ $title = __('Mandrill: How to send a regular email.', 'wpmandrill');
18
+ break;
19
+ case 'filter':
20
+ $title = __('Mandrill: How to modify a certain email using the <em>mandrill_payload</em> WordPress filter.', 'wpmandrill');
21
+ break;
22
+ case 'direct':
23
+ $title = __('Mandrill: How to send emails from within your plugins.', 'wpmandrill');
24
+ break;
25
+ }
26
+
27
+ $method = 'showSection' . ucwords($section);
28
+
29
+ $html = self::$method();
30
+
31
+ if ( $title != '' ) {
32
+ $html = <<<HTML
33
+ <div class="stuffbox" style="max-width: 90% !important;">
34
+ <h3>$title</h3>
35
+ <div style="width:90%; margin-left:auto;margin-right:auto;">
36
+ $html
37
+ </div>
38
+ </div>
39
+ HTML;
40
+ }
41
+
42
+ return $html;
43
+ }
44
+
45
+ static function showSectionIntro() {
46
+ return '<p>' . __('The purpose of this how-to is to show you how easy it is to start using the awesome platform that Mandrill offers to handle your transactional emails.', 'wpmandrill-how-tos').'</p>'
47
+ . '<ol>'
48
+ . '<li>'. __('Just by setting it up, all the emails sent from your WordPress installation will be sent using the power of Mandrill.', 'wpmandrill') . '</li>'
49
+ . '<li>'. __('If you want further customization, you can use the <strong>mandrill_payload</strong> filter we\'ve provided.', 'wpmandrill') . '</li>'
50
+ . '<li>'. __('And if you want an even greater integration between your application and Mandrill, we\'ve created a convenient call to send emails from within your plugins.', 'wpmandrill') . '</li>'
51
+ . '</ol>'
52
+ .'<p>' . __('You can learn more about all of these features right from this page.', 'wpmandrill').'</p>';
53
+ }
54
+
55
+ static function showSectionAuto() {
56
+
57
+ return '
58
+ <span class="setting-description">
59
+ <p>'.__('Simply install wpMandrill and configure it to make it handle all the email functions of your WordPress installation.', 'wpmandrill').'</p>
60
+ <p>'.__('Once it has been properly configured, it will replace the regular WordPress emailing processes, so it\'s basically transparent for you and for WordPress.', 'wpmandrill').'</p>
61
+ <p>'.__('To test wpMandrill, log out, and try to use the <em>Forgot your password?</em> feature in WordPress (you don\'t need to reset your password though. Just check the headers of the email that it sends you, and you\'ll see that it comes from Mandrill\'s servers).', 'wpmandrill').'</p>
62
+ </span>
63
+ ';
64
+ }
65
+
66
+ static function showSectionRegular() {
67
+ return '
68
+ <span class="setting-description">
69
+ <p>'.__('If you\'re a Plugin Developer, and you need to send a regular email using wpMandrill, you don\'t need to learn anything else. You can use the good ol\' <strong>wp_mail</strong> function, as you would normally do if you were not using this plugin.', 'wpmandrill').'</p>
70
+ <p>'.__('For example:', 'wpmandrill').'</p>
71
+ <p><blockquote><pre>'.__('&lt;?php wp_mail(\'your@address.com\', \'Your subject\', \'Your message\'); ?&gt;', 'wpmandrill').'</pre></blockquote></p>
72
+ </span>
73
+ ';
74
+ }
75
+
76
+ static function showSectionFilter() {
77
+ return '
78
+ <span class="setting-description">
79
+ <p>'.__('if you need to fine tune one or some of the emails sent through your WordPress installation, you will need to use the <em>mandrill_payload</em> filter.', 'wpmandrill').'</p>
80
+ <p>'.__('To use it, you must create a function that analyzes the payload that is about to be sent to Mandrill, and modify it based on your requirements. Then you\'ll need to add this function as the callback of the mentioned filter, using the <em>add_filter</em> WordPress call. And finally, insert it into your theme\'s functions.php file or you own plugin\'s file.', 'wpmandrill').'</p>
81
+ <p>'.__('You can use the following code as an skeleton for your own callbacks:', 'wpmandrill').'</p>
82
+ <p>
83
+ <blockquote><pre>
84
+ &lt;?php
85
+ &nbsp;&nbsp;&nbsp;function my_callback($message) {
86
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( my_condition($message) ) {
87
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$message = my_process($message)
88
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
89
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $message;
90
+ &nbsp;&nbsp;&nbsp;}
91
+ &nbsp;&nbsp;&nbsp;add_filter( \'mandrill_payload\', \'my_callback\' );
92
+ ?&gt;
93
+ </pre></blockquote>
94
+ </p>
95
+ <p>'.__('Let\'s say you\'re using the <a href="http://wordpress.org/extend/plugins/cart66-lite/" target="_blank">Cart66 Lite Ecommerce plugin</a> and you want to modify the emails sent from this plugin. Here\'s what you should do:', 'wpmandrill').'</p>
96
+ <p>
97
+ <blockquote><pre>
98
+ &lt;?php
99
+ &nbsp;&nbsp;&nbsp;function cart66Emails($message) {
100
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( in_array( \'wp_Cart66Common::mail\', $message[\'tags\'][\'automatic\'] ) ) {
101
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// do anything funny here...
102
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( isset($message[\'template\'][\'content\'][0][\'content\']) )
103
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$html = &$message[\'template\'][\'content\'][0][\'content\'];
104
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
105
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$html = &$message[\'html\'];
106
+
107
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$html = nl2br($html);
108
+
109
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
110
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $message;
111
+ &nbsp;&nbsp;&nbsp;}
112
+ &nbsp;&nbsp;&nbsp;add_filter( \'mandrill_payload\', \'cart66Emails\' );
113
+ ?&gt;
114
+ </pre></blockquote>
115
+ </p>
116
+ </span>
117
+ ';
118
+ }
119
+
120
+ static function showSectionDirect() {
121
+ return '
122
+ <span class="setting-description">
123
+ <p>'.__('If you are a Plugin Developer and you need to create a deep integration between Mandrill and your WordPress installation, wpMandrill will make your life easier.', 'wpmandrill').'</p>
124
+ <p>'.__('We have exposed a simple function that allows you to add tags and specify the template to use, in addition to specifying the To, Subject and Body sections of the email:','wpmandrill').'</p>
125
+ <p><blockquote><pre>'.__('&lt;?php wpMandrill::mail($to, $subject, $html, $headers = \'\', $attachments = array(), $tags = array(), $from_name = \'\', $from_email = \'\', $template_name = \'\'); ?&gt;', 'wpmandrill').'</pre></blockquote></p>
126
+ <p>'.__('But if you need Mandrill Powers, we have included a full-featured PHP class called Mandrill. It has every API call defined in Mandrill\'s API. Check it out at <em>/wp-content/plugin/wpmandrill/lib/mandrill.class.php</em>.', 'wpmandrill').'</p>
127
+ <p>'.__('To use it, just instantiate an object passing your API key, and make the calls:', 'wpmandrill').'</p>
128
+ <p><blockquote><pre>'.__('&lt;?php $mandrill = Mandrill($my_api_key); echo $mandrill->ping(); ?&gt;', 'wpmandrill').'</pre></blockquote></p>
129
+ </span>
130
+ ';
131
+ }
132
+
133
+ }
134
+
135
+ ?>
trunk/images/FreddieHead.png ADDED
Binary file
trunk/images/MandrillHead.png ADDED
Binary file
trunk/images/icon-ajax-loading.gif ADDED
Binary file
trunk/images/mandrill-head-icon.png ADDED
Binary file
trunk/images/rss_icon.gif ADDED
Binary file
trunk/js/highcharts.js ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Highcharts JS v2.2.1 (2012-03-15)
3
+
4
+ (c) 2009-2011 Torstein H?nsi
5
+
6
+ License: www.highcharts.com/license
7
+ */
8
+ (function(){function L(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function za(){for(var a=0,b=arguments,c=b.length,d={};a<c;a++)d[b[a++]]=b[a];return d}function S(a,b){return parseInt(a,b||10)}function Ab(a){return typeof a==="string"}function mb(a){return typeof a==="object"}function Fb(a){return Object.prototype.toString.call(a)==="[object Array]"}function Bb(a){return typeof a==="number"}function nb(a){return oa.log(a)/oa.LN10}function cb(a){return oa.pow(10,a)}function Gb(a,b){for(var c=
9
+ a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function s(a){return a!==X&&a!==null}function A(a,b,c){var d,e;if(Ab(b))s(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(s(b)&&mb(b))for(d in b)a.setAttribute(d,b[d]);return e}function Hb(a){return Fb(a)?a:[a]}function p(){var a=arguments,b,c,d=a.length;for(b=0;b<d;b++)if(c=a[b],typeof c!=="undefined"&&c!==null)return c}function P(a,b){if(Qb&&b&&b.opacity!==X)b.filter="alpha(opacity="+b.opacity*100+")";L(a.style,b)}function Aa(a,
10
+ b,c,d,e){a=x.createElement(a);b&&L(a,b);e&&P(a,{padding:0,border:Ma,margin:0});c&&P(a,c);d&&d.appendChild(a);return a}function pa(a,b){var c=function(){};c.prototype=new a;L(c.prototype,b);return c}function dc(a,b,c,d){var e=Ea.lang,f=isNaN(b=Ba(b))?2:b,b=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=a<0?"-":"",c=String(S(a=Ba(+a||0).toFixed(f))),g=c.length>3?c.length%3:0;return e+(g?c.substr(0,g)+d:"")+c.substr(g).replace(/(\d{3})(?=\d)/g,"$1"+d)+(f?b+Ba(a-c).toFixed(f).slice(2):"")}
11
+ function Na(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function ec(a,b,c,d){var e,c=p(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d<b.length;d++)if(a=b[d],e<=(b[d]+(b[d+1]||b[d]))/2)break;a*=c;return a}function Kc(a,b){var c=b||[[Rb,[1,2,5,10,20,25,50,100,200,500]],[ob,[1,2,5,10,15,30]],[pb,[1,2,5,10,15,30]],[va,[1,2,3,4,6,8,12]],[Ca,[1,2]],[Ya,[1,2]],[Da,[1,2,3,4,6]],[Za,null]],d=c[c.length-1],e=E[d[0]],f=d[1],g;for(g=0;g<c.length;g++)if(d=
12
+ c[g],e=E[d[0]],f=d[1],c[g+1]&&a<=(e*f[f.length-1]+E[c[g+1][0]])/2)break;e===E[Za]&&a<5*e&&(f=[1,2,5]);e===E[Za]&&a<5*e&&(f=[1,2,5]);c=ec(a/e,f);return{unitRange:e,count:c,unitName:d[0]}}function Lc(a,b,c,d){var e=[],f={},g=Ea.global.useUTC,h,i=new Date(b),b=a.unitRange,k=a.count;b>=E[ob]&&(i.setMilliseconds(0),i.setSeconds(b>=E[pb]?0:k*Ta(i.getSeconds()/k)));if(b>=E[pb])i[pc](b>=E[va]?0:k*Ta(i[fc]()/k));if(b>=E[va])i[qc](b>=E[Ca]?0:k*Ta(i[gc]()/k));if(b>=E[Ca])i[hc](b>=E[Da]?1:k*Ta(i[db]()/k));b>=
13
+ E[Da]&&(i[rc](b>=E[Za]?0:k*Ta(i[qb]()/k)),h=i[rb]());b>=E[Za]&&(h-=h%k,i[sc](h));if(b===E[Ya])i[hc](i[db]()-i[ic]()+p(d,1));d=1;h=i[rb]();for(var j=i.getTime(),l=i[qb](),i=i[db]();j<c;)e.push(j),b===E[Za]?j=sb(h+d*k,0):b===E[Da]?j=sb(h,l+d*k):!g&&(b===E[Ca]||b===E[Ya])?j=sb(h,l,i+d*k*(b===E[Ca]?1:7)):(j+=b*k,b<=E[va]&&j%E[Ca]===0&&(f[j]=Ca)),d++;e.push(j);e.info=L(a,{higherRanks:f,totalRange:b*k});return e}function tc(){this.symbol=this.color=0}function uc(a,b,c,d,e,f,g,h,i){var k=g.x,g=g.y,i=k+c+
14
+ (i?h:-a-h),j=g-b+d+15,l;i<7&&(i=c+k+h);i+a>c+e&&(i-=i+a-(c+e),j=g-b+d-h,l=!0);j<d+5?(j=d+5,l&&g>=j&&g<=j+b&&(j=g+d+h)):j+b>d+f&&(j=d+f-b-h);return{x:i,y:j}}function Mc(a,b){var c=a.length,d,e;for(e=0;e<c;e++)a[e].ss_i=e;a.sort(function(a,c){d=b(a,c);return d===0?a.ss_i-c.ss_i:d});for(e=0;e<c;e++)delete a[e].ss_i}function Sb(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function Ib(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Jb(a){for(var b in a)a[b]&&a[b].destroy&&
15
+ a[b].destroy(),delete a[b]}function Tb(a){tb||(tb=Aa(Ra));a&&tb.appendChild(a);tb.innerHTML=""}function jc(a,b){var c="Highcharts error #"+a+": www.highcharts.com/errors/"+a;if(b)throw c;else ca.console&&console.log(c)}function Cb(a){return parseFloat(a.toPrecision(14))}function Kb(a,b){Ub=p(a,b.animation)}function vc(){var a=Ea.global.useUTC,b=a?"getUTC":"get",c=a?"setUTC":"set";sb=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,p(c,1),p(g,0),p(h,0),p(i,0))).getTime()};fc=b+"Minutes";gc=b+"Hours";
16
+ ic=b+"Day";db=b+"Date";qb=b+"Month";rb=b+"FullYear";pc=c+"Minutes";qc=c+"Hours";hc=c+"Date";rc=c+"Month";sc=c+"FullYear"}function Sa(){}function wc(a,b){function c(a){function b(a,c){this.pos=a;this.type=c||"";this.isNew=!0;c||this.addLabel()}function c(a){if(a)this.options=a,this.id=a.id;return this}function d(a,b,c,e){this.isNegative=b;this.options=a;this.x=c;this.stack=e;this.alignOptions={align:a.align||(U?b?"left":"right":"center"),verticalAlign:a.verticalAlign||(U?"middle":b?"bottom":"top"),
17
+ y:p(a.y,U?4:b?14:-6),x:p(a.x,U?b?-6:6:0)};this.textAlign=a.textAlign||(U?b?"right":"left":"center")}function e(){var a=[],b=[],c;C=M=null;o(B.series,function(e){if(e.visible||!q.ignoreHiddenSeries){var f=e.options,g,h,i,j,k,m,l,n,Y,ea=f.threshold,B,o=[],xc=0;if(R&&ea<=0)ea=f.threshold=null;if(t)f=e.xData,f.length&&(C=Ua(p(C,f[0]),Sb(f)),M=W(p(M,f[0]),Ib(f)));else{var y,r,G,v=e.cropped,Z=e.xAxis.getExtremes(),V=!!e.modifyValue;g=f.stacking;Ha=g==="percent";if(g)k=f.stack,j=e.type+p(k,""),m="-"+j,e.stackKey=
18
+ j,h=a[j]||[],a[j]=h,i=b[m]||[],b[m]=i;Ha&&(C=0,M=99);f=e.processedXData;l=e.processedYData;B=l.length;for(c=0;c<B;c++)if(n=f[c],Y=l[c],Y!==null&&Y!==X&&(g?(r=(y=Y<ea)?i:h,G=y?m:j,Y=r[n]=s(r[n])?r[n]+Y:Y,qa[G]||(qa[G]={}),qa[G][n]||(qa[G][n]=new d(u.stackLabels,y,n,k)),qa[G][n].setTotal(Y)):V&&(Y=e.modifyValue(Y)),v||(f[c+1]||n)>=Z.min&&(f[c-1]||n)<=Z.max))if(n=Y.length)for(;n--;)Y[n]!==null&&(o[xc++]=Y[n]);else o[xc++]=Y;!Ha&&o.length&&(C=Ua(p(C,o[0]),Sb(o)),M=W(p(M,o[0]),Ib(o)));s(ea)&&(C>=ea?(C=
19
+ ea,Ma=!0):M<ea&&(M=ea,Na=!0))}}})}function f(a,b,c){for(var d,b=Cb(Ta(b/a)*a),c=Cb(Yb(c/a)*a),e=[];b<=c;){e.push(b);b=Cb(b+a);if(b===d)break;d=b}return e}function g(a,b,c,d){var e=[];if(!d)B._minorAutoInterval=null;if(a>=0.5)a=z(a),e=f(a,b,c);else if(a>=0.08){var h=Ta(b),i,j,k,n,m,l;for(i=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];h<c+1&&!l;h++){k=i.length;for(j=0;j<k&&!l;j++)n=nb(cb(h)*i[j]),n>b&&e.push(m),m>c&&(l=!0),m=n}}else if(b=cb(b),c=cb(c),a=u[d?"minorTickInterval":"tickInterval"],
20
+ a=p(a==="auto"?null:a,B._minorAutoInterval,(c-b)*(u.tickPixelInterval/(d?5:1))/((d?D/N.length:D)||1)),a=ec(a,null,oa.pow(10,Ta(oa.log(a)/oa.LN10))),e=Vb(f(a,b,c),nb),!d)B._minorAutoInterval=a/5;d||(Oa=a);return e}function h(){var a=[],b,c;if(R){c=N.length;for(b=1;b<c;b++)a=a.concat(g(Ga,N[b-1],N[b],!0))}else for(b=F+(N[0]-F)%Ga;b<=H;b+=Ga)a.push(b);return a}function i(){var a,b=M-C>=fb,c,d,e,f,g,h;t&&fb===X&&!R&&(s(u.min)||s(u.max)?fb=null:(o(B.series,function(a){f=a.xData;for(d=g=a.xIncrement?1:
21
+ f.length-1;d>0;d--)if(e=f[d]-f[d-1],c===X||e<c)c=e}),fb=Ua(c*5,M-C)));H-F<fb&&(a=(fb-H+F)/2,a=[F-a,p(u.min,F-a)],b&&(a[2]=C),F=Ib(a),h=[F+fb,p(u.max,F+fb)],b&&(h[2]=M),H=Sb(h),H-F<fb&&(a[0]=H-fb,a[1]=p(u.min,H-fb),F=Ib(a)))}function j(a){var b,c=u.tickInterval,d=u.tickPixelInterval;da?(na=m[t?"xAxis":"yAxis"][u.linkedTo],b=na.getExtremes(),F=p(b.min,b.dataMin),H=p(b.max,b.dataMax),u.type!==na.options.type&&jc(11,1)):(F=p(ba,u.min,C),H=p(ca,u.max,M));R&&(!a&&Ua(F,C)<=0&&jc(10,1),F=nb(F),H=nb(H));ja&&
22
+ (ba=F=W(F,H-ja),ca=H,a&&(ja=null));i();if(!Va&&!Ha&&!da&&s(F)&&s(H)){b=H-F||1;if(!s(u.min)&&!s(ba)&&Ea&&(C<0||!Ma))F-=b*Ea;if(!s(u.max)&&!s(ca)&&Ja&&(M>0||!Na))H+=b*Ja}Oa=F===H||F===void 0||H===void 0?1:da&&!c&&d===na.options.tickPixelInterval?na.tickInterval:p(c,Va?1:(H-F)*d/(D||1));t&&!a&&o(B.series,function(a){a.processData(F!==ma||H!==za)});ib();B.beforeSetTickPositions&&B.beforeSetTickPositions();B.postProcessTickInterval&&(Oa=B.postProcessTickInterval(Oa));!V&&!R&&(Wa=oa.pow(10,Ta(oa.log(Oa)/
23
+ oa.LN10)),s(u.tickInterval)||(Oa=ec(Oa,null,Wa,u)));B.tickInterval=Oa;Ga=u.minorTickInterval==="auto"&&Oa?Oa/5:u.minorTickInterval;(N=u.tickPositions||Xa&&Xa.apply(B,[F,H]))||(N=V?(B.getNonLinearTimeTicks||Lc)(Kc(Oa,u.units),F,H,u.startOfWeek,B.ordinalPositions,B.closestPointRange,!0):R?g(Oa,F,H):f(Oa,F,H));if(!da&&(a=N[0],c=N[N.length-1],u.startOnTick?F=a:F>a&&N.shift(),u.endOnTick?H=c:H<c&&N.pop(),gb||(gb={x:0,y:0}),!V&&N.length>gb[w]&&u.alignTicks!==!1))gb[w]=N.length}function k(a){a=(new c(a)).render();
24
+ ta.push(a);return a}function l(){var a=u.title,d=u.stackLabels,e=u.alternateGridColor,f=u.lineWidth,g,i,j=m.hasRendered&&s(ma)&&!isNaN(ma),n=(g=B.series.length&&s(F)&&s(H))||p(u.showEmpty,!0),Y,q;if(g||da)if(Ga&&!Va&&o(h(),function(a){va[a]||(va[a]=new b(a,"minor"));j&&va[a].isNew&&va[a].render(null,!0);va[a].isActive=!0;va[a].render()}),o(N.slice(1).concat([N[0]]),function(a,c){c=c===N.length-1?0:c+1;if(!da||a>=F&&a<=H)Pa[a]||(Pa[a]=new b(a)),j&&Pa[a].isNew&&Pa[a].render(c,!0),Pa[a].isActive=!0,
25
+ Pa[a].render(c)}),e&&o(N,function(a,b){if(b%2===0&&a<H)Da[a]||(Da[a]=new c),Y=a,q=N[b+1]!==X?N[b+1]:H,Da[a].options={from:R?cb(Y):Y,to:R?cb(q):q,color:e},Da[a].render(),Da[a].isActive=!0}),!B._addedPlotLB)o((u.plotLines||[]).concat(u.plotBands||[]),function(a){k(a)}),B._addedPlotLB=!0;o([Pa,va,Da],function(a){for(var b in a)a[b].isActive?a[b].isActive=!1:(a[b].destroy(),delete a[b])});f&&(g=x+(y?A:0)+T,i=ra-Lb-(y?hb:0)+T,g=I.crispLine([wa,G?x:g,G?i:E,fa,G?sa-Zb:g,G?i:ra-Lb],f),$?$.animate({d:g}):
26
+ $=I.path(g).attr({stroke:u.lineColor,"stroke-width":f,zIndex:7}).add(),$[n?"show":"hide"]());if(v&&n)n=G?x:E,f=S(a.style.fontSize||12),n={low:n+(G?0:D),middle:n+D/2,high:n+(G?D:0)}[a.align],f=(G?E+hb:x)+(G?1:-1)*(y?-1:1)*Ya+(r===2?f:0),v[v.isNew?"attr":"animate"]({x:G?n:f+(y?A:0)+T+(a.x||0),y:G?f-(y?hb:0)+T:n+(a.y||0)}),v.isNew=!1;if(d&&d.enabled){var t,yc,d=B.stackTotalGroup;if(!d)B.stackTotalGroup=d=I.g("stack-labels").attr({visibility:eb,zIndex:6}).translate(O,J).add();for(t in qa)for(yc in a=
27
+ qa[t],a)a[yc].render(d)}B.isDirty=!1}function n(a){for(var b=ta.length;b--;)ta[b].id===a&&ta[b].destroy()}var t=a.isX,y=a.opposite,G=U?!t:t,r=G?y?0:2:y?1:3,qa={},u=K(t?$b:kc,[Nc,Oc,zc,Pc][r],a),B=this,v,Z=u.type,V=Z==="datetime",R=Z==="logarithmic",T=u.offset||0,w=t?"x":"y",D=0,ua,ia,bb,jb,x,E,A,hb,Lb,Zb,Mb,ib,P,Q,bc,$,C,M,fb=u.minRange||u.maxZoom,ja=u.range,ba,ca,Aa,Ca,H=null,F=null,ma,za,Ea=u.minPadding,Ja=u.maxPadding,Ka=0,da=s(u.linkedTo),na,Ma,Na,Ha,Z=u.events,Sa,ta=[],Oa,Ga,Wa,N,Xa=u.tickPositioner,
28
+ Pa={},va={},Da={},Fa,La,Ya,Va=u.categories,db=u.labels.formatter||function(){var a=this.value,b=this.dateTimeLabelFormat;return b?ac(b,a):Oa%1E6===0?a/1E6+"M":Oa%1E3===0?a/1E3+"k":!Va&&a>=1E3?dc(a,0):a},Ra=G&&u.labels.staggerLines,ya=u.reversed,Ia=Va&&u.tickmarkPlacement==="between"?0.5:0;b.prototype={addLabel:function(){var a=this.pos,b=u.labels,c=Va&&G&&Va.length&&!b.step&&!b.staggerLines&&!b.rotation&&ka/Va.length||!G&&ka/2,d=a===N[0],e=a===N[N.length-1],f=Va&&s(Va[a])?Va[a]:a,g=this.label,h=N.info,
29
+ i;V&&h&&(i=u.dateTimeLabelFormats[h.higherRanks[a]||h.unitName]);this.isFirst=d;this.isLast=e;a=db.call({axis:B,chart:m,isFirst:d,isLast:e,dateTimeLabelFormat:i,value:R?Cb(cb(f)):f});c=c&&{width:W(1,z(c-2*(b.padding||10)))+ga};c=L(c,b.style);s(g)?g&&g.attr({text:a}).css(c):this.label=s(a)&&b.enabled?I.text(a,0,0,b.useHTML).attr({align:b.align,rotation:b.rotation}).css(c).add(Q):null},getLabelSize:function(){var a=this.label;return a?(this.labelBBox=a.getBBox())[G?"height":"width"]:0},getLabelSides:function(){var a=
30
+ u.labels,b=this.labelBBox.width,a=b*{left:0,center:0.5,right:1}[a.align]-a.x;return[-a,b-a]},handleOverflow:function(a){var b=!0,c=this.isFirst,d=this.isLast,e=this.label,f=e.x;if(c||d){var g=this.getLabelSides(),h=g[0],g=g[1],i=m.plotLeft,j=i+B.len,k=(a=Pa[N[a+(c?1:-1)]])&&a.label.x+a.getLabelSides()[c?0:1];c&&!ya||d&&ya?f+h<i&&(f=i-h,a&&f+g>k&&(b=!1)):f+g>j&&(f=j-g,a&&f+h<k&&(b=!1));e.x=f}return b},render:function(a,b){var c=this.type,d=this.label,e=this.pos,f=u.labels,g=this.gridLine,h=c?c+"Grid":
31
+ "grid",i=c?c+"Tick":"tick",j=u[h+"LineWidth"],k=u[h+"LineColor"],n=u[h+"LineDashStyle"],m=u[i+"Length"],h=u[i+"Width"]||0,l=u[i+"Color"],Y=u[i+"Position"],i=this.mark,q=f.step,ea=b&&Za||ra,qa=!0,o;o=G?Mb(e+Ia,null,null,b)+bb:x+T+(y?(b&&$a||sa)-Zb-x:0);ea=G?ea-Lb+T-(y?hb:0):ea-Mb(e+Ia,null,null,b)-bb;if(j){e=P(e+Ia,j,b);if(g===X){g={stroke:k,"stroke-width":j};if(n)g.dashstyle=n;if(!c)g.zIndex=1;this.gridLine=g=j?I.path(e).attr(g).add(bc):null}!b&&g&&e&&g.animate({d:e})}if(h)Y==="inside"&&(m=-m),y&&
32
+ (m=-m),c=I.crispLine([wa,o,ea,fa,o+(G?0:-m),ea+(G?m:0)],h),i?i.animate({d:c}):this.mark=I.path(c).attr({stroke:l,"stroke-width":h}).add(Q);if(d&&!isNaN(o))o=o+f.x-(Ia&&G?Ia*ia*(ya?-1:1):0),ea=ea+f.y-(Ia&&!G?Ia*ia*(ya?1:-1):0),s(f.y)||(ea+=S(d.styles.lineHeight)*0.9-d.getBBox().height/2),Ra&&(ea+=a/(q||1)%Ra*16),d.x=o,d.y=ea,this.isFirst&&!p(u.showFirstLabel,1)||this.isLast&&!p(u.showLastLabel,1)?qa=!1:!Ra&&G&&f.overflow==="justify"&&!this.handleOverflow(a)&&(qa=!1),q&&a%q&&(qa=!1),qa?(d[this.isNew?
33
+ "attr":"animate"]({x:d.x,y:d.y}),d.show(),this.isNew=!1):d.hide()},destroy:function(){Jb(this)}};c.prototype={render:function(){var a=this,b=(B.pointRange||0)/2,c=a.options,d=c.label,e=a.label,f=c.width,g=c.to,h=c.from,i=c.value,j,k=c.dashStyle,n=a.svgElem,m=[],l,Y,u=c.color;Y=c.zIndex;var ea=c.events;R&&(h=nb(h),g=nb(g),i=nb(i));if(f){if(m=P(i,f),b={stroke:u,"stroke-width":f},k)b.dashstyle=k}else if(s(h)&&s(g))h=W(h,F-b),g=Ua(g,H+b),j=P(g),(m=P(h))&&j?m.push(j[4],j[5],j[1],j[2]):m=null,b={fill:u};
34
+ else return;if(s(Y))b.zIndex=Y;if(n)m?n.animate({d:m},null,n.onGetPath):(n.hide(),n.onGetPath=function(){n.show()});else if(m&&m.length&&(a.svgElem=n=I.path(m).attr(b).add(),ea))for(l in k=function(b){n.on(b,function(c){ea[b].apply(a,[c])})},ea)k(l);if(d&&s(d.text)&&m&&m.length&&A>0&&hb>0){d=K({align:G&&j&&"center",x:G?!j&&4:10,verticalAlign:!G&&j&&"middle",y:G?j?16:10:j?6:-4,rotation:G&&!j&&90},d);if(!e)a.label=e=I.text(d.text,0,0).attr({align:d.textAlign||d.align,rotation:d.rotation,zIndex:Y}).css(d.style).add();
35
+ j=[m[1],m[4],p(m[6],m[1])];m=[m[2],m[5],p(m[7],m[2])];l=Sb(j);Y=Sb(m);e.align(d,!1,{x:l,y:Y,width:Ib(j)-l,height:Ib(m)-Y});e.show()}else e&&e.hide();return a},destroy:function(){Jb(this);Gb(ta,this)}};d.prototype={destroy:function(){Jb(this)},setTotal:function(a){this.cum=this.total=a},render:function(a){var b=this.options.formatter.call(this);this.label?this.label.attr({text:b,visibility:ab}):this.label=m.renderer.text(b,0,0).css(this.options.style).attr({align:this.textAlign,rotation:this.options.rotation,
36
+ visibility:ab}).add(a)},setOffset:function(a,b){var c=this.isNegative,d=B.translate(this.total,0,0,0,1),e=B.translate(0),e=Ba(d-e),f=m.xAxis[0].translate(this.x)+a,g=m.plotHeight,c={x:U?c?d:d-e:f,y:U?g-f-b:c?g-d-e:g-d,width:U?e:b,height:U?b:e};this.label&&this.label.align(this.alignOptions,null,c).attr({visibility:eb})}};Mb=function(a,b,c,d,e){var f=1,g=0,h=d?jb:ia,d=d?ma:F,e=u.ordinal||R&&e;h||(h=ia);c&&(f*=-1,g=D);ya&&(f*=-1,g-=f*D);b?(ya&&(a=D-a),a=a/h+d,e&&(a=B.lin2val(a))):(e&&(a=B.val2lin(a)),
37
+ a=f*(a-d)*h+g+f*Ka);return a};P=function(a,b,c){var d,e,f,a=Mb(a,null,null,c),g=c&&Za||ra,h=c&&$a||sa,i,c=e=z(a+bb);d=f=z(g-a-bb);if(isNaN(a))i=!0;else if(G){if(d=E,f=g-Lb,c<x||c>x+A)i=!0}else if(c=x,e=h-Zb,d<E||d>E+hb)i=!0;return i?null:I.crispLine([wa,c,d,fa,e,f],b||0)};ib=function(){var a=H-F,b=0,c,d;if(t)da?b=na.pointRange:o(B.series,function(a){b=W(b,a.pointRange);d=a.closestPointRange;!a.noSharedTooltip&&s(d)&&(c=s(c)?Ua(c,d):d)}),B.pointRange=b,B.closestPointRange=c;jb=ia;B.translationSlope=
38
+ ia=D/(a+b||1);bb=G?x:Lb;Ka=ia*(b/2)};xa.push(B);m[t?"xAxis":"yAxis"].push(B);U&&t&&ya===X&&(ya=!0);L(B,{addPlotBand:k,addPlotLine:k,adjustTickAmount:function(){if(gb&&gb[w]&&!V&&!Va&&!da&&u.alignTicks!==!1){var a=Fa,b=N.length;Fa=gb[w];if(b<Fa){for(;N.length<Fa;)N.push(Cb(N[N.length-1]+Oa));ia*=(b-1)/(Fa-1);H=N[N.length-1]}if(s(a)&&Fa!==a)B.isDirty=!0}},categories:Va,getExtremes:function(){return{min:R?Cb(cb(F)):F,max:R?Cb(cb(H)):H,dataMin:C,dataMax:M,userMin:ba,userMax:ca}},getPlotLinePath:P,getThreshold:function(a){var b=
39
+ R?cb(F):F,c=R?cb(H):H;b>a||a===null?a=b:c<a&&(a=c);return Mb(a,0,1,0,1)},isXAxis:t,options:u,plotLinesAndBands:ta,getOffset:function(){var a=B.series.length&&s(F)&&s(H),c=a||p(u.showEmpty,!0),d=0,e,f=0,g=u.title,h=u.labels,i=[-1,1,1,-1][r],j;Q||(Q=I.g("axis").attr({zIndex:7}).add(),bc=I.g("grid").attr({zIndex:u.gridZIndex||1}).add());La=0;if(a||da)o(N,function(a){Pa[a]?Pa[a].addLabel():Pa[a]=new b(a)}),o(N,function(a){if(r===0||r===2||{1:"left",3:"right"}[r]===h.align)La=W(Pa[a].getLabelSize(),La)}),
40
+ Ra&&(La+=(Ra-1)*16);else for(j in Pa)Pa[j].destroy(),delete Pa[j];if(g&&g.text){if(!v)v=B.axisTitle=I.text(g.text,0,0,g.useHTML).attr({zIndex:7,rotation:g.rotation||0,align:g.textAlign||{low:"left",middle:"center",high:"right"}[g.align]}).css(g.style).add(),v.isNew=!0;if(c)d=v.getBBox()[G?"height":"width"],f=p(g.margin,G?5:10),e=g.offset;v[c?"show":"hide"]()}T=i*p(u.offset,pa[r]);Ya=p(e,La+f+(r!==2&&La&&i*u.labels[G?"y":"x"]));pa[r]=W(pa[r],Ya+d+i*T)},render:l,setAxisSize:function(){var a=u.offsetLeft||
41
+ 0,b=u.offsetRight||0;x=p(u.left,O+a);E=p(u.top,J);A=p(u.width,ka-a+b);hb=p(u.height,la);Lb=ra-hb-E;Zb=sa-A-x;D=G?A:hb;B.left=x;B.top=E;B.len=D},setAxisTranslation:ib,setCategories:function(b,c){B.categories=a.categories=Va=b;o(B.series,function(a){a.translate();a.setTooltipPoints(!0)});B.isDirty=!0;p(c,!0)&&m.redraw()},setExtremes:function(a,b,c,d,e){c=p(c,!0);e=L(e,{min:a,max:b});aa(B,"setExtremes",e,function(){ba=a;ca=b;B.isDirtyExtremes=!0;c&&m.redraw(d)})},setScale:function(){var a,b,c,d;ma=F;
42
+ za=H;ua=D;D=G?A:hb;d=D!==ua;o(B.series,function(a){if(a.isDirtyData||a.isDirty||a.xAxis.isDirty)c=!0});if(d||c||da||ba!==Aa||ca!==Ca){e();j();Aa=ba;Ca=ca;if(!t)for(a in qa)for(b in qa[a])qa[a][b].cum=qa[a][b].total;if(!B.isDirty)B.isDirty=d||F!==ma||H!==za}},setTickPositions:j,translate:Mb,redraw:function(){ub.resetTracker&&ub.resetTracker();l();o(ta,function(a){a.render()});o(B.series,function(a){a.isDirty=!0})},removePlotBand:n,removePlotLine:n,reversed:ya,setTitle:function(a,b){u.title=K(u.title,
43
+ a);v=v.destroy();B.isDirty=!0;p(b,!0)&&m.redraw()},series:[],stacks:qa,destroy:function(){var a;Qa(B);for(a in qa)Jb(qa[a]),qa[a]=null;if(B.stackTotalGroup)B.stackTotalGroup=B.stackTotalGroup.destroy();o([Pa,va,Da,ta],function(a){Jb(a)});o([$,Q,bc,v],function(a){a&&a.destroy()});$=Q=bc=v=null}});for(Sa in Z)ha(B,Sa,Z[Sa]);if(R)B.val2lin=nb,B.lin2val=cb}function d(a){function b(){var c=this.points||Hb(this),d=c[0].series,e;e=[d.tooltipHeaderFormatter(c[0].key)];o(c,function(a){d=a.series;e.push(d.tooltipFormatter&&
44
+ d.tooltipFormatter(a)||a.point.tooltipFormatter(d.tooltipOptions.pointFormat))});e.push(a.footerFormat||"");return e.join("")}function c(a,b){l=n?a:(2*l+a)/3;q=n?b:(q+b)/2;t.attr({x:l,y:q});lb=Ba(a-l)>1||Ba(b-q)>1?function(){c(a,b)}:null}function d(){if(!n){var a=m.hoverPoints;t.hide();a&&o(a,function(a){a.setState()});m.hoverPoints=null;n=!0}}var e,f=a.borderWidth,g=a.crosshairs,h=[],i=a.style,j=a.shared,k=S(i.padding),n=!0,l=0,q=0;i.padding=0;var t=I.label("",0,0,null,null,null,a.useHTML).attr({padding:k,
45
+ fill:a.backgroundColor,"stroke-width":f,r:a.borderRadius,zIndex:8}).css(i).hide().add();Fa||t.shadow(a.shadow);return{shared:j,refresh:function(f){var i,k,l,q,r={},y=[];l=f.tooltipPos;i=a.formatter||b;var r=m.hoverPoints,v;j&&(!f.series||!f.series.noSharedTooltip)?(q=0,r&&o(r,function(a){a.setState()}),m.hoverPoints=f,o(f,function(a){a.setState(ta);q+=a.plotY;y.push(a.getLabelConfig())}),k=f[0].plotX,q=z(q)/f.length,r={x:f[0].category},r.points=y,f=f[0]):r=f.getLabelConfig();r=i.call(r);e=f.series;
46
+ k=p(k,f.plotX);q=p(q,f.plotY);i=z(l?l[0]:U?ka-q:k);k=z(l?l[1]:U?la-k:q);l=j||!e.isCartesian||e.tooltipOutsidePlot||Db(i,k);r===!1||!l?d():(n&&(t.show(),n=!1),t.attr({text:r}),v=a.borderColor||f.color||e.color||"#606060",t.attr({stroke:v}),l=uc(t.width,t.height,O,J,ka,la,{x:i,y:k},p(a.distance,12),U),c(z(l.x),z(l.y)));if(g){g=Hb(g);var R;l=g.length;for(var Z;l--;)if(R=f.series[l?"yAxis":"xAxis"],g[l]&&R)if(R=R.getPlotLinePath(l?p(f.stackY,f.y):f.x,1),h[l])h[l].attr({d:R,visibility:eb});else{Z={"stroke-width":g[l].width||
47
+ 1,stroke:g[l].color||"#C0C0C0",zIndex:g[l].zIndex||2};if(g[l].dashStyle)Z.dashstyle=g[l].dashStyle;h[l]=I.path(R).attr(Z).add()}}aa(m,"tooltipRefresh",{text:r,x:i+O,y:k+J,borderColor:v})},hide:d,hideCrosshairs:function(){o(h,function(a){a&&a.hide()})},destroy:function(){o(h,function(a){a&&a.destroy()});t&&(t=t.destroy())}}}function e(a){function b(a){var c,d,e,a=a||ca.event;if(!a.target)a.target=a.srcElement;if(a.originalEvent)a=a.originalEvent;if(a.event)a=a.event;c=a.touches?a.touches.item(0):a;
48
+ ya=Ac(D);d=ya.left;e=ya.top;Qb?(d=a.x,c=a.y):(d=c.pageX-d,c=c.pageY-e);return L(a,{chartX:z(d),chartY:z(c)})}function c(a){var b={xAxis:[],yAxis:[]};o(xa,function(c){var d=c.translate,e=c.isXAxis;b[e?"xAxis":"yAxis"].push({axis:c,value:d((U?!e:e)?a.chartX-O:la-a.chartY+J,!0)})});return b}function e(){var a=m.hoverSeries,b=m.hoverPoint;if(b)b.onMouseOut();if(a)a.onMouseOut();vb&&(vb.hide(),vb.hideCrosshairs());ob=null}function f(){if(n){var a={xAxis:[],yAxis:[]},b=n.getBBox(),c=b.x-O,d=b.y-J;k&&(o(xa,
49
+ function(e){if(e.options.zoomEnabled!==!1){var f=e.translate,g=e.isXAxis,h=U?!g:g,i=f(h?c:la-d-b.height,!0,0,0,1),f=f(h?c+b.width:la-d,!0,0,0,1);a[g?"xAxis":"yAxis"].push({axis:e,min:Ua(i,f),max:W(i,f)})}}),aa(m,"selection",a,zb));n=n.destroy()}P(D,{cursor:"auto"});m.mouseIsDown=Da=k=!1;Qa(x,Ga?"touchend":"mouseup",f)}function g(a){var b=s(a.pageX)?a.pageX:a.page.x,a=s(a.pageX)?a.pageY:a.page.y;ya&&!Db(b-ya.left-O,a-ya.top-J)&&e()}function h(){e();ya=null}var i,j,k,n,l=Fa?"":q.zoomType,t=/x/.test(l),
50
+ r=/y/.test(l),y=t&&!U||r&&U,p=r&&!U||t&&U;if(!db)m.trackerGroup=db=I.g("tracker").attr({zIndex:9}).add();if(a.enabled)m.tooltip=vb=d(a),Bb=setInterval(function(){lb&&lb()},32);(function(){D.onmousedown=function(a){a=b(a);!Ga&&a.preventDefault&&a.preventDefault();m.mouseIsDown=Da=!0;m.mouseDownX=i=a.chartX;j=a.chartY;ha(x,Ga?"touchend":"mouseup",f)};var d=function(c){if(!c||!(c.touches&&c.touches.length>1)){c=b(c);if(!Ga)c.returnValue=!1;var d=c.chartX,e=c.chartY,f=!Db(d-O,e-J);Ga&&c.type==="touchstart"&&
51
+ (A(c.target,"isTracker")?m.runTrackerClick||c.preventDefault():!kb&&!f&&c.preventDefault());f&&(d<O?d=O:d>O+ka&&(d=O+ka),e<J?e=J:e>J+la&&(e=J+la));if(Da&&c.type!=="touchstart"){if(k=Math.sqrt(Math.pow(i-d,2)+Math.pow(j-e,2)),k>10){var g=Db(i-O,j-J);if(Nb&&(t||r)&&g)n||(n=I.rect(O,J,y?1:ka,p?1:la,0).attr({fill:q.selectionMarkerFill||"rgba(69,114,167,0.25)",zIndex:7}).add());n&&y&&(c=d-i,n.attr({width:Ba(c),x:(c>0?0:c)+i}));n&&p&&(e-=j,n.attr({height:Ba(e),y:(e>0?0:e)+j}));g&&!n&&q.panning&&m.pan(d)}}else if(!f){var h,
52
+ d=m.hoverPoint,e=m.hoverSeries,l,o,g=sa,R=U?c.chartY:c.chartX-O;if(vb&&a.shared&&(!e||!e.noSharedTooltip)){h=[];l=Q.length;for(o=0;o<l;o++)if(Q[o].visible&&Q[o].options.enableMouseTracking!==!1&&!Q[o].noSharedTooltip&&Q[o].tooltipPoints.length)c=Q[o].tooltipPoints[R],c._dist=Ba(R-c.plotX),g=Ua(g,c._dist),h.push(c);for(l=h.length;l--;)h[l]._dist>g&&h.splice(l,1);if(h.length&&h[0].plotX!==ob)vb.refresh(h),ob=h[0].plotX}if(e&&e.tracker&&(c=e.tooltipPoints[R])&&c!==d)c.onMouseOver()}return f||!Nb}};D.onmousemove=
53
+ d;ha(D,"mouseleave",h);ha(x,"mousemove",g);D.ontouchstart=function(a){if(t||r)D.onmousedown(a);d(a)};D.ontouchmove=d;D.ontouchend=function(){k&&e()};D.onclick=function(a){var d=m.hoverPoint,a=b(a);a.cancelBubble=!0;if(!k)if(d&&(A(a.target,"isTracker")||A(a.target.parentNode,"isTracker"))){var e=d.plotX,f=d.plotY;L(d,{pageX:ya.left+O+(U?ka-f:e),pageY:ya.top+J+(U?la-e:f)});aa(d.series,"click",L(a,{point:d}));d.firePointEvent("click",a)}else L(a,c(a)),Db(a.chartX-O,a.chartY-J)&&aa(m,"click",a);k=!1}})();
54
+ L(this,{zoomX:t,zoomY:r,resetTracker:e,normalizeMouseEvent:b,destroy:function(){if(m.trackerGroup)m.trackerGroup=db=m.trackerGroup.destroy();Qa(D,"mouseleave",h);Qa(x,"mousemove",g);D.onclick=D.onmousedown=D.onmousemove=D.ontouchstart=D.ontouchend=D.ontouchmove=null}})}function f(a){var b=a.type||q.type||q.defaultSeriesType,c=Ha[b],d=m.hasRendered;if(d)if(U&&b==="column")c=Ha.bar;else if(!U&&b==="bar")c=Ha.column;b=new c;b.init(m,a);!d&&b.inverted&&(U=!0);if(b.isCartesian)Nb=b.isCartesian;Q.push(b);
55
+ return b}function g(){q.alignTicks!==!1&&o(xa,function(a){a.adjustTickAmount()});gb=null}function h(a){var b=m.isDirtyLegend,c,d=m.isDirtyBox,e=Q.length,f=e,h=m.clipRect;for(Kb(a,m);f--;)if(a=Q[f],a.isDirty&&a.options.stacking){c=!0;break}if(c)for(f=e;f--;)if(a=Q[f],a.options.stacking)a.isDirty=!0;o(Q,function(a){a.isDirty&&a.options.legendType==="point"&&(b=!0)});if(b&&Xa.renderLegend)Xa.renderLegend(),m.isDirtyLegend=!1;Nb&&(La||(gb=null,o(xa,function(a){a.setScale()})),g(),Wb(),o(xa,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes=
56
+ !1,aa(a,"afterSetExtremes",a.getExtremes());if(a.isDirty||d)a.redraw(),d=!0}));d&&(qb(),h&&(Ob(h),h.animate({width:m.plotSizeX,height:m.plotSizeY+1})));o(Q,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});ub&&ub.resetTracker&&ub.resetTracker();I.draw();aa(m,"redraw")}function i(){var a=v.xAxis||{},b=v.yAxis||{},a=Hb(a);o(a,function(a,b){a.index=b;a.isX=!0});b=Hb(b);o(b,function(a,b){a.index=b});a=a.concat(b);o(a,function(a){new c(a)});g()}function k(){var a=Ea.lang,b=q.resetZoomButton,
57
+ c=b.theme,d=c.states,e=b.relativeTo==="chart"?null:{x:O,y:J,width:ka,height:la};m.resetZoomButton=I.button(a.resetZoom,null,null,Fb,c,d&&d.hover).attr({align:b.position.align,title:a.resetZoomTitle}).add().align(b.position,!1,e)}function j(a,b){$=K(v.title,a);ja=K(v.subtitle,b);o([["title",a,$],["subtitle",b,ja]],function(a){var b=a[0],c=m[b],d=a[1],a=a[2];c&&d&&(c=c.destroy());a&&a.text&&!c&&(m[b]=I.text(a.text,0,0,a.useHTML).attr({align:a.align,"class":Ia+b,zIndex:a.zIndex||4}).css(a.style).add().align(a,
58
+ !1,ib))})}function l(){Ja=q.renderTo;na=Ia+lc++;Ab(Ja)&&(Ja=x.getElementById(Ja));Ja||jc(13,!0);Ja.innerHTML="";Ja.offsetWidth||(C=Ja.cloneNode(0),P(C,{position:wb,top:"-9999px",display:""}),x.body.appendChild(C));za=(C||Ja).offsetWidth;Ca=(C||Ja).offsetHeight;m.chartWidth=sa=q.width||za||600;m.chartHeight=ra=q.height||(Ca>19?Ca:400);m.container=D=Aa(Ra,{className:Ia+"container"+(q.className?" "+q.className:""),id:na},L({position:mc,overflow:ab,width:sa+ga,height:ra+ga,textAlign:"left",lineHeight:"normal"},
59
+ q.style),C||Ja);m.renderer=I=q.forExport?new Eb(D,sa,ra,!0):new Xb(D,sa,ra);Fa&&I.create(m,D,sa,ra);var a,b;Bc&&D.getBoundingClientRect&&(a=function(){P(D,{left:0,top:0});b=D.getBoundingClientRect();P(D,{left:-(b.left-S(b.left))+ga,top:-(b.top-S(b.top))+ga})},a(),ha(ca,"resize",a),ha(m,"destroy",function(){Qa(ca,"resize",a)}))}function n(){function a(c){var d=q.width||Ja.offsetWidth,e=q.height||Ja.offsetHeight,c=c?c.target:ca;if(d&&e&&(c===ca||c===x)){if(d!==za||e!==Ca)clearTimeout(b),b=setTimeout(function(){tb(d,
60
+ e,!1)},100);za=d;Ca=e}}var b;ha(ca,"resize",a);ha(m,"destroy",function(){Qa(ca,"resize",a)})}function t(){m&&aa(m,"endResize",null,function(){La-=1})}function r(){for(var a=U||q.inverted||q.type==="bar"||q.defaultSeriesType==="bar",b=v.series,c=b&&b.length;!a&&c--;)b[c].type==="bar"&&(a=!0);m.inverted=U=a}function Z(){var a=v.labels,b=v.credits,c;j();Xa=m.legend=new Rb;o(xa,function(a){a.setScale()});Wb();o(xa,function(a){a.setTickPositions(!0)});g();Wb();qb();Nb&&o(xa,function(a){a.render()});if(!m.seriesGroup)m.seriesGroup=
61
+ I.g("series-group").attr({zIndex:3}).add();o(Q,function(a){a.translate();a.setTooltipPoints();a.render()});a.items&&o(a.items,function(){var b=L(a.style,this.style),c=S(b.left)+O,d=S(b.top)+J+12;delete b.left;delete b.top;I.text(this.html,c,d).attr({zIndex:2}).css(b).add()});if(b.enabled&&!m.credits)c=b.href,m.credits=I.text(b.text,0,0).on("click",function(){if(c)location.href=c}).attr({align:b.position.align,zIndex:8}).css(b.style).add().align(b.position);m.hasRendered=!0}function V(){if(!Pb&&ca==
62
+ ca.top&&x.readyState!=="complete"||Fa&&!ca.canvg)Fa?Cc.push(V,v.global.canvasToolsURL):x.attachEvent("onreadystatechange",function(){x.detachEvent("onreadystatechange",V);x.readyState==="complete"&&V()});else{l();aa(m,"init");if(Highcharts.RangeSelector&&v.rangeSelector.enabled)m.rangeSelector=new Highcharts.RangeSelector(m);rb();sb();r();i();o(v.series||[],function(a){f(a)});if(Highcharts.Scroller&&(v.navigator.enabled||v.scrollbar.enabled))m.scroller=new Highcharts.Scroller(m);m.render=Z;m.tracker=
63
+ ub=new e(v.tooltip);Z();I.draw();b&&b.apply(m,[m]);o(m.callbacks,function(a){a.apply(m,[m])});C&&(Ja.appendChild(D),Tb(C));aa(m,"load")}}var v,y=a.series;a.series=null;v=K(Ea,a);v.series=a.series=y;var q=v.chart,y=q.margin,y=mb(y)?y:[y,y,y,y],T=p(q.marginTop,y[0]),w=p(q.marginRight,y[1]),E=p(q.marginBottom,y[2]),bb=p(q.marginLeft,y[3]),ia=q.spacingTop,ua=q.spacingRight,R=q.spacingBottom,jb=q.spacingLeft,ib,$,ja,J,ba,M,O,pa,Ja,C,D,na,za,Ca,sa,ra,$a,Za,ma,Na,Sa,da,m=this,kb=(y=q.events)&&!!y.click,
64
+ va,Db,vb,Da,xb,pb,Ya,la,ka,ub,db,Xa,Wa,yb,ya,Nb=q.showAxes,La=0,xa=[],gb,Q=[],U,I,lb,Bb,ob,qb,Wb,rb,sb,tb,zb,Fb,Rb=function(){function a(b,c){var d=b.legendItem,e=b.legendLine,g=b.legendSymbol,h=q.color,i=c?f.itemStyle.color:h,h=c?b.color:h;d&&d.css({fill:i});e&&e.attr({stroke:h});g&&g.attr({stroke:h,fill:h})}function b(a){var c=a.legendItem,d=a.legendLine,e=a._legendItemPos,f=e[0],e=e[1],g=a.legendSymbol,a=a.checkbox;c&&c.attr({x:r?f:Wa-f,y:e});d&&d.translate(r?f:Wa-f,e-4);g&&(c=f+g.xOff,g.attr({x:r?
65
+ c:Wa-c,y:e+g.yOff}));if(a)a.x=f,a.y=e}function c(){o(j,function(a){var b=a.checkbox,c=A.alignAttr;b&&P(b,{left:c.translateX+a.legendItemWidth+b.x-40+ga,top:c.translateY+b.y-11+ga})})}function d(b){var c,e,j,k,m=b.legendItem;k=b.series||b;var o=k.options,v=o&&o.borderWidth||0;if(!m){k=/^(bar|pie|area|column)$/.test(k.type);b.legendItem=m=I.text(f.labelFormatter.call(b),0,0,f.useHTML).css(b.visible?n:q).on("mouseover",function(){b.setState(ta);m.css(l)}).on("mouseout",function(){m.css(b.visible?n:q);
66
+ b.setState()}).on("click",function(){var a=function(){b.setVisible()};b.firePointEvent?b.firePointEvent("legendItemClick",null,a):aa(b,"legendItemClick",null,a)}).attr({align:r?"left":"right",zIndex:2}).add(A);if(!k&&o&&o.lineWidth){var u={"stroke-width":o.lineWidth,zIndex:2};if(o.dashStyle)u.dashstyle=o.dashStyle;b.legendLine=I.path([wa,(-h-i)*(r?1:-1),0,fa,-i*(r?1:-1),0]).attr(u).add(A)}if(k)j=I.rect(c=-h-i,e=-11,h,12,2).attr({zIndex:3}).add(A),r||(c+=h);else if(o&&o.marker&&o.marker.enabled)j=
67
+ o.marker.radius,j=I.symbol(b.symbol,c=-h/2-i-j,e=-4-j,2*j,2*j).attr(b.pointAttr[Ka]).attr({zIndex:3}).add(A),r||(c+=h/2);if(j)j.xOff=c+v%2/2,j.yOff=e+v%2/2;b.legendSymbol=j;a(b,b.visible);if(o&&o.showCheckbox)b.checkbox=Aa("input",{type:"checkbox",checked:b.selected,defaultChecked:b.selected},f.itemCheckboxStyle,D),ha(b.checkbox,"click",function(a){aa(b,"checkboxClick",{checked:a.target.checked},function(){b.select()})})}c=m.getBBox();e=b.legendItemWidth=f.itemWidth||h+i+c.width+t;w=c.height;if(g&&
68
+ s-V+e>(J||sa-2*t-V))s=V,z+=y+w+p;!g&&z+f.y+w>ra-ia-R&&(z=T,s+=Z,Z=0);Z=W(Z,e);x=W(x,z+p);b._legendItemPos=[s,z];g?s+=e:z+=y+w+p;C=J||W(s-V+(g?0:e),C)}function e(){s=V;z=T;x=C=0;A||(A=I.g("legend").attr({zIndex:7}).add());j=[];o(M,function(a){var b=a.options;b.showInLegend&&(j=j.concat(a.legendItems||(b.legendType==="point"?a.data:a)))});Mc(j,function(a,b){return(a.options.legendIndex||0)-(b.options.legendIndex||0)});jb&&j.reverse();o(j,d);Wa=J||C;yb=x-v+w;if(E||bb){Wa+=2*t;yb+=2*t;if(ua){if(Wa>0&&
69
+ yb>0)ua[ua.isNew?"attr":"animate"](ua.crisp(null,null,null,Wa,yb)),ua.isNew=!1}else ua=I.rect(0,0,Wa,yb,f.borderRadius,E||0).attr({stroke:f.borderColor,"stroke-width":E||0,fill:bb||Ma}).add(A).shadow(f.shadow),ua.isNew=!0;ua[j.length?"show":"hide"]()}o(j,b);for(var a=["left","right","top","bottom"],g,h=4;h--;)g=a[h],k[g]&&k[g]!=="auto"&&(f[h<2?"align":"verticalAlign"]=g,f[h<2?"x":"y"]=S(k[g])*(h%2?-1:1));j.length&&A.align(L(f,{width:Wa,height:yb}),!0,ib);La||c()}var f=m.options.legend;if(f.enabled){var g=
70
+ f.layout==="horizontal",h=f.symbolWidth,i=f.symbolPadding,j,k=f.style,n=f.itemStyle,l=f.itemHoverStyle,q=K(n,f.itemHiddenStyle),t=f.padding||S(k.padding),r=!f.rtl,y=f.itemMarginTop||0,p=f.itemMarginBottom||0,v=18,Z=0,V=4+t+h+i,T=t+y+v-5,s,z,x,w=0,ua,E=f.borderWidth,bb=f.backgroundColor,A,C,J=f.width,M=m.series,jb=f.reversed;e();ha(m,"endResize",c);return{colorizeItem:a,destroyItem:function(a){var b=a.checkbox;o(["legendItem","legendLine","legendSymbol"],function(b){a[b]&&a[b].destroy()});b&&Tb(a.checkbox)},
71
+ renderLegend:e,destroy:function(){ua&&(ua=ua.destroy());A&&(A=A.destroy())}}}};Db=function(a,b){return a>=0&&a<=ka&&b>=0&&b<=la};Fb=function(){var a=m.resetZoomButton;aa(m,"selection",{resetSelection:!0},zb);if(a)m.resetZoomButton=a.destroy()};zb=function(a){var b;m.resetZoomEnabled!==!1&&!m.resetZoomButton&&k();!a||a.resetSelection?o(xa,function(a){a.options.zoomEnabled!==!1&&(a.setExtremes(null,null,!1),b=!0)}):o(a.xAxis.concat(a.yAxis),function(a){var c=a.axis;if(m.tracker[c.isXAxis?"zoomX":"zoomY"])c.setExtremes(a.min,
72
+ a.max,!1),b=!0});b&&h(p(q.animation,m.pointCount<100))};m.pan=function(a){var b=m.xAxis[0],c=m.mouseDownX,d=b.pointRange/2,e=b.getExtremes(),f=b.translate(c-a,!0)+d,c=b.translate(c+ka-a,!0)-d;(d=m.hoverPoints)&&o(d,function(a){a.setState()});f>Ua(e.dataMin,e.min)&&c<W(e.dataMax,e.max)&&b.setExtremes(f,c,!0,!1);m.mouseDownX=a;P(D,{cursor:"move"})};Wb=function(){var a=v.legend,b=p(a.margin,10),c=a.x,d=a.y,e=a.align,f=a.verticalAlign,g;rb();if((m.title||m.subtitle)&&!s(T))(g=W(m.title&&!$.floating&&
73
+ !$.verticalAlign&&$.y||0,m.subtitle&&!ja.floating&&!ja.verticalAlign&&ja.y||0))&&(J=W(J,g+p($.margin,15)+ia));a.enabled&&!a.floating&&(e==="right"?s(w)||(ba=W(ba,Wa-c+b+ua)):e==="left"?s(bb)||(O=W(O,Wa+c+b+jb)):f==="top"?s(T)||(J=W(J,yb+d+b+ia)):f==="bottom"&&(s(E)||(M=W(M,yb-d+b+R))));m.extraBottomMargin&&(M+=m.extraBottomMargin);m.extraTopMargin&&(J+=m.extraTopMargin);Nb&&o(xa,function(a){a.getOffset()});s(bb)||(O+=pa[3]);s(T)||(J+=pa[0]);s(E)||(M+=pa[2]);s(w)||(ba+=pa[1]);sb()};tb=function(a,b,
74
+ c){var d=m.title,e=m.subtitle;La+=1;Kb(c,m);Za=ra;$a=sa;if(s(a))m.chartWidth=sa=z(a);if(s(b))m.chartHeight=ra=z(b);P(D,{width:sa+ga,height:ra+ga});I.setSize(sa,ra,c);ka=sa-O-ba;la=ra-J-M;gb=null;o(xa,function(a){a.isDirty=!0;a.setScale()});o(Q,function(a){a.isDirty=!0});m.isDirtyLegend=!0;m.isDirtyBox=!0;Wb();d&&d.align(null,null,ib);e&&e.align(null,null,ib);h(c);Za=null;aa(m,"resize");Ub===!1?t():setTimeout(t,Ub&&Ub.duration||500)};sb=function(){m.plotLeft=O=z(O);m.plotTop=J=z(J);m.plotWidth=ka=
75
+ z(sa-O-ba);m.plotHeight=la=z(ra-J-M);m.plotSizeX=U?la:ka;m.plotSizeY=U?ka:la;ib={x:jb,y:ia,width:sa-jb-ua,height:ra-ia-R};o(xa,function(a){a.setAxisSize();a.setAxisTranslation()})};rb=function(){J=p(T,ia);ba=p(w,ua);M=p(E,R);O=p(bb,jb);pa=[0,0,0,0]};qb=function(){var a=q.borderWidth||0,b=q.backgroundColor,c=q.plotBackgroundColor,d=q.plotBackgroundImage,e,f={x:O,y:J,width:ka,height:la};e=a+(q.shadow?8:0);if(a||b)ma?ma.animate(ma.crisp(null,null,null,sa-e,ra-e)):ma=I.rect(e/2,e/2,sa-e,ra-e,q.borderRadius,
76
+ a).attr({stroke:q.borderColor,"stroke-width":a,fill:b||Ma}).add().shadow(q.shadow);c&&(Na?Na.animate(f):Na=I.rect(O,J,ka,la,0).attr({fill:c}).add().shadow(q.plotShadow));d&&(Sa?Sa.animate(f):Sa=I.image(d,O,J,ka,la).add());q.plotBorderWidth&&(da?da.animate(da.crisp(null,O,J,ka,la)):da=I.rect(O,J,ka,la,0,q.plotBorderWidth).attr({stroke:q.plotBorderColor,"stroke-width":q.plotBorderWidth,zIndex:4}).add());m.isDirtyBox=!1};q.reflow!==!1&&ha(m,"load",n);if(y)for(va in y)ha(m,va,y[va]);m.options=v;m.series=
77
+ Q;m.xAxis=[];m.yAxis=[];m.addSeries=function(a,b,c){var d;a&&(Kb(c,m),b=p(b,!0),aa(m,"addSeries",{options:a},function(){d=f(a);d.isDirty=!0;m.isDirtyLegend=!0;b&&m.redraw()}));return d};m.animation=Fa?!1:p(q.animation,!0);m.Axis=c;m.destroy=function(){var a,b=D&&D.parentNode;if(m!==null){aa(m,"destroy");Qa(m);for(a=xa.length;a--;)xa[a]=xa[a].destroy();for(a=Q.length;a--;)Q[a]=Q[a].destroy();o("title,subtitle,seriesGroup,clipRect,credits,tracker,scroller,rangeSelector".split(","),function(a){var b=
78
+ m[a];b&&(m[a]=b.destroy())});o([ma,da,Na,Xa,vb,I,ub],function(a){a&&a.destroy&&a.destroy()});ma=da=Na=Xa=vb=I=ub=null;if(D)D.innerHTML="",Qa(D),b&&Tb(D),D=null;clearInterval(Bb);for(a in m)delete m[a];v=m=null}};m.get=function(a){var b,c,d;for(b=0;b<xa.length;b++)if(xa[b].options.id===a)return xa[b];for(b=0;b<Q.length;b++)if(Q[b].options.id===a)return Q[b];for(b=0;b<Q.length;b++){d=Q[b].points||[];for(c=0;c<d.length;c++)if(d[c].id===a)return d[c]}return null};m.getSelectedPoints=function(){var a=
79
+ [];o(Q,function(b){a=a.concat(nc(b.points,function(a){return a.selected}))});return a};m.getSelectedSeries=function(){return nc(Q,function(a){return a.selected})};m.hideLoading=function(){xb&&cc(xb,{opacity:0},{duration:v.loading.hideDuration||100,complete:function(){P(xb,{display:Ma})}});Ya=!1};m.initSeries=f;m.isInsidePlot=Db;m.redraw=h;m.setSize=tb;m.setTitle=j;m.showLoading=function(a){var b=v.loading;xb||(xb=Aa(Ra,{className:Ia+"loading"},L(b.style,{left:O+ga,top:J+ga,width:ka+ga,height:la+ga,
80
+ zIndex:10,display:Ma}),D),pb=Aa("span",null,b.labelStyle,xb));pb.innerHTML=a||v.lang.loading;Ya||(P(xb,{opacity:0,display:""}),cc(xb,{opacity:b.style.opacity},{duration:b.showDuration||0}),Ya=!0)};m.pointCount=0;m.counters=new tc;V()}var X,x=document,ca=window,oa=Math,z=oa.round,Ta=oa.floor,Yb=oa.ceil,W=oa.max,Ua=oa.min,Ba=oa.abs,ja=oa.cos,C=oa.sin,da=oa.PI,Dc=da*2/360,kb=navigator.userAgent,Qb=/msie/i.test(kb)&&!ca.opera,Xa=x.documentMode===8,Ec=/AppleWebKit/.test(kb),Bc=/Firefox/.test(kb),Pb=!!x.createElementNS&&
81
+ !!x.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect,Qc=Bc&&parseInt(kb.split("Firefox/")[1],10)<4,Fa=!Pb&&!Qb&&!!x.createElement("canvas").getContext,Xb,Ga=x.documentElement.ontouchstart!==X,Fc={},lc=0,tb,Ea,ac,Ub,La,E,Ra="div",wb="absolute",mc="relative",ab="hidden",Ia="highcharts-",eb="visible",ga="px",Ma="none",wa="M",fa="L",Gc="rgba(192,192,192,"+(Pb?1.0E-6:0.0020)+")",Ka="",ta="hover",Rb="millisecond",ob="second",pb="minute",va="hour",Ca="day",Ya="week",Da="month",Za="year",
82
+ sb,fc,gc,ic,db,qb,rb,pc,qc,hc,rc,sc,w=ca.HighchartsAdapter,na=w||{},Hc=na.getScript,o=na.each,nc=na.grep,Ac=na.offset,Vb=na.map,K=na.merge,ha=na.addEvent,Qa=na.removeEvent,aa=na.fireEvent,cc=na.animate,Ob=na.stop,Ha={};ca.Highcharts={};ac=function(a,b,c){if(!s(b)||isNaN(b))return"Invalid date";var a=p(a,"%Y-%m-%d %H:%M:%S"),d=new Date(b),e,f=d[gc](),g=d[ic](),h=d[db](),i=d[qb](),k=d[rb](),j=Ea.lang,l=j.weekdays,b={a:l[g].substr(0,3),A:l[g],d:Na(h),e:h,b:j.shortMonths[i],B:j.months[i],m:Na(i+1),y:k.toString().substr(2,
83
+ 2),Y:k,H:Na(f),I:Na(f%12||12),l:f%12||12,M:Na(d[fc]()),p:f<12?"AM":"PM",P:f<12?"am":"pm",S:Na(d.getSeconds()),L:Na(z(b%1E3),3)};for(e in b)a=a.replace("%"+e,b[e]);return c?a.substr(0,1).toUpperCase()+a.substr(1):a};tc.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};E=za(Rb,1,ob,1E3,pb,6E4,va,36E5,Ca,864E5,Ya,6048E5,Da,2592E6,Za,31556952E3);La={init:function(a,b,c){var b=b||"",d=a.shift,e=b.indexOf("C")>-1,f=e?7:3,g,b=b.split(" "),
84
+ c=[].concat(c),h,i,k=function(a){for(g=a.length;g--;)a[g]===wa&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&(k(b),k(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));d===1&&(c=[].concat(c).splice(0,f).concat(c));a.shift=0;if(b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);h&&(b=b.concat(h),c=c.concat(i));return[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(c===1)e=d;else if(f===b.length&&c<1)for(;f--;)d=
85
+ parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}};w&&w.init&&w.init(La);if(!w&&ca.jQuery){var ba=jQuery,Hc=ba.getScript,o=function(a,b){for(var c=0,d=a.length;c<d;c++)if(b.call(a[c],a[c],c,a)===!1)return c},nc=ba.grep,Vb=function(a,b){for(var c=[],d=0,e=a.length;d<e;d++)c[d]=b.call(a[d],a[d],d,a);return c},K=function(){var a=arguments;return ba.extend(!0,null,a[0],a[1],a[2],a[3])},Ac=function(a){return ba(a).offset()},ha=function(a,b,c){ba(a).bind(b,c)},Qa=function(a,
86
+ b,c){var d=x.removeEventListener?"removeEventListener":"detachEvent";x[d]&&!a[d]&&(a[d]=function(){});ba(a).unbind(b,c)},aa=function(a,b,c,d){var e=ba.Event(b),f="detached"+b,g;L(e,c);a[b]&&(a[f]=a[b],a[b]=null);o(["preventDefault","stopPropagation"],function(a){var b=e[a];e[a]=function(){try{b.call(e)}catch(c){a==="preventDefault"&&(g=!0)}}});ba(a).trigger(e);a[f]&&(a[b]=a[f],a[f]=null);d&&!e.isDefaultPrevented()&&!g&&d(e)},cc=function(a,b,c){var d=ba(a);if(b.d)a.toD=b.d,b.d=1;d.stop();d.animate(b,
87
+ c)},Ob=function(a){ba(a).stop()};ba.extend(ba.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}});var Ic=jQuery.fx,Jc=Ic.step;o(["cur","_default","width","height"],function(a,b){var c=b?Jc:Ic.prototype,d=c[a],e;d&&(c[a]=function(a){a=b?a:this;e=a.elem;return e.attr?e.attr(a.prop,a.now):d.apply(this,arguments)})});Jc.d=function(a){var b=a.elem;if(!a.started){var c=La.init(b,b.d,b.toD);a.start=c[0];a.end=c[1];a.started=!0}b.attr("d",La.step(a.start,a.end,a.pos,b.toD))}}w={enabled:!0,
88
+ align:"center",x:0,y:15,style:{color:"#666",fontSize:"11px",lineHeight:"14px"}};Ea={colors:"#4572A7,#AA4643,#89A54E,#80699B,#3D96AE,#DB843D,#92A8CD,#A47D7C,#B5CA92".split(","),symbols:["circle","diamond","square","triangle","triangle-down"],lang:{loading:"Loading...",months:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),shortMonths:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),weekdays:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),
89
+ decimalPoint:".",resetZoom:"Reset zoom",resetZoomTitle:"Reset zoom level 1:1",thousandsSep:","},global:{useUTC:!0,canvasToolsURL:"http://code.highcharts.com/2.2.1/modules/canvas-tools.js"},chart:{borderColor:"#4572A7",borderRadius:5,defaultSeriesType:"line",ignoreHiddenSeries:!0,spacingTop:10,spacingRight:10,spacingBottom:15,spacingLeft:10,style:{fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif',fontSize:"12px"},backgroundColor:"#FFFFFF",plotBorderColor:"#C0C0C0",
90
+ resetZoomButton:{theme:{zIndex:20},position:{align:"right",x:-10,y:10}}},title:{text:"Chart title",align:"center",y:15,style:{color:"#3E576F",fontSize:"16px"}},subtitle:{text:"",align:"center",y:30,style:{color:"#6D869F"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1E3},events:{},lineWidth:2,shadow:!0,marker:{enabled:!0,lineWidth:0,radius:4,lineColor:"#FFFFFF",states:{hover:{},select:{fillColor:"#FFFFFF",lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:K(w,
91
+ {enabled:!1,y:-6,formatter:function(){return this.y}}),cropThreshold:300,pointRange:0,showInLegend:!0,states:{hover:{marker:{}},select:{marker:{}}},stickyTracking:!0}},labels:{style:{position:wb,color:"#3E576F"}},legend:{enabled:!0,align:"center",layout:"horizontal",labelFormatter:function(){return this.name},borderWidth:1,borderColor:"#909090",borderRadius:5,shadow:!1,style:{padding:"5px"},itemStyle:{cursor:"pointer",color:"#3E576F"},itemHoverStyle:{color:"#000000"},itemHiddenStyle:{color:"#C0C0C0"},
92
+ itemCheckboxStyle:{position:wb,width:"13px",height:"13px"},symbolWidth:16,symbolPadding:5,verticalAlign:"bottom",x:0,y:0},loading:{labelStyle:{fontWeight:"bold",position:mc,top:"1em"},style:{position:wb,backgroundColor:"white",opacity:0.5,textAlign:"center"}},tooltip:{enabled:!0,backgroundColor:"rgba(255, 255, 255, .85)",borderWidth:2,borderRadius:5,headerFormat:'<span style="font-size: 10px">{point.key}</span><br/>',pointFormat:'<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
93
+ shadow:!0,shared:Fa,snap:Ga?25:10,style:{color:"#333333",fontSize:"12px",padding:"5px",whiteSpace:"nowrap"}},credits:{enabled:!0,text:"Highcharts.com",href:"http://www.highcharts.com",position:{align:"right",x:-10,verticalAlign:"bottom",y:-5},style:{cursor:"pointer",color:"#909090",fontSize:"10px"}}};var $b={dateTimeLabelFormats:za(Rb,"%H:%M:%S.%L",ob,"%H:%M:%S",pb,"%H:%M",va,"%H:%M",Ca,"%e. %b",Ya,"%e. %b",Da,"%b '%y",Za,"%Y"),endOnTick:!1,gridLineColor:"#C0C0C0",labels:w,lineColor:"#C0D0E0",lineWidth:1,
94
+ max:null,min:null,minPadding:0.01,maxPadding:0.01,minorGridLineColor:"#E0E0E0",minorGridLineWidth:1,minorTickColor:"#A0A0A0",minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickColor:"#C0D0E0",tickLength:5,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",tickWidth:1,title:{align:"middle",style:{color:"#6D869F",fontWeight:"bold"}},type:"linear"},kc=K($b,{endOnTick:!0,gridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{align:"right",x:-8,
95
+ y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:"Y-values"},stackLabels:{enabled:!1,formatter:function(){return this.total},style:w.style}}),Pc={labels:{align:"right",x:-8,y:null},title:{rotation:270}},Oc={labels:{align:"left",x:8,y:null},title:{rotation:90}},zc={labels:{align:"center",x:0,y:14,overflow:"justify"},title:{rotation:0}},Nc=K(zc,{labels:{y:-5,overflow:"justify"}}),M=Ea.plotOptions,w=M.line;M.spline=K(w);M.scatter=K(w,{lineWidth:0,states:{hover:{lineWidth:0}},
96
+ tooltip:{headerFormat:'<span style="font-size: 10px; color:{series.color}">{series.name}</span><br/>',pointFormat:"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>"}});M.area=K(w,{threshold:0});M.areaspline=K(M.area);M.column=K(w,{borderColor:"#FFFFFF",borderWidth:1,borderRadius:0,groupPadding:0.2,marker:null,pointPadding:0.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:0.1,shadow:!1},select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}},dataLabels:{y:null,verticalAlign:null},
97
+ threshold:0});M.bar=K(M.column,{dataLabels:{align:"left",x:5,y:null,verticalAlign:"middle"}});M.pie=K(w,{borderColor:"#FFFFFF",borderWidth:1,center:["50%","50%"],colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name},y:5},legendType:"point",marker:null,size:"75%",showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}}});vc();var ma=function(a){var b=[],c;(function(a){(c=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/.exec(a))?
98
+ b=[S(c[1]),S(c[2]),S(c[3]),parseFloat(c[4],10)]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))&&(b=[S(c[1],16),S(c[2],16),S(c[3],16),1])})(a);return{get:function(c){return b&&!isNaN(b[0])?c==="rgb"?"rgb("+b[0]+","+b[1]+","+b[2]+")":c==="a"?b[3]:"rgba("+b.join(",")+")":a},brighten:function(a){if(Bb(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=S(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},setOpacity:function(a){b[3]=a;return this}}};Sa.prototype={init:function(a,b){this.element=
99
+ b==="span"?Aa(b):x.createElementNS("http://www.w3.org/2000/svg",b);this.renderer=a;this.attrSetters={}},animate:function(a,b,c){b=p(b,Ub,!0);Ob(this);if(b){b=K(b);if(c)b.complete=c;cc(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName,i=this.renderer,k,j=this.attrSetters,l=this.shadows,n,o=this;Ab(a)&&s(b)&&(c=a,a={},a[c]=b);if(Ab(a))c=a,h==="circle"?c={x:"cx",y:"cy"}[c]||c:c==="strokeWidth"&&(c="stroke-width"),o=A(g,c)||this[c]||0,c!=="d"&&c!=="visibility"&&
100
+ (o=parseFloat(o));else for(c in a)if(k=!1,d=a[c],e=j[c]&&j[c](d,c),e!==!1){e!==X&&(d=e);if(c==="d")d&&d.join&&(d=d.join(" ")),/(NaN| {2}|^$)/.test(d)&&(d="M 0 0"),this.d=d;else if(c==="x"&&h==="text"){for(e=0;e<g.childNodes.length;e++)f=g.childNodes[e],A(f,"x")===A(g,"x")&&A(f,"x",d);this.rotation&&A(g,"transform","rotate("+this.rotation+" "+d+" "+S(a.y||A(g,"y"))+")")}else if(c==="fill")d=i.color(d,g,c);else if(h==="circle"&&(c==="x"||c==="y"))c={x:"cx",y:"cy"}[c]||c;else if(h==="rect"&&c==="r")A(g,
101
+ {rx:d,ry:d}),k=!0;else if(c==="translateX"||c==="translateY"||c==="rotation"||c==="verticalAlign")this[c]=d,this.updateTransform(),k=!0;else if(c==="stroke")d=i.color(d,g,c);else if(c==="dashstyle")if(c="stroke-dasharray",d=d&&d.toLowerCase(),d==="solid")d=Ma;else{if(d){d=d.replace("shortdashdotdot","3,1,1,1,1,1,").replace("shortdashdot","3,1,1,1").replace("shortdot","1,1,").replace("shortdash","3,1,").replace("longdash","8,3,").replace(/dot/g,"1,3,").replace("dash","4,3,").replace(/,$/,"").split(",");
102
+ for(e=d.length;e--;)d[e]=S(d[e])*a["stroke-width"];d=d.join(",")}}else c==="isTracker"?this[c]=d:c==="width"?d=S(d):c==="align"?(c="text-anchor",d={left:"start",center:"middle",right:"end"}[d]):c==="title"&&(e=x.createElementNS("http://www.w3.org/2000/svg","title"),e.appendChild(x.createTextNode(d)),g.appendChild(e));c==="strokeWidth"&&(c="stroke-width");Ec&&c==="stroke-width"&&d===0&&(d=1.0E-6);this.symbolName&&/^(x|y|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(n||(this.symbolAttr(a),n=!0),k=
103
+ !0);if(l&&/^(width|height|visibility|x|y|d|transform)$/.test(c))for(e=l.length;e--;)A(l[e],c,d);if((c==="width"||c==="height")&&h==="rect"&&d<0)d=0;c==="text"?(this.textStr=d,this.added&&i.buildText(this)):k||A(g,c,d)}if(Ec&&/Chrome\/(18|19)/.test(kb)&&h==="text"&&(a.x!==X||a.y!==X))c=g.parentNode,d=g.nextSibling,c&&(c.removeChild(g),d?c.insertBefore(g,d):c.appendChild(g));return o},symbolAttr:function(a){var b=this;o("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","),function(c){b[c]=
104
+ p(a[c],b[c])});b.attr({d:b.renderer.symbols[b.symbolName](b.x,b.y,b.width,b.height,b)})},clip:function(a){return this.attr("clip-path","url("+this.renderer.url+"#"+a.id+")")},crisp:function(a,b,c,d,e){var f,g={},h={},i,a=a||this.strokeWidth||this.attr&&this.attr("stroke-width")||0;i=z(a)%2/2;h.x=Ta(b||this.x||0)+i;h.y=Ta(c||this.y||0)+i;h.width=Ta((d||this.width||0)-2*i);h.height=Ta((e||this.height||0)-2*i);h.strokeWidth=a;for(f in h)this[f]!==h[f]&&(this[f]=g[f]=h[f]);return g},css:function(a){var b=
105
+ this.element,b=a&&a.width&&b.nodeName==="text",c,d="",e=function(a,b){return"-"+b.toLowerCase()};if(a&&a.color)a.fill=a.color;this.styles=a=L(this.styles,a);if(Qb&&!Pb)b&&delete a.width,P(this.element,a);else{for(c in a)d+=c.replace(/([A-Z])/g,e)+":"+a[c]+";";this.attr({style:d})}b&&this.added&&this.renderer.buildText(this);return this},on:function(a,b){var c=b;Ga&&a==="click"&&(a="touchstart",c=function(a){a.preventDefault();b()});this.element["on"+a]=c;return this},translate:function(a,b){return this.attr({translateX:a,
106
+ translateY:b})},invert:function(){this.inverted=!0;this.updateTransform();return this},htmlCss:function(a){var b=this.element;if(b=a&&b.tagName==="SPAN"&&a.width)delete a.width,this.textWidth=b,this.updateTransform();this.styles=L(this.styles,a);P(this.element,a);return this},htmlGetBBox:function(a){var b=this.element,c=this.bBox;if(!c||a){if(b.nodeName==="text")b.style.position=wb;c=this.bBox={x:b.offsetLeft,y:b.offsetTop,width:b.offsetWidth,height:b.offsetHeight}}return c},htmlUpdateTransform:function(){if(this.added){var a=
107
+ this.renderer,b=this.element,c=this.translateX||0,d=this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||"left",h={left:0,center:0.5,right:1}[g],i=g&&g!=="left",k=this.shadows;if(c||d)P(b,{marginLeft:c,marginTop:d}),k&&o(k,function(a){P(a,{marginLeft:c+1,marginTop:d+1})});this.inverted&&o(b.childNodes,function(c){a.invertChild(c,b)});if(b.tagName==="SPAN"){var j,l,k=this.rotation,n;j=0;var t=1,r=0,Z;n=S(this.textWidth);var V=this.xCorr||0,v=this.yCorr||0,y=[k,g,b.innerHTML,this.textWidth].join(",");
108
+ if(y!==this.cTT)s(k)&&(j=k*Dc,t=ja(j),r=C(j),P(b,{filter:k?["progid:DXImageTransform.Microsoft.Matrix(M11=",t,", M12=",-r,", M21=",r,", M22=",t,", sizingMethod='auto expand')"].join(""):Ma})),j=p(this.elemWidth,b.offsetWidth),l=p(this.elemHeight,b.offsetHeight),j>n&&(P(b,{width:n+ga,display:"block",whiteSpace:"normal"}),j=n),n=a.fontMetrics(b.style.fontSize).b,V=t<0&&-j,v=r<0&&-l,Z=t*r<0,V+=r*n*(Z?1-h:h),v-=t*n*(k?Z?h:1-h:1),i&&(V-=j*h*(t<0?-1:1),k&&(v-=l*h*(r<0?-1:1)),P(b,{textAlign:g})),this.xCorr=
109
+ V,this.yCorr=v;P(b,{left:e+V+ga,top:f+v+ga});this.cTT=y}}else this.alignOnAdd=!0},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=this.inverted,d=this.rotation,e=[];c&&(a+=this.attr("width"),b+=this.attr("height"));(a||b)&&e.push("translate("+a+","+b+")");c?e.push("rotate(90) scale(-1,1)"):d&&e.push("rotate("+d+" "+this.x+" "+this.y+")");e.length&&A(this.element,"transform",e.join(" "))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,
110
+ b,c){a?(this.alignOptions=a,this.alignByTranslate=b,c||this.renderer.alignedObjects.push(this)):(a=this.alignOptions,b=this.alignByTranslate);var c=p(c,this.renderer),d=a.align,e=a.verticalAlign,f=(c.x||0)+(a.x||0),g=(c.y||0)+(a.y||0),h={};/^(right|center)$/.test(d)&&(f+=(c.width-(a.width||0))/{right:1,center:2}[d]);h[b?"translateX":"x"]=z(f);/^(bottom|middle)$/.test(e)&&(g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1));h[b?"translateY":"y"]=z(g);this[this.placed?"animate":"attr"](h);this.placed=
111
+ !0;this.alignAttr=h;return this},getBBox:function(a){var b,c,d=this.rotation;c=this.element;var e=d*Dc;if(c.namespaceURI==="http://www.w3.org/2000/svg"){try{b=c.getBBox?L({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(f){}if(!b||b.width<0)b={width:0,height:0};a=b.width;c=b.height;if(d)b.width=Ba(c*C(e))+Ba(a*ja(e)),b.height=Ba(c*ja(e))+Ba(a*C(e))}else b=this.htmlGetBBox(a);return b},show:function(){return this.attr({visibility:eb})},hide:function(){return this.attr({visibility:ab})},
112
+ add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=A(f,"zIndex"),h;this.parentInverted=a&&a.inverted;this.textStr!==void 0&&b.buildText(this);if(g)c.handleZ=!0,g=S(g);if(c.handleZ)for(c=0;c<e.length;c++)if(a=e[c],b=A(a,"zIndex"),a!==f&&(S(b)>g||!s(g)&&s(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;aa(this,"add");return this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||
113
+ {},c=a.shadows,d=a.box,e,f;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=null;Ob(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(f=0;f<a.stops.length;f++)a.stops[f]=a.stops[f].destroy();a.stops=null}a.safeRemoveChild(b);c&&o(c,function(b){a.safeRemoveChild(b)});d&&d.destroy();Gb(a.renderer.alignedObjects,a);for(e in a)delete a[e];return null},empty:function(){for(var a=this.element,b=a.childNodes,c=b.length;c--;)a.removeChild(b[c])},shadow:function(a,b){var c=[],d,e,f=this.element,
114
+ g=this.parentInverted?"(-1,-1)":"(1,1)";if(a){for(d=1;d<=3;d++)e=f.cloneNode(0),A(e,{isShadow:"true",stroke:"rgb(0, 0, 0)","stroke-opacity":0.05*d,"stroke-width":7-2*d,transform:"translate"+g,fill:Ma}),b?b.element.appendChild(e):f.parentNode.insertBefore(e,f),c.push(e);this.shadows=c}return this}};var Eb=function(){this.init.apply(this,arguments)};Eb.prototype={Element:Sa,init:function(a,b,c,d){var e=location,f;f=this.createElement("svg").attr({xmlns:"http://www.w3.org/2000/svg",version:"1.1"});a.appendChild(f.element);
115
+ this.isSVG=!0;this.box=f.element;this.boxWrapper=f;this.alignedObjects=[];this.url=Qb?"":e.href.replace(/#.*?$/,"").replace(/([\('\)])/g,"\\$1");this.defs=this.createElement("defs").add();this.forExport=d;this.gradients={};this.setSize(b,c,!1)},destroy:function(){var a=this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();Jb(this.gradients||{});this.gradients=null;if(a)this.defs=a.destroy();return this.alignedObjects=null},createElement:function(a){var b=new this.Element;b.init(this,a);
116
+ return b},draw:function(){},buildText:function(a){for(var b=a.element,c=p(a.textStr,"").toString().replace(/<(b|strong)>/g,'<span style="font-weight:bold">').replace(/<(i|em)>/g,'<span style="font-style:italic">').replace(/<a/g,"<span").replace(/<\/(b|strong|i|em|a)>/g,"</span>").split(/<br.*?>/g),d=b.childNodes,e=/style="([^"]+)"/,f=/href="([^"]+)"/,g=A(b,"x"),h=a.styles,i=h&&S(h.width),k=h&&h.lineHeight,j,h=d.length;h--;)b.removeChild(d[h]);i&&!a.added&&this.box.appendChild(b);c[c.length-1]===""&&
117
+ c.pop();o(c,function(c,d){var h,r=0,p,c=c.replace(/<span/g,"|||<span").replace(/<\/span>/g,"</span>|||");h=c.split("|||");o(h,function(c){if(c!==""||h.length===1){var l={},o=x.createElementNS("http://www.w3.org/2000/svg","tspan");e.test(c)&&A(o,"style",c.match(e)[1].replace(/(;| |^)color([ :])/,"$1fill$2"));f.test(c)&&(A(o,"onclick",'location.href="'+c.match(f)[1]+'"'),P(o,{cursor:"pointer"}));c=(c.replace(/<(.|\n)*?>/g,"")||" ").replace(/&lt;/g,"<").replace(/&gt;/g,">");o.appendChild(x.createTextNode(c));
118
+ r?l.dx=3:l.x=g;if(!r){if(d){!Pb&&a.renderer.forExport&&P(o,{display:"block"});p=ca.getComputedStyle&&S(ca.getComputedStyle(j,null).getPropertyValue("line-height"));if(!p||isNaN(p))p=k||j.offsetHeight||18;A(o,"dy",p)}j=o}A(o,l);b.appendChild(o);r++;if(i)for(var c=c.replace(/-/g,"- ").split(" "),q,T=[];c.length||T.length;)q=a.getBBox().width,l=q>i,!l||c.length===1?(c=T,T=[],c.length&&(o=x.createElementNS("http://www.w3.org/2000/svg","tspan"),A(o,{dy:k||16,x:g}),b.appendChild(o),q>i&&(i=q))):(o.removeChild(o.firstChild),
119
+ T.unshift(c.pop())),c.length&&o.appendChild(x.createTextNode(c.join(" ").replace(/- /g,"-")))}})})},button:function(a,b,c,d,e,f,g){var h=this.label(a,b,c),i=0,k,j,l,n,o,a={x1:0,y1:0,x2:0,y2:1},e=K(za("stroke-width",1,"stroke","#999","fill",za("linearGradient",a,"stops",[[0,"#FFF"],[1,"#DDD"]]),"r",3,"padding",3,"style",za("color","black")),e);l=e.style;delete e.style;f=K(e,za("stroke","#68A","fill",za("linearGradient",a,"stops",[[0,"#FFF"],[1,"#ACF"]])),f);n=f.style;delete f.style;g=K(e,za("stroke",
120
+ "#68A","fill",za("linearGradient",a,"stops",[[0,"#9BD"],[1,"#CDF"]])),g);o=g.style;delete g.style;ha(h.element,"mouseenter",function(){h.attr(f).css(n)});ha(h.element,"mouseleave",function(){k=[e,f,g][i];j=[l,n,o][i];h.attr(k).css(j)});h.setState=function(a){(i=a)?a===2&&h.attr(g).css(o):h.attr(e).css(l)};return h.on("click",function(){d.call(h)}).attr(e).css(L({cursor:"default"},l))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=z(a[1])+b%2/2);a[2]===a[5]&&(a[2]=a[5]=z(a[2])+b%2/2);return a},path:function(a){return this.createElement("path").attr({d:a,
121
+ fill:Ma})},circle:function(a,b,c){a=mb(a)?a:{x:a,y:b,r:c};return this.createElement("circle").attr(a)},arc:function(a,b,c,d,e,f){if(mb(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;return this.symbol("arc",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0})},rect:function(a,b,c,d,e,f){if(mb(a))b=a.y,c=a.width,d=a.height,e=a.r,f=a.strokeWidth,a=a.x;e=this.createElement("rect").attr({rx:e,ry:e,fill:Ma});return e.attr(e.crisp(f,a,b,W(c,0),W(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects,
122
+ e=d.length;this.width=a;this.height=b;for(this.boxWrapper[p(c,!0)?"animate":"attr"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement("g");return s(a)?b.attr({"class":Ia+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:Ma};arguments.length>1&&L(f,{x:b,y:c,width:d,height:e});f=this.createElement("image").attr(f);f.element.setAttributeNS?f.element.setAttributeNS("http://www.w3.org/1999/xlink","href",a):f.element.setAttribute("hc-svg-href",a);return f},symbol:function(a,
123
+ b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(z(b),z(c),d,e,f),i=/^url\((.*?)\)$/,k;if(h)g=this.path(h),L(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&L(g,f);else if(i.test(a)){var j=function(a,b){a.attr({width:b[0],height:b[1]}).translate(-z(b[0]/2),-z(b[1]/2))};k=a.match(i)[1];a=Fc[k];g=this.image(k).attr({x:b,y:c});a?j(g,a):(g.attr({width:0,height:0}),Aa("img",{onload:function(){j(g,Fc[k]=[this.width,this.height])},src:k}))}return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return[wa,a+c/2,
124
+ b,"C",a+c+e,b,a+c+e,b+d,a+c/2,b+d,"C",a-e,b+d,a-e,b,a+c/2,b,"Z"]},square:function(a,b,c,d){return[wa,a,b,fa,a+c,b,a+c,b+d,a,b+d,"Z"]},triangle:function(a,b,c,d){return[wa,a+c/2,b,fa,a+c,b+d,a,b+d,"Z"]},"triangle-down":function(a,b,c,d){return[wa,a,b,fa,a+c,b,a+c/2,b+d,"Z"]},diamond:function(a,b,c,d){return[wa,a+c/2,b,fa,a+c,b+d/2,a+c/2,b+d,a,b+d/2,"Z"]},arc:function(a,b,c,d,e){var f=e.start,c=e.r||c||d,g=e.end-1.0E-6,d=e.innerR,h=ja(f),i=C(f),k=ja(g),g=C(g),e=e.end-f<da?0:1;return[wa,a+c*h,b+c*i,
125
+ "A",c,c,0,e,1,a+c*k,b+c*g,fa,a+d*k,b+d*g,"A",d,d,0,e,0,a+d*h,b+d*i,"Z"]}},clipRect:function(a,b,c,d){var e=Ia+lc++,f=this.createElement("clipPath").attr({id:e}).add(this.defs),a=this.rect(a,b,c,d,0).add(f);a.id=e;a.clipPath=f;return a},color:function(a,b,c){var d,e=/^rgba/;if(a&&a.linearGradient){var f=this,g=a.linearGradient,b=!Fb(g),c=f.gradients,h,i=g.x1||g[0]||0,k=g.y1||g[1]||0,j=g.x2||g[2]||0,l=g.y2||g[3]||0,n,t,r=[b,i,k,j,l,a.stops.join(",")].join(",");c[r]?g=A(c[r].element,"id"):(g=Ia+lc++,
126
+ h=f.createElement("linearGradient").attr(L({id:g,x1:i,y1:k,x2:j,y2:l},b?null:{gradientUnits:"userSpaceOnUse"})).add(f.defs),h.stops=[],o(a.stops,function(a){e.test(a[1])?(d=ma(a[1]),n=d.get("rgb"),t=d.get("a")):(n=a[1],t=1);a=f.createElement("stop").attr({offset:a[0],"stop-color":n,"stop-opacity":t}).add(h);h.stops.push(a)}),c[r]=h);return"url("+this.url+"#"+g+")"}else return e.test(a)?(d=ma(a),A(b,c+"-opacity",d.get("a")),d.get("rgb")):(b.removeAttribute(c+"-opacity"),a)},text:function(a,b,c,d){var e=
127
+ Ea.chart.style;if(d&&!this.forExport)return this.html(a,b,c);b=z(p(b,0));c=z(p(c,0));a=this.createElement("text").attr({x:b,y:c,text:a}).css({fontFamily:e.fontFamily,fontSize:e.fontSize});a.x=b;a.y=c;return a},html:function(a,b,c){var d=Ea.chart.style,e=this.createElement("span"),f=e.attrSetters,g=e.element,h=e.renderer;f.text=function(a){g.innerHTML=a;return!1};f.x=f.y=f.align=function(a,b){b==="align"&&(b="textAlign");e[b]=a;e.htmlUpdateTransform();return!1};e.attr({text:a,x:z(b),y:z(c)}).css({position:wb,
128
+ whiteSpace:"nowrap",fontFamily:d.fontFamily,fontSize:d.fontSize});e.css=e.htmlCss;if(h.isSVG)e.add=function(a){var b,c,d=h.box.parentNode;if(a){if(b=a.div,!b)b=a.div=Aa(Ra,{className:A(a.element,"class")},{position:wb,left:a.attr("translateX")+ga,top:a.attr("translateY")+ga},d),c=b.style,L(a.attrSetters,{translateX:function(a){c.left=a+ga},translateY:function(a){c.top=a+ga},visibility:function(a,b){c[b]=a}})}else b=d;b.appendChild(g);e.added=!0;e.alignOnAdd&&e.htmlUpdateTransform();return e};return e},
129
+ fontMetrics:function(a){var a=S(a||11),a=a<24?a+4:z(a*1.2),b=z(a*0.8);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h){function i(){var a=n.styles,a=a&&a.textAlign,b=v,c;c=h?0:ia;if(s(y)&&(a==="center"||a==="right"))b+={center:0.5,right:1}[a]*(y-p.width);(b!==t.x||c!==t.y)&&t.attr({x:b,y:c});t.x=b;t.y=c}function k(a,b){r?r.attr(a,b):x[a]=b}function j(){n.attr({text:a,x:b,y:c,anchorX:e,anchorY:f})}var l=this,n=l.g(),t=l.text("",0,0,g).attr({zIndex:1}).add(n),r,p,V="left",v=3,y,q,T,A,w=0,x={},ia,g=
130
+ n.attrSetters;ha(n,"add",j);g.width=function(a){y=a;return!1};g.height=function(a){q=a;return!1};g.padding=function(a){s(a)&&a!==v&&(v=a,i());return!1};g.align=function(a){V=a;return!1};g.text=function(a,b){t.attr(b,a);var c;c=t.element.style;p=(y===void 0||q===void 0||n.styles.textAlign)&&t.getBBox(!0);n.width=(y||p.width)+2*v;n.height=(q||p.height)+2*v;ia=v+l.fontMetrics(c&&c.fontSize).b;if(!r)c=h?-ia:0,n.box=r=d?l.symbol(d,0,c,n.width,n.height):l.rect(0,c,n.width,n.height,0,x["stroke-width"]),
131
+ r.add(n);r.attr(K({width:n.width,height:n.height},x));x=null;i();return!1};g["stroke-width"]=function(a,b){w=a%2/2;k(b,a);return!1};g.stroke=g.fill=g.r=function(a,b){k(b,a);return!1};g.anchorX=function(a,b){e=a;k(b,a+w-T);return!1};g.anchorY=function(a,b){f=a;k(b,a-A);return!1};g.x=function(a){a-={left:0,center:0.5,right:1}[V]*((y||p.width)+v);T=n.x=z(a);n.attr("translateX",T);return!1};g.y=function(a){A=n.y=z(a);n.attr("translateY",a);return!1};var ua=n.css;return L(n,{css:function(a){if(a){var b=
132
+ {},a=K({},a);o("fontSize,fontWeight,fontFamily,color,lineHeight,width".split(","),function(c){a[c]!==X&&(b[c]=a[c],delete a[c])});t.css(b)}return ua.call(n,a)},getBBox:function(){return r.getBBox()},shadow:function(a){r.shadow(a);return n},destroy:function(){Qa(n,"add",j);Qa(n.element,"mouseenter");Qa(n.element,"mouseleave");t&&(t=t.destroy());Sa.prototype.destroy.call(n)}})}};Xb=Eb;var $a;if(!Pb&&!Fa)$a={init:function(a,b){var c=["<",b,' filled="f" stroked="f"'],d=["position: ",wb,";"];(b==="shape"||
133
+ b===Ra)&&d.push("left:0;top:0;width:10px;height:10px;");Xa&&d.push("visibility: ",b===Ra?ab:eb);c.push(' style="',d.join(""),'"/>');if(b)c=b===Ra||b==="span"||b==="img"?c.join(""):a.prepVML(c),this.element=Aa(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);Xa&&d.gVis===ab&&P(c,{visibility:ab});d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();aa(this,
134
+ "add");return this},toggleChildren:function(a,b){for(var c=a.childNodes,d=c.length;d--;)P(c[d],{visibility:b}),c[d].nodeName==="DIV"&&this.toggleChildren(c[d],b)},updateTransform:Sa.prototype.htmlUpdateTransform,attr:function(a,b){var c,d,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,k=this.symbolName,j,l=this.shadows,n,o=this.attrSetters,r=this;Ab(a)&&s(b)&&(c=a,a={},a[c]=b);if(Ab(a))c=a,r=c==="strokeWidth"||c==="stroke-width"?this.strokeweight:this[c];else for(c in a)if(d=a[c],n=!1,
135
+ e=o[c]&&o[c](d,c),e!==!1&&d!==null){e!==X&&(d=e);if(k&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))j||(this.symbolAttr(a),j=!0),n=!0;else if(c==="d"){d=d||[];this.d=d.join(" ");e=d.length;for(n=[];e--;)n[e]=Bb(d[e])?z(d[e]*10)-5:d[e]==="Z"?"x":d[e];d=n.join(" ")||"x";f.path=d;if(l)for(e=l.length;e--;)l[e].path=d;n=!0}else if(c==="zIndex"||c==="visibility"){if(Xa&&c==="visibility"&&h==="DIV")f.gVis=d,this.toggleChildren(f,d),d===eb&&(d=null);d&&(g[c]=d);n=!0}else if(c==="width"||
136
+ c==="height")d=W(0,d),this[c]=d,this.updateClipping?(this[c]=d,this.updateClipping()):g[c]=d,n=!0;else if(c==="x"||c==="y")this[c]=d,g[{x:"left",y:"top"}[c]]=d;else if(c==="class")f.className=d;else if(c==="stroke")d=i.color(d,f,c),c="strokecolor";else if(c==="stroke-width"||c==="strokeWidth")f.stroked=d?!0:!1,c="strokeweight",this[c]=d,Bb(d)&&(d+=ga);else if(c==="dashstyle")(f.getElementsByTagName("stroke")[0]||Aa(i.prepVML(["<stroke/>"]),null,null,f))[c]=d||"solid",this.dashstyle=d,n=!0;else if(c===
137
+ "fill")h==="SPAN"?g.color=d:(f.filled=d!==Ma?!0:!1,d=i.color(d,f,c),c="fillcolor");else if(c==="translateX"||c==="translateY"||c==="rotation")this[c]=d,this.updateTransform(),n=!0;else if(c==="text")this.bBox=null,f.innerHTML=d,n=!0;if(l&&c==="visibility")for(e=l.length;e--;)l[e].style[c]=d;n||(Xa?f[c]=d:A(f,c,d))}return r},clip:function(a){var b=this,c=a.members;c.push(b);b.destroyClip=function(){Gb(c,b)};return b.css(a.getCSS(b.inverted))},css:Sa.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&
138
+ Tb(a)},destroy:function(){this.destroyClip&&this.destroyClip();return Sa.prototype.destroy.apply(this)},empty:function(){for(var a=this.element.childNodes,b=a.length,c;b--;)c=a[b],c.parentNode.removeChild(c)},on:function(a,b){this.element["on"+a]=function(){var a=ca.event;a.target=a.srcElement;b(a)};return this},shadow:function(a,b){var c=[],d,e=this.element,f=this.renderer,g,h=e.style,i,k=e.path;k&&typeof k.value!=="string"&&(k="x");if(a){for(d=1;d<=3;d++)i=['<shape isShadow="true" strokeweight="',
139
+ 7-2*d,'" filled="false" path="',k,'" coordsize="100,100" style="',e.style.cssText,'" />'],g=Aa(f.prepVML(i),null,{left:S(h.left)+1,top:S(h.top)+1}),i=['<stroke color="black" opacity="',0.05*d,'"/>'],Aa(f.prepVML(i),null,null,g),b?b.element.appendChild(g):e.parentNode.insertBefore(g,e),c.push(g);this.shadows=c}return this}},$a=pa(Sa,$a),w={Element:$a,isIE8:kb.indexOf("MSIE 8.0")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(Ra);e=d.element;e.style.position=mc;a.appendChild(d.element);
140
+ this.box=e;this.boxWrapper=d;this.setSize(b,c,!1);if(!x.namespaces.hcv)x.namespaces.add("hcv","urn:schemas-microsoft-com:vml"),x.createStyleSheet().cssText="hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } "},clipRect:function(a,b,c,d){var e=this.createElement();return L(e,{members:[],left:a,top:b,width:c,height:d,getCSS:function(a){var b=this.top,c=this.left,d=c+this.width,e=b+this.height,b={clip:"rect("+z(a?c:b)+"px,"+z(a?e:d)+"px,"+z(a?d:e)+
141
+ "px,"+z(a?b:c)+"px)"};!a&&Xa&&L(b,{width:d+ga,height:e+ga});return b},updateClipping:function(){o(e.members,function(a){a.css(e.getCSS(a.inverted))})}})},color:function(a,b,c){var d,e=/^rgba/;if(a&&a.linearGradient){var f,g,h=a.linearGradient,i=h.x1||h[0]||0,k=h.y1||h[1]||0,j=h.x2||h[2]||0,h=h.y2||h[3]||0,l,n,p,r;o(a.stops,function(a,b){e.test(a[1])?(d=ma(a[1]),f=d.get("rgb"),g=d.get("a")):(f=a[1],g=1);b?(p=f,r=g):(l=f,n=g)});if(c==="fill")a=90-oa.atan((h-k)/(j-i))*180/da,a=['<fill colors="0% ',l,
142
+ ",100% ",p,'" angle="',a,'" opacity="',r,'" o:opacity2="',n,'" type="gradient" focus="100%" method="sigma" />'],Aa(this.prepVML(a),null,null,b);else return f}else if(e.test(a)&&b.tagName!=="IMG")return d=ma(a),a=["<",c,' opacity="',d.get("a"),'"/>'],Aa(this.prepVML(a),null,null,b),d.get("rgb");else{b=b.getElementsByTagName(c);if(b.length)b[0].opacity=1;return a}},prepVML:function(a){var b=this.isIE8,a=a.join("");b?(a=a.replace("/>",' xmlns="urn:schemas-microsoft-com:vml" />'),a=a.indexOf('style="')===
143
+ -1?a.replace("/>",' style="display:inline-block;behavior:url(#default#VML);" />'):a.replace('style="','style="display:inline-block;behavior:url(#default#VML);')):a=a.replace("<","<hcv:");return a},text:Eb.prototype.html,path:function(a){return this.createElement("shape").attr({coordsize:"100 100",d:a})},circle:function(a,b,c){return this.symbol("circle").attr({x:a-c,y:b-c,width:2*c,height:2*c})},g:function(a){var b;a&&(b={className:Ia+a,"class":Ia+a});return this.createElement(Ra).attr(b)},image:function(a,
144
+ b,c,d,e){var f=this.createElement("img").attr({src:a});arguments.length>1&&f.css({left:b,top:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){if(mb(a))b=a.y,c=a.width,d=a.height,f=a.strokeWidth,a=a.x;var g=this.symbol("rect");g.r=e;return g.attr(g.crisp(f,a,b,W(c,0),W(d,0)))},invertChild:function(a,b){var c=b.style;P(a,{flip:"x",left:S(c.width)-10,top:S(c.height)-10,rotation:-90})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,c=e.r||c||d,d=ja(f),h=C(f),i=ja(g),k=C(g),e=e.innerR,
145
+ j=0.08/c,l=e&&0.25/e||0;if(g-f===0)return["x"];else 2*da-g+f<j?i=-j:g-f<l&&(i=ja(f+l));return["wa",a-c,b-c,a+c,b+c,a+c*d,b+c*h,a+c*i,b+c*k,"at",a-e,b-e,a+e,b+e,a+e*i,b+e*k,a+e*d,b+e*h,"x","e"]},circle:function(a,b,c,d){return["wa",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,"e"]},rect:function(a,b,c,d,e){if(!s(e))return[];var f=a+c,g=b+d,c=Ua(e.r||0,c,d);return[wa,a+c,b,fa,f-c,b,"wa",f-2*c,b,f,b+2*c,f-c,b,f,b+c,fa,f,g-c,"wa",f-2*c,g-2*c,f,g,f,g-c,f-c,g,fa,a+c,g,"wa",a,g-2*c,a+2*c,g,a+c,g,a,g-c,fa,a,b+c,"wa",
146
+ a,b,a+2*c,b+2*c,a,b+c,a+c,b,"x","e"]}}},$a=function(){this.init.apply(this,arguments)},$a.prototype=K(Eb.prototype,w),Xb=$a;var oc,Cc;Fa&&(oc=function(){},Cc=function(){function a(){var a=b.length,d;for(d=0;d<a;d++)b[d]();b=[]}var b=[];return{push:function(c,d){b.length===0&&Hc(d,a);b.push(c)}}}());Xb=$a||oc||Eb;wc.prototype.callbacks=[];var lb=function(){};lb.prototype={init:function(a,b,c){var d=a.chart.counters;this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint){b=
147
+ a.chart.options.colors;if(!this.options)this.options={};this.color=this.options.color=this.color||b[d.color++];d.wrapColor(b.length)}a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=typeof a;this.config=a;if(d==="number"||a===null)this.y=a;else if(typeof a[0]==="number")this.x=a[0],this.y=a[1];else if(d==="object"&&typeof a.length!=="number"){if(L(this,a),this.options=a,a.dataLabels)c._hasPointLabels=!0}else if(typeof a[0]==="string")this.name=a[0],this.y=a[1];if(this.x===
148
+ X)this.x=b===X?c.autoIncrement():b},destroy:function(){var a=this.series,b=a.chart.hoverPoints,c;a.chart.pointCount--;b&&(this.setState(),Gb(b,this));if(this===a.chart.hoverPoint)this.onMouseOut();a.chart.hoverPoints=null;if(this.graphic||this.dataLabel)Qa(this),this.destroyElements();this.legendItem&&this.series.chart.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a="graphic,tracker,dataLabel,group,connector,shadowGroup".split(","),b,c=6;c--;)b=a[c],this[b]&&
149
+ (this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},select:function(a,b){var c=this,d=c.series.chart,a=p(a,!c.selected);c.firePointEvent(a?"select":"unselect",{accumulate:b},function(){c.selected=a;c.setState(a&&"select");b||o(d.getSelectedPoints(),function(a){if(a.selected&&a!==c)a.selected=!1,a.setState(Ka),a.firePointEvent("unselect")})})},
150
+ onMouseOver:function(){var a=this.series,b=a.chart,c=b.tooltip,d=b.hoverPoint;if(d&&d!==this)d.onMouseOut();this.firePointEvent("mouseOver");c&&(!c.shared||a.noSharedTooltip)&&c.refresh(this);this.setState(ta);b.hoverPoint=this},onMouseOut:function(){this.firePointEvent("mouseOut");this.setState();this.series.chart.hoverPoint=null},tooltipFormatter:function(a){var b=this.series,c=b.tooltipOptions,d=String(this.y).split("."),d=d[1]?d[1].length:0,e=a.match(/\{(series|point)\.[a-zA-Z]+\}/g),f=/[{\.}]/,
151
+ g,h,i,k;for(k in e)h=e[k],Ab(h)&&h!==a&&(i=(" "+h).split(f),g={point:this,series:b}[i[1]],i=i[2],g=g===this&&(i==="y"||i==="open"||i==="high"||i==="low"||i==="close")?(c.valuePrefix||c.yPrefix||"")+dc(this[i],p(c.valueDecimals,c.yDecimals,d))+(c.valueSuffix||c.ySuffix||""):g[i],a=a.replace(h,g));return a},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=h.length,k=e.chart,b=p(b,!0);d.firePointEvent("update",{options:a},function(){d.applyOptions(a);mb(a)&&(e.getAttribs(),f&&f.attr(d.pointAttr[e.state]));
152
+ for(g=0;g<i;g++)if(h[g]===d){e.xData[g]=d.x;e.yData[g]=d.y;e.options.data[g]=a;break}e.isDirty=!0;e.isDirtyData=!0;b&&k.redraw(c)})},remove:function(a,b){var c=this,d=c.series,e=d.chart,f,g=d.data,h=g.length;Kb(b,e);a=p(a,!0);c.firePointEvent("remove",null,function(){for(f=0;f<h;f++)if(g[f]===c){g.splice(f,1);d.options.data.splice(f,1);d.xData.splice(f,1);d.yData.splice(f,1);break}c.destroy();d.isDirty=!0;d.isDirtyData=!0;a&&e.redraw()})},firePointEvent:function(a,b,c){var d=this,e=this.series.options;
153
+ (e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents();a==="click"&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});aa(this,a,b,c)},importEvents:function(){if(!this.hasImportedEvents){var a=K(this.series.options.point,this.options).events,b;this.events=a;for(b in a)ha(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a){var b=this.plotX,c=this.plotY,d=this.series,e=d.options.states,f=M[d.type].marker&&d.options.marker,
154
+ g=f&&!f.enabled,h=f&&f.states[a],i=h&&h.enabled===!1,k=d.stateMarkerGraphic,j=d.chart,l=this.pointAttr,a=a||Ka;if(!(a===this.state||this.selected&&a!=="select"||e[a]&&e[a].enabled===!1||a&&(i||g&&!h.enabled))){if(this.graphic)e=f&&this.graphic.symbolName&&l[a].r,this.graphic.attr(K(l[a],e?{x:b-e,y:c-e,width:2*e,height:2*e}:{}));else{if(a){if(!k)e=f.radius,d.stateMarkerGraphic=k=j.renderer.symbol(d.symbol,-e,-e,2*e,2*e).attr(l[a]).add(d.group);k.translate(b,c)}if(k)k[a?"show":"hide"]()}this.state=
155
+ a}}};var $=function(){};$.prototype={isCartesian:!0,type:"line",pointClass:lb,sorted:!0,pointAttrToOptions:{stroke:"lineColor","stroke-width":"lineWidth",fill:"fillColor",r:"radius"},init:function(a,b){var c,d;d=a.series.length;this.chart=a;this.options=b=this.setOptions(b);this.bindAxes();L(this,{index:d,name:b.name||"Series "+(d+1),state:Ka,pointAttr:{},visible:b.visible!==!1,selected:b.selected===!0});if(Fa)b.animation=!1;d=b.events;for(c in d)ha(this,c,d[c]);if(d&&d.click||b.point&&b.point.events&&
156
+ b.point.events.click||b.allowPointSelect)a.runTrackerClick=!0;this.getColor();this.getSymbol();this.setData(b.data,!1)},bindAxes:function(){var a=this,b=a.options,c=a.chart,d;a.isCartesian&&o(["xAxis","yAxis"],function(e){o(c[e],function(c){d=c.options;if(b[e]===d.index||b[e]===X&&d.index===0)c.series.push(a),a[e]=c,c.isDirty=!0})})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=p(b,a.pointStart,0);this.pointInterval=p(this.pointInterval,a.pointInterval,1);this.xIncrement=b+this.pointInterval;
157
+ return b},getSegments:function(){var a=-1,b=[],c,d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)d[c].y===null&&d.splice(c,1);d.length&&(b=[d])}else o(d,function(c,g){c.y===null?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=a.data;a.data=null;c=K(c[this.type],c.series,a);c.data=a.data=d;this.tooltipOptions=K(b.tooltip,c.tooltip);return c},getColor:function(){var a=
158
+ this.chart.options.colors,b=this.chart.counters;this.color=this.options.color||a[b.color++]||"#0000ff";b.wrapColor(a.length)},getSymbol:function(){var a=this.options.marker,b=this.chart,c=b.options.symbols,b=b.counters;this.symbol=a.symbol||c[b.symbol++];if(/^url/.test(this.symbol))a.radius=0;b.wrapSymbol(c.length)},addPoint:function(a,b,c,d){var e=this.data,f=this.graph,g=this.area,h=this.chart,i=this.xData,k=this.yData,j=f&&f.shift||0,l=this.options.data;Kb(d,h);if(f&&c)f.shift=j+1;if(g){if(c)g.shift=
159
+ j+1;g.isArea=!0}b=p(b,!0);d={series:this};this.pointClass.prototype.applyOptions.apply(d,[a]);i.push(d.x);k.push(this.valueCount===4?[d.open,d.high,d.low,d.close]:d.y);l.push(a);c&&(e[0]?e[0].remove(!1):(e.shift(),i.shift(),k.shift(),l.shift()));this.getAttribs();this.isDirtyData=this.isDirty=!0;b&&h.redraw()},setData:function(a,b){var c=this.points,d=this.options,e=this.initialColor,f=this.chart,g=null;this.xIncrement=null;this.pointRange=this.xAxis&&this.xAxis.categories&&1||d.pointRange;if(s(e))f.counters.color=
160
+ e;var h=[],i=[],k=a?a.length:[],j=this.valueCount===4;if(k>(d.turboThreshold||1E3)){for(e=0;g===null&&e<k;)g=a[e],e++;if(Bb(g)){g=p(d.pointStart,0);d=p(d.pointInterval,1);for(e=0;e<k;e++)h[e]=g,i[e]=a[e],g+=d;this.xIncrement=g}else if(Fb(g))if(j)for(e=0;e<k;e++)d=a[e],h[e]=d[0],i[e]=d.slice(1,5);else for(e=0;e<k;e++)d=a[e],h[e]=d[0],i[e]=d[1]}else for(e=0;e<k;e++)d={series:this},this.pointClass.prototype.applyOptions.apply(d,[a[e]]),h[e]=d.x,i[e]=j?[d.open,d.high,d.low,d.close]:d.y;this.data=[];this.options.data=
161
+ a;this.xData=h;this.yData=i;for(e=c&&c.length||0;e--;)c[e]&&c[e].destroy&&c[e].destroy();this.isDirty=this.isDirtyData=f.isDirtyBox=!0;p(b,!0)&&f.redraw(!1)},remove:function(a,b){var c=this,d=c.chart,a=p(a,!0);if(!c.isRemoving)c.isRemoving=!0,aa(c,"remove",null,function(){c.destroy();d.isDirtyLegend=d.isDirtyBox=!0;a&&d.redraw(b)});c.isRemoving=!1},processData:function(a){var b=this.xData,c=this.yData,d=b.length,e=0,f=d,g,h,i=this.xAxis,k=this.options,j=k.cropThreshold,l=this.isCartesian;if(l&&!this.isDirty&&
162
+ !i.isDirty&&!this.yAxis.isDirty&&!a)return!1;if(l&&this.sorted&&(!j||d>j||this.forceCrop))if(a=i.getExtremes(),i=a.min,j=a.max,b[d-1]<i||b[0]>j)b=[],c=[];else if(b[0]<i||b[d-1]>j){for(a=0;a<d;a++)if(b[a]>=i){e=W(0,a-1);break}for(;a<d;a++)if(b[a]>j){f=a+1;break}b=b.slice(e,f);c=c.slice(e,f);g=!0}for(a=b.length-1;a>0;a--)if(d=b[a]-b[a-1],d>0&&(h===X||d<h))h=d;this.cropped=g;this.cropStart=e;this.processedXData=b;this.processedYData=c;if(k.pointRange===null)this.pointRange=h||1;this.closestPointRange=
163
+ h},generatePoints:function(){var a=this.options.data,b=this.data,c,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,i,k=this.hasGroupedData,j,l=[],n;if(!b&&!k)b=[],b.length=a.length,b=this.data=b;for(n=0;n<g;n++)i=h+n,k?l[n]=(new f).init(this,[d[n]].concat(Hb(e[n]))):(b[i]?j=b[i]:b[i]=j=(new f).init(this,a[i],d[n]),l[n]=j);if(b&&(g!==(c=b.length)||k))for(n=0;n<c;n++)n===h&&!k&&(n+=g),b[n]&&b[n].destroyElements();this.data=b;this.points=l},translate:function(){this.processedXData||
164
+ this.processData();this.generatePoints();for(var a=this.chart,b=this.options,c=b.stacking,d=this.xAxis,e=d.categories,f=this.yAxis,g=this.points,h=g.length,i=!!this.modifyValue,k,j=f.series,l=j.length;l--;)if(j[l].visible){l===this.index&&(k=!0);break}for(l=0;l<h;l++){var j=g[l],n=j.x,o=j.y,r=j.low,p=f.stacks[(o<b.threshold?"-":"")+this.stackKey];j.plotX=z(d.translate(n,0,0,0,1)*10)/10;if(c&&this.visible&&p&&p[n]){r=p[n];n=r.total;r.cum=r=r.cum-o;o=r+o;if(k)r=b.threshold;c==="percent"&&(r=n?r*100/
165
+ n:0,o=n?o*100/n:0);j.percentage=n?j.y*100/n:0;j.stackTotal=n;j.stackY=o}j.yBottom=s(r)?f.translate(r,0,1,0,1):null;i&&(o=this.modifyValue(o,j));j.plotY=typeof o==="number"?z(f.translate(o,0,1,0,1)*10)/10:X;j.clientX=a.inverted?a.plotHeight-j.plotX:j.plotX;j.category=e&&e[j.x]!==X?e[j.x]:j.x}this.getSegments()},setTooltipPoints:function(a){var b=this.chart,c=b.inverted,d=[],b=z((c?b.plotTop:b.plotLeft)+b.plotSizeX),e,f;e=this.xAxis;var g,h,i=[];if(this.options.enableMouseTracking!==!1){if(a)this.tooltipPoints=
166
+ null;o(this.segments||this.points,function(a){d=d.concat(a)});e&&e.reversed&&(d=d.reverse());a=d.length;for(h=0;h<a;h++){g=d[h];e=d[h-1]?d[h-1]._high+1:0;for(f=g._high=d[h+1]?Ta((g.plotX+(d[h+1]?d[h+1].plotX:b))/2):b;e<=f;)i[c?b-e++:e++]=g}this.tooltipPoints=i}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat||"%A, %b %e, %Y",d=this.xAxis;return b.headerFormat.replace("{point.key}",d&&d.options.type==="datetime"?ac(c,a):a).replace("{series.name}",this.name).replace("{series.color}",
167
+ this.color)},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(Ga||!a.mouseIsDown){if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&aa(this,"mouseOver");this.setState(ta);a.hoverSeries=this}},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut();this&&a.events.mouseOut&&aa(this,"mouseOut");c&&!a.stickyTracking&&!c.shared&&c.hide();this.setState();b.hoverSeries=null},animate:function(a){var b=this.chart,c=this.clipRect,d=this.options.animation;
168
+ d&&!mb(d)&&(d={});if(a){if(!c.isAnimating)c.attr("width",0),c.isAnimating=!0}else c.animate({width:b.plotSizeX},d),this.animate=null},drawPoints:function(){var a,b=this.points,c=this.chart,d,e,f,g,h,i,k,j;if(this.options.marker.enabled)for(f=b.length;f--;)if(g=b[f],d=g.plotX,e=g.plotY,j=g.graphic,e!==X&&!isNaN(e))if(a=g.pointAttr[g.selected?"select":Ka],h=a.r,i=p(g.marker&&g.marker.symbol,this.symbol),k=i.indexOf("url")===0,j)j.animate(L({x:d-h,y:e-h},j.symbolName?{width:2*h,height:2*h}:{}));else if(h>
169
+ 0||k)g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(this.group)},convertAttribs:function(a,b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=p(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=M[a.type].marker?a.options.marker:a.options,c=b.states,d=c[ta],e,f=a.color,g={stroke:f,fill:f},h=a.points,i=[],k,j=a.pointAttrToOptions,l;a.options.marker?(d.radius=d.radius||b.radius+2,d.lineWidth=d.lineWidth||b.lineWidth+1):d.color=
170
+ d.color||ma(d.color||f).brighten(d.brightness).get();i[Ka]=a.convertAttribs(b,g);o([ta,"select"],function(b){i[b]=a.convertAttribs(c[b],i[Ka])});a.pointAttr=i;for(f=h.length;f--;){g=h[f];if((b=g.options&&g.options.marker||g.options)&&b.enabled===!1)b.radius=0;e=!1;if(g.options)for(l in j)s(b[j[l]])&&(e=!0);if(e){k=[];c=b.states||{};e=c[ta]=c[ta]||{};if(!a.options.marker)e.color=ma(e.color||g.options.color).brighten(e.brightness||d.brightness).get();k[Ka]=a.convertAttribs(b,i[Ka]);k[ta]=a.convertAttribs(c[ta],
171
+ i[ta],k[Ka]);k.select=a.convertAttribs(c.select,i.select,k[Ka])}else k=i;g.pointAttr=k}},destroy:function(){var a=this,b=a.chart,c=a.clipRect,d=/AppleWebKit\/533/.test(kb),e,f,g=a.data||[],h,i,k;aa(a,"destroy");Qa(a);o(["xAxis","yAxis"],function(b){if(k=a[b])Gb(k.series,a),k.isDirty=!0});a.legendItem&&a.chart.legend.destroyItem(a);for(f=g.length;f--;)(h=g[f])&&h.destroy&&h.destroy();a.points=null;if(c&&c!==b.clipRect)a.clipRect=c.destroy();o(["area","graph","dataLabelsGroup","group","tracker"],function(b){a[b]&&
172
+ (e=d&&b==="group"?"hide":"destroy",a[b][e]())});if(b.hoverSeries===a)b.hoverSeries=null;Gb(b.series,a);for(i in a)delete a[i]},drawDataLabels:function(){var a=this,b=a.options,c=b.dataLabels;if(c.enabled||a._hasPointLabels){var d,e,f=a.points,g,h,i,k=a.dataLabelsGroup,j=a.chart,l=a.xAxis,l=l?l.left:j.plotLeft,n=a.yAxis,n=n?n.top:j.plotTop,t=j.renderer,r=j.inverted,Z=a.type,V=b.stacking,v=Z==="column"||Z==="bar",y=c.verticalAlign===null,q=c.y===null,T=t.fontMetrics(c.style.fontSize),A=T.h,x=T.b,w,
173
+ ia;v&&(T={top:x,middle:x-A/2,bottom:-A+x},V?(y&&(c=K(c,{verticalAlign:"middle"})),q&&(c=K(c,{y:T[c.verticalAlign]}))):y?c=K(c,{verticalAlign:"top"}):q&&(c=K(c,{y:T[c.verticalAlign]})));k?k.translate(l,n):k=a.dataLabelsGroup=t.g("data-labels").attr({visibility:a.visible?eb:ab,zIndex:6}).translate(l,n).add();h=c;o(f,function(f){w=f.dataLabel;c=h;(g=f.options)&&g.dataLabels&&(c=K(c,g.dataLabels));if(ia=c.enabled){var l=f.barX&&f.barX+f.barW/2||p(f.plotX,-999),n=p(f.plotY,-999),o=c.y===null?f.y>=b.threshold?
174
+ -A+x:x:c.y;d=(r?j.plotWidth-n:l)+c.x;e=z((r?j.plotHeight-l:n)+o)}if(w&&a.isCartesian&&(!j.isInsidePlot(d,e)||!ia))f.dataLabel=w.destroy();else if(ia){l=c.align;i=c.formatter.call(f.getLabelConfig(),c);Z==="column"&&(d+={left:-1,right:1}[l]*f.barW/2||0);!V&&r&&f.y<0&&(l="right",d-=10);c.style.color=p(c.color,c.style.color,a.color,"black");if(w)w.attr({text:i}).animate({x:d,y:e});else if(s(i))w=f.dataLabel=t[c.rotation?"text":"label"](i,d,e,null,null,null,c.useHTML,!0).attr({align:l,fill:c.backgroundColor,
175
+ stroke:c.borderColor,"stroke-width":c.borderWidth,r:c.borderRadius,rotation:c.rotation,padding:c.padding,zIndex:1}).css(c.style).add(k).shadow(c.shadow);if(v&&b.stacking&&w)l=f.barX,n=f.barY,o=f.barW,f=f.barH,w.align(c,null,{x:r?j.plotWidth-n-f:l,y:r?j.plotHeight-l-o:n,width:r?f:o,height:r?o:f})}})}},drawGraph:function(){var a=this,b=a.options,c=a.graph,d=[],e,f=a.area,g=a.group,h=b.lineColor||a.color,i=b.lineWidth,k=b.dashStyle,j,l=a.chart.renderer,n=a.yAxis.getThreshold(b.threshold),t=/^area/.test(a.type),
176
+ r=[],s=[];o(a.segments,function(c){j=[];o(c,function(d,e){a.getPointSpline?j.push.apply(j,a.getPointSpline(c,d,e)):(j.push(e?fa:wa),e&&b.step&&j.push(d.plotX,c[e-1].plotY),j.push(d.plotX,d.plotY))});c.length>1?d=d.concat(j):r.push(c[0]);if(t){var e=[],f,g=j.length;for(f=0;f<g;f++)e.push(j[f]);g===3&&e.push(fa,j[1],j[2]);if(b.stacking&&a.type!=="areaspline")for(f=c.length-1;f>=0;f--)f<c.length-1&&b.step&&e.push(c[f+1].plotX,c[f].yBottom),e.push(c[f].plotX,c[f].yBottom);else e.push(fa,c[c.length-1].plotX,
177
+ n,fa,c[0].plotX,n);s=s.concat(e)}});a.graphPath=d;a.singlePoints=r;if(t)e=p(b.fillColor,ma(a.color).setOpacity(b.fillOpacity||0.75).get()),f?f.animate({d:s}):a.area=a.chart.renderer.path(s).attr({fill:e}).add(g);if(c)Ob(c),c.animate({d:d});else if(i){c={stroke:h,"stroke-width":i};if(k)c.dashstyle=k;a.graph=l.path(d).attr(c).add(g).shadow(b.shadow)}},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};c.attr(a).invert();d&&d.attr(a).invert()}var b=this,c=b.group,d=b.trackerGroup,
178
+ e=b.chart;ha(e,"resize",a);ha(b,"destroy",function(){Qa(e,"resize",a)});a();b.invertGroups=a},render:function(){var a=this,b=a.chart,c,d=a.options,e=d.clip!==!1,f=d.animation,g=f&&a.animate,f=g?f&&f.duration||500:0,h=a.clipRect,i=b.renderer;if(!h&&(h=a.clipRect=!b.hasRendered&&b.clipRect?b.clipRect:i.clipRect(0,0,b.plotSizeX,b.plotSizeY+1),!b.clipRect))b.clipRect=h;if(!a.group)c=a.group=i.g("series"),c.attr({visibility:a.visible?eb:ab,zIndex:d.zIndex}).translate(a.xAxis.left,a.yAxis.top).add(b.seriesGroup);
179
+ a.drawDataLabels();g&&a.animate(!0);a.getAttribs();a.drawGraph&&a.drawGraph();a.drawPoints();a.options.enableMouseTracking!==!1&&a.drawTracker();b.inverted&&a.invertGroups();e&&!a.hasRendered&&(c.clip(h),a.trackerGroup&&a.trackerGroup.clip(b.clipRect));g&&a.animate();setTimeout(function(){h.isAnimating=!1;if((c=a.group)&&h!==b.clipRect&&h.renderer){if(e)c.clip(a.clipRect=b.clipRect);h.destroy()}},f);a.isDirty=a.isDirtyData=!1;a.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirtyData,
180
+ c=this.group;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:this.xAxis.left,translateY:this.yAxis.top}));this.translate();this.setTooltipPoints(!0);this.render();b&&aa(this,"updatedData")},setState:function(a){var b=this.options,c=this.graph,d=b.states,b=b.lineWidth,a=a||Ka;if(this.state!==a)this.state=a,d[a]&&d[a].enabled===!1||(a&&(b=d[a].lineWidth||b+1),c&&!c.dashstyle&&c.attr({"stroke-width":b},a?0:500))},setVisible:function(a,b){var c=this.chart,d=this.legendItem,
181
+ e=this.group,f=this.tracker,g=this.dataLabelsGroup,h,i=this.points,k=c.options.chart.ignoreHiddenSeries;h=this.visible;h=(this.visible=a=a===X?!h:a)?"show":"hide";if(e)e[h]();if(f)f[h]();else if(i)for(e=i.length;e--;)if(f=i[e],f.tracker)f.tracker[h]();if(g)g[h]();d&&c.legend.colorizeItem(this,a);this.isDirty=!0;this.options.stacking&&o(c.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});if(k)c.isDirtyBox=!0;b!==!1&&c.redraw();aa(this,h)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},
182
+ select:function(a){this.selected=a=a===X?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;aa(this,a?"select":"unselect")},drawTrackerGroup:function(){var a=this.trackerGroup,b=this.chart;if(this.isCartesian){if(!a)this.trackerGroup=a=b.renderer.g().attr({zIndex:this.options.zIndex||1}).add(b.trackerGroup);a.translate(this.xAxis.left,this.yAxis.top)}return a},drawTracker:function(){var a=this,b=a.options,c=[].concat(a.graphPath),d=c.length,e=a.chart,f=e.renderer,g=e.options.tooltip.snap,h=
183
+ a.tracker,i=b.cursor,i=i&&{cursor:i},k=a.singlePoints,j=a.drawTrackerGroup(),l;if(d)for(l=d+1;l--;)c[l]===wa&&c.splice(l+1,0,c[l+1]-g,c[l+2],fa),(l&&c[l]===wa||l===d)&&c.splice(l,0,fa,c[l-2]+g,c[l-1]);for(l=0;l<k.length;l++)d=k[l],c.push(wa,d.plotX-g,d.plotY,fa,d.plotX+g,d.plotY);h?h.attr({d:c}):a.tracker=f.path(c).attr({isTracker:!0,stroke:Gc,fill:Ma,"stroke-linejoin":"bevel","stroke-width":b.lineWidth+2*g,visibility:a.visible?eb:ab}).on(Ga?"touchstart":"mouseover",function(){if(e.hoverSeries!==
184
+ a)a.onMouseOver()}).on("mouseout",function(){if(!b.stickyTracking)a.onMouseOut()}).css(i).add(j)}};w=pa($);Ha.line=w;w=pa($,{type:"area"});Ha.area=w;w=pa($,{type:"spline",getPointSpline:function(a,b,c){var d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1],h,i,k,j;if(c&&c<a.length-1){a=f.plotY;k=g.plotX;var g=g.plotY,l;h=(1.5*d+f.plotX)/2.5;i=(1.5*e+a)/2.5;k=(1.5*d+k)/2.5;j=(1.5*e+g)/2.5;l=(j-i)*(k-d)/(k-h)+e-j;i+=l;j+=l;i>a&&i>e?(i=W(a,e),j=2*e-i):i<a&&i<e&&(i=Ua(a,e),j=2*e-i);j>g&&j>e?(j=W(g,e),i=2*e-j):j<g&&
185
+ j<e&&(j=Ua(g,e),i=2*e-j);b.rightContX=k;b.rightContY=j}c?(b=["C",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=[wa,d,e];return b}});Ha.spline=w;w=pa(w,{type:"areaspline"});Ha.areaspline=w;var zb=pa($,{type:"column",tooltipOutsidePlot:!0,pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color",r:"borderRadius"},init:function(){$.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&o(b.series,function(b){if(b.type===
186
+ a.type)b.isDirty=!0})},translate:function(){var a=this,b=a.chart,c=a.options,d=c.stacking,e=c.borderWidth,f=0,g=a.xAxis,h=g.reversed,i={},k,j;$.prototype.translate.apply(a);o(b.series,function(b){if(b.type===a.type&&b.visible&&a.options.group===b.options.group)b.options.stacking?(k=b.stackKey,i[k]===X&&(i[k]=f++),j=i[k]):j=f++,b.columnIndex=j});var b=a.points,g=Ba(g.translationSlope)*(g.ordinalSlope||g.closestPointRange||1),l=g*c.groupPadding,n=(g-2*l)/f,t=c.pointWidth,r=s(t)?(n-t)/2:n*c.pointPadding,
187
+ w=Yb(W(p(t,n-2*r),1+2*e)),x=r+(l+((h?f-a.columnIndex:a.columnIndex)||0)*n-g/2)*(h?-1:1),v=a.yAxis.getThreshold(c.threshold),y=p(c.minPointLength,5);o(b,function(b){var f=b.plotY,g=p(b.yBottom,v),h=b.plotX+x,i=Yb(Ua(f,g)),j=Yb(W(f,g)-i),k=a.yAxis.stacks[(b.y<0?"-":"")+a.stackKey];d&&a.visible&&k&&k[b.x]&&k[b.x].setOffset(x,w);Ba(j)<y&&y&&(j=y,i=Ba(i-v)>y?g-y:v-(f<=v?y:0));L(b,{barX:h,barY:i,barW:w,barH:j});b.shapeType="rect";f={x:h,y:i,width:w,height:j,r:c.borderRadius,strokeWidth:e};e%2&&(f.y-=1,
188
+ f.height+=1);b.shapeArgs=f;b.trackerArgs=Ba(j)<3&&K(b.shapeArgs,{height:6,y:i-3})})},getSymbol:function(){},drawGraph:function(){},drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d,e;o(a.points,function(f){var g=f.plotY;if(g!==X&&!isNaN(g)&&f.y!==null)d=f.graphic,e=f.shapeArgs,d?(Ob(d),d.animate(c.Element.prototype.crisp.apply({},[e.strokeWidth,e.x,e.y,e.width,e.height]))):f.graphic=d=c[f.shapeType](e).attr(f.pointAttr[f.selected?"select":Ka]).add(a.group).shadow(b.shadow)})},drawTracker:function(){var a=
189
+ this,b=a.chart,c=b.renderer,d,e,f=+new Date,g=a.options,h=g.cursor,i=h&&{cursor:h},k=a.drawTrackerGroup(),j;o(a.points,function(h){e=h.tracker;d=h.trackerArgs||h.shapeArgs;delete d.strokeWidth;if(h.y!==null)e?e.attr(d):h.tracker=c[h.shapeType](d).attr({isTracker:f,fill:Gc,visibility:a.visible?eb:ab}).on(Ga?"touchstart":"mouseover",function(c){j=c.relatedTarget||c.fromElement;if(b.hoverSeries!==a&&A(j,"isTracker")!==f)a.onMouseOver();h.onMouseOver()}).on("mouseout",function(b){if(!g.stickyTracking&&
190
+ (j=b.relatedTarget||b.toElement,A(j,"isTracker")!==f))a.onMouseOut()}).css(i).add(h.group||k)})},animate:function(a){var b=this,c=b.points,d=b.options;if(!a)o(c,function(a){var c=a.graphic,a=a.shapeArgs,g=b.yAxis,h=d.threshold;c&&(c.attr({height:0,y:s(h)?g.getThreshold(h):g.translate(g.getExtremes().min,0,1,0,1)}),c.animate({height:a.height,y:a.y},d.animation))}),b.animate=null},remove:function(){var a=this,b=a.chart;b.hasRendered&&o(b.series,function(b){if(b.type===a.type)b.isDirty=!0});$.prototype.remove.apply(a,
191
+ arguments)}});Ha.column=zb;w=pa(zb,{type:"bar",init:function(){this.inverted=!0;zb.prototype.init.apply(this,arguments)}});Ha.bar=w;w=pa($,{type:"scatter",sorted:!1,translate:function(){var a=this;$.prototype.translate.apply(a);o(a.points,function(b){b.shapeType="circle";b.shapeArgs={x:b.plotX,y:b.plotY,r:a.chart.options.tooltip.snap}})},drawTracker:function(){for(var a=this,b=a.options.cursor,b=b&&{cursor:b},c=a.points,d=c.length,e;d--;)if(e=c[d].graphic)e.element._i=d;a._hasTracking?a._hasTracking=
192
+ !0:a.group.attr({isTracker:!0}).on(Ga?"touchstart":"mouseover",function(b){a.onMouseOver();if(b.target._i!==X)c[b.target._i].onMouseOver()}).on("mouseout",function(){if(!a.options.stickyTracking)a.onMouseOut()}).css(b)}});Ha.scatter=w;w=pa(lb,{init:function(){lb.prototype.init.apply(this,arguments);var a=this,b;L(a,{visible:a.visible!==!1,name:p(a.name,"Slice")});b=function(){a.slice()};ha(a,"select",b);ha(a,"unselect",b);return a},setVisible:function(a){var b=this.series.chart,c=this.tracker,d=this.dataLabel,
193
+ e=this.connector,f=this.shadowGroup,g;g=(this.visible=a=a===X?!this.visible:a)?"show":"hide";this.group[g]();if(c)c[g]();if(d)d[g]();if(e)e[g]();if(f)f[g]();this.legendItem&&b.legend.colorizeItem(this,a)},slice:function(a,b,c){var d=this.series.chart,e=this.slicedTranslation;Kb(c,d);p(b,!0);a=this.sliced=s(a)?a:!this.sliced;a={translateX:a?e[0]:d.plotLeft,translateY:a?e[1]:d.plotTop};this.group.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}});w=pa($,{type:"pie",isCartesian:!1,pointClass:w,
194
+ pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color"},getColor:function(){this.initialColor=this.chart.counters.color},animate:function(){var a=this;o(a.points,function(b){var c=b.graphic,b=b.shapeArgs,d=-da/2;c&&(c.attr({r:0,start:d,end:d}),c.animate({r:b.r,start:b.start,end:b.end},a.options.animation))});a.animate=null},setData:function(){$.prototype.setData.apply(this,arguments);this.processData();this.generatePoints()},translate:function(){this.generatePoints();var a=
195
+ 0,b=-0.25,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f=c.center.concat([c.size,c.innerSize||0]),g=this.chart,h=g.plotWidth,i=g.plotHeight,k,j,l,n=this.points,p=2*da,r,s=Ua(h,i),w,v,y,q=c.dataLabels.distance,f=Vb(f,function(a,b){return(w=/%$/.test(a))?[h,i,s,s][b]*S(a)/100:a});this.getX=function(a,b){l=oa.asin((a-f[1])/(f[2]/2+q));return f[0]+(b?-1:1)*ja(l)*(f[2]/2+q)};this.center=f;o(n,function(b){a+=b.y});o(n,function(c){r=a?c.y/a:0;k=z(b*p*1E3)/1E3;b+=r;j=z(b*p*1E3)/1E3;c.shapeType="arc";
196
+ c.shapeArgs={x:f[0],y:f[1],r:f[2]/2,innerR:f[3]/2,start:k,end:j};l=(j+k)/2;c.slicedTranslation=Vb([ja(l)*d+g.plotLeft,C(l)*d+g.plotTop],z);v=ja(l)*f[2]/2;y=C(l)*f[2]/2;c.tooltipPos=[f[0]+v*0.7,f[1]+y*0.7];c.labelPos=[f[0]+v+ja(l)*q,f[1]+y+C(l)*q,f[0]+v+ja(l)*e,f[1]+y+C(l)*e,f[0]+v,f[1]+y,q<0?"center":l<p/4?"left":"right",l];c.percentage=r*100;c.total=a});this.setTooltipPoints()},render:function(){this.getAttribs();this.drawPoints();this.options.enableMouseTracking!==!1&&this.drawTracker();this.drawDataLabels();
197
+ this.options.animation&&this.animate&&this.animate();this.isDirty=!1},drawPoints:function(){var a=this.chart,b=a.renderer,c,d,e,f=this.options.shadow,g,h;o(this.points,function(i){d=i.graphic;h=i.shapeArgs;e=i.group;g=i.shadowGroup;if(f&&!g)g=i.shadowGroup=b.g("shadow").attr({zIndex:4}).add();if(!e)e=i.group=b.g("point").attr({zIndex:5}).add();c=i.sliced?i.slicedTranslation:[a.plotLeft,a.plotTop];e.translate(c[0],c[1]);g&&g.translate(c[0],c[1]);d?d.animate(h):i.graphic=b.arc(h).attr(L(i.pointAttr[Ka],
198
+ {"stroke-linejoin":"round"})).add(i.group).shadow(f,g);i.visible===!1&&i.setVisible(!1)})},drawDataLabels:function(){var a=this.data,b,c=this.chart,d=this.options.dataLabels,e=p(d.connectorPadding,10),f=p(d.connectorWidth,1),g,h,i=p(d.softConnector,!0),k=d.distance,j=this.center,l=j[2]/2,j=j[1],n=k>0,t=[[],[]],r,s,w,v,y=2,q;if(d.enabled){$.prototype.drawDataLabels.apply(this);o(a,function(a){a.dataLabel&&t[a.labelPos[7]<da/2?0:1].push(a)});t[1].reverse();v=function(a,b){return b.y-a.y};for(a=t[0][0]&&
199
+ t[0][0].dataLabel&&t[0][0].dataLabel.getBBox().height;y--;){var x=[],A=[],z=t[y],E=z.length,C;for(q=j-l-k;q<=j+l+k;q+=a)x.push(q);w=x.length;if(E>w){h=[].concat(z);h.sort(v);for(q=E;q--;)h[q].rank=q;for(q=E;q--;)z[q].rank>=w&&z.splice(q,1);E=z.length}for(q=0;q<E;q++){b=z[q];h=b.labelPos;b=9999;for(s=0;s<w;s++)g=Ba(x[s]-h[1]),g<b&&(b=g,C=s);if(C<q&&x[q]!==null)C=q;else for(w<E-q+C&&x[q]!==null&&(C=w-E+q);x[C]===null;)C++;A.push({i:C,y:x[C]});x[C]=null}A.sort(v);for(q=0;q<E;q++){b=z[q];h=b.labelPos;
200
+ g=b.dataLabel;s=A.pop();r=h[1];w=b.visible===!1?ab:eb;C=s.i;s=s.y;if(r>s&&x[C+1]!==null||r<s&&x[C-1]!==null)s=r;r=this.getX(C===0||C===x.length-1?r:s,y);g.attr({visibility:w,align:h[6]})[g.moved?"animate":"attr"]({x:r+d.x+({left:e,right:-e}[h[6]]||0),y:s+d.y});g.moved=!0;if(n&&f)g=b.connector,h=i?[wa,r+(h[6]==="left"?5:-5),s,"C",r,s,2*h[2]-h[4],2*h[3]-h[5],h[2],h[3],fa,h[4],h[5]]:[wa,r+(h[6]==="left"?5:-5),s,fa,h[2],h[3],fa,h[4],h[5]],g?(g.animate({d:h}),g.attr("visibility",w)):b.connector=g=this.chart.renderer.path(h).attr({"stroke-width":f,
201
+ stroke:d.connectorColor||b.color||"#606060",visibility:w,zIndex:3}).translate(c.plotLeft,c.plotTop).add()}}}},drawTracker:zb.prototype.drawTracker,getSymbol:function(){}});Ha.pie=w;L(Highcharts,{Chart:wc,dateFormat:ac,pathAnim:La,getOptions:function(){return Ea},hasBidiBug:Qc,numberFormat:dc,Point:lb,Color:ma,Renderer:Xb,SVGRenderer:Eb,VMLRenderer:$a,CanVGRenderer:oc,seriesTypes:Ha,setOptions:function(a){$b=K($b,a.xAxis);kc=K(kc,a.yAxis);a.xAxis=a.yAxis=X;Ea=K(Ea,a);vc();return Ea},Series:$,addEvent:ha,
202
+ removeEvent:Qa,createElement:Aa,discardElement:Tb,css:P,each:o,extend:L,map:Vb,merge:K,pick:p,splat:Hb,extendClass:pa,placeBox:uc,product:"Highcharts",version:"2.2.1"})})();
trunk/js/mandrill.js ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ JSON.stringify = JSON.stringify || function (obj) {
2
+ var t = typeof (obj);
3
+ if (t != "object" || obj === null) {
4
+ // simple data type
5
+ if (t == "string") obj = '"'+obj+'"';
6
+ return String(obj);
7
+ }
8
+ else {
9
+ // recurse array or object
10
+ var n, v, json = [], arr = (obj && obj.constructor == Array);
11
+ for (n in obj) {
12
+ v = obj[n]; t = typeof(v);
13
+ if (t == "string") v = '"'+v+'"';
14
+ else if (t == "object" && v !== null) v = JSON.stringify(v);
15
+ json.push((arr ? "" : '"' + n + '":') + String(v));
16
+ }
17
+ return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
18
+ }
19
+ };
20
+
21
+ jQuery(document).bind( 'ready', function() {
22
+ jQuery('#filter,#display').bind('change keyup', function() {
23
+
24
+ if ( jQuery("#filter option:selected").val() == 'none' ) {
25
+ var display = 'block';
26
+ } else {
27
+ var display = 'none';
28
+ }
29
+
30
+ jQuery('#all_time').css('display',display);
31
+ showStats();
32
+ });
33
+ jQuery('.columns-prefs, #collapse-button').bind('click', function () {
34
+ redrawDashboardWidget();
35
+ });
36
+
37
+ if ( pagenow == 'dashboard_page_wpmandrill-reports' ) {
38
+ showStats();
39
+ }
40
+ });
41
+
42
+ function showStats() {
43
+ var filter = jQuery("#filter option:selected").val();
44
+ var display = jQuery("#display option:selected").val();
45
+ jQuery('#loading_data').css('display','block');
46
+
47
+ jQuery.ajax({
48
+ type: 'POST',
49
+ url: ajaxurl,
50
+ data: {
51
+ action: 'get_mandrill_stats',
52
+ filter: filter,
53
+ display: display,
54
+ },
55
+ success: function(data, textStatus, XMLHttpRequest){
56
+ jQuery('#loading_data').css('display','none');
57
+ eval(data);
58
+ },
59
+ error: function(MLHttpRequest, textStatus, errorThrown){
60
+ jQuery('#loading_data').css('display','none');
61
+ alert(errorThrown);
62
+ }
63
+ });
64
+
65
+ return false;
66
+ }
67
+
68
+ function redrawDashboardWidget() {
69
+ jQuery('#mandrill_widget div#filtered_recent').html('<div id="ajax-icon-container"><span id="loading_data"></span></div>');
70
+ jQuery.ajax({
71
+ type: 'POST',
72
+ url: ajaxurl,
73
+ data: {
74
+ action: 'get_dashboard_widget_stats',
75
+ ajax: true,
76
+ },
77
+ success: function(data, textStatus, XMLHttpRequest){
78
+ eval(data);
79
+ },
80
+ error: function(MLHttpRequest, textStatus, errorThrown){
81
+ alert(errorThrown);
82
+ jQuery('#mandrill_widget div#filtered_recent').html('');
83
+ }
84
+ });
85
+
86
+ return false;
87
+ }
trunk/js/modules/canvas-tools.js ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ A class to parse color values
3
+ @author Stoyan Stefanov <sstoo@gmail.com>
4
+ @link http://www.phpied.com/rgb-color-parser-in-javascript/
5
+ Use it if you like it
6
+
7
+ canvg.js - Javascript SVG parser and renderer on Canvas
8
+ MIT Licensed
9
+ Gabe Lerner (gabelerner@gmail.com)
10
+ http://code.google.com/p/canvg/
11
+
12
+ Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/
13
+
14
+ Highcharts JS v2.2.1 (2012-03-15)
15
+ CanVGRenderer Extension module
16
+
17
+ (c) 2011-2012 Torstein H?nsi, Erik Olsson
18
+
19
+ License: www.highcharts.com/license
20
+ */
21
+ function RGBColor(m){this.ok=!1;m.charAt(0)=="#"&&(m=m.substr(1,6));var m=m.replace(/ /g,""),m=m.toLowerCase(),a={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",
22
+ darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dodgerblue:"1e90ff",feldspar:"d19275",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",
23
+ gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgrey:"d3d3d3",lightgreen:"90ee90",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",
24
+ lightslateblue:"8470ff",lightslategray:"778899",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"00ff00",limegreen:"32cd32",linen:"faf0e6",magenta:"ff00ff",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370d8",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",
25
+ oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"d87093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",red:"ff0000",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",
26
+ slategray:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",violetred:"d02090",wheat:"f5deb3",white:"ffffff",whitesmoke:"f5f5f5",yellow:"ffff00",yellowgreen:"9acd32"},c;for(c in a)m==c&&(m=a[c]);var d=[{re:/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,example:["rgb(123, 234, 45)","rgb(255,234,245)"],process:function(b){return[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]}},{re:/^(\w{2})(\w{2})(\w{2})$/,
27
+ example:["#00ff00","336699"],process:function(b){return[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]}},{re:/^(\w{1})(\w{1})(\w{1})$/,example:["#fb0","f0f"],process:function(b){return[parseInt(b[1]+b[1],16),parseInt(b[2]+b[2],16),parseInt(b[3]+b[3],16)]}}];for(c=0;c<d.length;c++){var b=d[c].process,k=d[c].re.exec(m);if(k)channels=b(k),this.r=channels[0],this.g=channels[1],this.b=channels[2],this.ok=!0}this.r=this.r<0||isNaN(this.r)?0:this.r>255?255:this.r;this.g=this.g<0||isNaN(this.g)?0:
28
+ this.g>255?255:this.g;this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b;this.toRGB=function(){return"rgb("+this.r+", "+this.g+", "+this.b+")"};this.toHex=function(){var b=this.r.toString(16),a=this.g.toString(16),d=this.b.toString(16);b.length==1&&(b="0"+b);a.length==1&&(a="0"+a);d.length==1&&(d="0"+d);return"#"+b+a+d};this.getHelpXML=function(){for(var b=[],k=0;k<d.length;k++)for(var c=d[k].example,h=0;h<c.length;h++)b[b.length]=c[h];for(var j in a)b[b.length]=j;c=document.createElement("ul");
29
+ c.setAttribute("id","rgbcolor-examples");for(k=0;k<b.length;k++)try{var l=document.createElement("li"),o=new RGBColor(b[k]),n=document.createElement("div");n.style.cssText="margin: 3px; border: 1px solid black; background:"+o.toHex()+"; color:"+o.toHex();n.appendChild(document.createTextNode("test"));var q=document.createTextNode(" "+b[k]+" -> "+o.toRGB()+" -> "+o.toHex());l.appendChild(n);l.appendChild(q);c.appendChild(l)}catch(p){}return c}}
30
+ if(!window.console)window.console={},window.console.log=function(){},window.console.dir=function(){};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(m){for(var a=0;a<this.length;a++)if(this[a]==m)return a;return-1};
31
+ (function(){function m(){var a={FRAMERATE:30,MAX_VIRTUAL_PIXELS:3E4};a.init=function(c){a.Definitions={};a.Styles={};a.Animations=[];a.Images=[];a.ctx=c;a.ViewPort=new function(){this.viewPorts=[];this.Clear=function(){this.viewPorts=[]};this.SetCurrent=function(a,b){this.viewPorts.push({width:a,height:b})};this.RemoveCurrent=function(){this.viewPorts.pop()};this.Current=function(){return this.viewPorts[this.viewPorts.length-1]};this.width=function(){return this.Current().width};this.height=function(){return this.Current().height};
32
+ this.ComputeSize=function(a){return a!=null&&typeof a=="number"?a:a=="x"?this.width():a=="y"?this.height():Math.sqrt(Math.pow(this.width(),2)+Math.pow(this.height(),2))/Math.sqrt(2)}}};a.init();a.ImagesLoaded=function(){for(var c=0;c<a.Images.length;c++)if(!a.Images[c].loaded)return!1;return!0};a.trim=function(a){return a.replace(/^\s+|\s+$/g,"")};a.compressSpaces=function(a){return a.replace(/[\s\r\t\n]+/gm," ")};a.ajax=function(a){var d;return(d=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject("Microsoft.XMLHTTP"))?
33
+ (d.open("GET",a,!1),d.send(null),d.responseText):null};a.parseXml=function(a){if(window.DOMParser)return(new DOMParser).parseFromString(a,"text/xml");else{var a=a.replace(/<!DOCTYPE svg[^>]*>/,""),d=new ActiveXObject("Microsoft.XMLDOM");d.async="false";d.loadXML(a);return d}};a.Property=function(c,d){this.name=c;this.value=d;this.hasValue=function(){return this.value!=null&&this.value!==""};this.numValue=function(){if(!this.hasValue())return 0;var b=parseFloat(this.value);(this.value+"").match(/%$/)&&
34
+ (b/=100);return b};this.valueOrDefault=function(b){return this.hasValue()?this.value:b};this.numValueOrDefault=function(b){return this.hasValue()?this.numValue():b};var b=this;this.Color={addOpacity:function(d){var c=b.value;if(d!=null&&d!=""){var f=new RGBColor(b.value);f.ok&&(c="rgba("+f.r+", "+f.g+", "+f.b+", "+d+")")}return new a.Property(b.name,c)}};this.Definition={getDefinition:function(){var d=b.value.replace(/^(url\()?#([^\)]+)\)?$/,"$2");return a.Definitions[d]},isUrl:function(){return b.value.indexOf("url(")==
35
+ 0},getFillStyle:function(b){var d=this.getDefinition();return d!=null&&d.createGradient?d.createGradient(a.ctx,b):d!=null&&d.createPattern?d.createPattern(a.ctx,b):null}};this.Length={DPI:function(){return 96},EM:function(b){var d=12,c=new a.Property("fontSize",a.Font.Parse(a.ctx.font).fontSize);c.hasValue()&&(d=c.Length.toPixels(b));return d},toPixels:function(d){if(!b.hasValue())return 0;var c=b.value+"";return c.match(/em$/)?b.numValue()*this.EM(d):c.match(/ex$/)?b.numValue()*this.EM(d)/2:c.match(/px$/)?
36
+ b.numValue():c.match(/pt$/)?b.numValue()*1.25:c.match(/pc$/)?b.numValue()*15:c.match(/cm$/)?b.numValue()*this.DPI(d)/2.54:c.match(/mm$/)?b.numValue()*this.DPI(d)/25.4:c.match(/in$/)?b.numValue()*this.DPI(d):c.match(/%$/)?b.numValue()*a.ViewPort.ComputeSize(d):b.numValue()}};this.Time={toMilliseconds:function(){if(!b.hasValue())return 0;var a=b.value+"";if(a.match(/s$/))return b.numValue()*1E3;a.match(/ms$/);return b.numValue()}};this.Angle={toRadians:function(){if(!b.hasValue())return 0;var a=b.value+
37
+ "";return a.match(/deg$/)?b.numValue()*(Math.PI/180):a.match(/grad$/)?b.numValue()*(Math.PI/200):a.match(/rad$/)?b.numValue():b.numValue()*(Math.PI/180)}}};a.Font=new function(){this.Styles=["normal","italic","oblique","inherit"];this.Variants=["normal","small-caps","inherit"];this.Weights="normal,bold,bolder,lighter,100,200,300,400,500,600,700,800,900,inherit".split(",");this.CreateFont=function(d,b,c,e,f,g){g=g!=null?this.Parse(g):this.CreateFont("","","","","",a.ctx.font);return{fontFamily:f||
38
+ g.fontFamily,fontSize:e||g.fontSize,fontStyle:d||g.fontStyle,fontWeight:c||g.fontWeight,fontVariant:b||g.fontVariant,toString:function(){return[this.fontStyle,this.fontVariant,this.fontWeight,this.fontSize,this.fontFamily].join(" ")}}};var c=this;this.Parse=function(d){for(var b={},d=a.trim(a.compressSpaces(d||"")).split(" "),k=!1,e=!1,f=!1,g=!1,h="",j=0;j<d.length;j++)if(!e&&c.Styles.indexOf(d[j])!=-1){if(d[j]!="inherit")b.fontStyle=d[j];e=!0}else if(!g&&c.Variants.indexOf(d[j])!=-1){if(d[j]!="inherit")b.fontVariant=
39
+ d[j];e=g=!0}else if(!f&&c.Weights.indexOf(d[j])!=-1){if(d[j]!="inherit")b.fontWeight=d[j];e=g=f=!0}else if(k)d[j]!="inherit"&&(h+=d[j]);else{if(d[j]!="inherit")b.fontSize=d[j].split("/")[0];e=g=f=k=!0}if(h!="")b.fontFamily=h;return b}};a.ToNumberArray=function(c){for(var c=a.trim(a.compressSpaces((c||"").replace(/,/g," "))).split(" "),d=0;d<c.length;d++)c[d]=parseFloat(c[d]);return c};a.Point=function(a,d){this.x=a;this.y=d;this.angleTo=function(b){return Math.atan2(b.y-this.y,b.x-this.x)};this.applyTransform=
40
+ function(b){var a=this.x*b[1]+this.y*b[3]+b[5];this.x=this.x*b[0]+this.y*b[2]+b[4];this.y=a}};a.CreatePoint=function(c){c=a.ToNumberArray(c);return new a.Point(c[0],c[1])};a.CreatePath=function(c){for(var c=a.ToNumberArray(c),d=[],b=0;b<c.length;b+=2)d.push(new a.Point(c[b],c[b+1]));return d};a.BoundingBox=function(a,d,b,k){this.y2=this.x2=this.y1=this.x1=Number.NaN;this.x=function(){return this.x1};this.y=function(){return this.y1};this.width=function(){return this.x2-this.x1};this.height=function(){return this.y2-
41
+ this.y1};this.addPoint=function(b,a){if(b!=null){if(isNaN(this.x1)||isNaN(this.x2))this.x2=this.x1=b;if(b<this.x1)this.x1=b;if(b>this.x2)this.x2=b}if(a!=null){if(isNaN(this.y1)||isNaN(this.y2))this.y2=this.y1=a;if(a<this.y1)this.y1=a;if(a>this.y2)this.y2=a}};this.addX=function(b){this.addPoint(b,null)};this.addY=function(b){this.addPoint(null,b)};this.addBoundingBox=function(b){this.addPoint(b.x1,b.y1);this.addPoint(b.x2,b.y2)};this.addQuadraticCurve=function(b,a,d,c,k,l){d=b+2/3*(d-b);c=a+2/3*(c-
42
+ a);this.addBezierCurve(b,a,d,d+1/3*(k-b),c,c+1/3*(l-a),k,l)};this.addBezierCurve=function(b,a,d,c,k,l,o,n){var q=[b,a],p=[d,c],s=[k,l],m=[o,n];this.addPoint(q[0],q[1]);this.addPoint(m[0],m[1]);for(i=0;i<=1;i++)b=function(b){return Math.pow(1-b,3)*q[i]+3*Math.pow(1-b,2)*b*p[i]+3*(1-b)*Math.pow(b,2)*s[i]+Math.pow(b,3)*m[i]},a=6*q[i]-12*p[i]+6*s[i],d=-3*q[i]+9*p[i]-9*s[i]+3*m[i],c=3*p[i]-3*q[i],d==0?a!=0&&(a=-c/a,0<a&&a<1&&(i==0&&this.addX(b(a)),i==1&&this.addY(b(a)))):(c=Math.pow(a,2)-4*c*d,c<0||(k=
43
+ (-a+Math.sqrt(c))/(2*d),0<k&&k<1&&(i==0&&this.addX(b(k)),i==1&&this.addY(b(k))),a=(-a-Math.sqrt(c))/(2*d),0<a&&a<1&&(i==0&&this.addX(b(a)),i==1&&this.addY(b(a)))))};this.isPointInBox=function(b,a){return this.x1<=b&&b<=this.x2&&this.y1<=a&&a<=this.y2};this.addPoint(a,d);this.addPoint(b,k)};a.Transform=function(c){var d=this;this.Type={};this.Type.translate=function(b){this.p=a.CreatePoint(b);this.apply=function(b){b.translate(this.p.x||0,this.p.y||0)};this.applyToPoint=function(b){b.applyTransform([1,
44
+ 0,0,1,this.p.x||0,this.p.y||0])}};this.Type.rotate=function(b){b=a.ToNumberArray(b);this.angle=new a.Property("angle",b[0]);this.cx=b[1]||0;this.cy=b[2]||0;this.apply=function(b){b.translate(this.cx,this.cy);b.rotate(this.angle.Angle.toRadians());b.translate(-this.cx,-this.cy)};this.applyToPoint=function(b){var a=this.angle.Angle.toRadians();b.applyTransform([1,0,0,1,this.p.x||0,this.p.y||0]);b.applyTransform([Math.cos(a),Math.sin(a),-Math.sin(a),Math.cos(a),0,0]);b.applyTransform([1,0,0,1,-this.p.x||
45
+ 0,-this.p.y||0])}};this.Type.scale=function(b){this.p=a.CreatePoint(b);this.apply=function(b){b.scale(this.p.x||1,this.p.y||this.p.x||1)};this.applyToPoint=function(b){b.applyTransform([this.p.x||0,0,0,this.p.y||0,0,0])}};this.Type.matrix=function(b){this.m=a.ToNumberArray(b);this.apply=function(b){b.transform(this.m[0],this.m[1],this.m[2],this.m[3],this.m[4],this.m[5])};this.applyToPoint=function(b){b.applyTransform(this.m)}};this.Type.SkewBase=function(b){this.base=d.Type.matrix;this.base(b);this.angle=
46
+ new a.Property("angle",b)};this.Type.SkewBase.prototype=new this.Type.matrix;this.Type.skewX=function(b){this.base=d.Type.SkewBase;this.base(b);this.m=[1,0,Math.tan(this.angle.Angle.toRadians()),1,0,0]};this.Type.skewX.prototype=new this.Type.SkewBase;this.Type.skewY=function(b){this.base=d.Type.SkewBase;this.base(b);this.m=[1,Math.tan(this.angle.Angle.toRadians()),0,1,0,0]};this.Type.skewY.prototype=new this.Type.SkewBase;this.transforms=[];this.apply=function(b){for(var a=0;a<this.transforms.length;a++)this.transforms[a].apply(b)};
47
+ this.applyToPoint=function(b){for(var a=0;a<this.transforms.length;a++)this.transforms[a].applyToPoint(b)};for(var c=a.trim(a.compressSpaces(c)).split(/\s(?=[a-z])/),b=0;b<c.length;b++){var k=c[b].split("(")[0],e=c[b].split("(")[1].replace(")","");this.transforms.push(new this.Type[k](e))}};a.AspectRatio=function(c,d,b,k,e,f,g,h,j,l){var d=a.compressSpaces(d),d=d.replace(/^defer\s/,""),o=d.split(" ")[0]||"xMidYMid",d=d.split(" ")[1]||"meet",n=b/k,q=e/f,p=Math.min(n,q),m=Math.max(n,q);d=="meet"&&(k*=
48
+ p,f*=p);d=="slice"&&(k*=m,f*=m);j=new a.Property("refX",j);l=new a.Property("refY",l);j.hasValue()&&l.hasValue()?c.translate(-p*j.Length.toPixels("x"),-p*l.Length.toPixels("y")):(o.match(/^xMid/)&&(d=="meet"&&p==q||d=="slice"&&m==q)&&c.translate(b/2-k/2,0),o.match(/YMid$/)&&(d=="meet"&&p==n||d=="slice"&&m==n)&&c.translate(0,e/2-f/2),o.match(/^xMax/)&&(d=="meet"&&p==q||d=="slice"&&m==q)&&c.translate(b-k,0),o.match(/YMax$/)&&(d=="meet"&&p==n||d=="slice"&&m==n)&&c.translate(0,e-f));o=="none"?c.scale(n,
49
+ q):d=="meet"?c.scale(p,p):d=="slice"&&c.scale(m,m);c.translate(g==null?0:-g,h==null?0:-h)};a.Element={};a.Element.ElementBase=function(c){this.attributes={};this.styles={};this.children=[];this.attribute=function(b,d){var c=this.attributes[b];if(c!=null)return c;c=new a.Property(b,"");d==!0&&(this.attributes[b]=c);return c};this.style=function(b,d){var c=this.styles[b];if(c!=null)return c;c=this.attribute(b);if(c!=null&&c.hasValue())return c;c=this.parent;if(c!=null&&(c=c.style(b),c!=null&&c.hasValue()))return c;
50
+ c=new a.Property(b,"");d==!0&&(this.styles[b]=c);return c};this.render=function(b){if(this.style("display").value!="none"&&this.attribute("visibility").value!="hidden"){b.save();this.setContext(b);if(this.attribute("mask").hasValue()){var a=this.attribute("mask").Definition.getDefinition();a!=null&&a.apply(b,this)}else this.style("filter").hasValue()?(a=this.style("filter").Definition.getDefinition(),a!=null&&a.apply(b,this)):this.renderChildren(b);this.clearContext(b);b.restore()}};this.setContext=
51
+ function(){};this.clearContext=function(){};this.renderChildren=function(b){for(var a=0;a<this.children.length;a++)this.children[a].render(b)};this.addChild=function(b,d){var c=b;d&&(c=a.CreateElement(b));c.parent=this;this.children.push(c)};if(c!=null&&c.nodeType==1){for(var d=0;d<c.childNodes.length;d++){var b=c.childNodes[d];b.nodeType==1&&this.addChild(b,!0)}for(d=0;d<c.attributes.length;d++)b=c.attributes[d],this.attributes[b.nodeName]=new a.Property(b.nodeName,b.nodeValue);b=a.Styles[c.nodeName];
52
+ if(b!=null)for(var k in b)this.styles[k]=b[k];if(this.attribute("class").hasValue())for(var d=a.compressSpaces(this.attribute("class").value).split(" "),e=0;e<d.length;e++){b=a.Styles["."+d[e]];if(b!=null)for(k in b)this.styles[k]=b[k];b=a.Styles[c.nodeName+"."+d[e]];if(b!=null)for(k in b)this.styles[k]=b[k]}if(this.attribute("style").hasValue()){b=this.attribute("style").value.split(";");for(d=0;d<b.length;d++)a.trim(b[d])!=""&&(c=b[d].split(":"),k=a.trim(c[0]),c=a.trim(c[1]),this.styles[k]=new a.Property(k,
53
+ c))}this.attribute("id").hasValue()&&a.Definitions[this.attribute("id").value]==null&&(a.Definitions[this.attribute("id").value]=this)}};a.Element.RenderedElementBase=function(c){this.base=a.Element.ElementBase;this.base(c);this.setContext=function(d){if(this.style("fill").Definition.isUrl()){var b=this.style("fill").Definition.getFillStyle(this);if(b!=null)d.fillStyle=b}else if(this.style("fill").hasValue())b=this.style("fill"),this.style("fill-opacity").hasValue()&&(b=b.Color.addOpacity(this.style("fill-opacity").value)),
54
+ d.fillStyle=b.value=="none"?"rgba(0,0,0,0)":b.value;if(this.style("stroke").Definition.isUrl()){if(b=this.style("stroke").Definition.getFillStyle(this),b!=null)d.strokeStyle=b}else if(this.style("stroke").hasValue())b=this.style("stroke"),this.style("stroke-opacity").hasValue()&&(b=b.Color.addOpacity(this.style("stroke-opacity").value)),d.strokeStyle=b.value=="none"?"rgba(0,0,0,0)":b.value;if(this.style("stroke-width").hasValue())d.lineWidth=this.style("stroke-width").Length.toPixels();if(this.style("stroke-linecap").hasValue())d.lineCap=
55
+ this.style("stroke-linecap").value;if(this.style("stroke-linejoin").hasValue())d.lineJoin=this.style("stroke-linejoin").value;if(this.style("stroke-miterlimit").hasValue())d.miterLimit=this.style("stroke-miterlimit").value;if(typeof d.font!="undefined")d.font=a.Font.CreateFont(this.style("font-style").value,this.style("font-variant").value,this.style("font-weight").value,this.style("font-size").hasValue()?this.style("font-size").Length.toPixels()+"px":"",this.style("font-family").value).toString();
56
+ this.attribute("transform").hasValue()&&(new a.Transform(this.attribute("transform").value)).apply(d);this.attribute("clip-path").hasValue()&&(b=this.attribute("clip-path").Definition.getDefinition(),b!=null&&b.apply(d));if(this.style("opacity").hasValue())d.globalAlpha=this.style("opacity").numValue()}};a.Element.RenderedElementBase.prototype=new a.Element.ElementBase;a.Element.PathElementBase=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.path=function(d){d!=null&&d.beginPath();
57
+ return new a.BoundingBox};this.renderChildren=function(d){this.path(d);a.Mouse.checkPath(this,d);d.fillStyle!=""&&d.fill();d.strokeStyle!=""&&d.stroke();var b=this.getMarkers();if(b!=null){if(this.style("marker-start").Definition.isUrl()){var c=this.style("marker-start").Definition.getDefinition();c.render(d,b[0][0],b[0][1])}if(this.style("marker-mid").Definition.isUrl())for(var c=this.style("marker-mid").Definition.getDefinition(),e=1;e<b.length-1;e++)c.render(d,b[e][0],b[e][1]);this.style("marker-end").Definition.isUrl()&&
58
+ (c=this.style("marker-end").Definition.getDefinition(),c.render(d,b[b.length-1][0],b[b.length-1][1]))}};this.getBoundingBox=function(){return this.path()};this.getMarkers=function(){return null}};a.Element.PathElementBase.prototype=new a.Element.RenderedElementBase;a.Element.svg=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseClearContext=this.clearContext;this.clearContext=function(d){this.baseClearContext(d);a.ViewPort.RemoveCurrent()};this.baseSetContext=this.setContext;
59
+ this.setContext=function(d){d.strokeStyle="rgba(0,0,0,0)";d.lineCap="butt";d.lineJoin="miter";d.miterLimit=4;this.baseSetContext(d);this.attribute("x").hasValue()&&this.attribute("y").hasValue()&&d.translate(this.attribute("x").Length.toPixels("x"),this.attribute("y").Length.toPixels("y"));var b=a.ViewPort.width(),c=a.ViewPort.height();if(typeof this.root=="undefined"&&this.attribute("width").hasValue()&&this.attribute("height").hasValue()){var b=this.attribute("width").Length.toPixels("x"),c=this.attribute("height").Length.toPixels("y"),
60
+ e=0,f=0;this.attribute("refX").hasValue()&&this.attribute("refY").hasValue()&&(e=-this.attribute("refX").Length.toPixels("x"),f=-this.attribute("refY").Length.toPixels("y"));d.beginPath();d.moveTo(e,f);d.lineTo(b,f);d.lineTo(b,c);d.lineTo(e,c);d.closePath();d.clip()}a.ViewPort.SetCurrent(b,c);if(this.attribute("viewBox").hasValue()){var e=a.ToNumberArray(this.attribute("viewBox").value),f=e[0],g=e[1],b=e[2],c=e[3];a.AspectRatio(d,this.attribute("preserveAspectRatio").value,a.ViewPort.width(),b,a.ViewPort.height(),
61
+ c,f,g,this.attribute("refX").value,this.attribute("refY").value);a.ViewPort.RemoveCurrent();a.ViewPort.SetCurrent(e[2],e[3])}}};a.Element.svg.prototype=new a.Element.RenderedElementBase;a.Element.rect=function(c){this.base=a.Element.PathElementBase;this.base(c);this.path=function(d){var b=this.attribute("x").Length.toPixels("x"),c=this.attribute("y").Length.toPixels("y"),e=this.attribute("width").Length.toPixels("x"),f=this.attribute("height").Length.toPixels("y"),g=this.attribute("rx").Length.toPixels("x"),
62
+ h=this.attribute("ry").Length.toPixels("y");this.attribute("rx").hasValue()&&!this.attribute("ry").hasValue()&&(h=g);this.attribute("ry").hasValue()&&!this.attribute("rx").hasValue()&&(g=h);d!=null&&(d.beginPath(),d.moveTo(b+g,c),d.lineTo(b+e-g,c),d.quadraticCurveTo(b+e,c,b+e,c+h),d.lineTo(b+e,c+f-h),d.quadraticCurveTo(b+e,c+f,b+e-g,c+f),d.lineTo(b+g,c+f),d.quadraticCurveTo(b,c+f,b,c+f-h),d.lineTo(b,c+h),d.quadraticCurveTo(b,c,b+g,c),d.closePath());return new a.BoundingBox(b,c,b+e,c+f)}};a.Element.rect.prototype=
63
+ new a.Element.PathElementBase;a.Element.circle=function(c){this.base=a.Element.PathElementBase;this.base(c);this.path=function(d){var b=this.attribute("cx").Length.toPixels("x"),c=this.attribute("cy").Length.toPixels("y"),e=this.attribute("r").Length.toPixels();d!=null&&(d.beginPath(),d.arc(b,c,e,0,Math.PI*2,!0),d.closePath());return new a.BoundingBox(b-e,c-e,b+e,c+e)}};a.Element.circle.prototype=new a.Element.PathElementBase;a.Element.ellipse=function(c){this.base=a.Element.PathElementBase;this.base(c);
64
+ this.path=function(d){var b=4*((Math.sqrt(2)-1)/3),c=this.attribute("rx").Length.toPixels("x"),e=this.attribute("ry").Length.toPixels("y"),f=this.attribute("cx").Length.toPixels("x"),g=this.attribute("cy").Length.toPixels("y");d!=null&&(d.beginPath(),d.moveTo(f,g-e),d.bezierCurveTo(f+b*c,g-e,f+c,g-b*e,f+c,g),d.bezierCurveTo(f+c,g+b*e,f+b*c,g+e,f,g+e),d.bezierCurveTo(f-b*c,g+e,f-c,g+b*e,f-c,g),d.bezierCurveTo(f-c,g-b*e,f-b*c,g-e,f,g-e),d.closePath());return new a.BoundingBox(f-c,g-e,f+c,g+e)}};a.Element.ellipse.prototype=
65
+ new a.Element.PathElementBase;a.Element.line=function(c){this.base=a.Element.PathElementBase;this.base(c);this.getPoints=function(){return[new a.Point(this.attribute("x1").Length.toPixels("x"),this.attribute("y1").Length.toPixels("y")),new a.Point(this.attribute("x2").Length.toPixels("x"),this.attribute("y2").Length.toPixels("y"))]};this.path=function(d){var b=this.getPoints();d!=null&&(d.beginPath(),d.moveTo(b[0].x,b[0].y),d.lineTo(b[1].x,b[1].y));return new a.BoundingBox(b[0].x,b[0].y,b[1].x,b[1].y)};
66
+ this.getMarkers=function(){var a=this.getPoints(),b=a[0].angleTo(a[1]);return[[a[0],b],[a[1],b]]}};a.Element.line.prototype=new a.Element.PathElementBase;a.Element.polyline=function(c){this.base=a.Element.PathElementBase;this.base(c);this.points=a.CreatePath(this.attribute("points").value);this.path=function(d){var b=new a.BoundingBox(this.points[0].x,this.points[0].y);d!=null&&(d.beginPath(),d.moveTo(this.points[0].x,this.points[0].y));for(var c=1;c<this.points.length;c++)b.addPoint(this.points[c].x,
67
+ this.points[c].y),d!=null&&d.lineTo(this.points[c].x,this.points[c].y);return b};this.getMarkers=function(){for(var a=[],b=0;b<this.points.length-1;b++)a.push([this.points[b],this.points[b].angleTo(this.points[b+1])]);a.push([this.points[this.points.length-1],a[a.length-1][1]]);return a}};a.Element.polyline.prototype=new a.Element.PathElementBase;a.Element.polygon=function(c){this.base=a.Element.polyline;this.base(c);this.basePath=this.path;this.path=function(a){var b=this.basePath(a);a!=null&&(a.lineTo(this.points[0].x,
68
+ this.points[0].y),a.closePath());return b}};a.Element.polygon.prototype=new a.Element.polyline;a.Element.path=function(c){this.base=a.Element.PathElementBase;this.base(c);c=this.attribute("d").value;c=c.replace(/,/gm," ");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,"$1 $2");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,"$1 $2");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([^\s])/gm,"$1 $2");c=c.replace(/([^\s])([MmZzLlHhVvCcSsQqTtAa])/gm,"$1 $2");c=c.replace(/([0-9])([+\-])/gm,
69
+ "$1 $2");c=c.replace(/(\.[0-9]*)(\.)/gm,"$1 $2");c=c.replace(/([Aa](\s+[0-9]+){3})\s+([01])\s*([01])/gm,"$1 $3 $4 ");c=a.compressSpaces(c);c=a.trim(c);this.PathParser=new function(d){this.tokens=d.split(" ");this.reset=function(){this.i=-1;this.previousCommand=this.command="";this.start=new a.Point(0,0);this.control=new a.Point(0,0);this.current=new a.Point(0,0);this.points=[];this.angles=[]};this.isEnd=function(){return this.i>=this.tokens.length-1};this.isCommandOrEnd=function(){return this.isEnd()?
70
+ !0:this.tokens[this.i+1].match(/^[A-Za-z]$/)!=null};this.isRelativeCommand=function(){return this.command==this.command.toLowerCase()};this.getToken=function(){this.i+=1;return this.tokens[this.i]};this.getScalar=function(){return parseFloat(this.getToken())};this.nextCommand=function(){this.previousCommand=this.command;this.command=this.getToken()};this.getPoint=function(){return this.makeAbsolute(new a.Point(this.getScalar(),this.getScalar()))};this.getAsControlPoint=function(){var b=this.getPoint();
71
+ return this.control=b};this.getAsCurrentPoint=function(){var b=this.getPoint();return this.current=b};this.getReflectedControlPoint=function(){return this.previousCommand.toLowerCase()!="c"&&this.previousCommand.toLowerCase()!="s"?this.current:new a.Point(2*this.current.x-this.control.x,2*this.current.y-this.control.y)};this.makeAbsolute=function(b){if(this.isRelativeCommand())b.x=this.current.x+b.x,b.y=this.current.y+b.y;return b};this.addMarker=function(b,a,d){d!=null&&this.angles.length>0&&this.angles[this.angles.length-
72
+ 1]==null&&(this.angles[this.angles.length-1]=this.points[this.points.length-1].angleTo(d));this.addMarkerAngle(b,a==null?null:a.angleTo(b))};this.addMarkerAngle=function(b,a){this.points.push(b);this.angles.push(a)};this.getMarkerPoints=function(){return this.points};this.getMarkerAngles=function(){for(var b=0;b<this.angles.length;b++)if(this.angles[b]==null)for(var a=b+1;a<this.angles.length;a++)if(this.angles[a]!=null){this.angles[b]=this.angles[a];break}return this.angles}}(c);this.path=function(d){var b=
73
+ this.PathParser;b.reset();var c=new a.BoundingBox;for(d!=null&&d.beginPath();!b.isEnd();)switch(b.nextCommand(),b.command.toUpperCase()){case "M":var e=b.getAsCurrentPoint();b.addMarker(e);c.addPoint(e.x,e.y);d!=null&&d.moveTo(e.x,e.y);for(b.start=b.current;!b.isCommandOrEnd();)e=b.getAsCurrentPoint(),b.addMarker(e,b.start),c.addPoint(e.x,e.y),d!=null&&d.lineTo(e.x,e.y);break;case "L":for(;!b.isCommandOrEnd();){var f=b.current,e=b.getAsCurrentPoint();b.addMarker(e,f);c.addPoint(e.x,e.y);d!=null&&
74
+ d.lineTo(e.x,e.y)}break;case "H":for(;!b.isCommandOrEnd();)e=new a.Point((b.isRelativeCommand()?b.current.x:0)+b.getScalar(),b.current.y),b.addMarker(e,b.current),b.current=e,c.addPoint(b.current.x,b.current.y),d!=null&&d.lineTo(b.current.x,b.current.y);break;case "V":for(;!b.isCommandOrEnd();)e=new a.Point(b.current.x,(b.isRelativeCommand()?b.current.y:0)+b.getScalar()),b.addMarker(e,b.current),b.current=e,c.addPoint(b.current.x,b.current.y),d!=null&&d.lineTo(b.current.x,b.current.y);break;case "C":for(;!b.isCommandOrEnd();){var g=
75
+ b.current,f=b.getPoint(),h=b.getAsControlPoint(),e=b.getAsCurrentPoint();b.addMarker(e,h,f);c.addBezierCurve(g.x,g.y,f.x,f.y,h.x,h.y,e.x,e.y);d!=null&&d.bezierCurveTo(f.x,f.y,h.x,h.y,e.x,e.y)}break;case "S":for(;!b.isCommandOrEnd();)g=b.current,f=b.getReflectedControlPoint(),h=b.getAsControlPoint(),e=b.getAsCurrentPoint(),b.addMarker(e,h,f),c.addBezierCurve(g.x,g.y,f.x,f.y,h.x,h.y,e.x,e.y),d!=null&&d.bezierCurveTo(f.x,f.y,h.x,h.y,e.x,e.y);break;case "Q":for(;!b.isCommandOrEnd();)g=b.current,h=b.getAsControlPoint(),
76
+ e=b.getAsCurrentPoint(),b.addMarker(e,h,h),c.addQuadraticCurve(g.x,g.y,h.x,h.y,e.x,e.y),d!=null&&d.quadraticCurveTo(h.x,h.y,e.x,e.y);break;case "T":for(;!b.isCommandOrEnd();)g=b.current,h=b.getReflectedControlPoint(),b.control=h,e=b.getAsCurrentPoint(),b.addMarker(e,h,h),c.addQuadraticCurve(g.x,g.y,h.x,h.y,e.x,e.y),d!=null&&d.quadraticCurveTo(h.x,h.y,e.x,e.y);break;case "A":for(;!b.isCommandOrEnd();){var g=b.current,j=b.getScalar(),l=b.getScalar(),f=b.getScalar()*(Math.PI/180),o=b.getScalar(),h=b.getScalar(),
77
+ e=b.getAsCurrentPoint(),n=new a.Point(Math.cos(f)*(g.x-e.x)/2+Math.sin(f)*(g.y-e.y)/2,-Math.sin(f)*(g.x-e.x)/2+Math.cos(f)*(g.y-e.y)/2),q=Math.pow(n.x,2)/Math.pow(j,2)+Math.pow(n.y,2)/Math.pow(l,2);q>1&&(j*=Math.sqrt(q),l*=Math.sqrt(q));o=(o==h?-1:1)*Math.sqrt((Math.pow(j,2)*Math.pow(l,2)-Math.pow(j,2)*Math.pow(n.y,2)-Math.pow(l,2)*Math.pow(n.x,2))/(Math.pow(j,2)*Math.pow(n.y,2)+Math.pow(l,2)*Math.pow(n.x,2)));isNaN(o)&&(o=0);var p=new a.Point(o*j*n.y/l,o*-l*n.x/j),g=new a.Point((g.x+e.x)/2+Math.cos(f)*
78
+ p.x-Math.sin(f)*p.y,(g.y+e.y)/2+Math.sin(f)*p.x+Math.cos(f)*p.y),m=function(b,a){return(b[0]*a[0]+b[1]*a[1])/(Math.sqrt(Math.pow(b[0],2)+Math.pow(b[1],2))*Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)))},t=function(b,a){return(b[0]*a[1]<b[1]*a[0]?-1:1)*Math.acos(m(b,a))},o=t([1,0],[(n.x-p.x)/j,(n.y-p.y)/l]),q=[(n.x-p.x)/j,(n.y-p.y)/l],p=[(-n.x-p.x)/j,(-n.y-p.y)/l],n=t(q,p);if(m(q,p)<=-1)n=Math.PI;m(q,p)>=1&&(n=0);h==0&&n>0&&(n-=2*Math.PI);h==1&&n<0&&(n+=2*Math.PI);q=new a.Point(g.x-j*Math.cos((o+n)/
79
+ 2),g.y-l*Math.sin((o+n)/2));b.addMarkerAngle(q,(o+n)/2+(h==0?1:-1)*Math.PI/2);b.addMarkerAngle(e,n+(h==0?1:-1)*Math.PI/2);c.addPoint(e.x,e.y);d!=null&&(m=j>l?j:l,e=j>l?1:j/l,j=j>l?l/j:1,d.translate(g.x,g.y),d.rotate(f),d.scale(e,j),d.arc(0,0,m,o,o+n,1-h),d.scale(1/e,1/j),d.rotate(-f),d.translate(-g.x,-g.y))}break;case "Z":d!=null&&d.closePath(),b.current=b.start}return c};this.getMarkers=function(){for(var a=this.PathParser.getMarkerPoints(),b=this.PathParser.getMarkerAngles(),c=[],e=0;e<a.length;e++)c.push([a[e],
80
+ b[e]]);return c}};a.Element.path.prototype=new a.Element.PathElementBase;a.Element.pattern=function(c){this.base=a.Element.ElementBase;this.base(c);this.createPattern=function(d){var b=new a.Element.svg;b.attributes.viewBox=new a.Property("viewBox",this.attribute("viewBox").value);b.attributes.x=new a.Property("x",this.attribute("x").value);b.attributes.y=new a.Property("y",this.attribute("y").value);b.attributes.width=new a.Property("width",this.attribute("width").value);b.attributes.height=new a.Property("height",
81
+ this.attribute("height").value);b.children=this.children;var c=document.createElement("canvas");c.width=this.attribute("width").Length.toPixels("x");c.height=this.attribute("height").Length.toPixels("y");b.render(c.getContext("2d"));return d.createPattern(c,"repeat")}};a.Element.pattern.prototype=new a.Element.ElementBase;a.Element.marker=function(c){this.base=a.Element.ElementBase;this.base(c);this.baseRender=this.render;this.render=function(d,b,c){d.translate(b.x,b.y);this.attribute("orient").valueOrDefault("auto")==
82
+ "auto"&&d.rotate(c);this.attribute("markerUnits").valueOrDefault("strokeWidth")=="strokeWidth"&&d.scale(d.lineWidth,d.lineWidth);d.save();var e=new a.Element.svg;e.attributes.viewBox=new a.Property("viewBox",this.attribute("viewBox").value);e.attributes.refX=new a.Property("refX",this.attribute("refX").value);e.attributes.refY=new a.Property("refY",this.attribute("refY").value);e.attributes.width=new a.Property("width",this.attribute("markerWidth").value);e.attributes.height=new a.Property("height",
83
+ this.attribute("markerHeight").value);e.attributes.fill=new a.Property("fill",this.attribute("fill").valueOrDefault("black"));e.attributes.stroke=new a.Property("stroke",this.attribute("stroke").valueOrDefault("none"));e.children=this.children;e.render(d);d.restore();this.attribute("markerUnits").valueOrDefault("strokeWidth")=="strokeWidth"&&d.scale(1/d.lineWidth,1/d.lineWidth);this.attribute("orient").valueOrDefault("auto")=="auto"&&d.rotate(-c);d.translate(-b.x,-b.y)}};a.Element.marker.prototype=
84
+ new a.Element.ElementBase;a.Element.defs=function(c){this.base=a.Element.ElementBase;this.base(c);this.render=function(){}};a.Element.defs.prototype=new a.Element.ElementBase;a.Element.GradientBase=function(c){this.base=a.Element.ElementBase;this.base(c);this.gradientUnits=this.attribute("gradientUnits").valueOrDefault("objectBoundingBox");this.stops=[];for(c=0;c<this.children.length;c++)this.stops.push(this.children[c]);this.getGradient=function(){};this.createGradient=function(d,b){var c=this;this.attribute("xlink:href").hasValue()&&
85
+ (c=this.attribute("xlink:href").Definition.getDefinition());for(var e=this.getGradient(d,b),f=0;f<c.stops.length;f++)e.addColorStop(c.stops[f].offset,c.stops[f].color);if(this.attribute("gradientTransform").hasValue()){c=a.ViewPort.viewPorts[0];f=new a.Element.rect;f.attributes.x=new a.Property("x",-a.MAX_VIRTUAL_PIXELS/3);f.attributes.y=new a.Property("y",-a.MAX_VIRTUAL_PIXELS/3);f.attributes.width=new a.Property("width",a.MAX_VIRTUAL_PIXELS);f.attributes.height=new a.Property("height",a.MAX_VIRTUAL_PIXELS);
86
+ var g=new a.Element.g;g.attributes.transform=new a.Property("transform",this.attribute("gradientTransform").value);g.children=[f];f=new a.Element.svg;f.attributes.x=new a.Property("x",0);f.attributes.y=new a.Property("y",0);f.attributes.width=new a.Property("width",c.width);f.attributes.height=new a.Property("height",c.height);f.children=[g];g=document.createElement("canvas");g.width=c.width;g.height=c.height;c=g.getContext("2d");c.fillStyle=e;f.render(c);return c.createPattern(g,"no-repeat")}return e}};
87
+ a.Element.GradientBase.prototype=new a.Element.ElementBase;a.Element.linearGradient=function(c){this.base=a.Element.GradientBase;this.base(c);this.getGradient=function(a,b){var c=b.getBoundingBox(),e=this.gradientUnits=="objectBoundingBox"?c.x()+c.width()*this.attribute("x1").numValue():this.attribute("x1").Length.toPixels("x"),f=this.gradientUnits=="objectBoundingBox"?c.y()+c.height()*this.attribute("y1").numValue():this.attribute("y1").Length.toPixels("y"),g=this.gradientUnits=="objectBoundingBox"?
88
+ c.x()+c.width()*this.attribute("x2").numValue():this.attribute("x2").Length.toPixels("x"),c=this.gradientUnits=="objectBoundingBox"?c.y()+c.height()*this.attribute("y2").numValue():this.attribute("y2").Length.toPixels("y");return a.createLinearGradient(e,f,g,c)}};a.Element.linearGradient.prototype=new a.Element.GradientBase;a.Element.radialGradient=function(c){this.base=a.Element.GradientBase;this.base(c);this.getGradient=function(a,b){var c=b.getBoundingBox(),e=this.gradientUnits=="objectBoundingBox"?
89
+ c.x()+c.width()*this.attribute("cx").numValue():this.attribute("cx").Length.toPixels("x"),f=this.gradientUnits=="objectBoundingBox"?c.y()+c.height()*this.attribute("cy").numValue():this.attribute("cy").Length.toPixels("y"),g=e,h=f;this.attribute("fx").hasValue()&&(g=this.gradientUnits=="objectBoundingBox"?c.x()+c.width()*this.attribute("fx").numValue():this.attribute("fx").Length.toPixels("x"));this.attribute("fy").hasValue()&&(h=this.gradientUnits=="objectBoundingBox"?c.y()+c.height()*this.attribute("fy").numValue():
90
+ this.attribute("fy").Length.toPixels("y"));c=this.gradientUnits=="objectBoundingBox"?(c.width()+c.height())/2*this.attribute("r").numValue():this.attribute("r").Length.toPixels();return a.createRadialGradient(g,h,0,e,f,c)}};a.Element.radialGradient.prototype=new a.Element.GradientBase;a.Element.stop=function(c){this.base=a.Element.ElementBase;this.base(c);this.offset=this.attribute("offset").numValue();c=this.style("stop-color");this.style("stop-opacity").hasValue()&&(c=c.Color.addOpacity(this.style("stop-opacity").value));
91
+ this.color=c.value};a.Element.stop.prototype=new a.Element.ElementBase;a.Element.AnimateBase=function(c){this.base=a.Element.ElementBase;this.base(c);a.Animations.push(this);this.duration=0;this.begin=this.attribute("begin").Time.toMilliseconds();this.maxDuration=this.begin+this.attribute("dur").Time.toMilliseconds();this.getProperty=function(){var a=this.attribute("attributeType").value,b=this.attribute("attributeName").value;return a=="CSS"?this.parent.style(b,!0):this.parent.attribute(b,!0)};this.initialValue=
92
+ null;this.removed=!1;this.calcValue=function(){return""};this.update=function(a){if(this.initialValue==null)this.initialValue=this.getProperty().value;if(this.duration>this.maxDuration)if(this.attribute("repeatCount").value=="indefinite")this.duration=0;else return this.attribute("fill").valueOrDefault("remove")=="remove"&&!this.removed?(this.removed=!0,this.getProperty().value=this.initialValue,!0):!1;this.duration+=a;a=!1;if(this.begin<this.duration)a=this.calcValue(),this.attribute("type").hasValue()&&
93
+ (a=this.attribute("type").value+"("+a+")"),this.getProperty().value=a,a=!0;return a};this.progress=function(){return(this.duration-this.begin)/(this.maxDuration-this.begin)}};a.Element.AnimateBase.prototype=new a.Element.ElementBase;a.Element.animate=function(c){this.base=a.Element.AnimateBase;this.base(c);this.calcValue=function(){var a=this.attribute("from").numValue(),b=this.attribute("to").numValue();return a+(b-a)*this.progress()}};a.Element.animate.prototype=new a.Element.AnimateBase;a.Element.animateColor=
94
+ function(c){this.base=a.Element.AnimateBase;this.base(c);this.calcValue=function(){var a=new RGBColor(this.attribute("from").value),b=new RGBColor(this.attribute("to").value);if(a.ok&&b.ok){var c=a.r+(b.r-a.r)*this.progress(),e=a.g+(b.g-a.g)*this.progress(),a=a.b+(b.b-a.b)*this.progress();return"rgb("+parseInt(c,10)+","+parseInt(e,10)+","+parseInt(a,10)+")"}return this.attribute("from").value}};a.Element.animateColor.prototype=new a.Element.AnimateBase;a.Element.animateTransform=function(c){this.base=
95
+ a.Element.animate;this.base(c)};a.Element.animateTransform.prototype=new a.Element.animate;a.Element.font=function(c){this.base=a.Element.ElementBase;this.base(c);this.horizAdvX=this.attribute("horiz-adv-x").numValue();this.isArabic=this.isRTL=!1;this.missingGlyph=this.fontFace=null;this.glyphs=[];for(c=0;c<this.children.length;c++){var d=this.children[c];if(d.type=="font-face")this.fontFace=d,d.style("font-family").hasValue()&&(a.Definitions[d.style("font-family").value]=this);else if(d.type=="missing-glyph")this.missingGlyph=
96
+ d;else if(d.type=="glyph")d.arabicForm!=""?(this.isArabic=this.isRTL=!0,typeof this.glyphs[d.unicode]=="undefined"&&(this.glyphs[d.unicode]=[]),this.glyphs[d.unicode][d.arabicForm]=d):this.glyphs[d.unicode]=d}};a.Element.font.prototype=new a.Element.ElementBase;a.Element.fontface=function(c){this.base=a.Element.ElementBase;this.base(c);this.ascent=this.attribute("ascent").value;this.descent=this.attribute("descent").value;this.unitsPerEm=this.attribute("units-per-em").numValue()};a.Element.fontface.prototype=
97
+ new a.Element.ElementBase;a.Element.missingglyph=function(c){this.base=a.Element.path;this.base(c);this.horizAdvX=0};a.Element.missingglyph.prototype=new a.Element.path;a.Element.glyph=function(c){this.base=a.Element.path;this.base(c);this.horizAdvX=this.attribute("horiz-adv-x").numValue();this.unicode=this.attribute("unicode").value;this.arabicForm=this.attribute("arabic-form").value};a.Element.glyph.prototype=new a.Element.path;a.Element.text=function(c){this.base=a.Element.RenderedElementBase;
98
+ this.base(c);if(c!=null){this.children=[];for(var d=0;d<c.childNodes.length;d++){var b=c.childNodes[d];b.nodeType==1?this.addChild(b,!0):b.nodeType==3&&this.addChild(new a.Element.tspan(b),!1)}}this.baseSetContext=this.setContext;this.setContext=function(b){this.baseSetContext(b);if(this.style("dominant-baseline").hasValue())b.textBaseline=this.style("dominant-baseline").value;if(this.style("alignment-baseline").hasValue())b.textBaseline=this.style("alignment-baseline").value};this.renderChildren=
99
+ function(b){for(var a=this.style("text-anchor").valueOrDefault("start"),c=this.attribute("x").Length.toPixels("x"),d=this.attribute("y").Length.toPixels("y"),h=0;h<this.children.length;h++){var j=this.children[h];j.attribute("x").hasValue()?j.x=j.attribute("x").Length.toPixels("x"):(j.attribute("dx").hasValue()&&(c+=j.attribute("dx").Length.toPixels("x")),j.x=c);c=j.measureText(b);if(a!="start"&&(h==0||j.attribute("x").hasValue())){for(var l=c,o=h+1;o<this.children.length;o++){var n=this.children[o];
100
+ if(n.attribute("x").hasValue())break;l+=n.measureText(b)}j.x-=a=="end"?l:l/2}c=j.x+c;j.attribute("y").hasValue()?j.y=j.attribute("y").Length.toPixels("y"):(j.attribute("dy").hasValue()&&(d+=j.attribute("dy").Length.toPixels("y")),j.y=d);d=j.y;j.render(b)}}};a.Element.text.prototype=new a.Element.RenderedElementBase;a.Element.TextElementBase=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.getGlyph=function(a,b,c){var e=b[c],f=null;if(a.isArabic){var g="isolated";if((c==0||b[c-
101
+ 1]==" ")&&c<b.length-2&&b[c+1]!=" ")g="terminal";c>0&&b[c-1]!=" "&&c<b.length-2&&b[c+1]!=" "&&(g="medial");if(c>0&&b[c-1]!=" "&&(c==b.length-1||b[c+1]==" "))g="initial";typeof a.glyphs[e]!="undefined"&&(f=a.glyphs[e][g],f==null&&a.glyphs[e].type=="glyph"&&(f=a.glyphs[e]))}else f=a.glyphs[e];if(f==null)f=a.missingGlyph;return f};this.renderChildren=function(c){var b=this.parent.style("font-family").Definition.getDefinition();if(b!=null){var k=this.parent.style("font-size").numValueOrDefault(a.Font.Parse(a.ctx.font).fontSize),
102
+ e=this.parent.style("font-style").valueOrDefault(a.Font.Parse(a.ctx.font).fontStyle),f=this.getText();b.isRTL&&(f=f.split("").reverse().join(""));for(var g=a.ToNumberArray(this.parent.attribute("dx").value),h=0;h<f.length;h++){var j=this.getGlyph(b,f,h),l=k/b.fontFace.unitsPerEm;c.translate(this.x,this.y);c.scale(l,-l);var o=c.lineWidth;c.lineWidth=c.lineWidth*b.fontFace.unitsPerEm/k;e=="italic"&&c.transform(1,0,0.4,1,0,0);j.render(c);e=="italic"&&c.transform(1,0,-0.4,1,0,0);c.lineWidth=o;c.scale(1/
103
+ l,-1/l);c.translate(-this.x,-this.y);this.x+=k*(j.horizAdvX||b.horizAdvX)/b.fontFace.unitsPerEm;typeof g[h]!="undefined"&&!isNaN(g[h])&&(this.x+=g[h])}}else c.strokeStyle!=""&&c.strokeText(a.compressSpaces(this.getText()),this.x,this.y),c.fillStyle!=""&&c.fillText(a.compressSpaces(this.getText()),this.x,this.y)};this.getText=function(){};this.measureText=function(c){var b=this.parent.style("font-family").Definition.getDefinition();if(b!=null){var c=this.parent.style("font-size").numValueOrDefault(a.Font.Parse(a.ctx.font).fontSize),
104
+ k=0,e=this.getText();b.isRTL&&(e=e.split("").reverse().join(""));for(var f=a.ToNumberArray(this.parent.attribute("dx").value),g=0;g<e.length;g++){var h=this.getGlyph(b,e,g);k+=(h.horizAdvX||b.horizAdvX)*c/b.fontFace.unitsPerEm;typeof f[g]!="undefined"&&!isNaN(f[g])&&(k+=f[g])}return k}b=a.compressSpaces(this.getText());if(!c.measureText)return b.length*10;c.save();this.setContext(c);b=c.measureText(b).width;c.restore();return b}};a.Element.TextElementBase.prototype=new a.Element.RenderedElementBase;
105
+ a.Element.tspan=function(c){this.base=a.Element.TextElementBase;this.base(c);this.text=c.nodeType==3?c.nodeValue:c.childNodes.length>0?c.childNodes[0].nodeValue:c.text;this.getText=function(){return this.text}};a.Element.tspan.prototype=new a.Element.TextElementBase;a.Element.tref=function(c){this.base=a.Element.TextElementBase;this.base(c);this.getText=function(){var a=this.attribute("xlink:href").Definition.getDefinition();if(a!=null)return a.children[0].getText()}};a.Element.tref.prototype=new a.Element.TextElementBase;
106
+ a.Element.a=function(c){this.base=a.Element.TextElementBase;this.base(c);this.hasText=!0;for(var d=0;d<c.childNodes.length;d++)if(c.childNodes[d].nodeType!=3)this.hasText=!1;this.text=this.hasText?c.childNodes[0].nodeValue:"";this.getText=function(){return this.text};this.baseRenderChildren=this.renderChildren;this.renderChildren=function(b){if(this.hasText){this.baseRenderChildren(b);var c=new a.Property("fontSize",a.Font.Parse(a.ctx.font).fontSize);a.Mouse.checkBoundingBox(this,new a.BoundingBox(this.x,
107
+ this.y-c.Length.toPixels("y"),this.x+this.measureText(b),this.y))}else c=new a.Element.g,c.children=this.children,c.parent=this,c.render(b)};this.onclick=function(){window.open(this.attribute("xlink:href").value)};this.onmousemove=function(){a.ctx.canvas.style.cursor="pointer"}};a.Element.a.prototype=new a.Element.TextElementBase;a.Element.image=function(c){this.base=a.Element.RenderedElementBase;this.base(c);a.Images.push(this);this.img=document.createElement("img");this.loaded=!1;var d=this;this.img.onload=
108
+ function(){d.loaded=!0};this.img.src=this.attribute("xlink:href").value;this.renderChildren=function(b){var c=this.attribute("x").Length.toPixels("x"),d=this.attribute("y").Length.toPixels("y"),f=this.attribute("width").Length.toPixels("x"),g=this.attribute("height").Length.toPixels("y");f==0||g==0||(b.save(),b.translate(c,d),a.AspectRatio(b,this.attribute("preserveAspectRatio").value,f,this.img.width,g,this.img.height,0,0),b.drawImage(this.img,0,0),b.restore())}};a.Element.image.prototype=new a.Element.RenderedElementBase;
109
+ a.Element.g=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.getBoundingBox=function(){for(var c=new a.BoundingBox,b=0;b<this.children.length;b++)c.addBoundingBox(this.children[b].getBoundingBox());return c}};a.Element.g.prototype=new a.Element.RenderedElementBase;a.Element.symbol=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseSetContext=this.setContext;this.setContext=function(c){this.baseSetContext(c);if(this.attribute("viewBox").hasValue()){var b=
110
+ a.ToNumberArray(this.attribute("viewBox").value),k=b[0],e=b[1];width=b[2];height=b[3];a.AspectRatio(c,this.attribute("preserveAspectRatio").value,this.attribute("width").Length.toPixels("x"),width,this.attribute("height").Length.toPixels("y"),height,k,e);a.ViewPort.SetCurrent(b[2],b[3])}}};a.Element.symbol.prototype=new a.Element.RenderedElementBase;a.Element.style=function(c){this.base=a.Element.ElementBase;this.base(c);for(var c=c.childNodes[0].nodeValue+(c.childNodes.length>1?c.childNodes[1].nodeValue:
111
+ ""),c=c.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm,""),c=a.compressSpaces(c),c=c.split("}"),d=0;d<c.length;d++)if(a.trim(c[d])!="")for(var b=c[d].split("{"),k=b[0].split(","),b=b[1].split(";"),e=0;e<k.length;e++){var f=a.trim(k[e]);if(f!=""){for(var g={},h=0;h<b.length;h++){var j=b[h].indexOf(":"),l=b[h].substr(0,j),j=b[h].substr(j+1,b[h].length-j);l!=null&&j!=null&&(g[a.trim(l)]=new a.Property(a.trim(l),a.trim(j)))}a.Styles[f]=g;if(f=="@font-face"){f=g["font-family"].value.replace(/"/g,
112
+ "");g=g.src.value.split(",");for(h=0;h<g.length;h++)if(g[h].indexOf('format("svg")')>0){l=g[h].indexOf("url");j=g[h].indexOf(")",l);l=g[h].substr(l+5,j-l-6);l=a.parseXml(a.ajax(l)).getElementsByTagName("font");for(j=0;j<l.length;j++){var o=a.CreateElement(l[j]);a.Definitions[f]=o}}}}}};a.Element.style.prototype=new a.Element.ElementBase;a.Element.use=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseSetContext=this.setContext;this.setContext=function(a){this.baseSetContext(a);
113
+ this.attribute("x").hasValue()&&a.translate(this.attribute("x").Length.toPixels("x"),0);this.attribute("y").hasValue()&&a.translate(0,this.attribute("y").Length.toPixels("y"))};this.getDefinition=function(){var a=this.attribute("xlink:href").Definition.getDefinition();if(this.attribute("width").hasValue())a.attribute("width",!0).value=this.attribute("width").value;if(this.attribute("height").hasValue())a.attribute("height",!0).value=this.attribute("height").value;return a};this.path=function(a){var b=
114
+ this.getDefinition();b!=null&&b.path(a)};this.renderChildren=function(a){var b=this.getDefinition();b!=null&&b.render(a)}};a.Element.use.prototype=new a.Element.RenderedElementBase;a.Element.mask=function(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,b){var c=this.attribute("x").Length.toPixels("x"),e=this.attribute("y").Length.toPixels("y"),f=this.attribute("width").Length.toPixels("x"),g=this.attribute("height").Length.toPixels("y"),h=b.attribute("mask").value;b.attribute("mask").value=
115
+ "";var j=document.createElement("canvas");j.width=c+f;j.height=e+g;var l=j.getContext("2d");this.renderChildren(l);var o=document.createElement("canvas");o.width=c+f;o.height=e+g;var n=o.getContext("2d");b.render(n);n.globalCompositeOperation="destination-in";n.fillStyle=l.createPattern(j,"no-repeat");n.fillRect(0,0,c+f,e+g);a.fillStyle=n.createPattern(o,"no-repeat");a.fillRect(0,0,c+f,e+g);b.attribute("mask").value=h};this.render=function(){}};a.Element.mask.prototype=new a.Element.ElementBase;a.Element.clipPath=
116
+ function(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a){for(var b=0;b<this.children.length;b++)this.children[b].path&&(this.children[b].path(a),a.clip())};this.render=function(){}};a.Element.clipPath.prototype=new a.Element.ElementBase;a.Element.filter=function(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,b){var c=b.getBoundingBox(),e=this.attribute("x").Length.toPixels("x"),f=this.attribute("y").Length.toPixels("y");if(e==0||f==0)e=c.x1,f=c.y1;var g=
117
+ this.attribute("width").Length.toPixels("x"),h=this.attribute("height").Length.toPixels("y");if(g==0||h==0)g=c.width(),h=c.height();c=b.style("filter").value;b.style("filter").value="";var j=0.2*g,l=0.2*h,o=document.createElement("canvas");o.width=g+2*j;o.height=h+2*l;var n=o.getContext("2d");n.translate(-e+j,-f+l);b.render(n);for(var q=0;q<this.children.length;q++)this.children[q].apply(n,0,0,g+2*j,h+2*l);a.drawImage(o,0,0,g+2*j,h+2*l,e-j,f-l,g+2*j,h+2*l);b.style("filter",!0).value=c};this.render=
118
+ function(){}};a.Element.filter.prototype=new a.Element.ElementBase;a.Element.feGaussianBlur=function(c){function d(a,c,d,f,g){for(var h=0;h<g;h++)for(var j=0;j<f;j++)for(var l=a[h*f*4+j*4+3]/255,o=0;o<4;o++){for(var n=d[0]*(l==0?255:a[h*f*4+j*4+o])*(l==0||o==3?1:l),q=1;q<d.length;q++){var p=Math.max(j-q,0),m=a[h*f*4+p*4+3]/255,p=Math.min(j+q,f-1),p=a[h*f*4+p*4+3]/255,t=d[q],r;m==0?r=255:(r=Math.max(j-q,0),r=a[h*f*4+r*4+o]);m=r*(m==0||o==3?1:m);p==0?r=255:(r=Math.min(j+q,f-1),r=a[h*f*4+r*4+o]);n+=
119
+ t*(m+r*(p==0||o==3?1:p))}c[j*g*4+h*4+o]=n}}this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,c,e,f,g){var e=this.attribute("stdDeviation").numValue(),c=a.getImageData(0,0,f,g),e=Math.max(e,0.01),h=Math.ceil(e*4)+1;mask=[];for(var j=0;j<h;j++)mask[j]=Math.exp(-0.5*(j/e)*(j/e));e=mask;h=0;for(j=1;j<e.length;j++)h+=Math.abs(e[j]);h=2*h+Math.abs(e[0]);for(j=0;j<e.length;j++)e[j]/=h;tmp=[];d(c.data,tmp,e,f,g);d(tmp,c.data,e,g,f);a.clearRect(0,0,f,g);a.putImageData(c,0,0)}};a.Element.filter.prototype=
120
+ new a.Element.feGaussianBlur;a.Element.title=function(){};a.Element.title.prototype=new a.Element.ElementBase;a.Element.desc=function(){};a.Element.desc.prototype=new a.Element.ElementBase;a.Element.MISSING=function(a){console.log("ERROR: Element '"+a.nodeName+"' not yet implemented.")};a.Element.MISSING.prototype=new a.Element.ElementBase;a.CreateElement=function(c){var d=c.nodeName.replace(/^[^:]+:/,""),d=d.replace(/\-/g,""),b=null,b=typeof a.Element[d]!="undefined"?new a.Element[d](c):new a.Element.MISSING(c);
121
+ b.type=c.nodeName;return b};a.load=function(c,d){a.loadXml(c,a.ajax(d))};a.loadXml=function(c,d){a.loadXmlDoc(c,a.parseXml(d))};a.loadXmlDoc=function(c,d){a.init(c);var b=function(a){for(var b=c.canvas;b;)a.x-=b.offsetLeft,a.y-=b.offsetTop,b=b.offsetParent;window.scrollX&&(a.x+=window.scrollX);window.scrollY&&(a.y+=window.scrollY);return a};if(a.opts.ignoreMouse!=!0)c.canvas.onclick=function(c){c=b(new a.Point(c!=null?c.clientX:event.clientX,c!=null?c.clientY:event.clientY));a.Mouse.onclick(c.x,c.y)},
122
+ c.canvas.onmousemove=function(c){c=b(new a.Point(c!=null?c.clientX:event.clientX,c!=null?c.clientY:event.clientY));a.Mouse.onmousemove(c.x,c.y)};var k=a.CreateElement(d.documentElement),e=k.root=!0,f=function(){a.ViewPort.Clear();c.canvas.parentNode&&a.ViewPort.SetCurrent(c.canvas.parentNode.clientWidth,c.canvas.parentNode.clientHeight);if(a.opts.ignoreDimensions!=!0){if(k.style("width").hasValue())c.canvas.width=k.style("width").Length.toPixels("x"),c.canvas.style.width=c.canvas.width+"px";if(k.style("height").hasValue())c.canvas.height=
123
+ k.style("height").Length.toPixels("y"),c.canvas.style.height=c.canvas.height+"px"}var b=c.canvas.clientWidth||c.canvas.width,d=c.canvas.clientHeight||c.canvas.height;a.ViewPort.SetCurrent(b,d);if(a.opts!=null&&a.opts.offsetX!=null)k.attribute("x",!0).value=a.opts.offsetX;if(a.opts!=null&&a.opts.offsetY!=null)k.attribute("y",!0).value=a.opts.offsetY;if(a.opts!=null&&a.opts.scaleWidth!=null&&a.opts.scaleHeight!=null){var f=1,g=1;k.attribute("width").hasValue()&&(f=k.attribute("width").Length.toPixels("x")/
124
+ a.opts.scaleWidth);k.attribute("height").hasValue()&&(g=k.attribute("height").Length.toPixels("y")/a.opts.scaleHeight);k.attribute("width",!0).value=a.opts.scaleWidth;k.attribute("height",!0).value=a.opts.scaleHeight;k.attribute("viewBox",!0).value="0 0 "+b*f+" "+d*g;k.attribute("preserveAspectRatio",!0).value="none"}a.opts.ignoreClear!=!0&&c.clearRect(0,0,b,d);k.render(c);e&&(e=!1,a.opts!=null&&typeof a.opts.renderCallback=="function"&&a.opts.renderCallback())},g=!0;a.ImagesLoaded()&&(g=!1,f());
125
+ a.intervalID=setInterval(function(){var b=!1;g&&a.ImagesLoaded()&&(g=!1,b=!0);a.opts.ignoreMouse!=!0&&(b|=a.Mouse.hasEvents());if(a.opts.ignoreAnimation!=!0)for(var c=0;c<a.Animations.length;c++)b|=a.Animations[c].update(1E3/a.FRAMERATE);a.opts!=null&&typeof a.opts.forceRedraw=="function"&&a.opts.forceRedraw()==!0&&(b=!0);b&&(f(),a.Mouse.runEvents())},1E3/a.FRAMERATE)};a.stop=function(){a.intervalID&&clearInterval(a.intervalID)};a.Mouse=new function(){this.events=[];this.hasEvents=function(){return this.events.length!=
126
+ 0};this.onclick=function(a,d){this.events.push({type:"onclick",x:a,y:d,run:function(a){if(a.onclick)a.onclick()}})};this.onmousemove=function(a,d){this.events.push({type:"onmousemove",x:a,y:d,run:function(a){if(a.onmousemove)a.onmousemove()}})};this.eventElements=[];this.checkPath=function(a,d){for(var b=0;b<this.events.length;b++){var k=this.events[b];d.isPointInPath&&d.isPointInPath(k.x,k.y)&&(this.eventElements[b]=a)}};this.checkBoundingBox=function(a,d){for(var b=0;b<this.events.length;b++){var k=
127
+ this.events[b];d.isPointInBox(k.x,k.y)&&(this.eventElements[b]=a)}};this.runEvents=function(){a.ctx.canvas.style.cursor="";for(var c=0;c<this.events.length;c++)for(var d=this.events[c],b=this.eventElements[c];b;)d.run(b),b=b.parent;this.events=[];this.eventElements=[]}};return a}this.canvg=function(a,c,d){if(a==null&&c==null&&d==null)for(var c=document.getElementsByTagName("svg"),b=0;b<c.length;b++){a=c[b];d=document.createElement("canvas");d.width=a.clientWidth;d.height=a.clientHeight;a.parentNode.insertBefore(d,
128
+ a);a.parentNode.removeChild(a);var k=document.createElement("div");k.appendChild(a);canvg(d,k.innerHTML)}else d=d||{},typeof a=="string"&&(a=document.getElementById(a)),a.svg==null?(b=m(),a.svg=b):(b=a.svg,b.stop()),b.opts=d,a=a.getContext("2d"),typeof c.documentElement!="undefined"?b.loadXmlDoc(a,c):c.substr(0,1)=="<"?b.loadXml(a,c):b.load(a,c)}})();
129
+ if(CanvasRenderingContext2D)CanvasRenderingContext2D.prototype.drawSvg=function(m,a,c,d,b){canvg(this.canvas,m,{ignoreMouse:!0,ignoreAnimation:!0,ignoreDimensions:!0,ignoreClear:!0,offsetX:a,offsetY:c,scaleWidth:d,scaleHeight:b})};
130
+ (function(m){var a=m.css,c=m.CanVGRenderer,d=m.SVGRenderer,b=m.extend,k=m.merge,e=m.addEvent,f=m.placeBox,g=m.createElement,h=m.discardElement;b(c.prototype,d.prototype);b(c.prototype,{create:function(a,b,c,d){this.setContainer(b,c,d);this.configure(a)},setContainer:function(a,b,c){var d=a.style,e=a.parentNode,f=d.left,d=d.top,h=a.offsetWidth,k=a.offsetHeight,m={visibility:"hidden",position:"absolute"};this.init.apply(this,[a,b,c]);this.canvas=g("canvas",{width:h,height:k},{position:"relative",left:f,
131
+ top:d},a);this.ttLine=g("div",null,m,e);this.ttDiv=g("div",null,m,e);this.ttTimer=void 0;this.hiddenSvg=a=g("div",{width:h,height:k},{visibility:"hidden",left:f,top:d},e);a.appendChild(this.box)},configure:function(b){var c=this,d=b.options.tooltip,g=d.borderWidth,h=c.ttDiv,m=d.style,s=c.ttLine,t=parseInt(m.padding,10),m=k(m,{padding:t+"px","background-color":d.backgroundColor,"border-style":"solid","border-width":g+"px","border-radius":d.borderRadius+"px"});d.shadow&&(m=k(m,{"box-shadow":"1px 1px 3px gray",
132
+ "-webkit-box-shadow":"1px 1px 3px gray"}));a(h,m);a(s,{"border-left":"1px solid darkgray"});e(b,"tooltipRefresh",function(d){var e=b.container,g=e.offsetLeft,k=e.offsetTop;h.innerHTML=d.text;e=f(h.offsetWidth,h.offsetHeight,g,k,e.offsetWidth,e.offsetHeight,{x:d.x,y:d.y},12);a(h,{visibility:"visible",left:e.x+"px",top:e.y+"px","border-color":d.borderColor});a(s,{visibility:"visible",left:g+d.x+"px",top:k+b.plotTop+"px",height:b.plotHeight+"px"});c.ttTimer!==void 0&&clearTimeout(c.ttTimer);c.ttTimer=
133
+ setTimeout(function(){a(h,{visibility:"hidden"});a(s,{visibility:"hidden"})},3E3)})},destroy:function(){h(this.canvas);this.ttTimer!==void 0&&clearTimeout(this.ttTimer);h(this.ttLine);h(this.ttDiv);h(this.hiddenSvg);return d.prototype.destroy.apply(this)},color:function(a,b,c){a&&a.linearGradient&&(a=a.stops[a.stops.length-1][1]);return d.prototype.color.call(this,a,b,c)},draw:function(){window.canvg(this.canvas,this.hiddenSvg.innerHTML)}})})(Highcharts);
trunk/js/modules/exporting.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Highcharts JS v2.2.1 (2012-03-15)
3
+ Exporting module
4
+
5
+ (c) 2010-2011 Torstein H?nsi
6
+
7
+ License: www.highcharts.com/license
8
+ */
9
+ (function(){function x(a){for(var b=a.length;b--;)typeof a[b]==="number"&&(a[b]=Math.round(a[b])-0.5);return a}var f=Highcharts,y=f.Chart,z=f.addEvent,B=f.removeEvent,r=f.createElement,u=f.discardElement,t=f.css,s=f.merge,k=f.each,n=f.extend,C=Math.max,h=document,D=window,A=h.documentElement.ontouchstart!==void 0,v=f.getOptions();n(v.lang,{downloadPNG:"Download PNG image",downloadJPEG:"Download JPEG image",downloadPDF:"Download PDF document",downloadSVG:"Download SVG vector image",exportButtonTitle:"Export to raster or vector image",
10
+ printButtonTitle:"Print the chart"});v.navigation={menuStyle:{border:"1px solid #A0A0A0",background:"#FFFFFF"},menuItemStyle:{padding:"0 5px",background:"none",color:"#303030",fontSize:A?"14px":"11px"},menuItemHoverStyle:{background:"#4572A5",color:"#FFFFFF"},buttonOptions:{align:"right",backgroundColor:{linearGradient:[0,0,0,20],stops:[[0.4,"#F7F7F7"],[0.6,"#E3E3E3"]]},borderColor:"#B0B0B0",borderRadius:3,borderWidth:1,height:20,hoverBorderColor:"#909090",hoverSymbolFill:"#81A7CF",hoverSymbolStroke:"#4572A5",
11
+ symbolFill:"#E0E0E0",symbolStroke:"#A0A0A0",symbolX:11.5,symbolY:10.5,verticalAlign:"top",width:24,y:10}};v.exporting={type:"image/png",url:"http://export.highcharts.com/",width:800,buttons:{exportButton:{symbol:"exportIcon",x:-10,symbolFill:"#A8BF77",hoverSymbolFill:"#768F3E",_id:"exportButton",_titleKey:"exportButtonTitle",menuItems:[{textKey:"downloadPNG",onclick:function(){this.exportChart()}},{textKey:"downloadJPEG",onclick:function(){this.exportChart({type:"image/jpeg"})}},{textKey:"downloadPDF",
12
+ onclick:function(){this.exportChart({type:"application/pdf"})}},{textKey:"downloadSVG",onclick:function(){this.exportChart({type:"image/svg+xml"})}}]},printButton:{symbol:"printIcon",x:-36,symbolFill:"#B5C9DF",hoverSymbolFill:"#779ABF",_id:"printButton",_titleKey:"printButtonTitle",onclick:function(){this.print()}}}};n(y.prototype,{getSVG:function(a){var b=this,c,d,e,g=s(b.options,a);if(!h.createElementNS)h.createElementNS=function(a,b){var c=h.createElement(b);c.getBBox=function(){return f.Renderer.prototype.Element.prototype.getBBox.apply({element:c})};
13
+ return c};a=r("div",null,{position:"absolute",top:"-9999em",width:b.chartWidth+"px",height:b.chartHeight+"px"},h.body);n(g.chart,{renderTo:a,forExport:!0});g.exporting.enabled=!1;g.chart.plotBackgroundImage=null;g.series=[];k(b.series,function(a){e=s(a.options,{animation:!1,showCheckbox:!1,visible:a.visible});if(!e.isInternal){if(e&&e.marker&&/^url\(/.test(e.marker.symbol))e.marker.symbol="circle";g.series.push(e)}});c=new Highcharts.Chart(g);k(["xAxis","yAxis"],function(a){k(b[a],function(b,d){var e=
14
+ c[a][d],g=b.getExtremes(),f=g.userMin,g=g.userMax;(f!==void 0||g!==void 0)&&e.setExtremes(f,g,!0,!1)})});d=c.container.innerHTML;g=null;c.destroy();u(a);d=d.replace(/zIndex="[^"]+"/g,"").replace(/isShadow="[^"]+"/g,"").replace(/symbolName="[^"]+"/g,"").replace(/jQuery[0-9]+="[^"]+"/g,"").replace(/isTracker="[^"]+"/g,"").replace(/url\([^#]+#/g,"url(#").replace(/<svg /,'<svg xmlns:xlink="http://www.w3.org/1999/xlink" ').replace(/ href=/g," xlink:href=").replace(/&nbsp;/g,"\u00a0").replace(/&shy;/g,
15
+ "\u00ad").replace(/<IMG /g,"<image ").replace(/height=([^" ]+)/g,'height="$1"').replace(/width=([^" ]+)/g,'width="$1"').replace(/hc-svg-href="([^"]+)">/g,'xlink:href="$1"/>').replace(/id=([^" >]+)/g,'id="$1"').replace(/class=([^" ]+)/g,'class="$1"').replace(/ transform /g," ").replace(/:(path|rect)/g,"$1").replace(/style="([^"]+)"/g,function(a){return a.toLowerCase()});d=d.replace(/(url\(#highcharts-[0-9]+)&quot;/g,"$1").replace(/&quot;/g,"'");d.match(/ xmlns="/g).length===2&&(d=d.replace(/xmlns="[^"]+"/,
16
+ ""));return d},exportChart:function(a,b){var c,d=this.getSVG(s(this.options.exporting.chartOptions,b)),a=s(this.options.exporting,a);c=r("form",{method:"post",action:a.url},{display:"none"},h.body);k(["filename","type","width","svg"],function(b){r("input",{type:"hidden",name:b,value:{filename:a.filename||"chart",type:a.type,width:a.width,svg:d}[b]},null,c)});c.submit();u(c)},print:function(){var a=this,b=a.container,c=[],d=b.parentNode,e=h.body,g=e.childNodes;if(!a.isPrinting)a.isPrinting=!0,k(g,
17
+ function(a,b){if(a.nodeType===1)c[b]=a.style.display,a.style.display="none"}),e.appendChild(b),D.print(),setTimeout(function(){d.appendChild(b);k(g,function(a,b){if(a.nodeType===1)a.style.display=c[b]});a.isPrinting=!1},1E3)},contextMenu:function(a,b,c,d,e,g){var i=this,f=i.options.navigation,h=f.menuItemStyle,o=i.chartWidth,p=i.chartHeight,q="cache-"+a,j=i[q],l=C(e,g),m,w;if(!j)i[q]=j=r("div",{className:"highcharts-"+a},{position:"absolute",zIndex:1E3,padding:l+"px"},i.container),m=r("div",null,
18
+ n({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},f.menuStyle),j),w=function(){t(j,{display:"none"})},z(j,"mouseleave",w),k(b,function(a){if(a){var b=r("div",{onmouseover:function(){t(this,f.menuItemHoverStyle)},onmouseout:function(){t(this,h)},innerHTML:a.text||i.options.lang[a.textKey]},n({cursor:"pointer"},h),m);b[A?"ontouchstart":"onclick"]=function(){w();a.onclick.apply(i,arguments)};i.exportDivElements.push(b)}}),i.exportDivElements.push(m,
19
+ j),i.exportMenuWidth=j.offsetWidth,i.exportMenuHeight=j.offsetHeight;a={display:"block"};c+i.exportMenuWidth>o?a.right=o-c-e-l+"px":a.left=c-l+"px";d+g+i.exportMenuHeight>p?a.bottom=p-d-l+"px":a.top=d+g-l+"px";t(j,a)},addButton:function(a){function b(){p.attr(l);o.attr(j)}var c=this,d=c.renderer,e=s(c.options.navigation.buttonOptions,a),g=e.onclick,f=e.menuItems,h=e.width,k=e.height,o,p,q,a=e.borderWidth,j={stroke:e.borderColor},l={stroke:e.symbolStroke,fill:e.symbolFill},m=e.symbolSize||12;if(!c.exportDivElements)c.exportDivElements=
20
+ [],c.exportSVGElements=[];e.enabled!==!1&&(o=d.rect(0,0,h,k,e.borderRadius,a).align(e,!0).attr(n({fill:e.backgroundColor,"stroke-width":a,zIndex:19},j)).add(),q=d.rect(0,0,h,k,0).align(e).attr({id:e._id,fill:"rgba(255, 255, 255, 0.001)",title:c.options.lang[e._titleKey],zIndex:21}).css({cursor:"pointer"}).on("mouseover",function(){p.attr({stroke:e.hoverSymbolStroke,fill:e.hoverSymbolFill});o.attr({stroke:e.hoverBorderColor})}).on("mouseout",b).on("click",b).add(),f&&(g=function(){b();var a=q.getBBox();
21
+ c.contextMenu("export-menu",f,a.x,a.y,h,k)}),q.on("click",function(){g.apply(c,arguments)}),p=d.symbol(e.symbol,e.symbolX-m/2,e.symbolY-m/2,m,m).align(e,!0).attr(n(l,{"stroke-width":e.symbolStrokeWidth||1,zIndex:20})).add(),c.exportSVGElements.push(o,q,p))},destroyExport:function(){var a,b;for(a=0;a<this.exportSVGElements.length;a++)b=this.exportSVGElements[a],b.onclick=b.ontouchstart=null,this.exportSVGElements[a]=b.destroy();for(a=0;a<this.exportDivElements.length;a++)b=this.exportDivElements[a],
22
+ B(b,"mouseleave"),this.exportDivElements[a]=b.onmouseout=b.onmouseover=b.ontouchstart=b.onclick=null,u(b)}});f.Renderer.prototype.symbols.exportIcon=function(a,b,c,d){return x(["M",a,b+c,"L",a+c,b+d,a+c,b+d*0.8,a,b+d*0.8,"Z","M",a+c*0.5,b+d*0.8,"L",a+c*0.8,b+d*0.4,a+c*0.4,b+d*0.4,a+c*0.4,b,a+c*0.6,b,a+c*0.6,b+d*0.4,a+c*0.2,b+d*0.4,"Z"])};f.Renderer.prototype.symbols.printIcon=function(a,b,c,d){return x(["M",a,b+d*0.7,"L",a+c,b+d*0.7,a+c,b+d*0.4,a,b+d*0.4,"Z","M",a+c*0.2,b+d*0.4,"L",a+c*0.2,b,a+c*
23
+ 0.8,b,a+c*0.8,b+d*0.4,"Z","M",a+c*0.2,b+d*0.7,"L",a,b+d,a+c,b+d,a+c*0.8,b+d*0.7,"Z"])};y.prototype.callbacks.push(function(a){var b,c=a.options.exporting,d=c.buttons;if(c.enabled!==!1){for(b in d)a.addButton(d[b]);z(a,"destroy",a.destroyExport)}})})();
trunk/js/themes/dark-blue.js ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Dark blue theme for Highcharts JS
3
+ * @author Torstein Hønsi
4
+ */
5
+
6
+ Highcharts.theme = {
7
+ colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
8
+ "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
9
+ chart: {
10
+ backgroundColor: {
11
+ linearGradient: [0, 0, 250, 500],
12
+ stops: [
13
+ [0, 'rgb(48, 48, 96)'],
14
+ [1, 'rgb(0, 0, 0)']
15
+ ]
16
+ },
17
+ borderColor: '#000000',
18
+ borderWidth: 2,
19
+ className: 'dark-container',
20
+ plotBackgroundColor: 'rgba(255, 255, 255, .1)',
21
+ plotBorderColor: '#CCCCCC',
22
+ plotBorderWidth: 1
23
+ },
24
+ title: {
25
+ style: {
26
+ color: '#C0C0C0',
27
+ font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
28
+ }
29
+ },
30
+ subtitle: {
31
+ style: {
32
+ color: '#666666',
33
+ font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
34
+ }
35
+ },
36
+ xAxis: {
37
+ gridLineColor: '#333333',
38
+ gridLineWidth: 1,
39
+ labels: {
40
+ style: {
41
+ color: '#A0A0A0'
42
+ }
43
+ },
44
+ lineColor: '#A0A0A0',
45
+ tickColor: '#A0A0A0',
46
+ title: {
47
+ style: {
48
+ color: '#CCC',
49
+ fontWeight: 'bold',
50
+ fontSize: '12px',
51
+ fontFamily: 'Trebuchet MS, Verdana, sans-serif'
52
+
53
+ }
54
+ }
55
+ },
56
+ yAxis: {
57
+ gridLineColor: '#333333',
58
+ labels: {
59
+ style: {
60
+ color: '#A0A0A0'
61
+ }
62
+ },
63
+ lineColor: '#A0A0A0',
64
+ minorTickInterval: null,
65
+ tickColor: '#A0A0A0',
66
+ tickWidth: 1,
67
+ title: {
68
+ style: {
69
+ color: '#CCC',
70
+ fontWeight: 'bold',
71
+ fontSize: '12px',
72
+ fontFamily: 'Trebuchet MS, Verdana, sans-serif'
73
+ }
74
+ }
75
+ },
76
+ tooltip: {
77
+ backgroundColor: 'rgba(0, 0, 0, 0.75)',
78
+ style: {
79
+ color: '#F0F0F0'
80
+ }
81
+ },
82
+ toolbar: {
83
+ itemStyle: {
84
+ color: 'silver'
85
+ }
86
+ },
87
+ plotOptions: {
88
+ line: {
89
+ dataLabels: {
90
+ color: '#CCC'
91
+ },
92
+ marker: {
93
+ lineColor: '#333'
94
+ }
95
+ },
96
+ spline: {
97
+ marker: {
98
+ lineColor: '#333'
99
+ }
100
+ },
101
+ scatter: {
102
+ marker: {
103
+ lineColor: '#333'
104
+ }
105
+ },
106
+ candlestick: {
107
+ lineColor: 'white'
108
+ }
109
+ },
110
+ legend: {
111
+ itemStyle: {
112
+ font: '9pt Trebuchet MS, Verdana, sans-serif',
113
+ color: '#A0A0A0'
114
+ },
115
+ itemHoverStyle: {
116
+ color: '#FFF'
117
+ },
118
+ itemHiddenStyle: {
119
+ color: '#444'
120
+ }
121
+ },
122
+ credits: {
123
+ style: {
124
+ color: '#666'
125
+ }
126
+ },
127
+ labels: {
128
+ style: {
129
+ color: '#CCC'
130
+ }
131
+ },
132
+
133
+ navigation: {
134
+ buttonOptions: {
135
+ backgroundColor: {
136
+ linearGradient: [0, 0, 0, 20],
137
+ stops: [
138
+ [0.4, '#606060'],
139
+ [0.6, '#333333']
140
+ ]
141
+ },
142
+ borderColor: '#000000',
143
+ symbolStroke: '#C0C0C0',
144
+ hoverSymbolStroke: '#FFFFFF'
145
+ }
146
+ },
147
+
148
+ exporting: {
149
+ buttons: {
150
+ exportButton: {
151
+ symbolFill: '#55BE3B'
152
+ },
153
+ printButton: {
154
+ symbolFill: '#7797BE'
155
+ }
156
+ }
157
+ },
158
+
159
+ // scroll charts
160
+ rangeSelector: {
161
+ buttonTheme: {
162
+ fill: {
163
+ linearGradient: [0, 0, 0, 20],
164
+ stops: [
165
+ [0.4, '#888'],
166
+ [0.6, '#555']
167
+ ]
168
+ },
169
+ stroke: '#000000',
170
+ style: {
171
+ color: '#CCC',
172
+ fontWeight: 'bold'
173
+ },
174
+ states: {
175
+ hover: {
176
+ fill: {
177
+ linearGradient: [0, 0, 0, 20],
178
+ stops: [
179
+ [0.4, '#BBB'],
180
+ [0.6, '#888']
181
+ ]
182
+ },
183
+ stroke: '#000000',
184
+ style: {
185
+ color: 'white'
186
+ }
187
+ },
188
+ select: {
189
+ fill: {
190
+ linearGradient: [0, 0, 0, 20],
191
+ stops: [
192
+ [0.1, '#000'],
193
+ [0.3, '#333']
194
+ ]
195
+ },
196
+ stroke: '#000000',
197
+ style: {
198
+ color: 'yellow'
199
+ }
200
+ }
201
+ }
202
+ },
203
+ inputStyle: {
204
+ backgroundColor: '#333',
205
+ color: 'silver'
206
+ },
207
+ labelStyle: {
208
+ color: 'silver'
209
+ }
210
+ },
211
+
212
+ navigator: {
213
+ handles: {
214
+ backgroundColor: '#666',
215
+ borderColor: '#AAA'
216
+ },
217
+ outlineColor: '#CCC',
218
+ maskFill: 'rgba(16, 16, 16, 0.5)',
219
+ series: {
220
+ color: '#7798BF',
221
+ lineColor: '#A6C7ED'
222
+ }
223
+ },
224
+
225
+ scrollbar: {
226
+ barBackgroundColor: {
227
+ linearGradient: [0, 0, 0, 20],
228
+ stops: [
229
+ [0.4, '#888'],
230
+ [0.6, '#555']
231
+ ]
232
+ },
233
+ barBorderColor: '#CCC',
234
+ buttonArrowColor: '#CCC',
235
+ buttonBackgroundColor: {
236
+ linearGradient: [0, 0, 0, 20],
237
+ stops: [
238
+ [0.4, '#888'],
239
+ [0.6, '#555']
240
+ ]
241
+ },
242
+ buttonBorderColor: '#CCC',
243
+ rifleColor: '#FFF',
244
+ trackBackgroundColor: {
245
+ linearGradient: [0, 0, 0, 10],
246
+ stops: [
247
+ [0, '#000'],
248
+ [1, '#333']
249
+ ]
250
+ },
251
+ trackBorderColor: '#666'
252
+ },
253
+
254
+ // special colors for some of the
255
+ legendBackgroundColor: 'rgba(0, 0, 0, 0.5)',
256
+ legendBackgroundColorSolid: 'rgb(35, 35, 70)',
257
+ dataLabelsColor: '#444',
258
+ textColor: '#C0C0C0',
259
+ maskColor: 'rgba(255,255,255,0.3)'
260
+ };
261
+
262
+ // Apply the theme
263
+ var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
trunk/js/themes/dark-green.js ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Dark blue theme for Highcharts JS
3
+ * @author Torstein Hønsi
4
+ */
5
+
6
+ Highcharts.theme = {
7
+ colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
8
+ "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
9
+ chart: {
10
+ backgroundColor: {
11
+ linearGradient: [0, 0, 250, 500],
12
+ stops: [
13
+ [0, 'rgb(48, 96, 48)'],
14
+ [1, 'rgb(0, 0, 0)']
15
+ ]
16
+ },
17
+ borderColor: '#000000',
18
+ borderWidth: 2,
19
+ className: 'dark-container',
20
+ plotBackgroundColor: 'rgba(255, 255, 255, .1)',
21
+ plotBorderColor: '#CCCCCC',
22
+ plotBorderWidth: 1
23
+ },
24
+ title: {
25
+ style: {
26
+ color: '#C0C0C0',
27
+ font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
28
+ }
29
+ },
30
+ subtitle: {
31
+ style: {
32
+ color: '#666666',
33
+ font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
34
+ }
35
+ },
36
+ xAxis: {
37
+ gridLineColor: '#333333',
38
+ gridLineWidth: 1,
39
+ labels: {
40
+ style: {
41
+ color: '#A0A0A0'
42
+ }
43
+ },
44
+ lineColor: '#A0A0A0',
45
+ tickColor: '#A0A0A0',
46
+ title: {
47
+ style: {
48
+ color: '#CCC',
49
+ fontWeight: 'bold',
50
+ fontSize: '12px',
51
+ fontFamily: 'Trebuchet MS, Verdana, sans-serif'
52
+
53
+ }
54
+ }
55
+ },
56
+ yAxis: {
57
+ gridLineColor: '#333333',
58
+ labels: {
59
+ style: {
60
+ color: '#A0A0A0'
61
+ }
62
+ },
63
+ lineColor: '#A0A0A0',
64
+ minorTickInterval: null,
65
+ tickColor: '#A0A0A0',
66
+ tickWidth: 1,
67
+ title: {
68
+ style: {
69
+ color: '#CCC',
70
+ fontWeight: 'bold',
71
+ fontSize: '12px',
72
+ fontFamily: 'Trebuchet MS, Verdana, sans-serif'
73
+ }
74
+ }
75
+ },
76
+ tooltip: {
77
+ backgroundColor: 'rgba(0, 0, 0, 0.75)',
78
+ style: {
79
+ color: '#F0F0F0'
80
+ }
81
+ },
82
+ toolbar: {
83
+ itemStyle: {
84
+ color: 'silver'
85
+ }
86
+ },
87
+ plotOptions: {
88
+ line: {
89
+ dataLabels: {
90
+ color: '#CCC'
91
+ },
92
+ marker: {
93
+ lineColor: '#333'
94
+ }
95
+ },
96
+ spline: {
97
+ marker: {
98
+ lineColor: '#333'
99
+ }
100
+ },
101
+ scatter: {
102
+ marker: {
103
+ lineColor: '#333'
104
+ }
105
+ },
106
+ candlestick: {
107
+ lineColor: 'white'
108
+ }
109
+ },
110
+ legend: {
111
+ itemStyle: {
112
+ font: '9pt Trebuchet MS, Verdana, sans-serif',
113
+ color: '#A0A0A0'
114
+ },
115
+ itemHoverStyle: {
116
+ color: '#FFF'
117
+ },
118
+ itemHiddenStyle: {
119
+ color: '#444'
120
+ }
121
+ },
122
+ credits: {
123
+ style: {
124
+ color: '#666'
125
+ }
126
+ },
127
+ labels: {
128
+ style: {
129
+ color: '#CCC'
130
+ }
131
+ },
132
+
133
+ navigation: {
134
+ buttonOptions: {
135
+ backgroundColor: {
136
+ linearGradient: [0, 0, 0, 20],
137
+ stops: [
138
+ [0.4, '#606060'],
139
+ [0.6, '#333333']
140
+ ]
141
+ },
142
+ borderColor: '#000000',
143
+ symbolStroke: '#C0C0C0',
144
+ hoverSymbolStroke: '#FFFFFF'
145
+ }
146
+ },
147
+
148
+ exporting: {
149
+ buttons: {
150
+ exportButton: {
151
+ symbolFill: '#55BE3B'
152
+ },
153
+ printButton: {
154
+ symbolFill: '#7797BE'
155
+ }
156
+ }
157
+ },
158
+
159
+ // scroll charts
160
+ rangeSelector: {
161
+ buttonTheme: {
162
+ fill: {
163
+ linearGradient: [0, 0, 0, 20],
164
+ stops: [
165
+ [0.4, '#888'],
166
+ [0.6, '#555']
167
+ ]
168
+ },
169
+ stroke: '#000000',
170
+ style: {
171
+ color: '#CCC',
172
+ fontWeight: 'bold'
173
+ },
174
+ states: {
175
+ hover: {
176
+ fill: {
177
+ linearGradient: [0, 0, 0, 20],
178
+ stops: [
179
+ [0.4, '#BBB'],
180
+ [0.6, '#888']
181
+ ]
182
+ },
183
+ stroke: '#000000',
184
+ style: {
185
+ color: 'white'
186
+ }
187
+ },
188
+ select: {
189
+ fill: {
190
+ linearGradient: [0, 0, 0, 20],
191
+ stops: [
192
+ [0.1, '#000'],
193
+ [0.3, '#333']
194
+ ]
195
+ },
196
+ stroke: '#000000',
197
+ style: {
198
+ color: 'yellow'
199
+ }
200
+ }
201
+ }
202
+ },
203
+ inputStyle: {
204
+ backgroundColor: '#333',
205
+ color: 'silver'
206
+ },
207
+ labelStyle: {
208
+ color: 'silver'
209
+ }
210
+ },
211
+
212
+ navigator: {
213
+ handles: {
214
+ backgroundColor: '#666',
215
+ borderColor: '#AAA'
216
+ },
217
+ outlineColor: '#CCC',
218
+ maskFill: 'rgba(16, 16, 16, 0.5)',
219
+ series: {
220
+ color: '#7798BF',
221
+ lineColor: '#A6C7ED'
222
+ }
223
+ },
224
+
225
+ scrollbar: {
226
+ barBackgroundColor: {
227
+ linearGradient: [0, 0, 0, 20],
228
+ stops: [
229
+ [0.4, '#888'],
230
+ [0.6, '#555']
231
+ ]
232
+ },
233
+ barBorderColor: '#CCC',
234
+ buttonArrowColor: '#CCC',
235
+ buttonBackgroundColor: {
236
+ linearGradient: [0, 0, 0, 20],
237
+ stops: [
238
+ [0.4, '#888'],
239
+ [0.6, '#555']
240
+ ]
241
+ },
242
+ buttonBorderColor: '#CCC',
243
+ rifleColor: '#FFF',
244
+ trackBackgroundColor: {
245
+ linearGradient: [0, 0, 0, 10],
246
+ stops: [
247
+ [0, '#000'],
248
+ [1, '#333']
249
+ ]
250
+ },
251
+ trackBorderColor: '#666'
252
+ },
253
+
254
+ // special colors for some of the
255
+ legendBackgroundColor: 'rgba(0, 0, 0, 0.5)',
256
+ legendBackgroundColorSolid: 'rgb(35, 35, 70)',
257
+ dataLabelsColor: '#444',
258
+ textColor: '#C0C0C0',
259
+ maskColor: 'rgba(255,255,255,0.3)'
260
+ };
261
+
262
+ // Apply the theme
263
+ var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
trunk/js/themes/gray.js ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Gray theme for Highcharts JS
3
+ * @author Torstein Hønsi
4
+ */
5
+
6
+ Highcharts.theme = {
7
+ colors: ["#DDDF0D", "#7798BF", "#55BF3B", "#DF5353", "#aaeeee", "#ff0066", "#eeaaee",
8
+ "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
9
+ chart: {
10
+ backgroundColor: {
11
+ linearGradient: [0, 0, 0, 400],
12
+ stops: [
13
+ [0, 'rgb(96, 96, 96)'],
14
+ [1, 'rgb(16, 16, 16)']
15
+ ]
16
+ },
17
+ borderWidth: 0,
18
+ borderRadius: 15,
19
+ plotBackgroundColor: null,
20
+ plotShadow: false,
21
+ plotBorderWidth: 0
22
+ },
23
+ title: {
24
+ style: {
25
+ color: '#FFF',
26
+ font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
27
+ }
28
+ },
29
+ subtitle: {
30
+ style: {
31
+ color: '#DDD',
32
+ font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
33
+ }
34
+ },
35
+ xAxis: {
36
+ gridLineWidth: 0,
37
+ lineColor: '#999',
38
+ tickColor: '#999',
39
+ labels: {
40
+ style: {
41
+ color: '#999',
42
+ fontWeight: 'bold'
43
+ }
44
+ },
45
+ title: {
46
+ style: {
47
+ color: '#AAA',
48
+ font: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
49
+ }
50
+ }
51
+ },
52
+ yAxis: {
53
+ alternateGridColor: null,
54
+ minorTickInterval: null,
55
+ gridLineColor: 'rgba(255, 255, 255, .1)',
56
+ lineWidth: 0,
57
+ tickWidth: 0,
58
+ labels: {
59
+ style: {
60
+ color: '#999',
61
+ fontWeight: 'bold'
62
+ }
63
+ },
64
+ title: {
65
+ style: {
66
+ color: '#AAA',
67
+ font: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
68
+ }
69
+ }
70
+ },
71
+ legend: {
72
+ itemStyle: {
73
+ color: '#CCC'
74
+ },
75
+ itemHoverStyle: {
76
+ color: '#FFF'
77
+ },
78
+ itemHiddenStyle: {
79
+ color: '#333'
80
+ }
81
+ },
82
+ labels: {
83
+ style: {
84
+ color: '#CCC'
85
+ }
86
+ },
87
+ tooltip: {
88
+ backgroundColor: {
89
+ linearGradient: [0, 0, 0, 50],
90
+ stops: [
91
+ [0, 'rgba(96, 96, 96, .8)'],
92
+ [1, 'rgba(16, 16, 16, .8)']
93
+ ]
94
+ },
95
+ borderWidth: 0,
96
+ style: {
97
+ color: '#FFF'
98
+ }
99
+ },
100
+
101
+
102
+ plotOptions: {
103
+ line: {
104
+ dataLabels: {
105
+ color: '#CCC'
106
+ },
107
+ marker: {
108
+ lineColor: '#333'
109
+ }
110
+ },
111
+ spline: {
112
+ marker: {
113
+ lineColor: '#333'
114
+ }
115
+ },
116
+ scatter: {
117
+ marker: {
118
+ lineColor: '#333'
119
+ }
120
+ },
121
+ candlestick: {
122
+ lineColor: 'white'
123
+ }
124
+ },
125
+
126
+ toolbar: {
127
+ itemStyle: {
128
+ color: '#CCC'
129
+ }
130
+ },
131
+
132
+ navigation: {
133
+ buttonOptions: {
134
+ backgroundColor: {
135
+ linearGradient: [0, 0, 0, 20],
136
+ stops: [
137
+ [0.4, '#606060'],
138
+ [0.6, '#333333']
139
+ ]
140
+ },
141
+ borderColor: '#000000',
142
+ symbolStroke: '#C0C0C0',
143
+ hoverSymbolStroke: '#FFFFFF'
144
+ }
145
+ },
146
+
147
+ exporting: {
148
+ buttons: {
149
+ exportButton: {
150
+ symbolFill: '#55BE3B'
151
+ },
152
+ printButton: {
153
+ symbolFill: '#7797BE'
154
+ }
155
+ }
156
+ },
157
+
158
+ // scroll charts
159
+ rangeSelector: {
160
+ buttonTheme: {
161
+ fill: {
162
+ linearGradient: [0, 0, 0, 20],
163
+ stops: [
164
+ [0.4, '#888'],
165
+ [0.6, '#555']
166
+ ]
167
+ },
168
+ stroke: '#000000',
169
+ style: {
170
+ color: '#CCC',
171
+ fontWeight: 'bold'
172
+ },
173
+ states: {
174
+ hover: {
175
+ fill: {
176
+ linearGradient: [0, 0, 0, 20],
177
+ stops: [
178
+ [0.4, '#BBB'],
179
+ [0.6, '#888']
180
+ ]
181
+ },
182
+ stroke: '#000000',
183
+ style: {
184
+ color: 'white'
185
+ }
186
+ },
187
+ select: {
188
+ fill: {
189
+ linearGradient: [0, 0, 0, 20],
190
+ stops: [
191
+ [0.1, '#000'],
192
+ [0.3, '#333']
193
+ ]
194
+ },
195
+ stroke: '#000000',
196
+ style: {
197
+ color: 'yellow'
198
+ }
199
+ }
200
+ }
201
+ },
202
+ inputStyle: {
203
+ backgroundColor: '#333',
204
+ color: 'silver'
205
+ },
206
+ labelStyle: {
207
+ color: 'silver'
208
+ }
209
+ },
210
+
211
+ navigator: {
212
+ handles: {
213
+ backgroundColor: '#666',
214
+ borderColor: '#AAA'
215
+ },
216
+ outlineColor: '#CCC',
217
+ maskFill: 'rgba(16, 16, 16, 0.5)',
218
+ series: {
219
+ color: '#7798BF',
220
+ lineColor: '#A6C7ED'
221
+ }
222
+ },
223
+
224
+ scrollbar: {
225
+ barBackgroundColor: {
226
+ linearGradient: [0, 0, 0, 20],
227
+ stops: [
228
+ [0.4, '#888'],
229
+ [0.6, '#555']
230
+ ]
231
+ },
232
+ barBorderColor: '#CCC',
233
+ buttonArrowColor: '#CCC',
234
+ buttonBackgroundColor: {
235
+ linearGradient: [0, 0, 0, 20],
236
+ stops: [
237
+ [0.4, '#888'],
238
+ [0.6, '#555']
239
+ ]
240
+ },
241
+ buttonBorderColor: '#CCC',
242
+ rifleColor: '#FFF',
243
+ trackBackgroundColor: {
244
+ linearGradient: [0, 0, 0, 10],
245
+ stops: [
246
+ [0, '#000'],
247
+ [1, '#333']
248
+ ]
249
+ },
250
+ trackBorderColor: '#666'
251
+ },
252
+
253
+ // special colors for some of the demo examples
254
+ legendBackgroundColor: 'rgba(48, 48, 48, 0.8)',
255
+ legendBackgroundColorSolid: 'rgb(70, 70, 70)',
256
+ dataLabelsColor: '#444',
257
+ textColor: '#E0E0E0',
258
+ maskColor: 'rgba(255,255,255,0.3)'
259
+ };
260
+
261
+ // Apply the theme
262
+ var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
trunk/js/themes/grid.js ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Grid theme for Highcharts JS
3
+ * @author Torstein Hønsi
4
+ */
5
+
6
+ Highcharts.theme = {
7
+ colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],
8
+ chart: {
9
+ backgroundColor: {
10
+ linearGradient: [0, 0, 500, 500],
11
+ stops: [
12
+ [0, 'rgb(255, 255, 255)'],
13
+ [1, 'rgb(240, 240, 255)']
14
+ ]
15
+ },
16
+ borderWidth: 2,
17
+ plotBackgroundColor: 'rgba(255, 255, 255, .9)',
18
+ plotShadow: true,
19
+ plotBorderWidth: 1
20
+ },
21
+ title: {
22
+ style: {
23
+ color: '#000',
24
+ font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
25
+ }
26
+ },
27
+ subtitle: {
28
+ style: {
29
+ color: '#666666',
30
+ font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
31
+ }
32
+ },
33
+ xAxis: {
34
+ gridLineWidth: 1,
35
+ lineColor: '#000',
36
+ tickColor: '#000',
37
+ labels: {
38
+ style: {
39
+ color: '#000',
40
+ font: '11px Trebuchet MS, Verdana, sans-serif'
41
+ }
42
+ },
43
+ title: {
44
+ style: {
45
+ color: '#333',
46
+ fontWeight: 'bold',
47
+ fontSize: '12px',
48
+ fontFamily: 'Trebuchet MS, Verdana, sans-serif'
49
+
50
+ }
51
+ }
52
+ },
53
+ yAxis: {
54
+ minorTickInterval: 'auto',
55
+ lineColor: '#000',
56
+ lineWidth: 1,
57
+ tickWidth: 1,
58
+ tickColor: '#000',
59
+ labels: {
60
+ style: {
61
+ color: '#000',
62
+ font: '11px Trebuchet MS, Verdana, sans-serif'
63
+ }
64
+ },
65
+ title: {
66
+ style: {
67
+ color: '#333',
68
+ fontWeight: 'bold',
69
+ fontSize: '12px',
70
+ fontFamily: 'Trebuchet MS, Verdana, sans-serif'
71
+ }
72
+ }
73
+ },
74
+ legend: {
75
+ itemStyle: {
76
+ font: '9pt Trebuchet MS, Verdana, sans-serif',
77
+ color: 'black'
78
+
79
+ },
80
+ itemHoverStyle: {
81
+ color: '#039'
82
+ },
83
+ itemHiddenStyle: {
84
+ color: 'gray'
85
+ }
86
+ },
87
+ labels: {
88
+ style: {
89
+ color: '#99b'
90
+ }
91
+ }
92
+ };
93
+
94
+ // Apply the theme
95
+ var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
trunk/js/themes/skies.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Skies theme for Highcharts JS
3
+ * @author Torstein Hønsi
4
+ */
5
+
6
+ Highcharts.theme = {
7
+ colors: ["#514F78", "#42A07B", "#9B5E4A", "#72727F", "#1F949A", "#82914E", "#86777F", "#42A07B"],
8
+ chart: {
9
+ className: 'skies',
10
+ borderWidth: 0,
11
+ plotShadow: true,
12
+ plotBackgroundImage: '/demo/gfx/skies.jpg',
13
+ plotBackgroundColor: {
14
+ linearGradient: [0, 0, 250, 500],
15
+ stops: [
16
+ [0, 'rgba(255, 255, 255, 1)'],
17
+ [1, 'rgba(255, 255, 255, 0)']
18
+ ]
19
+ },
20
+ plotBorderWidth: 1
21
+ },
22
+ title: {
23
+ style: {
24
+ color: '#3E576F',
25
+ font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
26
+ }
27
+ },
28
+ subtitle: {
29
+ style: {
30
+ color: '#6D869F',
31
+ font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
32
+ }
33
+ },
34
+ xAxis: {
35
+ gridLineWidth: 0,
36
+ lineColor: '#C0D0E0',
37
+ tickColor: '#C0D0E0',
38
+ labels: {
39
+ style: {
40
+ color: '#666',
41
+ fontWeight: 'bold'
42
+ }
43
+ },
44
+ title: {
45
+ style: {
46
+ color: '#666',
47
+ font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
48
+ }
49
+ }
50
+ },
51
+ yAxis: {
52
+ alternateGridColor: 'rgba(255, 255, 255, .5)',
53
+ lineColor: '#C0D0E0',
54
+ tickColor: '#C0D0E0',
55
+ tickWidth: 1,
56
+ labels: {
57
+ style: {
58
+ color: '#666',
59
+ fontWeight: 'bold'
60
+ }
61
+ },
62
+ title: {
63
+ style: {
64
+ color: '#666',
65
+ font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
66
+ }
67
+ }
68
+ },
69
+ legend: {
70
+ itemStyle: {
71
+ font: '9pt Trebuchet MS, Verdana, sans-serif',
72
+ color: '#3E576F'
73
+ },
74
+ itemHoverStyle: {
75
+ color: 'black'
76
+ },
77
+ itemHiddenStyle: {
78
+ color: 'silver'
79
+ }
80
+ },
81
+ labels: {
82
+ style: {
83
+ color: '#3E576F'
84
+ }
85
+ }
86
+ };
87
+
88
+ // Apply the theme
89
+ var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
trunk/lang/wpmandrill-es_ES.mo ADDED
Binary file
trunk/lang/wpmandrill.po ADDED
@@ -0,0 +1,571 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: wpMandrill 1.0 rc1\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: 2012-04-26 16:25-0500\n"
6
+ "PO-Revision-Date: \n"
7
+ "Last-Translator: Will Castillo <will@mailchimp.com>\n"
8
+ "Language-Team: MailChimp <will@mailchimp.com>\n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "X-Poedit-Language: Spanish\n"
13
+ "X-Poedit-Country: UNITED STATES\n"
14
+ "X-Poedit-SourceCharset: utf-8\n"
15
+ "X-Poedit-Basepath: ../\n"
16
+ "X-Poedit-KeywordsList: __;_e\n"
17
+ "X-Poedit-SearchPath-0: .\n"
18
+
19
+ #: how-tos.php:14
20
+ msgid "Mandrill: How to tell WordPress to use wpMandrill."
21
+ msgstr "Mandrill: ¿Cómo decirle a WordPress que utilice wpMandrill?"
22
+
23
+ #: how-tos.php:17
24
+ msgid "Mandrill: How to send a regular email."
25
+ msgstr "Mandrill: ¿Cómo enviar un correo normal?"
26
+
27
+ #: how-tos.php:20
28
+ msgid "Mandrill: How to modify a certain email using the <em>mandrill_payload</em> WordPress filter."
29
+ msgstr "Mandrill: ¿Cómo modificar un correo determinado utilizando el filtro WordPress <em>mandrill_payload</em>?"
30
+
31
+ #: how-tos.php:23
32
+ msgid "Mandrill: How to send emails from within your plugins."
33
+ msgstr "Mandrill: ¿Cómo enviar correo desde tus plugins?"
34
+
35
+ #: how-tos.php:46
36
+ msgid "The purpose of this how-to is to show you how easy it is to start using the awesome platform that Mandrill offers to handle your transactional emails."
37
+ msgstr "El objeto de esta sección es mostrarte cuan fácil es es comenzar a utilizar la plataforma que Mandrill ofrece para manejar tus correos transaccionales."
38
+
39
+ #: how-tos.php:48
40
+ msgid "Just by setting it up, all the emails sent from your WordPress installation will be sent using the power of Mandrill."
41
+ msgstr "Sólo con configurarlo, todos los correos enviados desde tu instalación WordPress serán enviados utilizando el poder de Mandrill."
42
+
43
+ #: how-tos.php:49
44
+ msgid "If you want further customization, you can use the <strong>mandrill_payload</strong> filter we've provided."
45
+ msgstr "Si necesitas mayor personalización, puedes utilizar el filtro <strong>mandrill_payload</strong> que hemos provisto para ti."
46
+
47
+ #: how-tos.php:50
48
+ msgid "And if you want an even greater integration between your application and Mandrill, we've created a convenient call to send emails from within your plugins."
49
+ msgstr "Y si quieres una integración aún mayor entre tu aplicación y Mandrill, hemos creado una sencilla función para el envío de correos desde tus plugins."
50
+
51
+ #: how-tos.php:52
52
+ msgid "You can learn more about all of these features right from this page."
53
+ msgstr "Puedes conocer como usar cada una de estas características desde esta página."
54
+
55
+ #: how-tos.php:59
56
+ msgid "Simply install wpMandrill and configure it to make it handle all the email functions of your WordPress installation."
57
+ msgstr "Simplemente instala wpMandrill y configúralo, para hacer que este maneje todas las funciones de correo electrónico en tu instalación WordPress."
58
+
59
+ #: how-tos.php:60
60
+ msgid "Once it has been properly configured, it will replace the regular WordPress emailing processes, so it's basically transparent for you and for WordPress."
61
+ msgstr "Una vez que este ha sido correctamente configurado, este reemplazará los procesos regulares de envío de correo electrónico de WordPress, así que basicamente será transparente tanto para WordPress como para tí."
62
+
63
+ #: how-tos.php:61
64
+ msgid "To test wpMandrill, log out, and try to use the <em>Forgot your password?</em> feature in WordPress (you don't need to reset your password though. Just check the headers of the email that it sends you, and you'll see that it comes from Mandrill's servers)."
65
+ msgstr "Para probar wpMandrill, desconéctate de WordPress y utiliza la opción <em>¿Olvidáste tu Clave?</em> de WordPress (no necesitas eliminar tu clave actual, sólo revisa el correo que recibas y verás que fue enviado desde los servidores de Mandrill)."
66
+
67
+ #: how-tos.php:69
68
+ msgid "If you're a Plugin Developer, and you need to send a regular email using wpMandrill, you don't need to learn anything else. You can use the good ol' <strong>wp_mail</strong> function, as you would normally do if you were not using this plugin."
69
+ msgstr "Si eres un desarrollador de plugins, y necesitas enviar un correo regular utilizando wpMandrill, no necesitarás aprender nada adicional. Puedes usar la conocida funcion <strong>wp_mail</strong> que normalmente utilizarías si no estuvieses utilizando este plugin."
70
+
71
+ #: how-tos.php:70
72
+ msgid "For example:"
73
+ msgstr "Por ejemplo:"
74
+
75
+ #: how-tos.php:71
76
+ msgid "&lt;?php wp_mail('your@address.com', 'Your subject', 'Your message'); ?&gt;"
77
+ msgstr "&lt;?php wp_mail('tu@direccion.com', 'Tu Asunto', 'Tu mensaje'); ?&gt;"
78
+
79
+ #: how-tos.php:79
80
+ msgid "if you need to fine tune one or some of the emails sent through your WordPress installation, you will need to use the <em>mandrill_payload</em> filter."
81
+ msgstr "Si necesitas hacer ajustes particulares a uno a varios correos enviados a través de tu instalación WordPress, necesitarás usar el filtro <em>mandrill_payload</em>."
82
+
83
+ #: how-tos.php:80
84
+ msgid "To use it, you must create a function that analyzes the payload that is about to be sent to Mandrill, and modify it based on your requirements. Then you'll need to add this function as the callback of the mentioned filter, using the <em>add_filter</em> WordPress call. And finally, insert it into your theme's functions.php file or you own plugin's file."
85
+ msgstr "Para usarlo, debes crear una función que analice el payload que Mandrill está a punto de enviar, y modificarlo basado en tus requerimiento. Luego, necesitarás agregar esta función como el callback del filtro antes mencionado, utilizando la función de Wordpress <em>add_filter</em>. Finalmente, insertar ese código en el archivo functions.php de tu tema o en tu propio plugin."
86
+
87
+ #: how-tos.php:81
88
+ msgid "You can use the following code as an skeleton for your own callbacks:"
89
+ msgstr "Puedes utilizar el siguiente código como el esqueleto de tus propias llamadas."
90
+
91
+ #: how-tos.php:95
92
+ msgid "Let's say you're using the <a href=\"http://wordpress.org/extend/plugins/cart66-lite/\" target=\"_blank\">Cart66 Lite Ecommerce plugin</a> and you want to modify the emails sent from this plugin. Here's what you should do:"
93
+ msgstr "Asi que digamos que estás utilizando el <a href=\"http://wordpress.org/extend/plugins/cart66-lite/\" target=\"_blank\">plugin de Ecommerce Cart66 Lite</a> y quieres modificar los correos enviados desde este plugin. Aquí está lo que deberías hacer:"
94
+
95
+ #: how-tos.php:123
96
+ msgid "If you are a Plugin Developer and you need to create a deep integration between Mandrill and your WordPress installation, wpMandrill will make your life easier."
97
+ msgstr "Si eres un desarrollador de plugins y necesitas crear una integración más produnda entre Mandrill y tu instalación WordPress, wpMandrill te hará la vida más fácil."
98
+
99
+ #: how-tos.php:124
100
+ msgid "We have exposed a simple function that allows you to add tags and specify the template to use, in addition to specifying the To, Subject and Body sections of the email:"
101
+ msgstr "Hemos creado una simple función que te permite agregarle etiquetas y la plantilla a utilizar además de los campos Para, Asunto y Cuerpo de tu mensaje:"
102
+
103
+ #: how-tos.php:125
104
+ msgid "&lt;?php wpMandrill::mail($to, $subject, $html, $headers = '', $attachments = array(), $tags = array(), $from_name = '', $from_email = '', $template_name = ''); ?&gt;"
105
+ msgstr "&lt;?php wpMandrill::mail($para, $asunto, $html, $cabeceras = '', $adjuntos = array(), $etiquetas = array(), $campo_nombre = '', $campo_correo = '', $nombre_plantilla = ''); ?&gt;"
106
+
107
+ #: how-tos.php:126
108
+ msgid "But if you need Mandrill Powers, we have included a full-featured PHP class called Mandrill. It has every API call defined in Mandrill's API. Check it out at <em>/wp-content/plugin/wpmandrill/lib/mandrill.class.php</em>."
109
+ msgstr "Pero si necesitas Poderes de Mandrill, hemos incluido una clase PHP con todas las llamadas de la API de Mandrill incluidas, llamada Mandrill. Echale un vistazo en <em>/wp-content/plugin/wpmandrill/lib/mandrill.class.php</em>."
110
+
111
+ #: how-tos.php:127
112
+ msgid "To use it, just instantiate an object passing your API key, and make the calls:"
113
+ msgstr "Para usarla, simplemente instancia un objeto pasándole una Clave API y haz tus llamadas:"
114
+
115
+ #: how-tos.php:128
116
+ msgid "&lt;?php $mandrill = Mandrill($my_api_key); echo $mandrill->ping(); ?&gt;"
117
+ msgstr "&lt;?php $mandrill = Mandrill($my_api_key); echo $mandrill->ping(); ?&gt;"
118
+
119
+ #: wpmandrill.php:81
120
+ msgid "API Settings"
121
+ msgstr "Configuración de la API"
122
+
123
+ #: wpmandrill.php:82
124
+ msgid "API Key"
125
+ msgstr "Clave API"
126
+
127
+ #: wpmandrill.php:88
128
+ msgid "Sender Settings"
129
+ msgstr "Configuración del Remitente"
130
+
131
+ #: wpmandrill.php:89
132
+ msgid "FROM Name"
133
+ msgstr "Campo De:"
134
+
135
+ #: wpmandrill.php:90
136
+ msgid "FROM Email"
137
+ msgstr "Campo Email:"
138
+
139
+ #: wpmandrill.php:93
140
+ msgid "General Template"
141
+ msgstr "Plantilla General"
142
+
143
+ #: wpmandrill.php:94
144
+ #: wpmandrill.php:98
145
+ msgid "&nbsp;"
146
+ msgstr "&nbsp;"
147
+
148
+ #: wpmandrill.php:97
149
+ msgid "General Tags"
150
+ msgstr "Etiquetas Generales"
151
+
152
+ #: wpmandrill.php:104
153
+ msgid "Send a test email using these settings"
154
+ msgstr "Enviar un correo electrónico de prueba usando estas configuraciones"
155
+
156
+ #: wpmandrill.php:105
157
+ msgid "Send to"
158
+ msgstr "Enviar a"
159
+
160
+ #: wpmandrill.php:106
161
+ msgid "Subject"
162
+ msgstr "Asunto"
163
+
164
+ #: wpmandrill.php:107
165
+ msgid "Message"
166
+ msgstr "Mensaje"
167
+
168
+ #: wpmandrill.php:119
169
+ #: wpmandrill.php:235
170
+ msgid "Mandrill Settings"
171
+ msgstr "Configuración de Mandrill"
172
+
173
+ #: wpmandrill.php:120
174
+ msgid "Mandrill"
175
+ msgstr "Mandrill"
176
+
177
+ #: wpmandrill.php:128
178
+ #: wpmandrill.php:129
179
+ msgid "Mandrill Reports"
180
+ msgstr "Reportes Mandrill"
181
+
182
+ #: wpmandrill.php:151
183
+ msgid "Mandrill: wp_mail has been declared by another process or plugin, so you won't be able to use Mandrill until the problem is solved."
184
+ msgstr "Mandrill: wp?install ha sido declarado por otro proceso o plugin por lo que no podras usar Mandrill hasta que soluciones este inconveniente."
185
+
186
+ #: wpmandrill.php:180
187
+ msgid "To use this plugin you will need:"
188
+ msgstr "Para utilizar este plugin necesitarás:"
189
+
190
+ #: wpmandrill.php:182
191
+ msgid "Your Mandrill account."
192
+ msgstr "Tu cuenta Mandrill"
193
+
194
+ #: wpmandrill.php:183
195
+ msgid "At least one verified domain."
196
+ msgstr "Al menos un dominio verificado."
197
+
198
+ #: wpmandrill.php:184
199
+ msgid "A valid sender email address specified."
200
+ msgstr "Una dirección de correo electrónico de remitente válido."
201
+
202
+ #: wpmandrill.php:189
203
+ msgid "Once you have properly configured the settings, the plugin will take care of all the emails sent through your WordPress installation."
204
+ msgstr "Una vez que hayas completado la configuración, el plugin se hará cargo de todos los correos enviados a través de tu instalación WordPress."
205
+
206
+ #: wpmandrill.php:190
207
+ msgid "However, if you need to customize any part of the email before sending, you can do so by using the WordPress filter <strong>mandrill_payload</strong>."
208
+ msgstr "De cualquier forma, si alguna vez necesitas alterar cualquier parte del email antes de que este sea enviado, lo podrás hacer utilizando el filtro WordPress <strong>mandrill_payload</strong>."
209
+
210
+ #: wpmandrill.php:191
211
+ msgid "This filter has the same structure as Mandrill's API call <a href=\"http://mandrillapp.com/api/docs/messages.html#method=send\" target=\"_blank\">/messages/send</a>, except that it can have one additional parameter when the email is based on a template. The parameter is called \"<em>template</em>\", which is an associative array of two elements (the first element, a string whose key is \"<em>template_name</em>\", and a second parameter whose key is \"<em>template_content</em>\". Its value is an array with the same structure of the parameter \"<em>template_content</em>\" in the call <a href=\"http://mandrillapp.com/api/docs/messages.html#method=send-template\" target=\"_blank\">/messages/send-template</a>.)"
212
+ msgstr "Este filtro tiene la misma estructura de la llamada a la API de Mandrill <a href=\"http://mandrillapp.com/api/docs/messages.html#method=send\" target=\"_blank\">/messages/send</a>, excepto que esta podría tener un parámetro adicional cuando el email está basado en una plantilla. El parametro se llama \"<em>template</em>\", el cual es un arreglo asociativo de dos elementos (el primero, una cadena de caracteres cuya clave es \"<em>template_name</em>\", y un segundo parámetro cuya clave es \"<em>template_content</em>\" y su valor es una arreglo con la misma estructura del parámetro \"<em>template_content</em>\" de la llamada <a href=\"http://mandrillapp.com/api/docs/messages.html#method=send-template\" target=\"_blank\">/messages/send-template</a>.)"
213
+
214
+ #: wpmandrill.php:192
215
+ msgid "Note that if you're sending additional headers in your emails, the only valid headers are <em>From:</em>, <em>Reply-To:</em>, and <em>X-*:</em>. <em>Bcc:</em> is also valid, but Mandrill will send the blind carbon copy to only the first address, and the remaining will be silently discarted."
216
+ msgstr "Ten en cuenta que si estás intentando enviar cabeceras adicionales en tus correos, las únicas cabeceras válidas serán <em>From:</em>, <em>Reply-To:</em> y <em>X-*:</em>. <em>Bcc:</em> también es válido, pero Mandrill sólo enviará la copia oculta a la primera dirección, descartando silenciosamente el resto de las direcciones especificadas en el campo Bcc: que envíes."
217
+
218
+ #: wpmandrill.php:193
219
+ msgid "Also note that if any error occurs while sending the email, the plugin will try to send the message again using the native WordPress mailing capabilities."
220
+ msgstr "También ten presente que si ocurre cualquier error durante el envío del correo, el plugin intentará enviar el mensaje otra vez, utilizando las capacidades de envío de correo nativas de WordPress."
221
+
222
+ #: wpmandrill.php:194
223
+ msgid "Confirm that any change you made to the payload is in line with the <a href=\"http://mandrillapp.com/api/docs/\" target=\"_blank\">Mandrill's API's documentation</a>. Also, the <em>X-*:</em> headers, must be in line with the <a href=\"http://help.mandrill.com/customer/portal/articles/456744-smtp-headers-api\" target=\"_blank\">SMTP API documentation</a>. By using this plugin, you agree that you and your website will adhere to <a href=\"http://mandrill.com/legal/terms/\" target=\"_blank\">Mandrill's Terms of Use</a>."
224
+ msgstr "Asegúrate que cualquier cambio que hagas en el payload esté cónsono con la <a href=\"http://mandrillapp.com/api/docs/\" target=\"_blank\">Documentacion de la API de Mandrill</a>. También, las cabeceras <em>X-*:</em> deben estar en línea con la <a href=\"http://help.mandrill.com/customer/portal/articles/456744-smtp-headers-api\" target=\"_blank\">Documentación de la API SMTP</a>. Al utilizar este plugin estás aceptando adherirte tu y tu sitio web a los <a href=\"http://mandrill.com/legal/terms/\" target=\"_blank\">Términos y Condiciones de Mandrill</a>."
225
+
226
+ #: wpmandrill.php:195
227
+ msgid "if you have any question about Mandrill or this plugin, visit the <a href=\"http://help.mandrill.com/\" target=\"_blank\">Mandrill's Support Center</a>."
228
+ msgstr "Si tienes alguna pregunta sobre mandrill o este plugin, visita el <a href=\"http://help.mandrill.com/\" target=\"_blank\">Centro de Soporte de Mandrill</a>."
229
+
230
+ #: wpmandrill.php:213
231
+ msgid "Settings"
232
+ msgstr "Configuraciones"
233
+
234
+ #: wpmandrill.php:214
235
+ msgid "Reports"
236
+ msgstr "Reportes"
237
+
238
+ #: wpmandrill.php:226
239
+ #: stats.php:1
240
+ msgid "You do not have sufficient permissions to access this page."
241
+ msgstr "No tienes suficiente permisología para acceder a esta página."
242
+
243
+ #: wpmandrill.php:256
244
+ msgid "Send Email"
245
+ msgstr "Campo Email:"
246
+
247
+ #: wpmandrill.php:274
248
+ msgid "Latest from Mandrill..."
249
+ msgstr "Lo último de Mandrill..."
250
+
251
+ #: wpmandrill.php:288
252
+ msgid "News from MailChimp..."
253
+ msgstr "Noticias de MailChimp"
254
+
255
+ #: wpmandrill.php:315
256
+ msgid "Mandrill How-Tos"
257
+ msgstr "Mandrill: ¿Cómo hago?"
258
+
259
+ #: wpmandrill.php:342
260
+ msgid "You must define a valid sender email."
261
+ msgstr "Debes definir un correo electrónico de remitente válido."
262
+
263
+ #: wpmandrill.php:592
264
+ msgid "Test email send failed. "
265
+ msgstr "El correo electrónico de prueba falló."
266
+
267
+ #: wpmandrill.php:602
268
+ #, php-format
269
+ msgid "Test executed: %d emails sent, %d emails queued and %d emails rejected"
270
+ msgstr "Prueba ejecutada: %d emails enviados, %d emails encolados y %d emails rechazados"
271
+
272
+ #: wpmandrill.php:617
273
+ msgid "To get your API key, please visit your <a href=\"http://mandrillapp.com/settings/index\" target=\"_blank\">Mandrill Settings</a>"
274
+ msgstr "Para obtener tu Clave API, por favor visita tu <a href=\"http://mandrillapp.com/settings/index\" target=\"_blank\">Configuración Mandrill</a>"
275
+
276
+ #: wpmandrill.php:619
277
+ msgid "We are connected to your Mandrill Account."
278
+ msgstr "Estamos conectados a tu cuenta Mandrill."
279
+
280
+ #: wpmandrill.php:621
281
+ msgid "Sorry, invalid API key."
282
+ msgstr "Lo siento, Clave API inválida."
283
+
284
+ #: wpmandrill.php:637
285
+ msgid "No verified domains found."
286
+ msgstr "No se encontraros dominios verificados."
287
+
288
+ #: wpmandrill.php:649
289
+ msgid "This address will be used as the sender of the outgoing emails:"
290
+ msgstr "Esta dirección será utilizada como el remitente para los correos salientes:"
291
+
292
+ #: wpmandrill.php:655
293
+ msgid "Only verified domains are displayed here. If you need to verify a new domain, please visit your <a href=\"https://mandrillapp.com/settings/sending-domains\" target=\"_blank\">Mandrill Settings</a>"
294
+ msgstr "Aquí sólo se mostrarán dominios verificados. Si necesitas verificar un nuevo dominio, por favor visita tu <a href=\"https://mandrillapp.com/settings/sending-domains\" target=\"_blank\">Configuracipón Mandrill</a>"
295
+
296
+ #: wpmandrill.php:665
297
+ msgid "Name the recipients will see in their email clients:"
298
+ msgstr "Nombre que los destinatarios verán en sus clientes de correo:"
299
+
300
+ #: wpmandrill.php:676
301
+ #: wpmandrill.php:686
302
+ msgid "No templates found."
303
+ msgstr "No se encontraron plantillas."
304
+
305
+ #: wpmandrill.php:695
306
+ msgid "Select the template to use:"
307
+ msgstr "Seleccione la plantilla a utilizar:"
308
+
309
+ #: wpmandrill.php:701
310
+ msgid "<small>The selected template must have a <strong><em>mc:edit=\"main\"</em></strong> placeholder defined. The message will be shown there.</small>"
311
+ msgstr "<small>La plantilla seleccionada debe tener una sección <strong><em>mc:edit=\"main\"</em></strong> definida. El mensaje será mostrado ahí.</small>"
312
+
313
+ #: wpmandrill.php:711
314
+ msgid "If there are tags that you want appended to every call, list them here, one per line:"
315
+ msgstr "Si hay etiquetas que quieras agregar a cada llamada, lístalas aquí, una por línea."
316
+
317
+ #: wpmandrill.php:713
318
+ msgid "Also keep in mind that you can add or remove tags using the <em><a href=\"#\" onclick=\"jQuery('a#contextual-help-link').trigger('click');return false;\">mandrill_payload</a></em> WordPress filter."
319
+ msgstr "También recuerda que puedes agregar o eliminar etiquetas utilizando el filtro WordPress <em><a href=\"#\" onclick=\"jQuery('a#contextual-help-link').trigger('click');return false;\">mandrill_payload</a></em>."
320
+
321
+ #: wpmandrill.php:921
322
+ msgid "Mandrill Recent Statistics"
323
+ msgstr "Estadistas Recientes de Mandrill"
324
+
325
+ #: wpmandrill.php:943
326
+ #: wpmandrill.php:1159
327
+ #: stats.php:8
328
+ msgid "There was a problem retrieving statistics."
329
+ msgstr "Hubo un problema recuperando las estadísticas."
330
+
331
+ #: wpmandrill.php:1001
332
+ #: wpmandrill.php:1256
333
+ msgid "Sending Volume"
334
+ msgstr "Volumen de Envío"
335
+
336
+ #: wpmandrill.php:1002
337
+ #: wpmandrill.php:1257
338
+ msgid " emails"
339
+ msgstr " emails"
340
+
341
+ #: wpmandrill.php:1003
342
+ #: wpmandrill.php:1258
343
+ msgid "Total Volume per Day"
344
+ msgstr "Volumen Total por Período"
345
+
346
+ #: wpmandrill.php:1005
347
+ #: wpmandrill.php:1260
348
+ msgid "in the last few days"
349
+ msgstr "en los últimos días"
350
+
351
+ #: wpmandrill.php:1006
352
+ #: wpmandrill.php:1261
353
+ msgid "in the last few months"
354
+ msgstr "en los últimos meses"
355
+
356
+ #: wpmandrill.php:1007
357
+ #: wpmandrill.php:1262
358
+ msgid "Today"
359
+ msgstr "Hoy"
360
+
361
+ #: wpmandrill.php:1008
362
+ #: wpmandrill.php:1263
363
+ msgid "Last 7 Days"
364
+ msgstr "Últimos 7 Días"
365
+
366
+ #: wpmandrill.php:1009
367
+ #: wpmandrill.php:1264
368
+ msgid "Last 30 Days"
369
+ msgstr "Últimos 30 Días"
370
+
371
+ #: wpmandrill.php:1010
372
+ #: wpmandrill.php:1265
373
+ msgid "Last 60 Days"
374
+ msgstr "Últimos 60 Días"
375
+
376
+ #: wpmandrill.php:1011
377
+ #: wpmandrill.php:1266
378
+ msgid "Last 90 Days"
379
+ msgstr "Últimos 90 Días"
380
+
381
+ #: wpmandrill.php:1012
382
+ #: wpmandrill.php:1267
383
+ msgid "Periods"
384
+ msgstr "Períodos"
385
+
386
+ #: wpmandrill.php:1013
387
+ #: wpmandrill.php:1268
388
+ #: stats.php:30
389
+ msgid "Volume"
390
+ msgstr "Volumen"
391
+
392
+ #: wpmandrill.php:1014
393
+ #: wpmandrill.php:1269
394
+ msgid "Total:"
395
+ msgstr "Cuota:"
396
+
397
+ #: wpmandrill.php:1015
398
+ #: wpmandrill.php:1270
399
+ msgid "Unopened"
400
+ msgstr "No abiertos"
401
+
402
+ #: wpmandrill.php:1016
403
+ #: wpmandrill.php:1271
404
+ msgid "Bounced or Rejected"
405
+ msgstr "Rebotes o Rechazos"
406
+
407
+ #: wpmandrill.php:1017
408
+ #: wpmandrill.php:1272
409
+ msgid "Opened"
410
+ msgstr "Abiertos"
411
+
412
+ #: wpmandrill.php:1020
413
+ #: wpmandrill.php:1275
414
+ msgid "Average Sending Volume"
415
+ msgstr "Volumen de Envío Promedio"
416
+
417
+ #: wpmandrill.php:1021
418
+ #: wpmandrill.php:1276
419
+ msgid "/day"
420
+ msgstr "/día"
421
+
422
+ #: wpmandrill.php:1022
423
+ #: wpmandrill.php:1277
424
+ msgid "Average Volume per Day"
425
+ msgstr "Volumen Promedio por Período"
426
+
427
+ #: wpmandrill.php:1188
428
+ #: stats.php:57
429
+ msgid "Filter by:"
430
+ msgstr "Filtrar por:"
431
+
432
+ #: wpmandrill.php:1190
433
+ #: stats.php:59
434
+ msgid "No filter"
435
+ msgstr "Sin Filtro"
436
+
437
+ #: wpmandrill.php:1191
438
+ #: stats.php:60
439
+ msgid "Sender:"
440
+ msgstr "Remitente:"
441
+
442
+ #: wpmandrill.php:1198
443
+ #: stats.php:67
444
+ msgid "Tag:"
445
+ msgstr "Etiqueta:"
446
+
447
+ #: wpmandrill.php:1206
448
+ #: stats.php:75
449
+ msgid "Display:"
450
+ msgstr "Mostrar:"
451
+
452
+ #: wpmandrill.php:1208
453
+ #: stats.php:77
454
+ msgid "Total Volume per Period"
455
+ msgstr "Volumen Total por Período"
456
+
457
+ #: wpmandrill.php:1209
458
+ #: stats.php:78
459
+ msgid "Average Volume per Period"
460
+ msgstr "Volumen Promedio por Período"
461
+
462
+ #: stats.php:4
463
+ msgid "Mandrill Service Report"
464
+ msgstr "Reporte del Servicio Mandrill"
465
+
466
+ #: stats.php:20
467
+ msgid "Hourly Sending Volume and Open/Click Rate"
468
+ msgstr "Volumen de Envío y Tasa de Apertura y Cliqueo Por Horas"
469
+
470
+ #: stats.php:21
471
+ msgid "Hours"
472
+ msgstr "Horas"
473
+
474
+ #: stats.php:22
475
+ msgid "Hour"
476
+ msgstr "Hora"
477
+
478
+ #: stats.php:24
479
+ msgid "Daily Sending Volume and Open/Click Rate"
480
+ msgstr "Volumen de Envío y Tasa de Apertura y Cliqueo Diario"
481
+
482
+ #: stats.php:25
483
+ msgid "Days"
484
+ msgstr "Días"
485
+
486
+ #: stats.php:26
487
+ msgid "Day"
488
+ msgstr "Día"
489
+
490
+ #: stats.php:28
491
+ msgid "in the last 30 days"
492
+ msgstr "en los últimos 30 días"
493
+
494
+ #: stats.php:29
495
+ msgid "Open & Click Rate"
496
+ msgstr "Tasa de Apertura y Cliqueo"
497
+
498
+ #: stats.php:31
499
+ msgid "emails"
500
+ msgstr "emails"
501
+
502
+ #: stats.php:32
503
+ msgid "Open Rate"
504
+ msgstr "Tasa de Apertura"
505
+
506
+ #: stats.php:33
507
+ msgid "Click Rate"
508
+ msgstr "Tasa de Cliqueo"
509
+
510
+ #: stats.php:37
511
+ #, php-format
512
+ msgid "All-time statistics since %s: "
513
+ msgstr "Estadísticas desde %s:"
514
+
515
+ #: stats.php:40
516
+ msgid "Reputation:"
517
+ msgstr "Reputación:"
518
+
519
+ #: stats.php:41
520
+ msgid "Quota:"
521
+ msgstr "Cuota:"
522
+
523
+ #: stats.php:41
524
+ msgid "sends/hour"
525
+ msgstr "envíos/hora"
526
+
527
+ #: stats.php:42
528
+ msgid "Emails sent:"
529
+ msgstr "Correos enviados:"
530
+
531
+ #: stats.php:43
532
+ msgid "Emails delivered:"
533
+ msgstr "Correos entregados:"
534
+
535
+ #: stats.php:44
536
+ msgid "Tracked opens:"
537
+ msgstr "Aperturas registradas:"
538
+
539
+ #: stats.php:45
540
+ msgid "Tracked clicks:"
541
+ msgstr "Clicks registrados:"
542
+
543
+ #: stats.php:47
544
+ msgid "Rejects:"
545
+ msgstr "Rechazos:"
546
+
547
+ #: stats.php:48
548
+ msgid "Complaints:"
549
+ msgstr "Quejas:"
550
+
551
+ #: stats.php:49
552
+ msgid "Current backlog:"
553
+ msgstr "Backlog actual:"
554
+
555
+ #: stats.php:56
556
+ msgid "Filtered statistics:"
557
+ msgstr "Estadísticas filtradas:"
558
+
559
+ #: stats.php:353
560
+ msgid "For more detailed statistics, please visit your Mandrill Dashboard"
561
+ msgstr "Para estadísticas más detalladas, por favor visita tu Tablero Mandrill"
562
+
563
+ #~ msgid "Mandrill Test"
564
+ #~ msgstr "Prueba Mandrill"
565
+ #~ msgid "Mandrill How-tos"
566
+ #~ msgstr "Mandrill: ¿Cómo hago?"
567
+ #~ msgid "Testing Arena for Mandrill"
568
+ #~ msgstr "Caja de Arena de wpMandrill"
569
+ #~ msgid "Mandrill Report"
570
+ #~ msgstr "Reporte Mandrill"
571
+
trunk/legacy/function.wp_mail.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // Compact the input, apply the filters, and extract them back out
3
+ extract( apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) ) );
4
+
5
+ if ( !is_array($attachments) )
6
+ $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
7
+
8
+ global $phpmailer;
9
+
10
+ // (Re)create it, if it's gone missing
11
+ if ( !is_object( $phpmailer ) || !is_a( $phpmailer, 'PHPMailer' ) ) {
12
+ require_once ABSPATH . WPINC . '/class-phpmailer.php';
13
+ require_once ABSPATH . WPINC . '/class-smtp.php';
14
+ $phpmailer = new PHPMailer();
15
+ }
16
+
17
+ // Headers
18
+ if ( empty( $headers ) ) {
19
+ $headers = array();
20
+ } else {
21
+ if ( !is_array( $headers ) ) {
22
+ // Explode the headers out, so this function can take both
23
+ // string headers and an array of headers.
24
+ $tempheaders = explode( "\n", str_replace( "\r\n", "\n", $headers ) );
25
+ } else {
26
+ $tempheaders = $headers;
27
+ }
28
+ $headers = array();
29
+
30
+ // If it's actually got contents
31
+ if ( !empty( $tempheaders ) ) {
32
+ // Iterate through the raw headers
33
+ foreach ( (array) $tempheaders as $header ) {
34
+ if ( strpos($header, ':') === false ) {
35
+ if ( false !== stripos( $header, 'boundary=' ) ) {
36
+ $parts = preg_split('/boundary=/i', trim( $header ) );
37
+ $boundary = trim( str_replace( array( "'", '"' ), '', $parts[1] ) );
38
+ }
39
+ continue;
40
+ }
41
+ // Explode them out
42
+ list( $name, $content ) = explode( ':', trim( $header ), 2 );
43
+
44
+ // Cleanup crew
45
+ $name = trim( $name );
46
+ $content = trim( $content );
47
+
48
+ switch ( strtolower( $name ) ) {
49
+ // Mainly for legacy -- process a From: header if it's there
50
+ case 'from':
51
+ if ( strpos($content, '<' ) !== false ) {
52
+ // So... making my life hard again?
53
+ $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 );
54
+ $from_name = str_replace( '"', '', $from_name );
55
+ $from_name = trim( $from_name );
56
+
57
+ $from_email = substr( $content, strpos( $content, '<' ) + 1 );
58
+ $from_email = str_replace( '>', '', $from_email );
59
+ $from_email = trim( $from_email );
60
+ } else {
61
+ $from_email = trim( $content );
62
+ }
63
+ break;
64
+ case 'content-type':
65
+ if ( strpos( $content, ';' ) !== false ) {
66
+ list( $type, $charset ) = explode( ';', $content );
67
+ $content_type = trim( $type );
68
+ if ( false !== stripos( $charset, 'charset=' ) ) {
69
+ $charset = trim( str_replace( array( 'charset=', '"' ), '', $charset ) );
70
+ } elseif ( false !== stripos( $charset, 'boundary=' ) ) {
71
+ $boundary = trim( str_replace( array( 'BOUNDARY=', 'boundary=', '"' ), '', $charset ) );
72
+ $charset = '';
73
+ }
74
+ } else {
75
+ $content_type = trim( $content );
76
+ }
77
+ break;
78
+ case 'cc':
79
+ $cc = array_merge( (array) $cc, explode( ',', $content ) );
80
+ break;
81
+ case 'bcc':
82
+ $bcc = array_merge( (array) $bcc, explode( ',', $content ) );
83
+ break;
84
+ default:
85
+ // Add it to our grand headers array
86
+ $headers[trim( $name )] = trim( $content );
87
+ break;
88
+ }
89
+ }
90
+ }
91
+ }
92
+
93
+ // Empty out the values that may be set
94
+ $phpmailer->ClearAddresses();
95
+ $phpmailer->ClearAllRecipients();
96
+ $phpmailer->ClearAttachments();
97
+ $phpmailer->ClearBCCs();
98
+ $phpmailer->ClearCCs();
99
+ $phpmailer->ClearCustomHeaders();
100
+ $phpmailer->ClearReplyTos();
101
+
102
+ // From email and name
103
+ // If we don't have a name from the input headers
104
+ if ( !isset( $from_name ) )
105
+ $from_name = 'WordPress';
106
+
107
+ /* If we don't have an email from the input headers default to wordpress@$sitename
108
+ * Some hosts will block outgoing mail from this address if it doesn't exist but
109
+ * there's no easy alternative. Defaulting to admin_email might appear to be another
110
+ * option but some hosts may refuse to relay mail from an unknown domain. See
111
+ * http://trac.wordpress.org/ticket/5007.
112
+ */
113
+
114
+ if ( !isset( $from_email ) ) {
115
+ // Get the site domain and get rid of www.
116
+ $sitename = strtolower( $_SERVER['SERVER_NAME'] );
117
+ if ( substr( $sitename, 0, 4 ) == 'www.' ) {
118
+ $sitename = substr( $sitename, 4 );
119
+ }
120
+
121
+ $from_email = 'wordpress@' . $sitename;
122
+ }
123
+
124
+ // Plugin authors can override the potentially troublesome default
125
+ $phpmailer->From = apply_filters( 'wp_mail_from' , $from_email );
126
+ $phpmailer->FromName = apply_filters( 'wp_mail_from_name', $from_name );
127
+
128
+ // Set destination addresses
129
+ if ( !is_array( $to ) )
130
+ $to = explode( ',', $to );
131
+
132
+ foreach ( (array) $to as $recipient ) {
133
+ $phpmailer->AddAddress( trim( $recipient ) );
134
+ }
135
+
136
+ // Set mail's subject and body
137
+ $phpmailer->Subject = $subject;
138
+ $phpmailer->Body = $message;
139
+
140
+ // Add any CC and BCC recipients
141
+ if ( !empty( $cc ) ) {
142
+ foreach ( (array) $cc as $recipient ) {
143
+ $phpmailer->AddCc( trim($recipient) );
144
+ }
145
+ }
146
+
147
+ if ( !empty( $bcc ) ) {
148
+ foreach ( (array) $bcc as $recipient) {
149
+ $phpmailer->AddBcc( trim($recipient) );
150
+ }
151
+ }
152
+
153
+ // Set to use PHP's mail()
154
+ $phpmailer->IsMail();
155
+
156
+ // Set Content-Type and charset
157
+ // If we don't have a content-type from the input headers
158
+ if ( !isset( $content_type ) )
159
+ $content_type = 'text/plain';
160
+
161
+ $content_type = apply_filters( 'wp_mail_content_type', $content_type );
162
+
163
+ $phpmailer->ContentType = $content_type;
164
+
165
+ // Set whether it's plaintext, depending on $content_type
166
+ if ( 'text/html' == $content_type )
167
+ $phpmailer->IsHTML( true );
168
+
169
+ // If we don't have a charset from the input headers
170
+ if ( !isset( $charset ) )
171
+ $charset = get_bloginfo( 'charset' );
172
+
173
+ // Set the content-type and charset
174
+ $phpmailer->CharSet = apply_filters( 'wp_mail_charset', $charset );
175
+
176
+ // Set custom headers
177
+ if ( !empty( $headers ) ) {
178
+ foreach( (array) $headers as $name => $content ) {
179
+ $phpmailer->AddCustomHeader( sprintf( '%1$s: %2$s', $name, $content ) );
180
+ }
181
+
182
+ if ( false !== stripos( $content_type, 'multipart' ) && ! empty($boundary) )
183
+ $phpmailer->AddCustomHeader( sprintf( "Content-Type: %s;\n\t boundary=\"%s\"", $content_type, $boundary ) );
184
+ }
185
+
186
+ if ( !empty( $attachments ) ) {
187
+ foreach ( $attachments as $attachment ) {
188
+ $phpmailer->AddAttachment($attachment);
189
+ }
190
+ }
191
+
192
+ do_action_ref_array( 'phpmailer_init', array( &$phpmailer ) );
193
+
194
+ // Send!
195
+ $result = @$phpmailer->Send();
196
+
197
+ return $result;
198
+ ?>
trunk/lib/mandrill.class.php ADDED
@@ -0,0 +1,481 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mandrill_Exception extends Exception {
4
+ }
5
+
6
+ class Mandrill {
7
+ const API_VERSION = '1.0';
8
+ const END_POINT = 'https://mandrillapp.com/api/';
9
+
10
+ var $api;
11
+
12
+ function __construct($api) {
13
+ if ( empty($api) ) throw new Mandrill_Exception('Invalid API key');
14
+ try {
15
+
16
+ $response = $this->request('users/ping', array( 'key' => $api ) );
17
+ if ( $response != 'PONG!' ) throw new Mandrill_Exception('Invalid API key');
18
+
19
+ $this->api = $api;
20
+
21
+ } catch ( Exception $e ) {
22
+ throw new Mandrill_Exception($e->getMessage());
23
+ }
24
+ }
25
+
26
+ /**
27
+ * Work horse. Every API call use this function to actually make the request to Mandrill's servers.
28
+ *
29
+ * @link https://mandrillapp.com/api/docs/
30
+ *
31
+ * @param string $method API method name
32
+ * @param array $args query arguments
33
+ * @param string $http GET or POST request type
34
+ * @param string $output API response format (json,php,xml,yaml). json and xml are decoded into arrays automatically.
35
+ * @return array|string|Mandrill_Exception
36
+ */
37
+ function request($method, $args = array(), $http = 'POST', $output = 'json') {
38
+ if( !isset($args['key']) )
39
+ $args['key'] = $this->api;
40
+
41
+ $api_version = self::API_VERSION;
42
+ $dot_output = ('json' == $output) ? '' : ".{$output}";
43
+
44
+ $url = self::END_POINT . "{$api_version}/{$method}{$dot_output}";
45
+
46
+ switch ($http) {
47
+
48
+ case 'GET':
49
+
50
+ $url .= '?' . http_build_query($args);
51
+ $response = $this->http_request($url, array(),'GET');
52
+ break;
53
+
54
+ case 'POST':
55
+ $response = $this->http_request($url, $args, 'POST');
56
+ break;
57
+
58
+ default:
59
+ throw new Mandrill_Exception('Unknown request type');
60
+ }
61
+
62
+ $response_code = $response['header']['http_code'];
63
+ $body = $response['body'];
64
+
65
+ switch ($output) {
66
+
67
+ case 'json':
68
+
69
+ $body = json_decode($body, true);
70
+ break;
71
+
72
+ case 'php':
73
+
74
+ $body = unserialize($body);
75
+ break;
76
+ }
77
+
78
+ if( 200 == $response_code ) {
79
+
80
+ return $body;
81
+ }
82
+ else {
83
+
84
+ $message = isset( $body['message'] ) ? $body['message'] : '' ;
85
+
86
+ throw new Mandrill_Exception($message . ' - ' . $body, $response_code);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * @link https://mandrillapp.com/api/docs/users.html#method=ping
92
+ *
93
+ * @return array|Mandrill_Exception
94
+ */
95
+ function users_ping() {
96
+
97
+ return $this->request('users/ping');
98
+ }
99
+
100
+ /**
101
+ * @link https://mandrillapp.com/api/docs/users.html#method=info
102
+ *
103
+ * @return array|Mandrill_Exception
104
+ */
105
+ function users_info() {
106
+
107
+ return $this->request('users/info');
108
+ }
109
+
110
+ /**
111
+ * @link https://mandrillapp.com/api/docs/users.html#method=senders
112
+ *
113
+ * @return array|Mandrill_Exception
114
+ */
115
+ function users_senders() {
116
+
117
+ return $this->request('users/senders');
118
+ }
119
+
120
+ /**
121
+ * @link https://mandrillapp.com/api/docs/users.html#method=disable-sender
122
+ *
123
+ * @return array|Mandrill_Exception
124
+ */
125
+ function users_disable_sender($domain) {
126
+
127
+ return $this->request('users/disable-senders', array('domain' => $domain) );
128
+ }
129
+
130
+ /**
131
+ * @link https://mandrillapp.com/api/docs/users.html#method=verify-sender
132
+ *
133
+ * @return array|Mandrill_Exception
134
+ */
135
+ function users_verify_sender($email) {
136
+
137
+ return $this->request('users/verify-senders', array('domain' => $email) );
138
+ }
139
+
140
+ /**
141
+ * @link https://mandrillapp.com/api/docs/senders.html#method=domains
142
+ *
143
+ * @return array|Mandrill_Exception
144
+ */
145
+ function senders_domains() {
146
+
147
+ return $this->request('senders/domains');
148
+ }
149
+
150
+ /**
151
+ * @link https://mandrillapp.com/api/docs/senders.html#method=list
152
+ *
153
+ * @return array|Mandrill_Exception
154
+ */
155
+ function senders_list() {
156
+
157
+ return $this->request('senders/list');
158
+ }
159
+
160
+ /**
161
+ * @link https://mandrillapp.com/api/docs/senders.html#method=info
162
+ *
163
+ * @return array|Mandrill_Exception
164
+ */
165
+ function senders_info($email) {
166
+
167
+ return $this->request('senders/info', array( 'address' => $email) );
168
+ }
169
+
170
+ /**
171
+ * @link https://mandrillapp.com/api/docs/senders.html#method=time-series
172
+ *
173
+ * @return array|Mandrill_Exception
174
+ */
175
+ function senders_time_series($email) {
176
+
177
+ return $this->request('senders/time-series', array( 'address' => $email) );
178
+ }
179
+
180
+ /**
181
+ * @link https://mandrillapp.com/api/docs/tags.html#method=list
182
+ *
183
+ * @return array|Mandrill_Exception
184
+ */
185
+ function tags_list() {
186
+
187
+ return $this->request('tags/list');
188
+ }
189
+
190
+ /**
191
+ * @link https://mandrillapp.com/api/docs/tags.html#method=info
192
+ *
193
+ * @return array|Mandrill_Exception
194
+ */
195
+ function tags_info($tag) {
196
+
197
+ return $this->request('tags/info', array( 'tag' => $tag) );
198
+ }
199
+
200
+ /**
201
+ * @link https://mandrillapp.com/api/docs/tags.html#method=time-series
202
+ *
203
+ * @return array|Mandrill_Exception
204
+ */
205
+ function tags_time_series($tag) {
206
+
207
+ return $this->request('tags/time-series', array( 'tag' => $tag) );
208
+ }
209
+
210
+ /**
211
+ * @link https://mandrillapp.com/api/docs/tags.html#method=all-time-series
212
+ *
213
+ * @return array|Mandrill_Exception
214
+ */
215
+ function tags_all_time_series() {
216
+
217
+ return $this->request('tags/all-time-series');
218
+ }
219
+
220
+ /**
221
+ * @link https://mandrillapp.com/api/docs/templates.html#method=add
222
+ *
223
+ * @return array|Mandrill_Exception
224
+ */
225
+ function templates_add($name, $code) {
226
+
227
+ return $this->request('templates/add', array('name' => $name, 'code' => $code) );
228
+ }
229
+
230
+ /**
231
+ * @link https://mandrillapp.com/api/docs/templates.html#method=update
232
+ *
233
+ * @return array|Mandrill_Exception
234
+ */
235
+ function templates_update($name, $code) {
236
+
237
+ return $this->request('templates/update', array('name' => $name, 'code' => $code) );
238
+ }
239
+
240
+ /**
241
+ * @link https://mandrillapp.com/api/docs/templates.html#method=delete
242
+ *
243
+ * @return array|Mandrill_Exception
244
+ */
245
+ function templates_delete($name) {
246
+
247
+ return $this->request('templates/delete', array('name' => $name) );
248
+ }
249
+
250
+ /**
251
+ * @link https://mandrillapp.com/api/docs/templates.html#method=info
252
+ *
253
+ * @return array|Mandrill_Exception
254
+ */
255
+ function templates_info($name) {
256
+
257
+ return $this->request('templates/info', array('name' => $name) );
258
+ }
259
+
260
+ /**
261
+ * @link https://mandrillapp.com/api/docs/templates.html#method=list
262
+ *
263
+ * @return array|Mandrill_Exception
264
+ */
265
+ function templates_list() {
266
+
267
+ return $this->request('templates/list');
268
+ }
269
+
270
+ /**
271
+ * @link https://mandrillapp.com/api/docs/templates.html#method=time-series
272
+ *
273
+ * @return array|Mandrill_Exception
274
+ */
275
+ function templates_time_series($name) {
276
+
277
+ return $this->request('templates/time-series', array('name' => $name) );
278
+ }
279
+
280
+ /**
281
+ * @link https://mandrillapp.com/api/docs/urls.html#method=list
282
+ *
283
+ * @return array|Mandrill_Exception
284
+ */
285
+ function urls_list() {
286
+
287
+ return $this->request('urls/list');
288
+ }
289
+
290
+ /**
291
+ * @link https://mandrillapp.com/api/docs/urls.html#method=time-series
292
+ *
293
+ * @return array|Mandrill_Exception
294
+ */
295
+ function urls_time_series($name) {
296
+
297
+ return $this->request('urls/time-series', array('name' => $name) );
298
+ }
299
+
300
+ /**
301
+ * @link https://mandrillapp.com/api/docs/urls.html#method=search
302
+ *
303
+ * @return array|Mandrill_Exception
304
+ */
305
+ function urls_search($q) {
306
+
307
+ return $this->request('urls/search', array('q' => $q) );
308
+ }
309
+
310
+ /**
311
+ * @link https://mandrillapp.com/api/docs/webhooks.html#method=add
312
+ *
313
+ * @return array|Mandrill_Exception
314
+ */
315
+ function webhooks_add($url, $events) {
316
+
317
+ return $this->request('webhooks/add', array('url' => $url, 'events' => $events) );
318
+ }
319
+
320
+ /**
321
+ * @link https://mandrillapp.com/api/docs/webhooks.html#method=update
322
+ *
323
+ * @return array|Mandrill_Exception
324
+ */
325
+ function webhooks_update($url, $events) {
326
+
327
+ return $this->request('webhooks/update', array('url' => $url, 'events' => $events) );
328
+ }
329
+
330
+ /**
331
+ * @link https://mandrillapp.com/api/docs/webhooks.html#method=delete
332
+ *
333
+ * @return array|Mandrill_Exception
334
+ */
335
+ function webhooks_delete($id) {
336
+
337
+ return $this->request('webhooks/delete', array('id' => $id) );
338
+ }
339
+
340
+ /**
341
+ * @link https://mandrillapp.com/api/docs/webhooks.html#method=info
342
+ *
343
+ * @return array|Mandrill_Exception
344
+ */
345
+ function webhooks_info($id) {
346
+
347
+ return $this->request('webhooks/info', array('id' => $id) );
348
+ }
349
+
350
+ /**
351
+ * @link https://mandrillapp.com/api/docs/webhooks.html#method=list
352
+ *
353
+ * @return array|Mandrill_Exception
354
+ */
355
+ function webhooks_list() {
356
+ return $this->request('webhooks/list');
357
+ }
358
+
359
+ /**
360
+ * @link https://mandrillapp.com/api/docs/messages.html#method=search
361
+ *
362
+ * @return array|Mandrill_Exception
363
+ */
364
+ function messages_search($query, $date_from = '', $date_to = '', $tags = array(), $senders = array(), $limit = 100) {
365
+ return $this->request('messages/search', compact('query', 'date_from', 'date_to', 'tags', 'senders', 'limit'));
366
+ }
367
+
368
+ /**
369
+ * @link https://mandrillapp.com/api/docs/messages.html#method=send
370
+ *
371
+ * @return array|Mandrill_Exception
372
+ */
373
+ function messages_send($message) {
374
+ return $this->request('messages/send', array('message' => $message) );
375
+ }
376
+
377
+ /**
378
+ * @link https://mandrillapp.com/api/docs/messages.html#method=send-template
379
+ *
380
+ * @return array|Mandrill_Exception
381
+ */
382
+ function messages_send_template($template_name, $template_content, $message) {
383
+ return $this->request('messages/send-template', compact('template_name', 'template_content','message') );
384
+ }
385
+
386
+ function http_request($url, $fields = array(), $method = 'POST') {
387
+ if( !ini_get('safe_mode') ){
388
+ set_time_limit(60 * 60);
389
+ }
390
+
391
+ if ( !in_array( $method, array('POST','GET') ) ) $method = 'POST';
392
+ if ( !isset( $fields['key']) ) $fields['key'] = $this->api;
393
+
394
+ $ch = curl_init();
395
+ curl_setopt($ch, CURLOPT_URL, $url);
396
+
397
+ curl_setopt($ch, CURLOPT_POST, $method == 'POST');
398
+
399
+ curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($fields) ? http_build_query($fields) : $fields);
400
+
401
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
402
+ curl_setopt($ch, CURLOPT_HEADER, false);
403
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
404
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60 * 60 * 1000);
405
+
406
+ $response = curl_exec($ch);
407
+ $info = curl_getinfo($ch);
408
+ $error = curl_error($ch);
409
+
410
+ curl_close($ch);
411
+
412
+ return array('header' => $info, 'body' => $response, 'error' => $error);
413
+ }
414
+
415
+ static function getAttachmentStruct($path) {
416
+
417
+ $struct = array();
418
+
419
+ try {
420
+
421
+ if ( !@is_file($path) ) throw new Exception($path.' is not a valid file.');
422
+
423
+ $filename = basename($path);
424
+
425
+ if ( !function_exists('get_magic_quotes') ) {
426
+ function get_magic_quotes() { return false; }
427
+ }
428
+ if ( !function_exists('st_magic_quotes') ) {
429
+ function set_magic_quotes($value) { return true;}
430
+ }
431
+
432
+ if (strnatcmp(phpversion(),'6') >= 0) {
433
+ $magic_quotes = get_magic_quotes_runtime();
434
+ set_magic_quotes_runtime(0);
435
+ }
436
+
437
+ $file_buffer = file_get_contents($path);
438
+ $file_buffer = chunk_split(base64_encode($file_buffer), 76, "\n");
439
+
440
+ if (strnatcmp(phpversion(),'6') >= 0) set_magic_quotes_runtime($magic_quotes);
441
+
442
+ if (strnatcmp(phpversion(),'5.3') >= 0) {
443
+ $finfo = finfo_open(FILEINFO_MIME_TYPE);
444
+ $mime_type = finfo_file($finfo, $path);
445
+ } else {
446
+ $mime_type = mime_content_type($path);
447
+ }
448
+
449
+ if ( !Mandrill::isValidContentType($mime_type) )
450
+ throw new Exception($mime_type.' is not a valid content type (it should be '.implode('*,', self::getValidContentTypes() ).').');
451
+
452
+ $struct['type'] = $mime_type;
453
+ $struct['name'] = $filename;
454
+ $struct['content'] = $file_buffer;
455
+
456
+ } catch (Exception $e) {
457
+ throw new Mandrill_Exception('Error creating the attachment structure: '.$e->getMessage());
458
+ }
459
+
460
+ return $struct;
461
+ }
462
+
463
+ static function isValidContentType($ct) {
464
+ $valids = self::getValidContentTypes();
465
+
466
+ foreach ( $valids as $vct ) {
467
+ if ( strpos($ct, $vct) !== false ) return true;
468
+ }
469
+
470
+ return false;
471
+ }
472
+
473
+ static function getValidContentTypes() {
474
+ return array(
475
+ 'image/',
476
+ 'text/',
477
+ 'application/pdf',
478
+ );
479
+ }
480
+ }
481
+ ?>
trunk/readme.txt ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === wpMandrill ===
2
+ Contributors: MC_Will
3
+ Tags: mandrill, mailchimp, transactional email, email, email reliability, smtp, wp_mail, email templates
4
+ Requires at least: 3.0
5
+ Tested up to: 3.3.2
6
+ Stable tag: trunk
7
+
8
+ The wpMandrill plugin sends emails that are generated by WordPress through Mandrill, a transactional email service powered by MailChimp.
9
+ ** SE HABLA ESPAÑOL **
10
+
11
+ == Description ==
12
+
13
+ This plugin uses [Mandrill API](http://mandrillapp.com/api/docs/) to send outgoing emails from your Wordpress installation. It replaces the wp_mail function included with WordPress.
14
+
15
+ Emails are tracked and automatically tagged for statistics within the Mandrill Dashboard. You can also add general tags to every email sent, as well as particular tags based on selected emails defined by your requirements.
16
+
17
+ You can send certain types of attachments (image/*, text/* and application/pdf).
18
+
19
+ You can also use your own templates that have been added to your MailChimp account and shared with your Mandrill account.
20
+
21
+ There are a few levels of integrations between your WordPress installation and this plugin:
22
+
23
+ 1. The simplest option: Install it, configure it, and wpMandrill will start sending your emails through Mandrill.
24
+ 1. If you need to fine tune certain emails, you can change any email by creating a filter for the **mandrill_payload** hook.
25
+ 1. For further customization, we've exposed a function that allows you to send emails from within your plugins, instead of the regular wp_mail function: **wpMandrill::mail**
26
+ 1. If you need Mandrill Powers, we've included a full-featured class in the file lib/mandrill.class.php, where you'll find every call that can be done through the Mandrill API.
27
+
28
+ This plugin is currently released as **beta** for early adopter evaluation and finalizing of the initial feature set.
29
+
30
+ == Installation ==
31
+
32
+ 1. Upload `wpMandrill` to the `/wp-content/plugins/` directory
33
+ 1. Activate the plugin through the _Plugins_ menu in WordPress
34
+ 1. Configure plugin in _Settings > Mandrill_
35
+
36
+ == Frequently Asked Questions ==
37
+
38
+ = Why do I need a Mandrill API key? =
39
+
40
+ In order to use this plugin, you have to provide one of your Mandrill API keys. That's currently the only way we can get access to your Mandrill account.
41
+
42
+ = Do I need a MailChimp account? =
43
+
44
+ Not anymore! Mandrill is now officially in open beta to anyone so go get a [new account now!](http://mandrillapp.com/).
45
+
46
+ = Is all email routed through Mandrill? =
47
+
48
+ Yes. We try to send every single email sent through your WordPress installation. We also try to process your headers and attachments.
49
+
50
+ If the sending fails for any reason, the plugin will try to send it again using the WordPress wp_mail function.
51
+
52
+ == Screenshots ==
53
+
54
+ 1. Settings screen
55
+ 2. Statistics
56
+ 3. Dashboard widget
57
+
58
+ == Changelog ==
59
+
60
+ = 1.0 =
61
+ * Public release
62
+
63
+ = 1.01 =
64
+ * Removing How-To Plugin
65
+ * Adding How-To page
66
+
67
+ = 1.02 =
68
+ * Fixed: Dashboard widget title was displaying incorrectly when a filter was defined.
69
+
70
+ = 1.03 =
71
+ * Fixed: Test email were using an old function.
72
+ * Fixed: Some data type checking to avoid PHP warnings.
73
+
74
+ = 1.05 =
75
+ * Fixed: Contextual help tab getting open in all admin pages when plugin was not configured correctly.
76
+ * Fixed: Some references to verified domains. All domains are now verified in Mandrill.
77
+ * Fixed: Mandrill Class was returning Exceptions in two places (not throwing them).
trunk/screenshot-1.png ADDED
Binary file
trunk/screenshot-2.png ADDED
Binary file
trunk/screenshot-3.png ADDED
Binary file
trunk/stats.php ADDED
@@ -0,0 +1,366 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!current_user_can('manage_options')) wp_die( __('You do not have sufficient permissions to access this page.') ); ?>
2
+ <div class="wrap">
3
+ <div class="icon32" style="background: url('<?php echo plugins_url('images/mandrill-head-icon.png',__FILE__); ?>');"><br /></div>
4
+ <h2><?php _e('Mandrill Service Report', wpMandrill::WPDOMAIN); ?></h2><?php
5
+
6
+ $stats = self::getCurrentStats();
7
+ if ( empty($stats) ) {
8
+ echo '<p>' . __('There was a problem retrieving statistics.', self::WPDOMAIN) . '</p>';
9
+ echo '</div>';
10
+ return;
11
+ }
12
+
13
+ $delivered = $stats['general']['stats']['sent'] -
14
+ $stats['general']['stats']['hard_bounces'] -
15
+ $stats['general']['stats']['soft_bounces'] -
16
+ $stats['general']['stats']['rejects'];
17
+
18
+ $lit = array();
19
+
20
+ $lit['hourly']['title'] = __('Hourly Sending Volume and Open/Click Rate',self::WPDOMAIN);
21
+ $lit['hourly']['Xtitle'] = __('Hours',self::WPDOMAIN);
22
+ $lit['hourly']['tooltip'] = __('Hour',self::WPDOMAIN);
23
+
24
+ $lit['daily']['title'] = __('Daily Sending Volume and Open/Click Rate',self::WPDOMAIN);
25
+ $lit['daily']['Xtitle'] = __('Days',self::WPDOMAIN);
26
+ $lit['daily']['tooltip'] = __('Day',self::WPDOMAIN);
27
+
28
+ $lit['subtitle'] = __('in the last 30 days',self::WPDOMAIN);
29
+ $lit['Ytitle'] = __('Open & Click Rate',self::WPDOMAIN);
30
+ $lit['SerieName'] = __('Volume',self::WPDOMAIN);
31
+ $lit['emails'] = __('emails',self::WPDOMAIN);
32
+ $lit['openrate'] = __('Open Rate',self::WPDOMAIN);
33
+ $lit['clickrate'] = __('Click Rate',self::WPDOMAIN);
34
+
35
+ ?>
36
+ <div id="alltime_report">
37
+ <h3><?php echo sprintf(__('All-time statistics since %s: ', wpMandrill::WPDOMAIN),date('m/d/Y',strtotime($stats['general']['created_at']))); ?></h3>
38
+
39
+ <div id="alltime_report_canvas">
40
+ <div class="stat_box"><?php _e('Reputation:', wpMandrill::WPDOMAIN); ?><br/><span><?=$stats['general']['reputation']?>%</span></div>
41
+ <div class="stat_box"><?php _e('Quota:', wpMandrill::WPDOMAIN); ?><br/><span><?=$stats['general']['hourly_quota']?> <?php _e('sends/hour', wpMandrill::WPDOMAIN); ?></span></div>
42
+ <div class="stat_box"><?php _e('Emails sent:', wpMandrill::WPDOMAIN); ?><br/><span><?=$stats['general']['stats']['sent']?></span></div>
43
+ <div class="stat_box"><?php _e('Emails delivered:', wpMandrill::WPDOMAIN); ?><br/><span><?=$delivered?> (<?=$delivered*100/($stats['general']['stats']['sent']?$stats['general']['stats']['sent']:1)?>%)</span></div>
44
+ <div class="stat_box"><?php _e('Tracked opens:', wpMandrill::WPDOMAIN); ?><br/><span><?=$stats['general']['stats']['opens']?></span></div>
45
+ <div class="stat_box"><?php _e('Tracked clicks:', wpMandrill::WPDOMAIN); ?><br/><span><?=$stats['general']['stats']['clicks']?></span></div>
46
+ <?php
47
+ if ( $stats['general']['stats']['rejects'] ) echo '<div class="stat_box warning">'.__('Rejects:', wpMandrill::WPDOMAIN).'<br/><span>'.$stats['general']['stats']['rejects'].'</span></div>';
48
+ if ( $stats['general']['stats']['complaints'] ) echo '<div class="stat_box warning">'.__('Complaints:', wpMandrill::WPDOMAIN).'<br/><span>'.$stats['general']['stats']['complaints'].'</span></div>';
49
+ if ( $stats['general']['backlog'] ) echo '<div class="stat_box warning">'.__('Current backlog:', wpMandrill::WPDOMAIN).'<br/><span>'.$stats['general']['backlog'].' emails</span></div>';
50
+ ?>
51
+ </div>
52
+ </div>
53
+
54
+ <div style="clear: both;"></div>
55
+ <div id="filtered_reports">
56
+ <h3><?php _e('Filtered statistics:', wpMandrill::WPDOMAIN); ?></h3>
57
+ <label for="filter"><?php _e('Filter by:', wpMandrill::WPDOMAIN); ?> </label>
58
+ <select id="filter" name="filter">
59
+ <option value="none" selected="selected" ><?php _e('No filter', wpMandrill::WPDOMAIN); ?></option>
60
+ <optgroup label="<?php _e('Sender:', wpMandrill::WPDOMAIN); ?>">
61
+ <?php
62
+ foreach ( array_keys($stats['stats']['hourly']['senders']) as $sender) {
63
+ echo '<option value="s:'.$sender.'">'.$sender.'</option>';
64
+ }
65
+ ?>
66
+ </optgroup>
67
+ <optgroup label="<?php _e('Tag:', wpMandrill::WPDOMAIN); ?>">
68
+ <?php
69
+ if ( isset($stats['stats']['hourly']['tags']['detailed_stats'])
70
+ && is_array($stats['stats']['hourly']['tags']['detailed_stats']) ) {
71
+
72
+ foreach ( array_keys($stats['stats']['hourly']['tags']['detailed_stats']) as $tag) {
73
+ echo '<option value="'.$tag.'">'.$tag.'</option>';
74
+ }
75
+
76
+ }
77
+ ?>
78
+ </optgroup>
79
+ </select>
80
+ <label for="display"><?php _e('Display:', wpMandrill::WPDOMAIN); ?> </label>
81
+ <select id="display" name="display">
82
+ <option value="volume"><?php _e('Total Volume per Period', wpMandrill::WPDOMAIN); ?></option>
83
+ <option value="average"><?php _e('Average Volume per Period', wpMandrill::WPDOMAIN); ?></option>
84
+ </select><div id="ajax-icon-container"><span id="loading_data" class="hidden"></span></div>
85
+ <div id="filtered_reports_canvas">
86
+ <div id="filtered_recent" style="width: 50%;float: left;"></div>
87
+ <div id="filtered_oldest" style="width: 50%;float: left;"></div>
88
+ </div>
89
+ <div style="clear: both;"></div>
90
+ </div>
91
+ <br/><br/>
92
+ <div id="hourly_report">
93
+ <script type="text/javascript">
94
+ jQuery(function () {
95
+ var chart;
96
+ jQuery(document).ready(function() {
97
+ chart = new Highcharts.Chart({
98
+ chart: {
99
+ renderTo: 'hourly_report_canvas',
100
+ zoomType: 'xy',
101
+ spacingBottom: 30
102
+ },
103
+ exporting: {
104
+ enabled: true,
105
+ },
106
+ title: {
107
+ text: '<?php echo $lit['hourly']['title']; ?>'
108
+ },
109
+ subtitle: {
110
+ text: '<?php echo $lit['subtitle']; ?>'
111
+ },
112
+ xAxis: [{
113
+ categories: [<?=implode(',',array_keys($stats['graph']['hourly']['delivered']));?>],
114
+ title: {
115
+ enabled: true,
116
+ text: '<?php echo $lit['hourly']['Xtitle']; ?>',
117
+ style: {
118
+ fontWeight: 'normal'
119
+ }
120
+ }
121
+ }],
122
+ yAxis: [{
123
+ min: 0,
124
+ max: 100,
125
+ labels: {
126
+ formatter: function() {
127
+ return this.value +'%';
128
+ },
129
+ style: {
130
+ color: '#666666'
131
+ }
132
+ },
133
+ title: {
134
+ text: '<?php echo $lit['Ytitle']; ?>',
135
+ style: {
136
+ color: '#666666'
137
+ }
138
+ }
139
+ }, {
140
+ title: {
141
+ text: '<?php echo $lit['SerieName']; ?>',
142
+ style: {
143
+ color: '#4572A7'
144
+ }
145
+ },
146
+ labels: {
147
+ formatter: function() {
148
+ return this.value +' <?php echo $lit['emails']; ?>';
149
+ },
150
+ style: {
151
+ color: '#4572A7'
152
+ }
153
+ },
154
+ opposite: true
155
+ }],
156
+ tooltip: {
157
+ formatter: function() {
158
+ return '<?php echo $lit['hourly']['tooltip']; ?> '+
159
+ this.x +': '+ this.y +
160
+ (this.series.name == '<?php echo $lit['SerieName']; ?>' ? ' <?php echo $lit['emails']; ?>' : '%');
161
+ }
162
+ },
163
+ plotOptions: {
164
+ column: {
165
+ fillOpacity: 0.5
166
+ }
167
+ },
168
+ credits: {
169
+ enabled: false,
170
+ href: "http://www.mandrillapp.com/",
171
+ text: "MandrillApp.com"
172
+ },
173
+ legend: {
174
+ align: 'right',
175
+ x: -100,
176
+ verticalAlign: 'top',
177
+ y: 20,
178
+ floating: true,
179
+ backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || 'white',
180
+ borderColor: '#CCC',
181
+ borderWidth: 1,
182
+ shadow: false
183
+ },
184
+ series: [{
185
+ name: 'Volume',
186
+ color: '#4572A7',
187
+ type: 'column',
188
+ yAxis: 1,
189
+ data: [<?=implode(',',$stats['graph']['hourly']['delivered']);?>],
190
+ dataLabels: {
191
+ enabled: true,
192
+ rotation: -90,
193
+ color: '#FFFFFF',
194
+ align: 'right',
195
+ x: -3,
196
+ y: 10,
197
+ formatter: function() {
198
+ return this.y;
199
+ },
200
+ style: {
201
+ font: 'normal 13px Verdana, sans-serif'
202
+ }
203
+ },
204
+ }, {
205
+ name: '<?php echo $lit['openrate']; ?>',
206
+ color: '#89A54E',
207
+ type: 'spline',
208
+ data: [<?=implode(',',$stats['graph']['hourly']['open_rate']);?>]
209
+ }, {
210
+ name: '<?php echo $lit['clickrate']; ?>',
211
+ color: '#deA54E',
212
+ type: 'spline',
213
+ data: [<?=implode(',',$stats['graph']['hourly']['click_rate']);?>]
214
+ }]
215
+ });
216
+ });
217
+ chart = new Highcharts.Chart({
218
+ chart: {
219
+ renderTo: 'daily_report_canvas',
220
+ zoomType: 'xy',
221
+ spacingBottom: 30
222
+ },
223
+ title: {
224
+ text: '<?php echo $lit['daily']['title']; ?>'
225
+ },
226
+ subtitle: {
227
+ text: '<?php echo $lit['subtitle']; ?>'
228
+ },
229
+ xAxis: [{
230
+ categories: [<?=implode(',',array_keys($stats['graph']['daily']['delivered']));?>],
231
+ title: {
232
+ enabled: true,
233
+ text: '<?php echo $lit['daily']['Xtitle']; ?>',
234
+ style: {
235
+ fontWeight: 'normal'
236
+ }
237
+ },
238
+ labels: {
239
+ rotation: -45,
240
+ align: 'right',
241
+ style: {
242
+ font: 'normal 13px Verdana, sans-serif'
243
+ }
244
+ }
245
+ }],
246
+ yAxis: [{
247
+ min: 0,
248
+ max: 100,
249
+ labels: {
250
+ formatter: function() {
251
+ return this.value +'%';
252
+ },
253
+ style: {
254
+ color: '#666666'
255
+ }
256
+ },
257
+ title: {
258
+ text: '<?php echo $lit['Ytitle']; ?>',
259
+ style: {
260
+ color: '#666666'
261
+ }
262
+ }
263
+ }, {
264
+ title: {
265
+ text: '<?php echo $lit['SerieName']; ?>',
266
+ style: {
267
+ color: '#4572A7'
268
+ }
269
+ },
270
+ dataLabels: {
271
+ enabled: true,
272
+ rotation: -90,
273
+ color: '#FFFFFF',
274
+ align: 'right',
275
+ x: -3,
276
+ y: 10,
277
+ formatter: function() {
278
+ return this.y;
279
+ },
280
+ style: {
281
+ font: 'normal 13px Verdana, sans-serif'
282
+ }
283
+ },
284
+ labels: {
285
+ formatter: function() {
286
+ return this.value +' <?php echo $lit['emails']; ?>';
287
+ },
288
+ style: {
289
+ color: '#4572A7'
290
+ }
291
+ },
292
+ opposite: true
293
+ }],
294
+ tooltip: {
295
+ formatter: function() {
296
+ return '<?php echo $lit['daily']['tooltip']; ?> '+
297
+ this.x +': '+ this.y +
298
+ (this.series.name == '<?php echo $lit['SerieName']; ?>' ? ' <?php echo $lit['emails']; ?>' : '%');
299
+ }
300
+ },
301
+ plotOptions: {
302
+ column: {
303
+ fillOpacity: 0.5
304
+ }
305
+ },
306
+ credits: {
307
+ enabled: false,
308
+ href: "http://www.mandrillapp.com/",
309
+ text: "MandrillApp.com"
310
+ },
311
+ legend: {
312
+ align: 'right',
313
+ x: -100,
314
+ verticalAlign: 'top',
315
+ y: 20,
316
+ floating: true,
317
+ backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || 'white',
318
+ borderColor: '#CCC',
319
+ borderWidth: 1,
320
+ shadow: false
321
+ },
322
+ series: [{
323
+ name: '<?php echo $lit['SerieName']; ?>',
324
+ color: '#4572A7',
325
+ type: 'column',
326
+ yAxis: 1,
327
+ data: [<?=implode(',',$stats['graph']['daily']['delivered']);?>],
328
+ dataLabels: {
329
+ enabled: true,
330
+ rotation: -90,
331
+ color: '#FFFFFF',
332
+ align: 'right',
333
+ x: -3,
334
+ y: 10,
335
+ formatter: function() {
336
+ return this.y;
337
+ },
338
+ style: {
339
+ font: 'normal 13px Verdana, sans-serif'
340
+ }
341
+ },
342
+ }, {
343
+ name: '<?php echo $lit['openrate']; ?>',
344
+ color: '#89A54E',
345
+ type: 'spline',
346
+ data: [<?=implode(',',$stats['graph']['daily']['open_rate']);?>]
347
+ }, {
348
+ name: '<?php echo $lit['clickrate']; ?>',
349
+ color: '#deA54E',
350
+ type: 'spline',
351
+ data: [<?=implode(',',$stats['graph']['daily']['click_rate']);?>]
352
+ }]
353
+ });
354
+ });
355
+ </script>
356
+ <div id="hourly_report_canvas"></div><br/><br/>
357
+ <div id="daily_report_canvas"></div>
358
+ <h3><a href="http://mandrillapp.com/" target="_target"><?php _e('For more detailed statistics, please visit your Mandrill Dashboard',self::WPDOMAIN); ?></a>.
359
+ <?php // echo str_replace(' ','&nbsp;&nbsp;&nbsp;&nbsp;',nl2br(print_r($graph_data,true))); ?></h3>
360
+ </div>
361
+ <?php
362
+
363
+ // echo "<div style=\"display:none;\">\n".print_r($stats,true) . "\n</div>";
364
+ wpMandrill::$stats = $stats;
365
+
366
+ ?>
trunk/uninstall.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if( !defined( 'WP_UNINSTALL_PLUGIN' ) )
4
+ exit();
5
+
6
+ delete_option( 'wpmandrill' );
7
+ delete_option( 'wpmandrill-test' );
8
+ delete_transient('mandrill-stats');
9
+ ?>
trunk/wpmandrill.php ADDED
@@ -0,0 +1,1729 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: wpMandrill
4
+ Description: wpMandrill sends emails, generated by WordPress using Mandrill.
5
+ Author: Mandrill
6
+ Author URI: http://mandrillapp.com/
7
+ Plugin URI: http://connect.mailchimp.com/integrations/wpmandrill
8
+ Version: 1.05
9
+ Text Domain: wpmandrill
10
+ */
11
+
12
+ wpMandrill::on_load();
13
+
14
+ class wpMandrill {
15
+ const WPDOMAIN = 'wpmandrill';
16
+
17
+ static $settings;
18
+ static $report;
19
+ static $stats;
20
+ static $mandrill;
21
+ static $conflict;
22
+ static $error;
23
+
24
+ static function on_load() {
25
+
26
+ define('WPMANDRILL_API_VERSION', '1.0');
27
+
28
+ add_action('admin_init', array(__CLASS__, 'adminInit'));
29
+ add_action('admin_menu', array(__CLASS__, 'adminMenu'));
30
+
31
+ add_filter('contextual_help', array(__CLASS__, 'showContextualHelp'), 10, 3);
32
+
33
+ add_action('admin_print_footer_scripts', array(__CLASS__,'openContextualHelp'));
34
+ add_action('wp_ajax_get_mandrill_stats', array(__CLASS__,'getAjaxStats'));
35
+ add_action('wp_ajax_get_dashboard_widget_stats', array(__CLASS__,'showDashboardWidget'));
36
+
37
+ load_plugin_textdomain(self::WPDOMAIN, false, dirname( plugin_basename( __FILE__ ) ).'/lang');
38
+
39
+ try {
40
+
41
+ require_once( plugin_dir_path( __FILE__ ) . '/lib/mandrill.class.php');
42
+ $api_key = self::getAPIKey();
43
+ if ( $api_key && !isset(self::$mandrill) ) self::$mandrill = new Mandrill($api_key);
44
+
45
+ } catch ( Exception $e ) {
46
+ if ( $api_key ) {
47
+ self::$error = $e->getMessage();
48
+ add_action('admin_notices', array(__CLASS__, 'adminNoticeError'));
49
+ }
50
+ }
51
+
52
+ if( function_exists('wp_mail') ) {
53
+ self::$conflict = true;
54
+ add_action('admin_notices', array(__CLASS__, 'adminNotices'));
55
+ return;
56
+ }
57
+
58
+ self::$conflict = false;
59
+ if( self::isReady() ) {
60
+
61
+ function wp_mail( $to, $subject, $message, $headers = '', $attachments = array() ) {
62
+
63
+ try {
64
+
65
+ $sent = self::mail( $to, $subject, $message, $headers, $attachments );
66
+
67
+ if ( is_wp_error($sent)
68
+ || !isset($sent[0]['status'])
69
+ || ( isset($sent[0]['status']) && 'sent' != $sent[0]['status'] ) ) {
70
+
71
+ return self::wp_mail_native( $to, $subject, $message, $headers, $attachments );
72
+ }
73
+
74
+ return true;
75
+ } catch ( Exception $e ) {
76
+ return self::wp_mail_native( $to, $subject, $message, $headers, $attachments );
77
+ }
78
+ }
79
+ }
80
+
81
+ }
82
+
83
+ /**
84
+ * Sets up options page and sections.
85
+ */
86
+ static function adminInit() {
87
+
88
+ add_filter('plugin_action_links',array(__CLASS__,'showPluginActionLinks'), 10,5);
89
+ add_action('admin_enqueue_scripts', array(__CLASS__,'showAdminEnqueueScripts'));
90
+
91
+ register_setting(self::WPDOMAIN, self::WPDOMAIN, array(__CLASS__,'formValidate'));
92
+
93
+ // SMTP Settings
94
+ add_settings_section('wpmandrill-api', __('API Settings', self::WPDOMAIN), '__return_false', self::WPDOMAIN);
95
+ add_settings_field('api-key', __('API Key', self::WPDOMAIN), array(__CLASS__, 'askAPIKey'), self::WPDOMAIN, 'wpmandrill-api');
96
+
97
+ if( self::isConnected() ) {
98
+ add_action('wp_dashboard_setup', array( __CLASS__,'addDashboardWidgets') );
99
+
100
+ // Verified Addresses
101
+ add_settings_section('wpmandrill-addresses', __('Sender Settings', self::WPDOMAIN), '__return_false', self::WPDOMAIN);
102
+ add_settings_field('from-name', __('FROM Name', self::WPDOMAIN), array(__CLASS__, 'askFromName'), self::WPDOMAIN, 'wpmandrill-addresses');
103
+ add_settings_field('from-email', __('FROM Email', self::WPDOMAIN), array(__CLASS__, 'askFromEmail'), self::WPDOMAIN, 'wpmandrill-addresses');
104
+
105
+ // Template
106
+ add_settings_section('wpmandrill-templates', __('General Template', self::WPDOMAIN), '__return_false', self::WPDOMAIN);
107
+ add_settings_field('template', __('&nbsp;', self::WPDOMAIN), array(__CLASS__, 'askTemplate'), self::WPDOMAIN, 'wpmandrill-templates');
108
+
109
+ // Tags
110
+ add_settings_section('wpmandrill-tags', __('General Tags', self::WPDOMAIN), '__return_false', self::WPDOMAIN);
111
+ add_settings_field('tags', __('&nbsp;', self::WPDOMAIN), array(__CLASS__, 'askTags'), self::WPDOMAIN, 'wpmandrill-tags');
112
+
113
+ if ( self::isReady() ) {
114
+ // Email Test
115
+ register_setting('wpmandrill-test', 'wpmandrill-test', array(__CLASS__, 'sendTestEmail'));
116
+
117
+ add_settings_section('mandrill-email-test', __('Send a test email using these settings', self::WPDOMAIN), '__return_false', 'wpmandrill-test');
118
+ add_settings_field('email-to', __('Send to', self::WPDOMAIN), array(__CLASS__, 'askTestEmailTo'), 'wpmandrill-test', 'mandrill-email-test');
119
+ add_settings_field('email-subject', __('Subject', self::WPDOMAIN), array(__CLASS__, 'askTestEmailSubject'), 'wpmandrill-test', 'mandrill-email-test');
120
+ add_settings_field('email-message', __('Message', self::WPDOMAIN), array(__CLASS__, 'askTestEmailMessage'), 'wpmandrill-test', 'mandrill-email-test');
121
+ }
122
+
123
+ }
124
+ }
125
+
126
+ /**
127
+ * Creates option page's entry in Settings section of menu.
128
+ */
129
+ static function adminMenu() {
130
+
131
+ self::$settings = add_options_page(
132
+ __('Mandrill Settings', self::WPDOMAIN),
133
+ __('Mandrill', self::WPDOMAIN),
134
+ 'manage_options',
135
+ self::WPDOMAIN,
136
+ array(__CLASS__,'showOptionsPage')
137
+ );
138
+
139
+ if( self::isConnected() ) {
140
+ self::$report = add_dashboard_page(
141
+ __('Mandrill Reports', self::WPDOMAIN),
142
+ __('Mandrill Reports', self::WPDOMAIN),
143
+ 'manage_options',
144
+ self::WPDOMAIN.'-reports',
145
+ array(__CLASS__,'showReportPage')
146
+ );
147
+ if ( self::isPluginPage('-reports') ) {
148
+ wp_register_script('highcharts', plugins_url('/js/highcharts.js', __FILE__), array('jquery'), null, true);
149
+ wp_register_script('mandrill-report-export', plugins_url("js/modules/exporting.js", __FILE__), array('highcharts'), null, true);
150
+ wp_enqueue_script('highcharts');
151
+ wp_enqueue_script('mandrill-report-export');
152
+ }
153
+ }
154
+
155
+ wp_register_style( 'mandrill_stylesheet', plugins_url('/css/mandrill.css', __FILE__) );
156
+ wp_enqueue_style( 'mandrill_stylesheet' );
157
+ wp_register_script('mandrill', plugins_url('/js/mandrill.js', __FILE__), array(), null, true);
158
+ wp_enqueue_script('mandrill');
159
+ }
160
+
161
+
162
+ static function adminNotices() {
163
+ if ( self::$conflict ) {
164
+ echo '<div class="error"><p>'.__('Mandrill: wp_mail has been declared by another process or plugin, so you won\'t be able to use Mandrill until the problem is solved.', self::WPDOMAIN) . '</p></div>';
165
+ }
166
+ }
167
+
168
+ static function adminNoticeError() {
169
+ echo '<div class="error"><p>We found an error:<br/>'.self::$error.'</p></div>';
170
+ }
171
+
172
+ static function showAdminEnqueueScripts($hook_suffix) {
173
+ if( $hook_suffix == self::$report && self::isReady() ) {
174
+ wp_register_script('mandrill-report-theme', plugins_url("js/themes/gray.js", __FILE__), array(''), null, true);
175
+ wp_register_script('mandrill-report-script', plugins_url("js/mandrill.js", __FILE__), array('highcharts'), null, true);
176
+ wp_register_script('mandrill-report-export', plugins_url("js/modules/exporting.js", __FILE__), array('highcharts'), null, true);
177
+
178
+ wp_enqueue_script('mandrill-report-script');
179
+ wp_enqueue_script('mandrill-report-theme');
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Generates source of contextual help panel.
185
+ */
186
+ static function showContextualHelp($contextual_help, $screen_id, $screen) {
187
+ if ($screen_id == self::$settings) {
188
+ $dir = dirname( plugin_basename( __FILE__ ) ).'/images';
189
+
190
+ $ok = array();
191
+ $ok['account'] = ( !self::getAPIKey() ) ? ' class="missing"' : '';
192
+ $ok['domains'] = ( !self::ListVerifiedDomains() ) ? ' class="missing"' : '';
193
+ $ok['email'] = ( !self::getFromEmail() ) ? ' class="missing"' : '';
194
+
195
+ $requirements = '';
196
+ if ($ok['account'] . $ok['domains'] . $ok['email'] != '' ) {
197
+ $requirements = '<p>' . __('To use this plugin you will need:', self::WPDOMAIN) . '</p>'
198
+ . '<ol>'
199
+ . '<li'.$ok['account'].'>'. __('Your Mandrill account.', self::WPDOMAIN) . '</li>'
200
+ . '<li'.$ok['domains'].'>' . __('At least one domain defined in your Mandrill account.', self::WPDOMAIN) . '</li>'
201
+ . '<li'.$ok['email'].'>' . __('A valid sender email address.', self::WPDOMAIN) . '</li>'
202
+ . '</ol>';
203
+ }
204
+
205
+ return $requirements
206
+ . '<p>' . __('Once you have properly configured the settings, the plugin will take care of all the emails sent through your WordPress installation.', self::WPDOMAIN).'</p>'
207
+ . '<p>' . __('However, if you need to customize any part of the email before sending, you can do so by using the WordPress filter <strong>mandrill_payload</strong>.', self::WPDOMAIN).'</p>'
208
+ . '<p>' . __('This filter has the same structure as Mandrill\'s API call <a href="http://mandrillapp.com/api/docs/messages.html#method=send" target="_blank">/messages/send</a>, except that it can have one additional parameter when the email is based on a template. The parameter is called "<em>template</em>", which is an associative array of two elements (the first element, a string whose key is "<em>template_name</em>", and a second parameter whose key is "<em>template_content</em>". Its value is an array with the same structure of the parameter "<em>template_content</em>" in the call <a href="http://mandrillapp.com/api/docs/messages.html#method=send-template" target="_blank">/messages/send-template</a>.)', self::WPDOMAIN).'</p>'
209
+ . '<p>' . __('Note that if you\'re sending additional headers in your emails, the only valid headers are <em>From:</em>, <em>Reply-To:</em>, and <em>X-*:</em>. <em>Bcc:</em> is also valid, but Mandrill will send the blind carbon copy to only the first address, and the remaining will be silently discarted.', self::WPDOMAIN).'</p>'
210
+ . '<p>' . __('Also note that if any error occurs while sending the email, the plugin will try to send the message again using the native WordPress mailing capabilities.', self::WPDOMAIN).'</p>'
211
+ . '<p>' . __('Confirm that any change you made to the payload is in line with the <a href="http://mandrillapp.com/api/docs/" target="_blank">Mandrill\'s API\'s documentation</a>. Also, the <em>X-*:</em> headers, must be in line with the <a href="http://help.mandrill.com/customer/portal/articles/456744-smtp-headers-api" target="_blank">SMTP API documentation</a>. By using this plugin, you agree that you and your website will adhere to <a href="http://mandrill.com/legal/terms/" target="_blank">Mandrill\'s Terms of Use</a>.', self::WPDOMAIN).'</p>'
212
+ . '<p>' . __('if you have any question about Mandrill or this plugin, visit the <a href="http://help.mandrill.com/" target="_blank">Mandrill\'s Support Center</a>.', self::WPDOMAIN).'</p>'
213
+ ;
214
+ }
215
+
216
+ return $contextual_help;
217
+ }
218
+
219
+ /**
220
+ * Adds link to settings page in list of plugins
221
+ */
222
+ static function showPluginActionLinks($actions, $plugin_file) {
223
+ static $plugin;
224
+
225
+ if (!isset($plugin))
226
+ $plugin = plugin_basename(__FILE__);
227
+
228
+ if ($plugin == $plugin_file) {
229
+
230
+ $settings = array('settings' => '<a href="options-general.php?page=wpmandrill">' . __('Settings', self::WPDOMAIN) . '</a>');
231
+
232
+ if ( self::isReady() ) {
233
+ $report = array('report' => '<a href="index.php?page=wpmandrill-reports">' . __('Reports', self::WPDOMAIN) . '</a>');
234
+ $actions = array_merge($settings, $actions, $report);
235
+ } else {
236
+ $actions = array_merge($settings, $actions);
237
+ }
238
+
239
+ }
240
+
241
+ return $actions;
242
+ }
243
+
244
+ /**
245
+ * Generates source of options page.
246
+ */
247
+ static function showOptionsPage() {
248
+ if (!current_user_can('manage_options'))
249
+ wp_die( __('You do not have sufficient permissions to access this page.') );
250
+
251
+ if ( isset($_GET['show']) && $_GET['show'] == 'how-tos' ) {
252
+ self::showHowTos();
253
+ return;
254
+ }
255
+ ?>
256
+ <div class="wrap">
257
+ <div class="icon32" style="background: url('<?php echo plugins_url('images/mandrill-head-icon.png',__FILE__); ?>');"><br /></div>
258
+ <h2><?php _e('Mandrill Settings', self::WPDOMAIN); ?> <small><a href="options-general.php?page=<?=self::WPDOMAIN; ?>&show=how-tos">view how-tos</a></small></h2>
259
+
260
+ <div style="float: left;width: 70%;">
261
+ <form method="post" action="options.php">
262
+
263
+ <div class="stuffbox">
264
+ <?php settings_fields(self::WPDOMAIN); ?>
265
+ <?php do_settings_sections(self::WPDOMAIN); ?>
266
+ </div>
267
+
268
+ <p class="submit"><input type="submit" name="Submit" class="button-primary" value="<?php esc_attr_e('Save Changes') ?>" /></p>
269
+ </form>
270
+
271
+
272
+ <?php if( self::isReady() ) { ?>
273
+ <form method="post" action="options.php">
274
+ <div class="stuffbox" style="max-width: 90% !important;">
275
+ <?php settings_fields('wpmandrill-test'); ?>
276
+ <?php do_settings_sections('wpmandrill-test'); ?>
277
+ </div>
278
+
279
+ <p class="submit"><input type="submit" name="Submit" class="button-primary" value="<?php _e('Send Email', self::WPDOMAIN) ?>" /></p>
280
+ </form>
281
+ <?php } ?>
282
+
283
+ </div>
284
+
285
+ <div style="float: left;width: 20%;">
286
+ <?php
287
+ $rss = fetch_feed('http://mandrill.com/blog/feed');
288
+ $maxitems = 0;
289
+ if (!is_wp_error( $rss ) ) {
290
+ $maxitems = $rss->get_item_quantity(5);
291
+ $rss_items = $rss->get_items(0, $maxitems);
292
+ }
293
+
294
+ if ( $maxitems > 0 ) {
295
+ ?>
296
+ <div class="news mandrill">
297
+ <h3 class="news_header"><?php _e('Latest from Mandrill...', self::WPDOMAIN); ?></h3>
298
+ <ul>
299
+ <?php
300
+ foreach ( $rss_items as $item ) { ?>
301
+ <li>
302
+ <a href='<?php echo esc_url( $item->get_permalink() ); ?>'
303
+ title='<?php echo 'Posted '.$item->get_date('j F Y | g:i a'); ?>'>
304
+ <?php echo esc_html( $item->get_title() ); ?></a>
305
+ </li>
306
+ <?php } ?>
307
+ </ul>
308
+ </div>
309
+ <?php } ?>
310
+ <div class="news">
311
+ <h3 class="news_header"><?php _e('News from MailChimp...', self::WPDOMAIN); ?></h3><?php
312
+ $rss = fetch_feed('http://mailchimp.com/blog/feed');
313
+ if (!is_wp_error( $rss ) ) {
314
+ $maxitems = $rss->get_item_quantity(5);
315
+ $rss_items = $rss->get_items(0, $maxitems);
316
+ } ?>
317
+ <ul>
318
+ <?php if ($maxitems == 0) echo '<li>No news!</li>';
319
+ else
320
+ foreach ( $rss_items as $item ) { ?>
321
+ <li>
322
+ <a href='<?php echo esc_url( $item->get_permalink() ); ?>'
323
+ title='<?php echo 'Posted '.$item->get_date('j F Y | g:i a'); ?>'>
324
+ <?php echo esc_html( $item->get_title() ); ?></a>
325
+ </li>
326
+ <?php } ?>
327
+ </ul>
328
+ </div>
329
+ </div>
330
+ </div>
331
+ <?php
332
+ }
333
+
334
+ static function showHowTos() {
335
+ ?>
336
+ <div class="wrap">
337
+ <div class="icon32" style="background: url('<?php echo plugins_url('images/mandrill-head-icon.png',__FILE__); ?>');"><br /></div>
338
+ <h2><?php _e('Mandrill How-Tos', self::WPDOMAIN); ?> <small><a href="options-general.php?page=<?=self::WPDOMAIN; ?>">back to settings</a></small></h2>
339
+ <?php
340
+ require plugin_dir_path( __FILE__ ) . '/how-tos.php';
341
+
342
+ echo wpMandrill_HowTos::show('intro');
343
+ echo wpMandrill_HowTos::show('auto');
344
+ echo wpMandrill_HowTos::show('regular');
345
+ echo wpMandrill_HowTos::show('filter');
346
+ echo wpMandrill_HowTos::show('direct');
347
+
348
+ ?>
349
+ </div>
350
+ <?php
351
+ }
352
+
353
+ static function showReportPage() {
354
+ require plugin_dir_path( __FILE__ ) . '/stats.php';
355
+ }
356
+
357
+ /**
358
+ * Processes submitted settings from.
359
+ */
360
+ static function formValidate($input) {
361
+ if ( !empty($input['from_domain']) && ( empty($input['from_username']) || !self::isDomainEnabled($input['from_domain']) ) ) {
362
+ add_settings_error(
363
+ self::WPDOMAIN,
364
+ 'from-email',
365
+ __('You must define a valid sender email.', self::WPDOMAIN),
366
+ 'error'
367
+ );
368
+
369
+
370
+ $input['from_username'] = '';
371
+ $input['from_domain'] = '';
372
+ }
373
+
374
+ return array_map('wp_strip_all_tags', $input);
375
+ }
376
+
377
+ /**
378
+ * Opens contextual help section.
379
+ */
380
+ static function openContextualHelp() {
381
+ if ( !self::isPluginPage() || self::isReady() )
382
+ return;
383
+
384
+ ?>
385
+ <script type="text/javascript">
386
+ jQuery(document).bind( 'ready', function() {
387
+ jQuery('a#contextual-help-link').trigger('click');
388
+ });
389
+ </script>
390
+ <?php
391
+ }
392
+
393
+ /******************************************************************
394
+ ** Helper functions
395
+ *******************************************************************
396
+
397
+
398
+ /**
399
+ * @return mixed
400
+ */
401
+ static function getOption( $name, $default = false ) {
402
+
403
+ $options = get_option(self::WPDOMAIN);
404
+
405
+ if( isset( $options[$name] ) )
406
+ return $options[$name];
407
+
408
+ return $default;
409
+ }
410
+
411
+ /**
412
+ * @return boolean
413
+ */
414
+ static function isReady() {
415
+ return self::isConnected() && self::isConfigured();
416
+ }
417
+
418
+ /**
419
+ * @return boolean
420
+ */
421
+ static function isConnected() {
422
+ $result = false;
423
+
424
+ if ( isset(self::$mandrill)) {
425
+ try {
426
+ $result = ( self::$mandrill->users_ping() == 'PONG!' );
427
+ } catch ( Exception $e) {}
428
+ }
429
+ return $result;
430
+ }
431
+
432
+ /**
433
+ * @return boolean
434
+ */
435
+ static function isConfigured() {
436
+ return self::getAPIKey() && self::getFromEmail();
437
+ }
438
+
439
+ /**
440
+ * @return boolean
441
+ */
442
+ static function setOption( $name, $value ) {
443
+
444
+ $options = get_option(self::WPDOMAIN);
445
+
446
+ $options[$name] = $value;
447
+
448
+ $result = update_option(self::WPDOMAIN, $options);
449
+
450
+ return $result;
451
+ }
452
+
453
+ /**
454
+ * @return string|boolean
455
+ */
456
+ static function getAPIKey() {
457
+
458
+ return self::getOption('api_key');
459
+ }
460
+
461
+ /**
462
+ * @return string|boolean
463
+ */
464
+ static function getFromUsername() {
465
+
466
+ return self::getOption('from_username');
467
+ }
468
+
469
+ /**
470
+ * @return string|boolean
471
+ */
472
+ static function getFromDomain() {
473
+
474
+ return self::getOption('from_domain');
475
+ }
476
+
477
+ /**
478
+ * @return string|boolean
479
+ */
480
+ static function getFromEmail() {
481
+ if ( self::getOption('from_username') && self::getOption('from_domain') ) {
482
+ return self::getOption('from_username') . '@' . self::getOption('from_domain');
483
+ }
484
+ }
485
+
486
+ /**
487
+ * @return string|boolean
488
+ */
489
+ static function getFromName() {
490
+
491
+ return self::getOption('from_name');
492
+ }
493
+
494
+ /**
495
+ * @return string|boolean
496
+ */
497
+ static function getTemplate() {
498
+
499
+ return self::getOption('template');
500
+ }
501
+
502
+ /**
503
+ * @return string|boolean
504
+ */
505
+ static function getTags() {
506
+
507
+ return self::getOption('tags');
508
+ }
509
+
510
+ /**
511
+ * @param string $subject
512
+ * @return array
513
+ */
514
+ static function findTags($tags) {
515
+
516
+ // Getting general tags
517
+ $gtags = explode("\n",self::getTags());
518
+
519
+ // Finding tags based on WP Backtrace
520
+ $trace = debug_backtrace();
521
+ $level = 4;
522
+ $function = $trace[$level]['function'];
523
+
524
+ $wtags = array();
525
+ if( 'include' == $function || 'require' == $function ) {
526
+
527
+ $file = basename($trace[$level]['args'][0]);
528
+ $wtags[] = "wp_{$file}";
529
+ }
530
+ else {
531
+ if( isset( $trace[$level]['class'] ) )
532
+ $function = $trace[$level]['class'].$trace[$level]['type'].$function;
533
+ $wtags[] = "wp_{$function}";
534
+ }
535
+
536
+ return array('user' => $tags, 'general' => $gtags, 'automatic' => $wtags);
537
+ }
538
+
539
+ /**
540
+ * @return boolean
541
+ */
542
+ static function isPluginPage($sufix = '') {
543
+
544
+ return ( isset( $_GET['page'] ) && $_GET['page'] == self::WPDOMAIN . $sufix);
545
+ }
546
+
547
+ /**
548
+ * Return the list of the verified domains for the current users. Or false.
549
+ *
550
+ * @return array|bool
551
+ */
552
+ static function listVerifiedDomains() {
553
+ if ( !self::isConnected() ) return array();
554
+
555
+ $domains = self::$mandrill->senders_domains();
556
+ if ( is_wp_error($domains) || empty($domains) ) return false;
557
+ /*
558
+ foreach ( $domains as $index => $domain ) {
559
+ if ( !$domains[$index]['is_enabled'] ) {
560
+ unset($domains[$index]);
561
+ }
562
+ }
563
+ */
564
+ return array_values($domains);
565
+ }
566
+
567
+
568
+ /**
569
+ * @return boolean
570
+ */
571
+ static function isDomainEnabled($domain) {
572
+ if ( empty($domain) ) return false;
573
+
574
+ $domains = self::ListVerifiedDomains();
575
+ foreach ( $domains as $curdomain ) {
576
+ if ( $curdomain['domain'] == $domain ) {
577
+ return true;
578
+ }
579
+ }
580
+
581
+ return false;
582
+ }
583
+
584
+ /**
585
+ * @return boolean
586
+ */
587
+ static function isTemplateValid($template) {
588
+ if ( empty($template) || !self::isConnected() ) return false;
589
+
590
+ $templates = self::$mandrill->templates_list();
591
+ foreach ( $templates as $curtemplate ) {
592
+ if ( $curtemplate['name'] == $template ) {
593
+ return true;
594
+ }
595
+ }
596
+
597
+ return false;
598
+ }
599
+
600
+ /**
601
+ * Processes submitted email test form.
602
+ */
603
+ static function sendTestEmail($input) {
604
+
605
+ if (isset($input['email_to']) && !empty($input['email_to'])) {
606
+
607
+ $to = $input['email_to'];
608
+ $subject = isset($input['email_subject']) ? $input['email_subject'] : '';
609
+ $message = isset($input['email_message']) ? $input['email_message'] : '';
610
+
611
+ $test = self::mail($to, $subject, $message);
612
+
613
+ if (is_wp_error($test)) {
614
+
615
+ add_settings_error('email-to', 'email-to', __('Test email send failed. ', self::WPDOMAIN) . $test->get_error_message());
616
+
617
+ return array_map('wp_strip_all_tags', $input);
618
+ } else {
619
+ $result = array();
620
+
621
+ $result['sent'] = 0;
622
+ $result['queue'] = 0;
623
+ $result['rejected'] = 0;
624
+
625
+ foreach ( $test as $email ) {
626
+ if ( !isset($result[$email['status']]) ) $result[$email['status']] = 0;
627
+ $result[$email['status']]++;
628
+ }
629
+
630
+
631
+ add_settings_error('email-to', 'email-to', sprintf(__('Test executed: %d emails sent, %d emails queued and %d emails rejected', self::WPDOMAIN), $result['sent'],$result['queue'],$result['rejected']), $result['sent'] ? 'updated' : 'error' );
632
+ }
633
+ }
634
+
635
+ return array();
636
+ }
637
+
638
+ // Following methods generate parts of settings and test forms.
639
+ static function askAPIKey() {
640
+ echo '<div class="inside">';
641
+
642
+ $api_key = self::getOption('api_key');
643
+ ?><input id='api_key' name='wpmandrill[api_key]' size='45' type='text' value="<?php esc_attr_e( $api_key ); ?>" /><?php
644
+
645
+ if ( empty($api_key) ) {
646
+ ?><br/><span class="setting-description"><small><em><?php _e('To get your API key, please visit your <a href="http://mandrillapp.com/settings/index" target="_blank">Mandrill Settings</a>', self::WPDOMAIN); ?></em></small></span><?php
647
+ } elseif ( self::isConnected() ) {
648
+ ?><br/><span class="setting-description"><small><em><?php _e('We are connected to your Mandrill Account.', self::WPDOMAIN); ?></em></small></span><?php
649
+ } else {
650
+ ?><br/><span class="setting-description"><small><em><?php _e('Sorry, invalid API key.', self::WPDOMAIN); ?></em></small></span><?php
651
+ }
652
+
653
+ echo '</div>';
654
+ }
655
+
656
+ static function askFromEmail() {
657
+ echo '<div class="inside">';
658
+
659
+ $from_username = self::getFromUsername();
660
+ $from_domain = self::getFromDomain();
661
+ $from_email = self::getFromEmail();
662
+
663
+ $domains = self::ListVerifiedDomains();
664
+ if ( !$domains ) {
665
+
666
+ _e('No domains found.', self::WPDOMAIN);
667
+
668
+ if ( $from_email ) {
669
+ self::setOption('from_username', false);
670
+ self::setOption('from_domain', false);
671
+ self::setOption('from_email', false);
672
+ }
673
+
674
+ echo '</div>';
675
+ return;
676
+ }
677
+
678
+ ?><span class="setting-description"><em><?php _e('This address will be used as the sender of the outgoing emails:', self::WPDOMAIN); ?></em></span><br />
679
+ <input id="from_username" name="wpmandrill[from_username]" type="text" value="<?php esc_attr_e($from_username);?>" style="text-align:right;width:100px">@
680
+ <select id="from_domain" name="wpmandrill[from_domain]"><?php
681
+ foreach( $domains as $curdomain ) {
682
+ ?><option value="<?php esc_attr_e($curdomain['domain']); ?>" <?php selected($curdomain['domain'], $from_domain); ?>><?php esc_html_e($curdomain['domain']); ?></option><?php
683
+ }
684
+ ?></select><br/><span class="setting-description"><small><em><?php _e('If you need to add a new domain, please visit your <a href="https://mandrillapp.com/settings/sending-domains" target="_blank">Mandrill Settings</a>', self::WPDOMAIN); ?></em></small></span><?php
685
+
686
+ echo '</div>';
687
+ }
688
+
689
+ static function askFromName() {
690
+ echo '<div class="inside">';
691
+
692
+ $from_name = self::getFromName();
693
+
694
+ ?><span class="setting-description"><em><?php _e('Name the recipients will see in their email clients:', self::WPDOMAIN); ?></em></span><br />
695
+ <input name="wpmandrill[from_name]" type="text" value="<?php esc_attr_e($from_name); ?>">
696
+ <?php
697
+
698
+ echo '</div>';
699
+ }
700
+
701
+ static function askTemplate() {
702
+ echo '<div class="inside">';
703
+
704
+ if ( !self::isConnected() ) {
705
+ _e('No templates found.', self::WPDOMAIN);
706
+
707
+ echo '</div>';
708
+ return;
709
+ }
710
+
711
+ $template = self::getTemplate();
712
+ $templates = self::$mandrill->templates_list();
713
+ if( is_wp_error($templates) || empty($templates)) {
714
+
715
+ _e('No templates found.', self::WPDOMAIN);
716
+
717
+ if( $templates )
718
+ self::setOption('templates', false);
719
+
720
+ echo '</div>';
721
+ return;
722
+ }
723
+
724
+ ?><span class="setting-description"><em><?php _e('Select the template to use:', self::WPDOMAIN); ?></em></span><br />
725
+ <select name="wpmandrill[template]">
726
+ <option value="">-None-</option><?php
727
+ foreach( $templates as $curtemplate ) {
728
+ ?><option value="<?php esc_attr_e($curtemplate['name']); ?>" <?php selected($curtemplate['name'], $template); ?>><?php esc_html_e($curtemplate['name']); ?></option><?php
729
+ }
730
+ ?></select><br/><span class="setting-description"><em><?php _e('<small>The selected template must have a <strong><em>mc:edit="main"</em></strong> placeholder defined. The message will be shown there.</small>', self::WPDOMAIN); ?></em></span><?php
731
+
732
+ echo '</div>';
733
+ }
734
+
735
+ static function askTags() {
736
+ echo '<div class="inside">';
737
+
738
+ $tags = self::getTags();
739
+
740
+ ?><span class="setting-description"><em><?php _e('If there are tags that you want appended to every call, list them here, one per line:', self::WPDOMAIN); ?></em></span><br />
741
+ <textarea name="wpmandrill[tags]" cols="25" rows="3"><?php echo $tags; ?></textarea><br/>
742
+ <span class="setting-description"><small><em><?php _e('Also keep in mind that you can add or remove tags using the <em><a href="#" onclick="jQuery(\'a#contextual-help-link\').trigger(\'click\');return false;">mandrill_payload</a></em> WordPress filter.', self::WPDOMAIN); ?></em></small></span>
743
+ <?php
744
+
745
+ echo '</div>';
746
+ }
747
+
748
+ static function askTestEmailTo() {
749
+ echo '<div class="inside">';
750
+ ?><input id='email_to' name='wpmandrill-test[email_to]' size='45' type='text' value="<?php esc_attr_e( self::getTestEmailOption('email_to') ); ?>"/><?php
751
+ echo '</div>';
752
+ }
753
+
754
+ static function askTestEmailSubject() {
755
+ echo '<div class="inside">';
756
+ ?><input id='email_subject' name='wpmandrill-test[email_subject]' size='45' type='text' value="<?php esc_attr_e( self::getTestEmailOption('email_subject') ); ?>" /><?php
757
+ echo '</div>';
758
+ }
759
+
760
+ static function askTestEmailMessage() {
761
+ echo '<div class="inside">';
762
+ ?><textarea rows="5" cols="45" name="wpmandrill-test[email_message]" ><?php esc_html_e( self::getTestEmailOption('email_message') ); ?></textarea><?php
763
+ echo '</div>';
764
+ }
765
+
766
+ /**
767
+ * @param string $field
768
+ * @return string|bool
769
+ */
770
+ static function getTestEmailOption($field) {
771
+
772
+ if ( function_exists('is_multisite') && is_multisite() )
773
+ $email = get_site_option(self::WPDOMAIN . '-test');
774
+ else
775
+ $email = get_option(self::WPDOMAIN . '-test');
776
+
777
+ if( isset( $email[$field] ) )
778
+ return $email[$field];
779
+
780
+ return false;
781
+ }
782
+
783
+
784
+ /******************************************************************
785
+ ** Stats-related functions
786
+ *******************************************************************/
787
+
788
+ /**
789
+ * @return array
790
+ */
791
+ static function GetRawStatistics() {
792
+ if ( !self::isConnected() ) return array();
793
+
794
+ $stats = array();
795
+ $final = array();
796
+
797
+ $stats['user'] = self::$mandrill->users_info();
798
+
799
+ $data = array();
800
+ $container = self::$mandrill->tags_list();
801
+ foreach ( $container as $tag ) {
802
+ $data[$tag['tag']] = self::$mandrill->tags_info($tag['tag']);
803
+ }
804
+ $stats['tags'] = $data;
805
+
806
+ $data = array();
807
+ $container = self::$mandrill->senders_list();
808
+ foreach ( $container as $sender ) {
809
+ $data[$sender['address']] = self::$mandrill->senders_info($sender['address']);
810
+ }
811
+ $stats['senders'] = $data;
812
+
813
+ $stats['urls'] = self::$mandrill->urls_list();
814
+
815
+
816
+ $final['general'] = $stats['user'];
817
+ $final['urls'] = $stats['urls'];
818
+
819
+ $final['stats'] = array();
820
+ $final['stats']['hourly']['senders'] = array();;
821
+ $final['stats']['hourly']['tags'] = array();
822
+
823
+ $final['general']['stats'] = $final['general']['stats']['all_time'];
824
+ $final['stats']['hourly']['tags']['general_stats'] = self::$mandrill->tags_all_time_series();
825
+
826
+ foreach ( array('today', 'last_7_days','last_30_days','last_60_days','last_90_days') as $timeframe) {
827
+ if ( isset($stats['user']['stats'][$timeframe]) ) $final['stats']['periods']['account'][$timeframe] = $stats['user']['stats'][$timeframe];
828
+
829
+ foreach ($stats['tags'] as $index => $entity) {
830
+ if ( !in_array($entity['tag'], $final['stats']['hourly']['tags']) )
831
+ $final['stats']['hourly']['tags']['detailed_stats'][$entity['tag']] = self::$mandrill->tags_time_series($entity['tag']);
832
+
833
+ if ( isset($entity['stats'][$timeframe]) )
834
+ $final['stats']['periods']['tags'][$timeframe][$index] = $entity['stats'][$timeframe];
835
+
836
+ }
837
+
838
+ foreach ($stats['senders'] as $index => $entity) {
839
+ if ( !in_array($entity['address'], $final['stats']['hourly']['senders']) )
840
+ $final['stats']['hourly']['senders'][$entity['address']] = self::$mandrill->senders_time_series($entity['address']);
841
+ if ( isset($entity['stats'][$timeframe]) )
842
+ $final['stats']['periods']['senders'][$timeframe][$index] = $entity['stats'][$timeframe];
843
+ }
844
+ }
845
+
846
+ return $final;
847
+ }
848
+
849
+ static function getProcessedStats() {
850
+ $stats = self::GetRawStatistics();
851
+ if ( empty($stats) ) return $stats;
852
+
853
+ $graph_data = array();
854
+ for ( $i = 0; $i < 24; $i++ ) {
855
+ $graph_data['hourly']['delivered'][ sprintf('"%02s"',$i) ] = 0;
856
+ $graph_data['hourly']['opens'][ sprintf('"%02s"',$i) ] = 0;
857
+ $graph_data['hourly']['clicks'][ sprintf('"%02s"',$i) ] = 0;
858
+
859
+ $graph_data['hourly']['open_rate'][ sprintf('"%02s"',$i) ] = 0;
860
+ $graph_data['hourly']['click_rate'][ sprintf('"%02s"',$i) ] = 0;
861
+ }
862
+
863
+ for ( $i = 29; $i >= 0; $i-- ) {
864
+ $day = date('m/d', strtotime ( "-$i day" , time() ) );
865
+
866
+ $graph_data['daily']['delivered'][ sprintf('"%02s"',$day) ] = 0;
867
+ $graph_data['daily']['opens'][ sprintf('"%02s"',$day) ] = 0;
868
+ $graph_data['daily']['clicks'][ sprintf('"%02s"',$day) ] = 0;
869
+
870
+ $graph_data['daily']['open_rate'][ sprintf('"%02s"',$day) ] = 0;
871
+ $graph_data['daily']['click_rate'][ sprintf('"%02s"',$day) ] = 0;
872
+ }
873
+
874
+ $timeOffset = get_option('gmt_offset');
875
+ $timeOffset = is_numeric($timeOffset) ? $timeOffset * 3600 : 0;
876
+
877
+ foreach ( $stats['stats']['hourly']['senders'] as $data_by_sender ) {
878
+ foreach ( $data_by_sender as $data ) {
879
+ if ( isset($data['time']) ) {
880
+ $hour = '"' . date('H',strtotime($data['time'])+$timeOffset) . '"';
881
+ $day = '"' . date('m/d', strtotime($data['time'])+$timeOffset) . '"';
882
+
883
+ if ( !isset($graph_data['hourly']['delivered'][$hour]) ) $graph_data['hourly']['delivered'][$hour] = 0;
884
+ if ( !isset($graph_data['hourly']['opens'][$hour]) ) $graph_data['hourly']['opens'][$hour] = 0;
885
+ if ( !isset($graph_data['hourly']['clicks'][$hour]) ) $graph_data['hourly']['clicks'][$hour] = 0;
886
+ if ( !isset($graph_data['daily']['delivered'][$hour]) ) $graph_data['daily']['delivered'][$hour] = 0;
887
+ if ( !isset($graph_data['daily']['opens'][$hour]) ) $graph_data['daily']['opens'][$hour] = 0;
888
+ if ( !isset($graph_data['daily']['clicks'][$hour]) ) $graph_data['daily']['clicks'][$hour] = 0;
889
+
890
+ $graph_data['hourly']['delivered'][$hour] += $data['sent'] - $data['hard_bounces'] - $data['soft_bounces'] - $data['rejects'];
891
+ $graph_data['hourly']['opens'][$hour] += $data['unique_opens'];
892
+ $graph_data['hourly']['clicks'][$hour] += $data['unique_clicks'];
893
+
894
+ $graph_data['daily']['delivered'][$day] += $data['sent'] - $data['hard_bounces'] - $data['soft_bounces'] - $data['rejects'];
895
+ $graph_data['daily']['opens'][$day] += $data['unique_opens'];
896
+ $graph_data['daily']['clicks'][$day] += $data['unique_clicks'];
897
+ }
898
+ }
899
+ }
900
+
901
+ foreach (array_keys($graph_data['hourly']['delivered']) as $hour ) {
902
+ if ($graph_data['hourly']['delivered'][$hour]) {
903
+ $graph_data['hourly']['open_rate'][$hour] = number_format($graph_data['hourly']['opens'][$hour] * 100 / $graph_data['hourly']['delivered'][$hour],2);
904
+ $graph_data['hourly']['click_rate'][$hour] = number_format($graph_data['hourly']['clicks'][$hour] * 100 / $graph_data['hourly']['delivered'][$hour],2);
905
+ }
906
+ }
907
+
908
+ foreach (array_keys($graph_data['daily']['delivered']) as $day ) {
909
+ if ($graph_data['daily']['delivered'][$day]) {
910
+ $graph_data['daily']['open_rate'][$day] = number_format($graph_data['daily']['opens'][$day] * 100 / $graph_data['daily']['delivered'][$day],2);
911
+ $graph_data['daily']['click_rate'][$day] = number_format($graph_data['daily']['clicks'][$day] * 100 / $graph_data['daily']['delivered'][$day],2);
912
+ }
913
+
914
+ }
915
+
916
+ $stats['graph'] = $graph_data;
917
+
918
+ return $stats;
919
+ }
920
+
921
+ static function getCurrentStats() {
922
+
923
+ $stats = get_transient(self::WPDOMAIN.'-stats');
924
+ if ( empty($stats) ) {
925
+
926
+ $stats = self::GetProcessedStats();
927
+ if ( !empty($stats) ) set_transient(self::WPDOMAIN.'-stats', $stats, 60 * 60);
928
+
929
+ }
930
+
931
+ return $stats;
932
+ }
933
+
934
+ static function addDashboardWidgets() {
935
+ $widget_id = 'mandrill_widget';
936
+
937
+ $widget_options = get_option('dashboard_widget_options');
938
+
939
+ if ( !$widget_options || !isset($widget_options[$widget_id])) {
940
+ $filter = 'none';
941
+ $display = 'volume';
942
+ } else {
943
+
944
+ $filter = $widget_options[$widget_id]['filter'];
945
+ $display = $widget_options[$widget_id]['display'];
946
+ }
947
+
948
+ if ( $filter == 'none' ) {
949
+ $filter_used = '';
950
+ } elseif ( substr($filter,0,2) == 's:' ) {
951
+ $filter = substr($filter,2);
952
+ $filter_used = 'Sender: '.$filter;
953
+ } else {
954
+ $filter_used = 'Tag: '.$filter;
955
+ }
956
+
957
+ wp_add_dashboard_widget( "mandrill_widget",
958
+ __("Mandrill Recent Statistics", self::WPDOMAIN) . (!empty($filter_used) ? ' &raquo; ' . $filter_used : ''),
959
+ array(__CLASS__, 'showDashboardWidget'),
960
+ array(__CLASS__, 'showDashboardWidgetOptions')
961
+ );
962
+
963
+ global $wp_meta_boxes;
964
+
965
+ $normal_dashboard = $wp_meta_boxes['dashboard']['normal']['core'];
966
+
967
+ $backup = array('mandrill_widget' => $normal_dashboard['mandrill_widget']);
968
+ unset($normal_dashboard['mandrill_widget']);
969
+
970
+ $sorted_dashboard = array_merge($backup, $normal_dashboard);
971
+
972
+ $wp_meta_boxes['dashboard']['normal']['core'] = $sorted_dashboard;
973
+ }
974
+
975
+ static function showDashboardWidget() {
976
+ $isAjaxCall = isset($_POST['ajax']) && $_POST['ajax'] ? true : false;
977
+
978
+ $stats = self::getCurrentStats();
979
+ if ( empty($stats) ) {
980
+ echo '<p>' . __('There was a problem retrieving statistics.', self::WPDOMAIN) . '</p>';
981
+
982
+ if ( !$isAjaxCall) return;
983
+ else exit();
984
+ }
985
+
986
+
987
+ $widget_id = 'mandrill_widget';
988
+ $widget_options = get_option('dashboard_widget_options');
989
+
990
+ if ( !$widget_options || !isset($widget_options[$widget_id])) {
991
+ $filter = 'none';
992
+ $display = 'volume';
993
+ } else {
994
+
995
+ $filter = $widget_options[$widget_id]['filter'];
996
+ $display = $widget_options[$widget_id]['display'];
997
+ }
998
+
999
+ if ( $filter == 'none' ) {
1000
+ $filter_type = 'account';
1001
+ $filter_used = '';
1002
+ } elseif ( substr($filter,0,2) == 's:' ) {
1003
+ $filter_type = 'senders';
1004
+ $filter = substr($filter,2);
1005
+ $filter_used = 'Filtering by sender: '.$filter;
1006
+ } else {
1007
+ $filter_type = 'tags';
1008
+ $filter_used = 'Filtering by tag: '.$tag;
1009
+ }
1010
+
1011
+ $data = array();
1012
+ foreach ( array('today', 'last_7_days') as $period ) {
1013
+ if ( $filter_type == 'account' ) {
1014
+ $data['sent'][$period] = $stats['stats']['periods'][$filter_type][$period]['sent'];
1015
+ $data['opens'][$period] = $stats['stats']['periods'][$filter_type][$period]['unique_opens'];
1016
+ $data['bounces'][$period] = $stats['stats']['periods'][$filter_type][$period]['hard_bounces'] +
1017
+ $stats['stats']['periods'][$filter_type][$period]['soft_bounces'] +
1018
+ $stats['stats']['periods'][$filter_type][$period]['rejects'];
1019
+
1020
+ $data['unopens'][$period] = $stats['stats']['periods'][$filter_type][$period]['sent'] -
1021
+ $data['opens'][$period] -
1022
+ $data['bounces'][$period];
1023
+ } else {
1024
+ $data['sent'][$period] = $stats['stats']['periods'][$filter_type][$period][$filter]['sent'];
1025
+ $data['opens'][$period] = $stats['stats']['periods'][$filter_type][$period][$filter]['unique_opens'];
1026
+ $data['bounces'][$period] = $stats['stats']['periods'][$filter_type][$period][$filter]['hard_bounces'] +
1027
+ $stats['stats']['periods'][$filter_type][$period][$filter]['soft_bounces'] +
1028
+ $stats['stats']['periods'][$filter_type][$period][$filter]['rejects'];
1029
+
1030
+ $data['unopens'][$period] = $stats['stats']['periods'][$filter_type][$period][$filter]['sent'] -
1031
+ $data['opens'][$period] -
1032
+ $data['bounces'][$period];
1033
+ }
1034
+ }
1035
+
1036
+ $lit = array();
1037
+
1038
+ $lit['title'] = __('Sending Volume', self::WPDOMAIN);
1039
+ $lit['label_suffix'] = __(' emails', self::WPDOMAIN);
1040
+ $lit['Ylabel'] = __('Total Volume per Day', self::WPDOMAIN);
1041
+
1042
+ $lit['last_few_days'] = __('in the last few days', self::WPDOMAIN);
1043
+ $lit['last_few_months']= __('in the last few months', self::WPDOMAIN);
1044
+ $lit['today'] = __('Today', self::WPDOMAIN);
1045
+ $lit['last7days'] = __('Last 7 Days', self::WPDOMAIN);
1046
+ $lit['last30days'] = __('Last 30 Days', self::WPDOMAIN);
1047
+ $lit['last60days'] = __('Last 60 Days', self::WPDOMAIN);
1048
+ $lit['last90days'] = __('Last 90 Days', self::WPDOMAIN);
1049
+ $lit['periods'] = __('Periods', self::WPDOMAIN);
1050
+ $lit['volume'] = __('Volume', self::WPDOMAIN);
1051
+ $lit['total'] = __('Total:', self::WPDOMAIN);
1052
+ $lit['unopened'] = __('Unopened', self::WPDOMAIN);
1053
+ $lit['bounced'] = __('Bounced or Rejected', self::WPDOMAIN);
1054
+ $lit['opened'] = __('Opened', self::WPDOMAIN);
1055
+
1056
+ if ( $display == 'average' ) {
1057
+ $lit['title'] = __('Average Sending Volume', self::WPDOMAIN);
1058
+ $lit['label_suffix'] .= __('/day', self::WPDOMAIN);
1059
+ $lit['Ylabel'] = __('Average Volume per Day', self::WPDOMAIN);
1060
+
1061
+ foreach ( array(1 => 'today', 7 => 'last_7_days') as $days => $period ) {
1062
+ $data['opens'][$period] = number_format($data['opens'][$period] / $days,2);
1063
+ $data['bounces'][$period] = number_format($data['bounces'][$period] / $days,2);
1064
+ $data['unopens'][$period] = number_format($data['unopens'][$period] / $days,2);
1065
+ }
1066
+ }
1067
+ // Filling arrays for recent stats
1068
+ $unopens['recent'] = $data['unopens']['today'] . ',' . $data['unopens']['last_7_days'];
1069
+ $opens['recent'] = $data['opens']['today'] . ',' . $data['opens']['last_7_days'];
1070
+ $bounces['recent'] = $data['bounces']['today'] . ',' . $data['bounces']['last_7_days'];
1071
+
1072
+
1073
+ $js = '';
1074
+ if ( !$isAjaxCall ) {
1075
+ $js .= '<script type="text/javascript" src="'.plugins_url('/js/highcharts.js', __FILE__).'"></script>';
1076
+ $js .= '<script type="text/javascript" src="'.plugins_url('/js/modules/exporting.js', __FILE__).'"></script>';
1077
+
1078
+ $js .= '
1079
+ <div style="height:400px;">
1080
+ <div id="filtered_recent"></div>
1081
+ </div>
1082
+ <script type="text/javascript">
1083
+ jQuery(document).bind( \'ready\', function() {
1084
+ ';
1085
+ }
1086
+ $js .= <<<JS
1087
+ jQuery(function () {
1088
+ var chart;
1089
+ chart = new Highcharts.Chart({
1090
+ chart: {
1091
+ renderTo: 'filtered_recent',
1092
+ zoomType: 'xy',
1093
+ type: 'column'
1094
+ },
1095
+ title: {
1096
+ text: '{$lit['title']}'
1097
+ },
1098
+ subtitle: {
1099
+ text: '{$lit['last_few_days']}'
1100
+ },
1101
+ xAxis: [{
1102
+ categories: ['{$lit['today']}','{$lit['last7days']}'],
1103
+ title: {
1104
+ enabled: true,
1105
+ text: '{$lit['periods']}',
1106
+ style: {
1107
+ fontWeight: 'normal'
1108
+ }
1109
+ }
1110
+ }],
1111
+ yAxis: [{
1112
+ min: 0,
1113
+ title: {
1114
+ text: '{$lit['Ylabel']} ',
1115
+ style: {
1116
+ color: '#4572A7'
1117
+ }
1118
+ },
1119
+ labels: {
1120
+ formatter: function() {
1121
+ return this.value +' {$lit['label_suffix']}';
1122
+ },
1123
+ style: {
1124
+ color: '#4572A7'
1125
+ }
1126
+ },
1127
+ stackLabels: {
1128
+ enabled: true,
1129
+ style: {
1130
+ fontWeight: 'bold',
1131
+ color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
1132
+ }
1133
+ }
1134
+ }],
1135
+ tooltip: {
1136
+ formatter: function() {
1137
+ return '<b>'+ this.x +'</b><br/>'+
1138
+ this.series.name +': '+ this.y +'{$lit['label_suffix']}<br/>'+
1139
+ '{$lit['total']} '+ this.point.stackTotal+'{$lit['label_suffix']}';
1140
+ }
1141
+ },
1142
+ legend: {
1143
+ align: 'right',
1144
+ x: -20,
1145
+ verticalAlign: 'top',
1146
+ y: 40,
1147
+ floating: true,
1148
+ backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || 'white',
1149
+ borderColor: '#CCC',
1150
+ borderWidth: 1,
1151
+ shadow: false
1152
+ },
1153
+ credits: {
1154
+ enabled: false,
1155
+ href: 'http://www.mandrillapp.com/',
1156
+ text: 'MandrillApp.com'
1157
+ },
1158
+ plotOptions: {
1159
+ column: {
1160
+ stacking: 'normal',
1161
+ dataLabels: {
1162
+ enabled: true,
1163
+ color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
1164
+ }
1165
+ }
1166
+ },
1167
+ series: [{
1168
+ name: '{$lit['unopened']}',
1169
+ data: [{$unopens['recent']}]
1170
+ }, {
1171
+ name: '{$lit['bounced']}',
1172
+ data: [{$bounces['recent']}]
1173
+ }, {
1174
+ name: '{$lit['opened']}',
1175
+ data: [{$opens['recent']}]
1176
+ }]
1177
+ });
1178
+ });
1179
+ JS;
1180
+
1181
+ if ( !$isAjaxCall ) {
1182
+ $js .= '
1183
+ });
1184
+ </script>';
1185
+ }
1186
+
1187
+ echo $js;
1188
+
1189
+ if ( $isAjaxCall ) exit();
1190
+
1191
+ }
1192
+
1193
+ static function showDashboardWidgetOptions() {
1194
+ $stats = self::getCurrentStats();
1195
+ if ( empty($stats) ) {
1196
+ echo '<p>' . __('There was a problem retrieving statistics.', self::WPDOMAIN) . '</p>';
1197
+ return;
1198
+ }
1199
+
1200
+ $widget_id = 'mandrill_widget';
1201
+
1202
+ if ( function_exists('is_multisite') && is_multisite() )
1203
+ $widget_options = get_site_option('dashboard_widget_options');
1204
+ else
1205
+ $widget_options = get_option('dashboard_widget_options');
1206
+
1207
+ if ( !$widget_options )
1208
+ $widget_options = array();
1209
+
1210
+ if ( !isset($widget_options[$widget_id]) )
1211
+ $widget_options[$widget_id] = array();
1212
+
1213
+ if ( 'POST' == $_SERVER['REQUEST_METHOD'] && isset($_POST) ) {
1214
+ $filter = $_POST['filter'];
1215
+ $display = $_POST['display'];
1216
+
1217
+ $widget_options[$widget_id]['filter'] = $filter;
1218
+ $widget_options[$widget_id]['display'] = $display;
1219
+ update_option( 'dashboard_widget_options', $widget_options );
1220
+ }
1221
+
1222
+ $filter = isset( $widget_options[$widget_id]['filter'] ) ? $widget_options[$widget_id]['filter'] : '';
1223
+ $display = isset( $widget_options[$widget_id]['display'] ) ? $widget_options[$widget_id]['display'] : '';
1224
+ ?>
1225
+ <label for="filter"><?php _e('Filter by:', self::WPDOMAIN); ?> </label>
1226
+ <select id="filter" name="filter">
1227
+ <option value="none" <?=selected($filter, 'none');?>><?php _e('No filter', self::WPDOMAIN); ?></option>
1228
+ <optgroup label="<?php _e('Sender:', self::WPDOMAIN); ?>">
1229
+ <?php
1230
+ foreach ( array_keys($stats['stats']['hourly']['senders']) as $sender) {
1231
+ echo '<option value="s:'.$sender.'" '.selected($filter, 's:'.$sender).'>'.$sender.'</option>';
1232
+ }
1233
+ ?>
1234
+ </optgroup>
1235
+ <optgroup label="<?php _e('Tag:', self::WPDOMAIN); ?>">
1236
+ <?php
1237
+ foreach ( array_keys($stats['stats']['hourly']['tags']['detailed_stats']) as $tag) {
1238
+ echo '<option value="'.$tag.'" '.selected($filter, $tag).'>'.$tag.'</option>';
1239
+ }
1240
+ ?>
1241
+ </optgroup>
1242
+ </select>
1243
+ <label for="display"><?php _e('Display:', self::WPDOMAIN); ?> </label>
1244
+ <select id="display" name="display">
1245
+ <option value="volume" <?=selected($display, 'volume');?>><?php _e('Total Volume per Period', self::WPDOMAIN); ?></option>
1246
+ <option value="average" <?=selected($display, 'average');?>><?php _e('Average Volume per Period', self::WPDOMAIN); ?></option>
1247
+ </select><?php
1248
+ }
1249
+
1250
+ static function getAjaxStats() {
1251
+ $stats = self::getCurrentStats();
1252
+ if ( empty($stats) ) {
1253
+ exit();
1254
+ }
1255
+
1256
+ $filter = $_POST['filter'];
1257
+ $display = $_POST['display'];
1258
+
1259
+ if ( $filter == 'none' ) {
1260
+ $filter_type = 'account';
1261
+ } elseif ( substr($filter,0,2) == 's:' ) {
1262
+ $filter_type = 'senders';
1263
+ $filter = substr($filter,2);
1264
+ } else {
1265
+ $filter_type = 'tags';
1266
+ }
1267
+
1268
+ $data = array();
1269
+ foreach ( array('today', 'last_7_days', 'last_30_days', 'last_60_days', 'last_90_days') as $period ) {
1270
+ if ( $filter_type == 'account' ) {
1271
+ $data['opens'][$period] = $stats['stats']['periods'][$filter_type][$period]['unique_opens'];
1272
+ $data['bounces'][$period] = $stats['stats']['periods'][$filter_type][$period]['hard_bounces'] +
1273
+ $stats['stats']['periods'][$filter_type][$period]['soft_bounces'] +
1274
+ $stats['stats']['periods'][$filter_type][$period]['rejects'];
1275
+
1276
+ $data['unopens'][$period] = $stats['stats']['periods'][$filter_type][$period]['sent'] -
1277
+ $data['opens'][$period] -
1278
+ $data['bounces'][$period];
1279
+ } else {
1280
+ $data['opens'][$period] = $stats['stats']['periods'][$filter_type][$period][$filter]['unique_opens'];
1281
+ $data['bounces'][$period] = $stats['stats']['periods'][$filter_type][$period][$filter]['hard_bounces'] +
1282
+ $stats['stats']['periods'][$filter_type][$period][$filter]['soft_bounces'] +
1283
+ $stats['stats']['periods'][$filter_type][$period][$filter]['rejects'];
1284
+
1285
+ $data['unopens'][$period] = $stats['stats']['periods'][$filter_type][$period][$filter]['sent'] -
1286
+ $data['opens'][$period] -
1287
+ $data['bounces'][$period];
1288
+ }
1289
+ }
1290
+
1291
+ $lit = array();
1292
+
1293
+ $lit['title'] = __('Sending Volume', self::WPDOMAIN);
1294
+ $lit['label_suffix'] = __(' emails', self::WPDOMAIN);
1295
+ $lit['Ylabel'] = __('Total Volume per Day', self::WPDOMAIN);
1296
+
1297
+ $lit['last_few_days'] = __('in the last few days', self::WPDOMAIN);
1298
+ $lit['last_few_months']= __('in the last few months', self::WPDOMAIN);
1299
+ $lit['today'] = __('Today', self::WPDOMAIN);
1300
+ $lit['last7days'] = __('Last 7 Days', self::WPDOMAIN);
1301
+ $lit['last30days'] = __('Last 30 Days', self::WPDOMAIN);
1302
+ $lit['last60days'] = __('Last 60 Days', self::WPDOMAIN);
1303
+ $lit['last90days'] = __('Last 90 Days', self::WPDOMAIN);
1304
+ $lit['periods'] = __('Periods', self::WPDOMAIN);
1305
+ $lit['volume'] = __('Volume', self::WPDOMAIN);
1306
+ $lit['total'] = __('Total:', self::WPDOMAIN);
1307
+ $lit['unopened'] = __('Unopened', self::WPDOMAIN);
1308
+ $lit['bounced'] = __('Bounced or Rejected', self::WPDOMAIN);
1309
+ $lit['opened'] = __('Opened', self::WPDOMAIN);
1310
+
1311
+ if ( $display == 'average' ) {
1312
+ $lit['title'] = __('Average Sending Volume', self::WPDOMAIN);
1313
+ $lit['label_suffix'] .= __('/day', self::WPDOMAIN);
1314
+ $lit['Ylabel'] = __('Average Volume per Day', self::WPDOMAIN);
1315
+
1316
+ foreach ( array(1 => 'today', 7 => 'last_7_days', 30 => 'last_30_days', 60 => 'last_60_days', 90 => 'last_90_days') as $days => $period ) {
1317
+ $data['opens'][$period] = number_format($data['opens'][$period] / $days,2);
1318
+ $data['bounces'][$period] = number_format($data['bounces'][$period] / $days,2);
1319
+ $data['unopens'][$period] = number_format($data['unopens'][$period] / $days,2);
1320
+ }
1321
+ }
1322
+
1323
+ // Filling arrays for recent stats
1324
+ $unopens['recent'] = $data['unopens']['today'] . ',' . $data['unopens']['last_7_days'];
1325
+ $opens['recent'] = $data['opens']['today'] . ',' . $data['opens']['last_7_days'];
1326
+ $bounces['recent'] = $data['bounces']['today'] . ',' . $data['bounces']['last_7_days'];
1327
+
1328
+ // Filling arrays for older stats
1329
+ $unopens['oldest'] = $data['unopens']['last_30_days'] . ',' . $data['unopens']['last_60_days'] . ',' . $data['unopens']['last_90_days'];
1330
+ $opens['oldest'] = $data['opens']['last_30_days'] . ',' . $data['opens']['last_60_days'] . ',' . $data['opens']['last_90_days'];
1331
+ $bounces['oldest'] = $data['bounces']['last_30_days'] . ',' . $data['bounces']['last_60_days'] . ',' . $data['bounces']['last_90_days'];
1332
+
1333
+ $js = <<<JS
1334
+ jQuery(function () {
1335
+ var chart;
1336
+ chart = new Highcharts.Chart({
1337
+ chart: {
1338
+ renderTo: 'filtered_recent',
1339
+ zoomType: 'xy',
1340
+ type: 'column'
1341
+ },
1342
+ title: {
1343
+ text: '{$lit['title']}'
1344
+ },
1345
+ subtitle: {
1346
+ text: '{$lit['last_few_days']}'
1347
+ },
1348
+ xAxis: [{
1349
+ categories: ['{$lit['today']}','{$lit['last7days']}'],
1350
+ title: {
1351
+ enabled: true,
1352
+ text: '{$lit['periods']}',
1353
+ style: {
1354
+ fontWeight: 'normal'
1355
+ }
1356
+ }
1357
+ }],
1358
+ yAxis: [{
1359
+ min: 0,
1360
+ title: {
1361
+ text: '{$lit['Ylabel']} ',
1362
+ style: {
1363
+ color: '#4572A7'
1364
+ }
1365
+ },
1366
+ labels: {
1367
+ formatter: function() {
1368
+ return this.value +' {$lit['label_suffix']}';
1369
+ },
1370
+ style: {
1371
+ color: '#4572A7'
1372
+ }
1373
+ },
1374
+ stackLabels: {
1375
+ enabled: true,
1376
+ style: {
1377
+ fontWeight: 'bold',
1378
+ color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
1379
+ }
1380
+ }
1381
+ }],
1382
+ tooltip: {
1383
+ formatter: function() {
1384
+ return '<b>'+ this.x +'</b><br/>'+
1385
+ this.series.name +': '+ this.y +'{$lit['label_suffix']}<br/>'+
1386
+ '{$lit['total']} '+ this.point.stackTotal+'{$lit['label_suffix']}';
1387
+ }
1388
+ },
1389
+ legend: {
1390
+ align: 'right',
1391
+ x: -20,
1392
+ verticalAlign: 'top',
1393
+ y: 40,
1394
+ floating: true,
1395
+ backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || 'white',
1396
+ borderColor: '#CCC',
1397
+ borderWidth: 1,
1398
+ shadow: false
1399
+ },
1400
+ credits: {
1401
+ enabled: false,
1402
+ href: "http://www.mandrillapp.com/",
1403
+ text: "MandrillApp.com"
1404
+ },
1405
+ plotOptions: {
1406
+ column: {
1407
+ stacking: 'normal',
1408
+ dataLabels: {
1409
+ enabled: true,
1410
+ color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
1411
+ }
1412
+ }
1413
+ },
1414
+ series: [{
1415
+ name: '{$lit['unopened']}',
1416
+ data: [{$unopens['recent']}]
1417
+ }, {
1418
+ name: '{$lit['bounced']}',
1419
+ data: [{$bounces['recent']}]
1420
+ }, {
1421
+ name: '{$lit['opened']}',
1422
+ data: [{$opens['recent']}]
1423
+ }]
1424
+ });
1425
+ chart = new Highcharts.Chart({
1426
+ chart: {
1427
+ renderTo: 'filtered_oldest',
1428
+ zoomType: 'xy',
1429
+ type: 'column'
1430
+ },
1431
+ title: {
1432
+ text: '{$lit['title']}'
1433
+ },
1434
+ subtitle: {
1435
+ text: '{$lit['last_few_months']}'
1436
+ },
1437
+ xAxis: [{
1438
+ categories: ['{$lit['last30days']}','{$lit['last60days']}','{$lit['last90days']}'],
1439
+ title: {
1440
+ enabled: true,
1441
+ text: '{$lit['periods']}',
1442
+ style: {
1443
+ fontWeight: 'normal'
1444
+ }
1445
+ }
1446
+ }],
1447
+ yAxis: [{
1448
+ min: 0,
1449
+ title: {
1450
+ text: '{$lit['Ylabel']} ',
1451
+ style: {
1452
+ color: '#4572A7'
1453
+ }
1454
+ },
1455
+ labels: {
1456
+ formatter: function() {
1457
+ return this.value +' {$lit['label_suffix']}';
1458
+ },
1459
+ style: {
1460
+ color: '#4572A7'
1461
+ }
1462
+ },
1463
+ stackLabels: {
1464
+ enabled: true,
1465
+ style: {
1466
+ fontWeight: 'bold',
1467
+ color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
1468
+ }
1469
+ }
1470
+ }],
1471
+ tooltip: {
1472
+ formatter: function() {
1473
+ return '<b>'+ this.x +'</b><br/>'+
1474
+ this.series.name +': '+ this.y +'{$lit['label_suffix']}<br/>'+
1475
+ '{$lit['total']} '+ this.point.stackTotal+'{$lit['label_suffix']}';
1476
+ }
1477
+ },
1478
+ legend: {
1479
+ align: 'right',
1480
+ x: -20,
1481
+ verticalAlign: 'top',
1482
+ y: 40,
1483
+ floating: true,
1484
+ backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || 'white',
1485
+ borderColor: '#CCC',
1486
+ borderWidth: 1,
1487
+ shadow: false
1488
+ },
1489
+ credits: {
1490
+ enabled: false,
1491
+ href: "http://www.mandrillapp.com/",
1492
+ text: "MandrillApp.com"
1493
+ },
1494
+ plotOptions: {
1495
+ column: {
1496
+ stacking: 'normal',
1497
+ dataLabels: {
1498
+ enabled: true,
1499
+ color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
1500
+ }
1501
+ }
1502
+ },
1503
+ series: [{
1504
+ name: '{$lit['unopened']}',
1505
+ data: [{$unopens['oldest']}]
1506
+ }, {
1507
+ name: '{$lit['bounced']}',
1508
+ data: [{$bounces['oldest']}]
1509
+ }, {
1510
+ name: '{$lit['opened']}',
1511
+ data: [{$opens['oldest']}]
1512
+ }]
1513
+ });
1514
+ });
1515
+ JS;
1516
+ echo $js;
1517
+
1518
+ exit();
1519
+ }
1520
+
1521
+
1522
+ /******************************************************************
1523
+ ** Function to actually send the emails
1524
+ *******************************************************************
1525
+ /**
1526
+ * @param string|array $to recipients, array or comma-separated string
1527
+ * @param string $subject email subject
1528
+ * @param string $html email body
1529
+ * @param string|array $headers array or comma-separated string with additional headers for the email
1530
+ * @param array $attachments Array of paths for the files to be attached to the message.
1531
+ * @param array $tags Array of tags to be attached to the message.
1532
+ * @param string $from_name the name to use in the From field of the message
1533
+ * @param string $from_email a valid email address to use with this account
1534
+ * @param string $template_name a valid template name for the account
1535
+ * @return array|WP_Error
1536
+ */
1537
+ static function mail( $to, $subject, $html, $headers = '', $attachments = array(), $tags = array(), $from_name = '', $from_email = '', $template_name = '' ) {
1538
+ try {
1539
+ $message = compact('html', 'text', 'subject', 'from_name', 'from_email', 'to', 'headers', 'attachments');
1540
+ return self::sendEmail($message, $tags, $template_name);
1541
+ } catch ( Exception $e ) {
1542
+ return new WP_Error( __($e->getMessage(), self::WPDOMAIN) );
1543
+ }
1544
+ }
1545
+
1546
+ /**
1547
+ * @return boolean
1548
+ */
1549
+ static function wp_mail_native( $to, $subject, $message, $headers = '', $attachments = array() ) {
1550
+ require plugin_dir_path( __FILE__ ) . '/legacy/function.wp_mail.php';
1551
+ }
1552
+
1553
+ /**
1554
+ * @link https://mandrillapp.com/api/docs/messages.html#method=send
1555
+ *
1556
+ * @param array $message
1557
+ * @param boolean $track_opens
1558
+ * @param boolean $track_clicks
1559
+ * @param array $tags
1560
+ * @return array|WP_Error
1561
+ */
1562
+ static function sendEmail( $message, $tags = array(), $template_name = '', $track_opens = true, $track_clicks = true ) {
1563
+
1564
+ try {
1565
+ // Checking if we are connected to Mandrill
1566
+ if ( !self::isConnected() ) throw new Exception('Invalid API Key');
1567
+
1568
+ /************
1569
+ *
1570
+ * Processing supplied fields to make them valid for the Mandrill API
1571
+ *
1572
+ *************************/
1573
+
1574
+ // Checking the user-specified headers
1575
+ if ( empty( $message['headers'] ) ) {
1576
+ $message['headers'] = array();
1577
+ } else {
1578
+ if ( !is_array( $message['headers'] ) ) {
1579
+ $tempheaders = explode( "\n", str_replace( "\r\n", "\n", $message['headers'] ) );
1580
+ } else {
1581
+ $tempheaders = $message['headers'];
1582
+ }
1583
+ $message['headers'] = array();
1584
+
1585
+ // If it's actually got contents
1586
+ if ( !empty( $tempheaders ) ) {
1587
+ // Iterate through the raw headers
1588
+ foreach ( (array) $tempheaders as $header ) {
1589
+ if ( strpos($header, ':') === false ) continue;
1590
+
1591
+ // Explode them out
1592
+ list( $name, $content ) = explode( ':', trim( $header ), 2 );
1593
+
1594
+ // Cleanup crew
1595
+ $name = trim( $name );
1596
+ $content = trim( $content );
1597
+
1598
+ switch ( strtolower( $name ) ) {
1599
+ case 'from':
1600
+ if ( strpos($content, '<' ) !== false ) {
1601
+ // So... making my life hard again?
1602
+ $from_name = substr( $content, 0, strpos( $content, '<' ) - 1 );
1603
+ $from_name = str_replace( '"', '', $from_name );
1604
+ $from_name = trim( $from_name );
1605
+
1606
+ $from_email = substr( $content, strpos( $content, '<' ) + 1 );
1607
+ $from_email = str_replace( '>', '', $from_email );
1608
+ $from_email = trim( $from_email );
1609
+ } else {
1610
+ $from_name = '';
1611
+ $from_email = trim( $content );
1612
+ }
1613
+ $message['from_email'] = $from_email;
1614
+ $message['from_name'] = $from_name;
1615
+ break;
1616
+
1617
+ case 'bcc':
1618
+ // Note: Mandrill's API only accept one BCC address. The other addresses supplied will be silently discarted
1619
+ $bcc = array_merge( (array) $bcc, explode( ',', $content ) );
1620
+
1621
+ $message['bcc_address'] = $bcc[0];
1622
+ break;
1623
+
1624
+ case 'reply-to':
1625
+ $message['headers'][trim( $name )] = trim( $content );
1626
+ break;
1627
+
1628
+ default:
1629
+ if ( substr($name,0,2) == 'x-' ) {
1630
+ $message['headers'][trim( $name )] = trim( $content );
1631
+ }
1632
+ break;
1633
+ }
1634
+ }
1635
+ }
1636
+ }
1637
+
1638
+ // Checking the To: field
1639
+ if( !is_array($message['to']) ) $message['to'] = explode(',', $message['to']);
1640
+
1641
+ $processed_to = array();
1642
+ foreach ( $message['to'] as $email ) {
1643
+ $processed_to[] = array( 'email' => $email );
1644
+ }
1645
+ $message['to'] = $processed_to;
1646
+
1647
+ // Checking the From: field
1648
+ if ( empty($message['from_email']) ) $message['from_email'] = self::getFromEmail();
1649
+ if ( empty($message['from_name'] ) ) $message['from_name'] = self::getFromName();
1650
+
1651
+ list($dummy,$domain) = explode('@', $message['from_email']);
1652
+ if ( !self::isDomainEnabled( $domain ) )
1653
+ throw new Exception('The domain of the email you provided has not been verified by Mandrill.');
1654
+
1655
+ // Chechking the tags.
1656
+ $message['tags'] = self::findTags($tags);
1657
+
1658
+ // Checking the attachments
1659
+ $message['attachments'] = self::processAttachments($message['attachments']);
1660
+
1661
+ // Default values for other parameters
1662
+ $message['auto_text'] = true;
1663
+ $message['track_opens'] = $track_opens;
1664
+ $message['track_clicks']= $track_clicks;
1665
+
1666
+ // Common transformations for the HTML part
1667
+ $message['html'] = nl2br($message['html']);
1668
+
1669
+ // Defining template to use
1670
+
1671
+ $template = '';
1672
+ // If user specified a given template, check if it is valid for this Mandrill account
1673
+ if ( !empty($template_name) && self::isTemplateValid($template_name) ) {
1674
+ $template = $template_name;
1675
+ } else {
1676
+ $template = self::getTemplate(); // If no template was specified or the specified was invalid, use the general one.
1677
+ }
1678
+
1679
+ if ( $template ) {
1680
+ $template_content = array( array('name' => 'main', 'content' => $message['html']) );
1681
+
1682
+ $message['html'] = '';
1683
+ $message['template']['name'] = $template;
1684
+ $message['template']['content'] = $template_content;
1685
+ }
1686
+
1687
+ // Letting the user filter/change the message payload
1688
+ $message = apply_filters('mandrill_payload', $message);
1689
+
1690
+ // Setting the tags property correctly to be received by the Mandrill's API
1691
+ if ( !is_array($message['tags']['user']) ) $message['tags']['user'] = array();
1692
+ if ( !is_array($message['tags']['general']) ) $message['tags']['general'] = array();
1693
+ if ( !is_array($message['tags']['automatic']) ) $message['tags']['automatic'] = array();
1694
+
1695
+ $message['tags'] = array_merge( $message['tags']['user'], $message['tags']['general'], $message['tags']['automatic'] );
1696
+
1697
+ // Sending the message
1698
+ if ( empty($message['template']) || empty($message['template']['name']) || empty($message['template']['content']) ) {
1699
+ return self::$mandrill->messages_send($message);
1700
+ } else {
1701
+ $template = $message['template']['name'];
1702
+ $template_content = $message['template']['content'];
1703
+ unset($message['template']);
1704
+
1705
+ return self::$mandrill->messages_send_template($template, $template_content, $message);
1706
+ }
1707
+
1708
+ } catch ( Exception $e) {
1709
+ return new WP_Error( $e->getMessage() );
1710
+ }
1711
+ }
1712
+
1713
+ static function processAttachments($attachments) {
1714
+ if ( !is_array($attachments) )
1715
+ $attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
1716
+
1717
+ foreach ( $attachments as $index => $attachment ) {
1718
+ try {
1719
+ $attachments[$index] = Mandrill::getAttachmentStruct($attachment);
1720
+ } catch ( Exception $e ) {
1721
+ return new WP_Error( $e->getMessage() );
1722
+ }
1723
+ }
1724
+
1725
+ return $attachments;
1726
+ }
1727
+
1728
+ }
1729
+ ?>
wpmandrill.php CHANGED
@@ -606,6 +606,10 @@ jQuery(document).bind( 'ready', function() {
606
  $result[$email['status']]++;
607
  }
608
 
 
 
 
 
609
  add_settings_error('email-to', 'email-to', sprintf(__('Test executed: %d emails sent, %d emails queued and %d emails rejected', self::WPDOMAIN), $result['sent'],$result['queue'],$result['rejected']), $result['sent'] ? 'updated' : 'error' );
610
  }
611
  }
606
  $result[$email['status']]++;
607
  }
608
 
609
+ if ( !isset($result['sent']) ) $result['sent'] = 0;
610
+ if ( !isset($result['queue']) ) $result['queue'] = 0;
611
+ if ( !isset($result['rejected']) ) $result['rejected'] = 0;
612
+
613
  add_settings_error('email-to', 'email-to', sprintf(__('Test executed: %d emails sent, %d emails queued and %d emails rejected', self::WPDOMAIN), $result['sent'],$result['queue'],$result['rejected']), $result['sent'] ? 'updated' : 'error' );
614
  }
615
  }